From: linus.walleij@linaro.org (Linus Walleij)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] ARM: SMP_TWD: make setup()/stop() reentrant
Date: Fri, 19 Oct 2012 11:56:29 +0200 [thread overview]
Message-ID: <1350640589-31821-1-git-send-email-linus.walleij@linaro.org> (raw)
This makes the SMP_TWD clock .setup()/.stop() pair reentrant by
not re-fetching the clk and re-registering the clock event every
time .setup() is called. We also make sure to call the
clk_enable()/clk_disable() pair on subsequent calls.
As it has been brought to my knowledge that this pair is going
to be called from atomic contexts for CPU clusters coming and
going, the clk_prepare()/clk_unprepare() calls cannot be called
on subsequent .setup()/.stop() iterations.
The patch assumes that the code will make sure that
twd_set_mode() is called through .set_mode() on the clock
event *after* the .setup() call, so that the timer registers
are fully re-programmed after a new .setup() cycle.
Cc: Shawn Guo <shawn.guo@linaro.org>
Reported-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Peter/Shawn: can you please respond with a Tested-by from your
system(s) to indicate if this works as expected?
---
arch/arm/kernel/smp_twd.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index b92d524..229231a 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -31,6 +31,7 @@ static void __iomem *twd_base;
static struct clk *twd_clk;
static unsigned long twd_timer_rate;
+static bool initial_setup_called;
static struct clock_event_device __percpu **twd_evt;
static int twd_ppi;
@@ -93,6 +94,8 @@ static void twd_timer_stop(struct clock_event_device *clk)
{
twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
disable_percpu_irq(clk->irq);
+ if (!IS_ERR(twd_clk))
+ clk_disable(twd_clk);
}
#ifdef CONFIG_COMMON_CLK
@@ -265,8 +268,21 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
struct clock_event_device **this_cpu_clk;
- if (!twd_clk)
- twd_clk = twd_get_clock();
+ /*
+ * If the basic setup has been done before, don't bother
+ * with yet again looking up the clock and register the clock
+ * source.
+ */
+ if (initial_setup_called) {
+ if (!IS_ERR(twd_clk))
+ clk_enable(twd_clk);
+ __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+ enable_percpu_irq(clk->irq, 0);
+ return 0;
+ }
+ initial_setup_called = true;
+
+ twd_clk = twd_get_clock();
if (!IS_ERR_OR_NULL(twd_clk))
twd_timer_rate = clk_get_rate(twd_clk);
--
1.7.11.7
next reply other threads:[~2012-10-19 9:56 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-19 9:56 Linus Walleij [this message]
2012-10-19 16:15 ` [PATCH v2] ARM: SMP_TWD: make setup()/stop() reentrant Shawn Guo
2012-10-22 5:13 ` Shawn Guo
2012-10-22 6:51 ` Santosh Shilimkar
2012-10-22 10:14 ` Linus Walleij
2012-10-22 14:14 ` Shawn Guo
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=1350640589-31821-1-git-send-email-linus.walleij@linaro.org \
--to=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).