From cd7f245ba42eb0d18bdfc3f29e2856f09227528e Mon Sep 17 00:00:00 2001
From: Felipe Contreras <felipe.contreras@nokia.com>
Date: Thu, 11 Aug 2011 01:28:08 +0300
Subject: [PATCH] staging: tidspbridge: split gpt requests
Otherwise I get this:
BUG: sleeping function called from invalid context at kernel/mutex.c:287
in_atomic(): 1, irqs_disabled(): 0, pid: 305, name: mboxd/0
3 locks held by mboxd/0/305:
#0: (mboxd){+.+...}, at: [<b0081778>] worker_thread+0x154/0x2bc
#1: (&mq->work){+.+...}, at: [<b0081778>] worker_thread+0x154/0x2bc
#2: (pwr_lock){+.....}, at: [<af12f870>] handle_hibernation_from_dsp+0x1c/0x158 [bridgedriver]
[<b003f75c>] (unwind_backtrace+0x0/0xd4) from [<b03a3ac4>] (mutex_lock_nested+0x30/0x32c)
[<b03a3ac4>] (mutex_lock_nested+0x30/0x32c) from [<b00568f8>] (clk_set_parent+0x34/0xf8)
[<b00568f8>] (clk_set_parent+0x34/0xf8) from [<b005e2e0>] (omap_dm_timer_set_source+0x34/0x58)
[<b005e2e0>] (omap_dm_timer_set_source+0x34/0x58) from [<b005e424>] (omap_dm_timer_reset+0x78/0xd0)
[<b005e424>] (omap_dm_timer_reset+0x78/0xd0) from [<b005e490>] (omap_dm_timer_free+0x14/0x48)
[<b005e490>] (omap_dm_timer_free+0x14/0x48) from [<af1309d4>] (dsp_clk_disable+0x98/0x15c [bridgedriver])
[<af1309d4>] (dsp_clk_disable+0x98/0x15c [bridgedriver]) from [<af130abc>] (dsp_clock_disable_all+0x24/0x34 [bridgedriver])
[<af130abc>] (dsp_clock_disable_all+0x24/0x34 [bridgedriver]) from [<af12f914>] (handle_hibernation_from_dsp+0xc0/0x158 [bridgedriver])
[<af12f914>] (handle_hibernation_from_dsp+0xc0/0x158 [bridgedriver]) from [<af12c2bc>] (io_mbox_msg+0x8c/0x100 [bridgedriver])
[<af12c2bc>] (io_mbox_msg+0x8c/0x100 [bridgedriver]) from [<af07043c>] (mbox_rx_work+0x3c/0xa0 [mailbox])
[<af07043c>] (mbox_rx_work+0x3c/0xa0 [mailbox]) from [<b00817e4>] (worker_thread+0x1c0/0x2bc)
[<b00817e4>] (worker_thread+0x1c0/0x2bc) from [<b008513c>] (kthread+0x7c/0x84)
[<b008513c>] (kthread+0x7c/0x84) from [<b003b9d4>] (kernel_thread_exit+0x0/0x8)
------------[ cut here ]------------
WARNING: at kernel/mutex.c:214 mutex_lock_nested+0xb0/0x32c()
Signed-off-by: Felipe Contreras <felipe.contreras@nokia.com>
---
drivers/staging/tidspbridge/core/dsp-clock.c | 49 ++++++++++++++++++-
drivers/staging/tidspbridge/core/tiomap3430.c | 3 +
.../staging/tidspbridge/include/dspbridge/clk.h | 4 ++
3 files changed, 53 insertions(+), 3 deletions(-)
@@ -115,6 +115,7 @@ static s8 get_clk_type(u8 id)
void dsp_clk_exit(void)
{
dsp_clock_disable_all(dsp_clocks);
+ dsp_clock_release_all();
clk_put(iva2_clk);
clk_put(ssi.sst_fck);
@@ -146,6 +147,45 @@ void dsp_clk_init(void)
ssi.sst_fck, ssi.ssr_fck, ssi.ick);
}
+int dsp_clk_request(enum dsp_clk_id clk_id)
+{
+ struct omap_dm_timer *t;
+
+ if (get_clk_type(clk_id) != GPT_CLK)
+ return -EPERM;
+
+ t = omap_dm_timer_request_specific(DMT_ID(clk_id));
+ if (!t)
+ return -EPERM;
+ timer[clk_id - 1] = t;
+
+ return 0;
+}
+
+int dsp_clk_release(enum dsp_clk_id clk_id)
+{
+ if (get_clk_type(clk_id) != GPT_CLK)
+ return -EPERM;
+
+ omap_dm_timer_free(timer[clk_id - 1]);
+ timer[clk_id - 1] = NULL;
+
+ return 0;
+}
+
+void dsp_clock_release_all(void)
+{
+ int i;
+
+ /* release dm timer clocks */
+ for (i = 0; i < ARRAY_SIZE(timer); i++) {
+ if (!timer[i])
+ continue;
+ omap_dm_timer_free(timer[i]);
+ timer[i] = NULL;
+ }
+}
+
#ifdef CONFIG_OMAP_MCBSP
static void mcbsp_clk_prepare(bool flag, u8 id)
{
@@ -252,8 +292,9 @@ int dsp_clk_enable(enum dsp_clk_id clk_id)
clk_enable(iva2_clk);
break;
case GPT_CLK:
- timer[clk_id - 1] =
- omap_dm_timer_request_specific(DMT_ID(clk_id));
+ if (!timer[clk_id - 1])
+ return -EINVAL;
+ omap_dm_timer_enable(timer[clk_id - 1]);
break;
#ifdef CONFIG_OMAP_MCBSP
case MCBSP_CLK:
@@ -330,7 +371,9 @@ int dsp_clk_disable(enum dsp_clk_id clk_id)
clk_disable(iva2_clk);
break;
case GPT_CLK:
- omap_dm_timer_free(timer[clk_id - 1]);
+ if (!timer[clk_id - 1])
+ return -EINVAL;
+ omap_dm_timer_disable(timer[clk_id - 1]);
break;
#ifdef CONFIG_OMAP_MCBSP
case MCBSP_CLK:
@@ -512,6 +512,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
if (ul_load_monitor_timer != 0xFFFF) {
clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
ul_load_monitor_timer;
+ dsp_clk_request(ul_load_monitor_timer - BPWR_GP_TIMER5 + DSP_CLK_GPT5);
dsp_peripheral_clk_ctrl(dev_context, &clk_cmd);
} else {
dev_dbg(bridge, "Not able to get the symbol for Load "
@@ -523,6 +524,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
if (ul_bios_gp_timer != 0xFFFF) {
clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
ul_bios_gp_timer;
+ dsp_clk_request(ul_bios_gp_timer - BPWR_GP_TIMER5 + DSP_CLK_GPT5);
dsp_peripheral_clk_ctrl(dev_context, &clk_cmd);
} else {
dev_dbg(bridge,
@@ -691,6 +693,7 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
OMAP3430_RST3_IVA2, OMAP3430_IVA2_MOD, RM_RSTCTRL);
dsp_clock_disable_all(dev_context->dsp_per_clks);
+ dsp_clock_release_all();
dsp_clk_disable(DSP_CLK_IVA2);
return status;
@@ -62,6 +62,10 @@ extern void dsp_clk_exit(void);
*/
extern void dsp_clk_init(void);
+int dsp_clk_request(enum dsp_clk_id clk_id);
+int dsp_clk_release(enum dsp_clk_id clk_id);
+void dsp_clock_release_all(void);
+
void dsp_gpt_wait_overflow(short int clk_id, unsigned int load);
/*
--
1.7.6