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,
Daniel Walker <dwalker@fifo99.com>,
Bryan Huntsman <bryanh@codeaurora.org>
Subject: [PATCHv7 08/11] ARM: msm: Divorce msm_timer from local timer API
Date: Mon, 3 Jun 2013 13:33:59 -0700 [thread overview]
Message-ID: <1370291642-13259-9-git-send-email-sboyd@codeaurora.org> (raw)
In-Reply-To: <1370291642-13259-1-git-send-email-sboyd@codeaurora.org>
Separate the msm_timer 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.
Acked-by: David Brown <davidb@codeaurora.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>,
Cc: Daniel Walker <dwalker@fifo99.com>
Cc: Bryan Huntsman <bryanh@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
arch/arm/mach-msm/timer.c | 126 +++++++++++++++++++++++++---------------------
1 file changed, 70 insertions(+), 56 deletions(-)
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 284313f..df947aa 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -16,6 +16,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -25,7 +26,6 @@
#include <linux/of_irq.h>
#include <asm/mach/time.h>
-#include <asm/localtimer.h>
#include <asm/sched_clock.h>
#include "common.h"
@@ -49,7 +49,7 @@ static void __iomem *sts_base;
static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+ struct clock_event_device *evt = dev_id;
/* Stop the timer tick */
if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
@@ -101,18 +101,7 @@ static void msm_timer_set_mode(enum clock_event_mode mode,
writel_relaxed(ctrl, event_base + TIMER_ENABLE);
}
-static struct clock_event_device msm_clockevent = {
- .name = "gp_timer",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .rating = 200,
- .set_next_event = msm_timer_set_next_event,
- .set_mode = msm_timer_set_mode,
-};
-
-static union {
- struct clock_event_device *evt;
- struct clock_event_device * __percpu *percpu_evt;
-} msm_evt;
+static struct clock_event_device __percpu *msm_evt;
static void __iomem *source_base;
@@ -138,37 +127,65 @@ static struct clocksource msm_clocksource = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-#ifdef CONFIG_LOCAL_TIMERS
+static int msm_timer_irq;
+static int msm_timer_has_ppi;
+
static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
{
- /* Use existing clock_event for cpu 0 */
- if (!smp_processor_id())
- return 0;
-
- evt->irq = msm_clockevent.irq;
- evt->name = "local_timer";
- evt->features = msm_clockevent.features;
- evt->rating = msm_clockevent.rating;
+ int cpu = smp_processor_id();
+ int err;
+
+ evt->irq = msm_timer_irq;
+ evt->name = "msm_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = 200;
evt->set_mode = msm_timer_set_mode;
evt->set_next_event = msm_timer_set_next_event;
+ evt->cpumask = cpumask_of(cpu);
+
+ clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
+
+ if (msm_timer_has_ppi) {
+ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
+ } else {
+ err = request_irq(evt->irq, msm_timer_interrupt,
+ IRQF_TIMER | IRQF_NOBALANCING |
+ IRQF_TRIGGER_RISING, "gp_timer", evt);
+ if (err)
+ pr_err("request_irq failed\n");
+ }
- *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
- clockevents_config_and_register(evt, GPT_HZ, 4, 0xf0000000);
- enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
return 0;
}
-static void msm_local_timer_stop(struct clock_event_device *evt)
+static void __cpuinit msm_local_timer_stop(struct clock_event_device *evt)
{
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
disable_percpu_irq(evt->irq);
}
-static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
- .setup = msm_local_timer_setup,
- .stop = msm_local_timer_stop,
+static int __cpuinit msm_timer_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * Grab cpu pointer in each case to avoid spurious
+ * preemptible warnings
+ */
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ msm_local_timer_setup(this_cpu_ptr(msm_evt));
+ break;
+ case CPU_DYING:
+ msm_local_timer_stop(this_cpu_ptr(msm_evt));
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msm_timer_cpu_nb __cpuinitdata = {
+ .notifier_call = msm_timer_cpu_notify,
};
-#endif /* CONFIG_LOCAL_TIMERS */
static notrace u32 msm_sched_clock_read(void)
{
@@ -178,38 +195,35 @@ static notrace u32 msm_sched_clock_read(void)
static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
bool percpu)
{
- struct clock_event_device *ce = &msm_clockevent;
struct clocksource *cs = &msm_clocksource;
- int res;
+ int res = 0;
+
+ msm_timer_irq = irq;
+ msm_timer_has_ppi = percpu;
+
+ msm_evt = alloc_percpu(struct clock_event_device);
+ if (!msm_evt) {
+ pr_err("memory allocation failed for clockevents\n");
+ goto err;
+ }
- ce->cpumask = cpumask_of(0);
- ce->irq = irq;
+ if (percpu)
+ res = request_percpu_irq(irq, msm_timer_interrupt,
+ "gp_timer", msm_evt);
- clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff);
- if (percpu) {
- msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *);
- if (!msm_evt.percpu_evt) {
- pr_err("memory allocation failed for %s\n", ce->name);
+ if (res) {
+ pr_err("request_percpu_irq failed\n");
+ } else {
+ res = register_cpu_notifier(&msm_timer_cpu_nb);
+ if (res) {
+ free_percpu_irq(irq, msm_evt);
goto err;
}
- *__this_cpu_ptr(msm_evt.percpu_evt) = ce;
- res = request_percpu_irq(ce->irq, msm_timer_interrupt,
- ce->name, msm_evt.percpu_evt);
- if (!res) {
- enable_percpu_irq(ce->irq, IRQ_TYPE_EDGE_RISING);
-#ifdef CONFIG_LOCAL_TIMERS
- local_timer_register(&msm_local_timer_ops);
-#endif
- }
- } else {
- msm_evt.evt = ce;
- res = request_irq(ce->irq, msm_timer_interrupt,
- IRQF_TIMER | IRQF_NOBALANCING |
- IRQF_TRIGGER_RISING, ce->name, &msm_evt.evt);
+
+ /* Immediately configure the timer on the boot CPU */
+ msm_local_timer_setup(__this_cpu_ptr(msm_evt));
}
- if (res)
- pr_err("request_irq failed for %s\n", ce->name);
err:
writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
res = clocksource_register_hz(cs, dgt_hz);
--
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: [PATCHv7 08/11] ARM: msm: Divorce msm_timer from local timer API
Date: Mon, 3 Jun 2013 13:33:59 -0700 [thread overview]
Message-ID: <1370291642-13259-9-git-send-email-sboyd@codeaurora.org> (raw)
In-Reply-To: <1370291642-13259-1-git-send-email-sboyd@codeaurora.org>
Separate the msm_timer 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.
Acked-by: David Brown <davidb@codeaurora.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>,
Cc: Daniel Walker <dwalker@fifo99.com>
Cc: Bryan Huntsman <bryanh@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
arch/arm/mach-msm/timer.c | 126 +++++++++++++++++++++++++---------------------
1 file changed, 70 insertions(+), 56 deletions(-)
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 284313f..df947aa 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -16,6 +16,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -25,7 +26,6 @@
#include <linux/of_irq.h>
#include <asm/mach/time.h>
-#include <asm/localtimer.h>
#include <asm/sched_clock.h>
#include "common.h"
@@ -49,7 +49,7 @@ static void __iomem *sts_base;
static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+ struct clock_event_device *evt = dev_id;
/* Stop the timer tick */
if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
@@ -101,18 +101,7 @@ static void msm_timer_set_mode(enum clock_event_mode mode,
writel_relaxed(ctrl, event_base + TIMER_ENABLE);
}
-static struct clock_event_device msm_clockevent = {
- .name = "gp_timer",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .rating = 200,
- .set_next_event = msm_timer_set_next_event,
- .set_mode = msm_timer_set_mode,
-};
-
-static union {
- struct clock_event_device *evt;
- struct clock_event_device * __percpu *percpu_evt;
-} msm_evt;
+static struct clock_event_device __percpu *msm_evt;
static void __iomem *source_base;
@@ -138,37 +127,65 @@ static struct clocksource msm_clocksource = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-#ifdef CONFIG_LOCAL_TIMERS
+static int msm_timer_irq;
+static int msm_timer_has_ppi;
+
static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
{
- /* Use existing clock_event for cpu 0 */
- if (!smp_processor_id())
- return 0;
-
- evt->irq = msm_clockevent.irq;
- evt->name = "local_timer";
- evt->features = msm_clockevent.features;
- evt->rating = msm_clockevent.rating;
+ int cpu = smp_processor_id();
+ int err;
+
+ evt->irq = msm_timer_irq;
+ evt->name = "msm_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = 200;
evt->set_mode = msm_timer_set_mode;
evt->set_next_event = msm_timer_set_next_event;
+ evt->cpumask = cpumask_of(cpu);
+
+ clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
+
+ if (msm_timer_has_ppi) {
+ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
+ } else {
+ err = request_irq(evt->irq, msm_timer_interrupt,
+ IRQF_TIMER | IRQF_NOBALANCING |
+ IRQF_TRIGGER_RISING, "gp_timer", evt);
+ if (err)
+ pr_err("request_irq failed\n");
+ }
- *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
- clockevents_config_and_register(evt, GPT_HZ, 4, 0xf0000000);
- enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
return 0;
}
-static void msm_local_timer_stop(struct clock_event_device *evt)
+static void __cpuinit msm_local_timer_stop(struct clock_event_device *evt)
{
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
disable_percpu_irq(evt->irq);
}
-static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
- .setup = msm_local_timer_setup,
- .stop = msm_local_timer_stop,
+static int __cpuinit msm_timer_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * Grab cpu pointer in each case to avoid spurious
+ * preemptible warnings
+ */
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ msm_local_timer_setup(this_cpu_ptr(msm_evt));
+ break;
+ case CPU_DYING:
+ msm_local_timer_stop(this_cpu_ptr(msm_evt));
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msm_timer_cpu_nb __cpuinitdata = {
+ .notifier_call = msm_timer_cpu_notify,
};
-#endif /* CONFIG_LOCAL_TIMERS */
static notrace u32 msm_sched_clock_read(void)
{
@@ -178,38 +195,35 @@ static notrace u32 msm_sched_clock_read(void)
static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
bool percpu)
{
- struct clock_event_device *ce = &msm_clockevent;
struct clocksource *cs = &msm_clocksource;
- int res;
+ int res = 0;
+
+ msm_timer_irq = irq;
+ msm_timer_has_ppi = percpu;
+
+ msm_evt = alloc_percpu(struct clock_event_device);
+ if (!msm_evt) {
+ pr_err("memory allocation failed for clockevents\n");
+ goto err;
+ }
- ce->cpumask = cpumask_of(0);
- ce->irq = irq;
+ if (percpu)
+ res = request_percpu_irq(irq, msm_timer_interrupt,
+ "gp_timer", msm_evt);
- clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff);
- if (percpu) {
- msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *);
- if (!msm_evt.percpu_evt) {
- pr_err("memory allocation failed for %s\n", ce->name);
+ if (res) {
+ pr_err("request_percpu_irq failed\n");
+ } else {
+ res = register_cpu_notifier(&msm_timer_cpu_nb);
+ if (res) {
+ free_percpu_irq(irq, msm_evt);
goto err;
}
- *__this_cpu_ptr(msm_evt.percpu_evt) = ce;
- res = request_percpu_irq(ce->irq, msm_timer_interrupt,
- ce->name, msm_evt.percpu_evt);
- if (!res) {
- enable_percpu_irq(ce->irq, IRQ_TYPE_EDGE_RISING);
-#ifdef CONFIG_LOCAL_TIMERS
- local_timer_register(&msm_local_timer_ops);
-#endif
- }
- } else {
- msm_evt.evt = ce;
- res = request_irq(ce->irq, msm_timer_interrupt,
- IRQF_TIMER | IRQF_NOBALANCING |
- IRQF_TRIGGER_RISING, ce->name, &msm_evt.evt);
+
+ /* Immediately configure the timer on the boot CPU */
+ msm_local_timer_setup(__this_cpu_ptr(msm_evt));
}
- if (res)
- pr_err("request_irq failed for %s\n", ce->name);
err:
writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
res = clocksource_register_hz(cs, dgt_hz);
--
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-06-03 20:33 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-03 20:33 [PATCHv7 00/11] Remove ARM local timer API Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` [PATCHv7 01/11] clockevents: Prefer CPU local devices over global devices Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-06 15:12 ` Daniel Lezcano
2013-06-06 15:12 ` Daniel Lezcano
2013-06-06 18:04 ` Stephen Boyd
2013-06-06 18:04 ` Stephen Boyd
2013-06-06 22:30 ` Daniel Lezcano
2013-06-06 22:30 ` Daniel Lezcano
2013-06-06 22:38 ` Stephen Boyd
2013-06-06 22:38 ` Stephen Boyd
2013-06-12 21:44 ` Stephen Boyd
2013-06-12 21:44 ` Stephen Boyd
2013-06-13 9:33 ` Daniel Lezcano
2013-06-13 9:33 ` Daniel Lezcano
2013-06-13 13:15 ` Thomas Gleixner
2013-06-13 13:15 ` Thomas Gleixner
2013-06-13 18:39 ` Stephen Boyd
2013-06-13 18:39 ` Stephen Boyd
2013-06-13 20:16 ` Sören Brinkmann
2013-06-13 20:16 ` Sören Brinkmann
2013-06-13 20:16 ` Sören Brinkmann
2013-06-18 10:22 ` Mark Rutland
2013-06-18 10:22 ` Mark Rutland
2013-06-19 16:30 ` Stephen Boyd
2013-06-19 16:30 ` Stephen Boyd
2013-06-21 17:07 ` Stephen Boyd
2013-06-21 17:07 ` Stephen Boyd
2013-06-24 20:07 ` Stephen Boyd
2013-06-24 20:07 ` Stephen Boyd
2013-06-24 20:30 ` [tip:timers/core] " tip-bot for Stephen Boyd
2013-06-03 20:33 ` [PATCHv7 02/11] clocksource: add generic dummy timer driver Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-06 16:23 ` Daniel Lezcano
2013-06-06 16:23 ` Daniel Lezcano
2013-06-24 20:30 ` [tip:timers/core] clocksource: Add " tip-bot for Mark Rutland
2013-06-03 20:33 ` [PATCHv7 03/11] ARM: smp: Remove duplicate dummy timer implementation Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` [PATCHv7 04/11] ARM: smp_twd: Divorce smp_twd from local timer API Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` [PATCHv7 05/11] ARM: OMAP2+: Divorce " Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` [PATCHv7 06/11] ARM: EXYNOS4: Divorce mct " Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` [PATCHv7 07/11] ARM: PRIMA2: Divorce timer-marco " Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd
2013-06-03 20:33 ` Stephen Boyd [this message]
2013-06-03 20:33 ` [PATCHv7 08/11] ARM: msm: Divorce msm_timer " Stephen Boyd
2013-06-03 20:34 ` [PATCHv7 09/11] clocksource: time-armada-370-xp: Fix sparse warning Stephen Boyd
2013-06-03 20:34 ` Stephen Boyd
2013-06-03 20:34 ` [PATCHv7 10/11] clocksource: time-armada-370-xp: Divorce from local timer API Stephen Boyd
2013-06-03 20:34 ` Stephen Boyd
2013-06-03 20:34 ` [PATCHv7 11/11] ARM: smp: Remove " Stephen Boyd
2013-06-03 20:34 ` 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=1370291642-13259-9-git-send-email-sboyd@codeaurora.org \
--to=sboyd@codeaurora.org \
--cc=bryanh@codeaurora.org \
--cc=dwalker@fifo99.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: link
Be 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.