From: Stephen Boyd <sboyd@codeaurora.org> To: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Barry Song <baohua.song@csr.com> Subject: [PATCHv3 06/10] ARM: PRIMA2: Divorce timer-marco from local timer API Date: Wed, 13 Mar 2013 11:17:52 -0700 [thread overview] Message-ID: <1363198676-30417-7-git-send-email-sboyd@codeaurora.org> (raw) In-Reply-To: <1363198676-30417-1-git-send-email-sboyd@codeaurora.org> Separate the marco local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource. Cc: Barry Song <baohua.song@csr.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> --- arch/arm/mach-prima2/timer-marco.c | 98 ++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-prima2/timer-marco.c b/arch/arm/mach-prima2/timer-marco.c index f4eea2e..d54aac2 100644 --- a/arch/arm/mach-prima2/timer-marco.c +++ b/arch/arm/mach-prima2/timer-marco.c @@ -10,6 +10,7 @@ #include <linux/interrupt.h> #include <linux/clockchips.h> #include <linux/clocksource.h> +#include <linux/cpu.h> #include <linux/bitops.h> #include <linux/irq.h> #include <linux/clk.h> @@ -18,7 +19,6 @@ #include <linux/of_irq.h> #include <linux/of_address.h> #include <asm/sched_clock.h> -#include <asm/localtimer.h> #include <asm/mach/time.h> #include "common.h" @@ -154,13 +154,7 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); } -static struct clock_event_device sirfsoc_clockevent = { - .name = "sirfsoc_clockevent", - .rating = 200, - .features = CLOCK_EVT_FEAT_ONESHOT, - .set_mode = sirfsoc_timer_set_mode, - .set_next_event = sirfsoc_timer_set_next_event, -}; +static struct clock_event_device __percpu *sirfsoc_clockevent; static struct clocksource sirfsoc_clocksource = { .name = "sirfsoc_clocksource", @@ -176,11 +170,8 @@ static struct irqaction sirfsoc_timer_irq = { .name = "sirfsoc_timer0", .flags = IRQF_TIMER | IRQF_NOBALANCING, .handler = sirfsoc_timer_interrupt, - .dev_id = &sirfsoc_clockevent, }; -#ifdef CONFIG_LOCAL_TIMERS - static struct irqaction sirfsoc_timer1_irq = { .name = "sirfsoc_timer1", .flags = IRQF_TIMER | IRQF_NOBALANCING, @@ -189,56 +180,75 @@ static struct irqaction sirfsoc_timer1_irq = { static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce) { - /* Use existing clock_event for cpu 0 */ - if (!smp_processor_id()) - return 0; + int cpu = smp_processor_id(); + struct irqaction *action; + + if (cpu == 0) + action = &sirfsoc_timer_irq; + else + action = &sirfsoc_timer1_irq; - ce->irq = sirfsoc_timer1_irq.irq; + ce->irq = action->irq; ce->name = "local_timer"; - ce->features = sirfsoc_clockevent.features; - ce->rating = sirfsoc_clockevent.rating; + ce->features = CLOCK_EVT_FEAT_ONESHOT; + ce->rating = 200; ce->set_mode = sirfsoc_timer_set_mode; ce->set_next_event = sirfsoc_timer_set_next_event; - ce->shift = sirfsoc_clockevent.shift; - ce->mult = sirfsoc_clockevent.mult; - ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns; - ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns; + clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60); + ce->max_delta_ns = clockevent_delta2ns(-2, ce); + ce->min_delta_ns = clockevent_delta2ns(2, ce); + ce->cpumask = cpumask_of(cpu); - sirfsoc_timer1_irq.dev_id = ce; - BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq)); - irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1)); + action->dev_id = ce; + BUG_ON(setup_irq(ce->irq, action)); + irq_set_affinity(action->irq, cpumask_of(cpu)); clockevents_register_device(ce); return 0; } -static void sirfsoc_local_timer_stop(struct clock_event_device *ce) +static void __cpuinit sirfsoc_local_timer_stop(struct clock_event_device *ce) { + int cpu = smp_processor_id(); + sirfsoc_timer_count_disable(1); - remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); + if (cpu == 0) + remove_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq); + else + remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); +} + +static int __cpuinit sirfsoc_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + struct clock_event_device *evt = this_cpu_ptr(sirfsoc_clockevent); + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + sirfsoc_local_timer_setup(evt); + break; + case CPU_DYING: + sirfsoc_local_timer_stop(evt); + break; + } + + return NOTIFY_OK; } -static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = { - .setup = sirfsoc_local_timer_setup, - .stop = sirfsoc_local_timer_stop, +static struct notifier_block sirfsoc_cpu_nb __cpuinitdata = { + .notifier_call = sirfsoc_cpu_notify, }; -#endif /* CONFIG_LOCAL_TIMERS */ static void __init sirfsoc_clockevent_init(void) { - clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60); - - sirfsoc_clockevent.max_delta_ns = - clockevent_delta2ns(-2, &sirfsoc_clockevent); - sirfsoc_clockevent.min_delta_ns = - clockevent_delta2ns(2, &sirfsoc_clockevent); - - sirfsoc_clockevent.cpumask = cpumask_of(0); - clockevents_register_device(&sirfsoc_clockevent); -#ifdef CONFIG_LOCAL_TIMERS - local_timer_register(&sirfsoc_local_timer_ops); -#endif + sirfsoc_clockevent = alloc_percpu(struct clock_event_device); + BUG_ON(!sirfsoc_clockevent); + + BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb)); + + /* Immediately configure the timer on the boot CPU */ + sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent)); } /* initialize the kernel jiffy timer source */ @@ -281,8 +291,6 @@ void __init sirfsoc_marco_timer_init(void) BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); - BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); - sirfsoc_clockevent_init(); } @@ -306,11 +314,9 @@ static void __init sirfsoc_of_timer_map(void) if (!sirfsoc_timer_irq.irq) panic("No irq passed for timer0 via DT\n"); -#ifdef CONFIG_LOCAL_TIMERS sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); if (!sirfsoc_timer1_irq.irq) panic("No irq passed for timer1 via DT\n"); -#endif of_node_put(np); } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
WARNING: multiple messages have this Message-ID (diff)
From: sboyd@codeaurora.org (Stephen Boyd) To: linux-arm-kernel@lists.infradead.org Subject: [PATCHv3 06/10] ARM: PRIMA2: Divorce timer-marco from local timer API Date: Wed, 13 Mar 2013 11:17:52 -0700 [thread overview] Message-ID: <1363198676-30417-7-git-send-email-sboyd@codeaurora.org> (raw) In-Reply-To: <1363198676-30417-1-git-send-email-sboyd@codeaurora.org> Separate the marco local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource. Cc: Barry Song <baohua.song@csr.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> --- arch/arm/mach-prima2/timer-marco.c | 98 ++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-prima2/timer-marco.c b/arch/arm/mach-prima2/timer-marco.c index f4eea2e..d54aac2 100644 --- a/arch/arm/mach-prima2/timer-marco.c +++ b/arch/arm/mach-prima2/timer-marco.c @@ -10,6 +10,7 @@ #include <linux/interrupt.h> #include <linux/clockchips.h> #include <linux/clocksource.h> +#include <linux/cpu.h> #include <linux/bitops.h> #include <linux/irq.h> #include <linux/clk.h> @@ -18,7 +19,6 @@ #include <linux/of_irq.h> #include <linux/of_address.h> #include <asm/sched_clock.h> -#include <asm/localtimer.h> #include <asm/mach/time.h> #include "common.h" @@ -154,13 +154,7 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); } -static struct clock_event_device sirfsoc_clockevent = { - .name = "sirfsoc_clockevent", - .rating = 200, - .features = CLOCK_EVT_FEAT_ONESHOT, - .set_mode = sirfsoc_timer_set_mode, - .set_next_event = sirfsoc_timer_set_next_event, -}; +static struct clock_event_device __percpu *sirfsoc_clockevent; static struct clocksource sirfsoc_clocksource = { .name = "sirfsoc_clocksource", @@ -176,11 +170,8 @@ static struct irqaction sirfsoc_timer_irq = { .name = "sirfsoc_timer0", .flags = IRQF_TIMER | IRQF_NOBALANCING, .handler = sirfsoc_timer_interrupt, - .dev_id = &sirfsoc_clockevent, }; -#ifdef CONFIG_LOCAL_TIMERS - static struct irqaction sirfsoc_timer1_irq = { .name = "sirfsoc_timer1", .flags = IRQF_TIMER | IRQF_NOBALANCING, @@ -189,56 +180,75 @@ static struct irqaction sirfsoc_timer1_irq = { static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce) { - /* Use existing clock_event for cpu 0 */ - if (!smp_processor_id()) - return 0; + int cpu = smp_processor_id(); + struct irqaction *action; + + if (cpu == 0) + action = &sirfsoc_timer_irq; + else + action = &sirfsoc_timer1_irq; - ce->irq = sirfsoc_timer1_irq.irq; + ce->irq = action->irq; ce->name = "local_timer"; - ce->features = sirfsoc_clockevent.features; - ce->rating = sirfsoc_clockevent.rating; + ce->features = CLOCK_EVT_FEAT_ONESHOT; + ce->rating = 200; ce->set_mode = sirfsoc_timer_set_mode; ce->set_next_event = sirfsoc_timer_set_next_event; - ce->shift = sirfsoc_clockevent.shift; - ce->mult = sirfsoc_clockevent.mult; - ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns; - ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns; + clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60); + ce->max_delta_ns = clockevent_delta2ns(-2, ce); + ce->min_delta_ns = clockevent_delta2ns(2, ce); + ce->cpumask = cpumask_of(cpu); - sirfsoc_timer1_irq.dev_id = ce; - BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq)); - irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1)); + action->dev_id = ce; + BUG_ON(setup_irq(ce->irq, action)); + irq_set_affinity(action->irq, cpumask_of(cpu)); clockevents_register_device(ce); return 0; } -static void sirfsoc_local_timer_stop(struct clock_event_device *ce) +static void __cpuinit sirfsoc_local_timer_stop(struct clock_event_device *ce) { + int cpu = smp_processor_id(); + sirfsoc_timer_count_disable(1); - remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); + if (cpu == 0) + remove_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq); + else + remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); +} + +static int __cpuinit sirfsoc_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + struct clock_event_device *evt = this_cpu_ptr(sirfsoc_clockevent); + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + sirfsoc_local_timer_setup(evt); + break; + case CPU_DYING: + sirfsoc_local_timer_stop(evt); + break; + } + + return NOTIFY_OK; } -static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = { - .setup = sirfsoc_local_timer_setup, - .stop = sirfsoc_local_timer_stop, +static struct notifier_block sirfsoc_cpu_nb __cpuinitdata = { + .notifier_call = sirfsoc_cpu_notify, }; -#endif /* CONFIG_LOCAL_TIMERS */ static void __init sirfsoc_clockevent_init(void) { - clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60); - - sirfsoc_clockevent.max_delta_ns = - clockevent_delta2ns(-2, &sirfsoc_clockevent); - sirfsoc_clockevent.min_delta_ns = - clockevent_delta2ns(2, &sirfsoc_clockevent); - - sirfsoc_clockevent.cpumask = cpumask_of(0); - clockevents_register_device(&sirfsoc_clockevent); -#ifdef CONFIG_LOCAL_TIMERS - local_timer_register(&sirfsoc_local_timer_ops); -#endif + sirfsoc_clockevent = alloc_percpu(struct clock_event_device); + BUG_ON(!sirfsoc_clockevent); + + BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb)); + + /* Immediately configure the timer on the boot CPU */ + sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent)); } /* initialize the kernel jiffy timer source */ @@ -281,8 +291,6 @@ void __init sirfsoc_marco_timer_init(void) BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); - BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); - sirfsoc_clockevent_init(); } @@ -306,11 +314,9 @@ static void __init sirfsoc_of_timer_map(void) if (!sirfsoc_timer_irq.irq) panic("No irq passed for timer0 via DT\n"); -#ifdef CONFIG_LOCAL_TIMERS sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); if (!sirfsoc_timer1_irq.irq) panic("No irq passed for timer1 via DT\n"); -#endif of_node_put(np); } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
next prev parent reply other threads:[~2013-03-13 18:17 UTC|newest] Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-03-13 18:17 [PATCHv3 00/10] Remove ARM local timer API Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` [PATCHv3 01/10] clocksource: add generic dummy timer driver Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-21 18:09 ` Mark Rutland 2013-03-21 18:09 ` Mark Rutland 2013-03-21 18:09 ` Mark Rutland 2013-03-21 18:13 ` Stephen Boyd 2013-03-21 18:13 ` Stephen Boyd 2013-03-21 18:13 ` Stephen Boyd 2013-03-22 18:03 ` Mark Rutland 2013-03-22 18:03 ` Mark Rutland 2013-03-22 18:03 ` Mark Rutland 2013-03-25 16:49 ` Stephen Boyd 2013-03-25 16:49 ` Stephen Boyd 2013-03-25 16:49 ` Stephen Boyd 2013-03-25 18:00 ` Mark Rutland 2013-03-25 18:00 ` Mark Rutland 2013-03-25 18:00 ` Mark Rutland 2013-03-25 20:47 ` Thomas Gleixner 2013-03-25 20:47 ` Thomas Gleixner 2013-03-25 20:47 ` Thomas Gleixner 2013-03-26 15:26 ` Mark Rutland 2013-03-26 15:26 ` Mark Rutland 2013-03-26 15:26 ` Mark Rutland 2013-03-26 2:14 ` Stephen Boyd 2013-03-26 2:14 ` Stephen Boyd 2013-03-26 2:14 ` Stephen Boyd 2013-03-26 11:28 ` Mark Rutland 2013-03-26 11:28 ` Mark Rutland 2013-03-26 11:28 ` Mark Rutland 2013-04-05 1:46 ` Stephen Boyd 2013-04-05 1:46 ` Stephen Boyd 2013-04-05 1:46 ` Stephen Boyd 2013-03-13 18:17 ` [PATCHv3 02/10] ARM: smp: Remove duplicate dummy timer implementation Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` [PATCHv3 03/10] ARM: smp_twd: Divorce smp_twd from local timer API Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-28 15:22 ` Mark Rutland 2013-03-28 15:22 ` Mark Rutland 2013-03-28 15:22 ` Mark Rutland 2013-03-28 20:09 ` Stephen Boyd 2013-03-28 20:09 ` Stephen Boyd 2013-03-28 20:09 ` Stephen Boyd 2013-04-02 8:41 ` Mark Rutland 2013-04-02 8:41 ` Mark Rutland 2013-04-02 8:41 ` Mark Rutland 2013-03-13 18:17 ` [PATCHv3 04/10] ARM: OMAP2+: Divorce " Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` [PATCHv3 05/10] ARM: EXYNOS4: Divorce mct " Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd [this message] 2013-03-13 18:17 ` [PATCHv3 06/10] ARM: PRIMA2: Divorce timer-marco " Stephen Boyd 2013-03-13 18:17 ` [PATCHv3 07/10] ARM: msm: Divorce msm_timer " Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-13 18:17 ` [PATCHv3 08/10] clocksource: time-armada-370-xp: Fix sparse warning Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-20 17:06 ` Gregory CLEMENT 2013-03-20 17:06 ` Gregory CLEMENT 2013-03-13 18:17 ` [PATCHv3 09/10] clocksource: time-armada-370-xp: Divorce from local timer API Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd 2013-03-20 17:09 ` Gregory CLEMENT 2013-03-20 17:09 ` Gregory CLEMENT 2013-03-20 17:20 ` Stephen Boyd 2013-03-20 17:20 ` Stephen Boyd 2013-03-20 17:26 ` Gregory CLEMENT 2013-03-20 17:26 ` Gregory CLEMENT 2013-03-20 17:44 ` Gregory CLEMENT 2013-03-20 17:44 ` Gregory CLEMENT 2013-03-20 18:00 ` Stephen Boyd 2013-03-20 18:00 ` Stephen Boyd 2013-03-20 17:21 ` Gregory CLEMENT 2013-03-20 17:21 ` Gregory CLEMENT 2013-03-13 18:17 ` [PATCHv3 10/10] ARM: smp: Remove " Stephen Boyd 2013-03-13 18:17 ` Stephen Boyd
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1363198676-30417-7-git-send-email-sboyd@codeaurora.org \ --to=sboyd@codeaurora.org \ --cc=baohua.song@csr.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-arm-msm@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.