0022A ("Power State Coordination Interface System Software on
ARM processors").
-config LOCAL_TIMERS
- bool "Use local timer interrupts"
- depends on SMP
- default y
- help
- Enable support for local timers on SMP platforms, rather then the
- legacy IPI broadcast method. Local timers allows the system
- accounting to be spread across the timer interval, preventing a
- "thundering herd" at every timer tick.
-
# The GPIO number here must be sorted by descending number. In case of
# a multiplatform kernel, we just want the highest value required by the
# selected platforms.
+++ /dev/null
-/*
- * arch/arm/include/asm/localtimer.h
- *
- * Copyright (C) 2004-2005 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARM_LOCALTIMER_H
-#define __ASM_ARM_LOCALTIMER_H
-
-#include <linux/errno.h>
-
-struct clock_event_device;
-
-struct local_timer_ops {
- int (*setup)(struct clock_event_device *);
- void (*stop)(struct clock_event_device *);
-};
-
-#ifdef CONFIG_LOCAL_TIMERS
-/*
- * Register a local timer driver
- */
-int local_timer_register(struct local_timer_ops *);
-#else
-static inline int local_timer_register(struct local_timer_ops *ops)
-{
- return -ENXIO;
-}
-#endif
-
-#endif
#include <asm/sections.h>
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
-#include <asm/localtimer.h>
#include <asm/smp_plat.h>
#include <asm/virt.h>
#include <asm/mach/arch.h>
}
#ifdef CONFIG_HOTPLUG_CPU
-static void percpu_timer_stop(void);
-
static int platform_cpu_kill(unsigned int cpu)
{
if (smp_ops.cpu_kill)
*/
migrate_irqs();
- /*
- * Stop the local timer for this CPU.
- */
- percpu_timer_stop();
-
/*
* Flush user cache and TLB mappings, and then remove this CPU
* from the vm mask set of all processes.
store_cpu_topology(cpuid);
}
-static void percpu_timer_setup(void);
-
/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
set_cpu_online(cpu, true);
complete(&cpu_running);
- /*
- * Setup the percpu timer for this CPU.
- */
- percpu_timer_setup();
-
local_irq_enable();
local_fiq_enable();
if (max_cpus > ncores)
max_cpus = ncores;
if (ncores > 1 && max_cpus) {
- /*
- * Enable the local timer or broadcast device for the
- * boot CPU, but only if we have more than one CPU.
- */
- percpu_timer_setup();
-
/*
* Initialise the present map, which describes the set of CPUs
* actually populated at the present time. A platform should
return sum;
}
-/*
- * Timer (local or broadcast) support
- */
-static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
-
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
void tick_broadcast(const struct cpumask *mask)
{
}
#endif
-static struct local_timer_ops *lt_ops;
-
-#ifdef CONFIG_LOCAL_TIMERS
-int local_timer_register(struct local_timer_ops *ops)
-{
- if (!is_smp() || !setup_max_cpus)
- return -ENXIO;
-
- if (lt_ops)
- return -EBUSY;
-
- lt_ops = ops;
- return 0;
-}
-#endif
-
-static void __cpuinit percpu_timer_setup(void)
-{
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
-
- evt->cpumask = cpumask_of(cpu);
-
- if (lt_ops)
- lt_ops->setup(evt);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * The generic clock events code purposely does not stop the local timer
- * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
- * manually here.
- */
-static void percpu_timer_stop(void)
-{
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
-
- if (lt_ops)
- lt_ops->stop(evt);
-}
-#endif
-
static DEFINE_RAW_SPINLOCK(stop_lock);
/*