diff options
author | Andy Green <andy.green@linaro.org> | 2012-04-25 14:26:04 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-04-25 14:26:04 +0800 |
commit | 1456e06c1c55e607395a3048d0da28db6f8ae314 (patch) | |
tree | c7f1608fe1c9700285b8890ca090b055527b0aa5 | |
parent | 7ad0c883cd8a3be6a9d468e8b2491d336a569088 (diff) |
debug lumptilt-3.4-omap5-eng-4
Signed-off-by: Andy Green <andy.green@linaro.org>
-rw-r--r-- | arch/arm/Kconfig | 7 | ||||
-rw-r--r-- | arch/arm/include/asm/localtimer.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/smp_twd.h | 15 | ||||
-rw-r--r-- | arch/arm/kernel/arch_timer.c | 5 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 36 | ||||
-rw-r--r-- | arch/arm/kernel/smp_twd.c | 102 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 45 |
8 files changed, 24 insertions, 193 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d5042f9f3ad..a4422262328 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1583,10 +1583,6 @@ config HAVE_ARM_TWD help This options enables support for the ARM timer and watchdog unit -config ARM_SMP_TWD - bool - select HAVE_ARM_TWD if SMP - choice prompt "Memory split" default VMSPLIT_3G @@ -1625,8 +1621,9 @@ config HOTPLUG_CPU config LOCAL_TIMERS bool "Use local timer interrupts" - depends on SMP #&& !ARM_SMP_TWD + depends on SMP default y + select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT) help Enable support for local timers on SMP platforms, rather then the legacy IPI broadcast method. Local timers allows the system diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index 6d69fd2b559..f77ffc1eb0c 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -20,12 +20,6 @@ struct local_timer_ops { }; #ifdef CONFIG_LOCAL_TIMERS - -/* - * Stop the local timer - */ -void local_timer_stop(struct clock_event_device *); - /* * Register a local timer driver */ diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index c9df3d2746d..0f01f4677bd 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -20,9 +20,6 @@ #include <linux/ioport.h> -struct clock_event_device; -struct resource; - struct twd_local_timer { struct resource res[2]; }; @@ -44,17 +41,5 @@ static inline void twd_local_timer_of_register(void) { } #endif -//int __cpuinit twd_timer_setup(struct clock_event_device *); -//void twd_timer_stop(struct clock_event_device *); -struct resource; - -#ifdef CONFIG_HAVE_ARM_TWD -int twd_timer_register(struct resource *res, int res_nr); -#else -static inline int twd_timer_register(struct resource *res, int res_nr) -{ - return 0; -} -#endif #endif diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index d27cfc3f8b9..a2df492a938 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -130,20 +130,17 @@ static int arch_timer_set_next_event(unsigned long evt, static void __cpuinit arch_timer_setup(void *data) { - extern void smp_timer_broadcast(const struct cpumask *mask); struct clock_event_device *clk = data; /* Be safe... */ arch_timer_stop(); - clk->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_C3STOP; + clk->features = CLOCK_EVT_FEAT_ONESHOT; clk->name = "arch_sys_timer"; clk->rating = 450; clk->set_mode = arch_timer_set_mode; clk->set_next_event = arch_timer_set_next_event; clk->irq = arch_timer_ppi; clk->cpumask = cpumask_of(smp_processor_id()); - clk->broadcast = smp_timer_broadcast; clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index f401c3870fa..ac606c76a65 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -124,6 +124,7 @@ int __cpuinit __cpu_up(unsigned int cpu) } #ifdef CONFIG_HOTPLUG_CPU +static void percpu_timer_stop(void); /* * __cpu_disable runs on the processor to be shutdown. @@ -150,6 +151,11 @@ int __cpu_disable(void) 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. */ @@ -237,7 +243,6 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) } static void percpu_timer_setup(void); -static void broadcast_timer_setup(void); /* * This is the secondary CPU boot entry. We're using this CPUs @@ -288,10 +293,9 @@ asmlinkage void __cpuinit secondary_start_kernel(void) complete(&cpu_running); /* - * Setup the broadcast timer for this CPU. + * Setup the percpu timer for this CPU. */ - broadcast_timer_setup(); - + percpu_timer_setup(); local_irq_enable(); local_fiq_enable(); @@ -339,10 +343,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) max_cpus = ncores; if (ncores > 1 && max_cpus) { /* - * Enable the broadcast device for the boot CPU, but - * only if we have more than one CPU. + * Enable the local timer or broadcast device for the + * boot CPU, but only if we have more than one CPU. */ - broadcast_timer_setup(); + percpu_timer_setup(); /* * Initialise the present map, which describes the set of CPUs @@ -414,7 +418,7 @@ u64 smp_irq_stat_cpu(unsigned int cpu) } /* - * Broadcast timer support + * Timer (local or broadcast) support */ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); @@ -425,7 +429,7 @@ static void ipi_timer(void) } #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST -void smp_timer_broadcast(const struct cpumask *mask) +static void smp_timer_broadcast(const struct cpumask *mask) { smp_cross_call(mask, IPI_TIMER); } @@ -433,17 +437,13 @@ void smp_timer_broadcast(const struct cpumask *mask) #define smp_timer_broadcast NULL #endif -#if !(defined(CONFIG_ARM_SMP_TWD) || defined(CONFIG_ARM_ARCH_TIMER)) static void broadcast_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { } -static void __cpuinit broadcast_timer_setup(void) +static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) { - unsigned int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - evt->name = "dummy_timer"; evt->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC | @@ -451,15 +451,9 @@ static void __cpuinit broadcast_timer_setup(void) evt->rating = 400; evt->mult = 1; evt->set_mode = broadcast_timer_set_mode; - evt->cpumask = cpumask_of(cpu); - evt->broadcast = smp_timer_broadcast; clockevents_register_device(evt); } -#else -static void __cpuinit broadcast_timer_setup(void) -{} -#endif static struct local_timer_ops *lt_ops; @@ -483,7 +477,7 @@ static void __cpuinit percpu_timer_setup(void) evt->broadcast = smp_timer_broadcast; if (!lt_ops || lt_ops->setup(evt)) - broadcast_timer_setup(); + broadcast_timer_setup(evt); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 46a3ede5e09..53aa9a91d16 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -16,17 +16,16 @@ #include <linux/device.h> #include <linux/err.h> #include <linux/smp.h> -#include <linux/cpu.h> #include <linux/jiffies.h> #include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/of_irq.h> #include <linux/of_address.h> -#include <linux/interrupt.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> +#include <asm/hardware/gic.h> /* set up by the platform code */ static void __iomem *twd_base; @@ -34,8 +33,6 @@ static void __iomem *twd_base; static struct clk *twd_clk; static unsigned long twd_timer_rate; static struct clock_event_device __percpu **twd_evt; - -static struct clock_event_device __percpu **twd_evt; static int twd_ppi; static void twd_set_mode(enum clock_event_mode mode, @@ -91,13 +88,12 @@ static int twd_timer_ack(void) return 0; } -#if 1 + static void twd_timer_stop(struct clock_event_device *clk) { twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk); disable_percpu_irq(clk->irq); } -#endif #ifdef CONFIG_CPU_FREQ @@ -186,7 +182,7 @@ static void __cpuinit twd_calibrate_rate(void) static irqreturn_t twd_handler(int irq, void *dev_id) { - struct clock_event_device *evt = dev_id; + struct clock_event_device *evt = *(struct clock_event_device **)dev_id; if (twd_timer_ack()) { evt->event_handler(evt); @@ -225,8 +221,6 @@ static struct clk *twd_get_clock(void) return clk; } -extern void smp_timer_broadcast(const struct cpumask *mask); - /* * Setup the local clock events for a CPU. */ @@ -247,15 +241,10 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; - clk->rating = 450; /* Make sure this is higher than broadcast */ + clk->rating = 350; clk->set_mode = twd_set_mode; clk->set_next_event = twd_set_next_event; clk->irq = twd_ppi; - clk->shift = 20; - clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift); - clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); - clk->min_delta_ns = clockevent_delta2ns(0xf, clk); - clk->broadcast = smp_timer_broadcast; this_cpu_clk = __this_cpu_ptr(twd_evt); *this_cpu_clk = clk; @@ -355,86 +344,3 @@ out: WARN(err, "twd_local_timer_of_register failed (%d)\n", err); } #endif -static struct clock_event_device __percpu *twd_clock_event; -static int twd_ppi; - -static void __cpuinit twd_setup(void *data) -{ - struct clock_event_device *clk = data; - clk->cpumask = cpumask_of(smp_processor_id()); - clk->irq = twd_ppi; - twd_timer_setup(clk); -} - -static void __cpuinit twd_teardown(void *data) -{ - struct clock_event_device *clk = data; - twd_timer_stop(clk); -} - -static int __cpuinit twd_cpu_notify(struct notifier_block *self, - unsigned long action, void *data) -{ - int cpu = (int)data; - struct clock_event_device *clk = per_cpu_ptr(twd_clock_event, cpu); - - switch (action) { - case CPU_STARTING: - case CPU_STARTING_FROZEN: - smp_call_function_single(cpu, twd_setup, clk, 1); - break; - - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - smp_call_function_single(cpu, twd_teardown, clk, 1); - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata twd_cpu_nb = { - .notifier_call = twd_cpu_notify, -}; - -int __init twd_timer_register(struct resource *res, int res_nr) -{ - struct clock_event_device *clk; - int err; - - if (res_nr != 2 || res[1].start < 0) - return -EINVAL; - - if (twd_base) - return -EBUSY; - - twd_ppi = res[1].start; - twd_base = ioremap(res[0].start, resource_size(&res[0])); - twd_clock_event = alloc_percpu(struct clock_event_device); - if (!twd_base || !twd_clock_event) { - err = -ENOMEM; - goto out_free; - } - - err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_clock_event); - if (err) { - pr_err("twd: can't register interrupt %d (%d)\n", - twd_ppi, err); - goto out_free; - } - - /* Immediately configure the timer on the boot CPU */ - clk = per_cpu_ptr(twd_clock_event, smp_processor_id()); - twd_setup(clk); - - register_cpu_notifier(&twd_cpu_nb); - - return 0; - -out_free: - iounmap(twd_base); - twd_base = NULL; - free_percpu(twd_clock_event); - - return err; -} diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 3ae992a1858..2b52699f585 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -47,7 +47,6 @@ config ARCH_OMAP4 select ARM_GIC select HAVE_SMP select LOCAL_TIMERS if SMP - select ARM_SMP_TWD select PL310_ERRATA_588369 select PL310_ERRATA_727915 select ARM_ERRATA_720789 diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 49c449582ea..9df8bb155b4 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -339,45 +339,6 @@ OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE, OMAP_SYS_TIMER(3_secure) #endif -#ifdef CONFIG_ARM_SMP_TWD -static struct resource omap4_twd_resources[] __initdata = { - { - .start = OMAP44XX_LOCAL_TWD_BASE, - .end = OMAP44XX_LOCAL_TWD_BASE + 0x10, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP44XX_IRQ_LOCALTIMER, - .end = OMAP44XX_IRQ_LOCALTIMER, - .flags = IORESOURCE_IRQ, - }, -}; - -static void __init omap4_twd_init(void) -{ - int err; - - /* Local timers are not supprted on OMAP4430 ES1.0 */ - if (omap_rev() == OMAP4430_REV_ES1_0) - return; - - err = twd_timer_register(omap4_twd_resources, - ARRAY_SIZE(omap4_twd_resources)); - if (err) - pr_err("twd_timer_register failed %d\n", err); -} - -#else -#define omap4_twd_init NULL -#endif - -/* main twd code wants to see this, despite it is deprecated now */ - -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - return 0; -} - #ifdef CONFIG_ARCH_OMAP4 #ifdef CONFIG_LOCAL_TIMERS static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, @@ -389,7 +350,6 @@ static void __init omap4_timer_init(void) { omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE); - #ifdef CONFIG_LOCAL_TIMERS /* Local timers are not supprted on OMAP4430 ES1.0 */ if (omap_rev() != OMAP4430_REV_ES1_0) { @@ -400,10 +360,9 @@ static void __init omap4_timer_init(void) pr_err("twd_local_timer_register failed %d\n", err); } #endif - late_time_init = omap4_twd_init; } OMAP_SYS_TIMER(4) -#endif /* CONFIG_ARCH_OMAP4 */ +#endif #ifdef CONFIG_ARM_ARCH_TIMER static struct resource arch_timer_resources[] = { @@ -442,7 +401,7 @@ static void __init omap5_timer_init(void) late_time_init = arch_timer_init; } OMAP_SYS_TIMER(5) -#endif /* CONFIG_ARCH_OMAP5 */ +#endif /** * omap2_dm_timer_set_src - change the timer input clock source |