From: Omar Ramirez Luna <omar.ramirez@ti.com>
To: Tony Lindgren <tony@atomide.com>
Cc: Russell King <linux@arm.linux.org.uk>,
Tarun Kanti DebBarma <tarun.kanti@ti.com>,
Kevin Hilman <khilman@ti.com>,
Santosh Shilimkar <santosh.shilimkar@ti.com>,
Benoit Cousson <b-cousson@ti.com>,
linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Omar Ramirez Luna <omar.ramirez@ti.com>
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
WARNING: multiple messages have this Message-ID (diff)
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: 14+ 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
2011-11-25 4:12 ` Omar Ramirez Luna [this message]
2011-11-25 4:12 ` [PATCH 1/2] ARM: OMAP: dmtimer: fix sleeping function called from invalid context Omar Ramirez Luna
2011-12-09 21:34 ` Tony Lindgren
2011-12-09 21:34 ` Tony Lindgren
2011-12-09 22:10 ` Ramirez Luna, Omar
2011-12-09 22:10 ` Ramirez Luna, Omar
2011-12-12 23:08 ` Tony Lindgren
2011-12-12 23:08 ` Tony Lindgren
2011-12-13 1:49 ` Ramirez Luna, Omar
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
2011-11-25 4:12 ` 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=b-cousson@ti.com \
--cc=khilman@ti.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-omap@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=santosh.shilimkar@ti.com \
--cc=tarun.kanti@ti.com \
--cc=tony@atomide.com \
/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.