From: omar.ramirez@ti.com (Omar Ramirez Luna)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] ARM: OMAP: dmtimer: fix sleeping function called from invalid context
Date: Thu, 24 Nov 2011 22:12:49 -0600 [thread overview]
Message-ID: <1322194370-8073-2-git-send-email-omar.ramirez@ti.com> (raw)
In-Reply-To: <1322194370-8073-1-git-send-email-omar.ramirez@ti.com>
omap_dm_timer_request* holds a spin_lock_irqsave while inner routines call
clk_get_sys which holds a mutex_lock, given that mutex can be put to sleep
a BUG message is triggered. This occurs in 2 ocassions.
1. When the fck is gotten at the beginning of omap_dm_timer_prepare by using
clk_get (which will call clk_get_sys), this was fixed by getting the clock
handles on probe.
2. When omap_dm_timer_set_source tries to get the clock handles (with clk_get)
for the fck and source clock, this was moved to be made after
spin_unlock_irqsave when the context is not atomic anymore.
Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 69 +++++++++++++++++++++++++----------------
1 files changed, 42 insertions(+), 27 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index af3b92b..2acd4de 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -134,22 +134,13 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
- int ret;
-
- timer->fclk = clk_get(&timer->pdev->dev, "fck");
- if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
- timer->fclk = NULL;
- dev_err(&timer->pdev->dev, ": No fclk handle.\n");
- return -EINVAL;
- }
if (pdata->needs_manual_reset)
omap_dm_timer_reset(timer);
- ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
-
timer->posted = 1;
- return ret;
+
+ return 0;
}
struct omap_dm_timer *omap_dm_timer_request(void)
@@ -168,19 +159,26 @@ struct omap_dm_timer *omap_dm_timer_request(void)
break;
}
- if (timer) {
- ret = omap_dm_timer_prepare(timer);
- if (ret) {
- timer->reserved = 0;
- timer = NULL;
- }
+ if (!timer) {
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+ goto err_no_timer;
}
+
+ omap_dm_timer_prepare(timer);
+
spin_unlock_irqrestore(&dm_timer_lock, flags);
- if (!timer)
- pr_debug("%s: timer request failed!\n", __func__);
+ ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+ if (ret) {
+ timer->reserved = 0;
+ goto err_no_timer;
+ }
return timer;
+
+err_no_timer:
+ pr_debug("%s: timer request failed!\n", __func__);
+ return NULL;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_request);
@@ -199,19 +197,26 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
}
}
- if (timer) {
- ret = omap_dm_timer_prepare(timer);
- if (ret) {
- timer->reserved = 0;
- timer = NULL;
- }
+ if (!timer) {
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+ goto err_no_timer;
}
+
+ omap_dm_timer_prepare(timer);
+
spin_unlock_irqrestore(&dm_timer_lock, flags);
- if (!timer)
- pr_debug("%s: timer%d request failed!\n", __func__, id);
+ ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+ if (ret) {
+ timer->reserved = 0;
+ goto err_no_timer;
+ }
return timer;
+
+err_no_timer:
+ pr_debug("%s: timer%d request failed!\n", __func__, id);
+ return NULL;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
@@ -658,6 +663,14 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
goto err_free_mem;
}
+ timer->fclk = clk_get(&pdev->dev, "fck");
+ if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
+ timer->fclk = NULL;
+ dev_err(&pdev->dev, ": No fclk handle for id %d.\n", pdev->id);
+ ret = -EINVAL;
+ goto err_clk_handle;
+ }
+
timer->id = pdev->id;
timer->irq = irq->start;
timer->reserved = pdata->reserved;
@@ -686,6 +699,8 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
return 0;
+err_clk_handle:
+ iounmap(timer->io_base);
err_free_mem:
kfree(timer);
--
1.7.5.4
next prev parent reply other threads:[~2011-11-25 4:12 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-25 4:12 [PATCH 0/2] ARM: OMAP: dmtimer: scheduling while atomic fixes Omar Ramirez Luna
2011-11-25 4:12 ` Omar Ramirez Luna [this message]
2011-12-09 21:34 ` [PATCH 1/2] ARM: OMAP: dmtimer: fix sleeping function called from invalid context Tony Lindgren
2011-12-09 22:10 ` Ramirez Luna, Omar
2011-12-12 23:08 ` Tony Lindgren
2011-12-13 1:49 ` Ramirez Luna, Omar
2011-11-25 4:12 ` [PATCH 2/2] ARM: OMAP: dmtimer: reorganize omap_dm_timer_request_* Omar Ramirez Luna
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=1322194370-8073-2-git-send-email-omar.ramirez@ti.com \
--to=omar.ramirez@ti.com \
--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).