Re: tidspbridge issue with omap_dm_timer_free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 10, 2011 at 9:42 PM, Felipe Contreras
<felipe.contreras@xxxxxxxxx> wrote:
> I am trying to use a more recent version of the tidspbridge code in
> the Nokia N9, but I'm stuck with this warning that is caused by using
> the dm timer framework.

Actually, the problem only happens on the 'dspbridge' branch, which
has some unmerged patches. These patches introduce some new mutexes
that trigger this.

My proposed solution is to request the dm timers at initialization
time, and just enable/disable them on wake/hibernate, which is a bit
similar to what was happening before, and probably more efficient and
proper.

I'm attaching the patch.

-- 
Felipe Contreras
From cd7f245ba42eb0d18bdfc3f29e2856f09227528e Mon Sep 17 00:00:00 2001
From: Felipe Contreras <felipe.contreras@xxxxxxxxx>
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@xxxxxxxxx>
---
 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(-)

diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c
index aac06c0..b0aa831 100644
--- a/drivers/staging/tidspbridge/core/dsp-clock.c
+++ b/drivers/staging/tidspbridge/core/dsp-clock.c
@@ -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:
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index ecd865b..fbcea0b 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -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;
diff --git a/drivers/staging/tidspbridge/include/dspbridge/clk.h b/drivers/staging/tidspbridge/include/dspbridge/clk.h
index 685341c..14c5d7d 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/clk.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/clk.h
@@ -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


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux