linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Omar Ramirez Luna <omar.ramirez@ti.com>
To: l-o <linux-omap@vger.kernel.org>
Cc: Omar Ramirez Luna <omar.ramirez@ti.com>,
	Fernando Guzman Lugo <fernando.lugo@ti.com>,
	Armando Uribe <x0095078@ti.com>,
	Felipe Contreras <felipe.contreras@gmail.com>
Subject: [PATCH 8/8] staging: tidspbridge: protect critical sections on PM routines
Date: Wed, 23 Mar 2011 12:49:53 -0600	[thread overview]
Message-ID: <1300906193-1732-9-git-send-email-omar.ramirez@ti.com> (raw)
In-Reply-To: <1300906193-1732-1-git-send-email-omar.ramirez@ti.com>

To fix some race conditions which:

- Wake the dsp, through the GFLUSH register, while tidspbridge has
  initiated a power off transition but hasn't disabled the peripheral
  clocks nor set the brd_state to HIB or self HIB. This cancels dsp
  transition but cuts off the clocks.

- Wake the dsp, through sm_interrupt_dsp, same as above.

- Wake the domain only, if the peripheral clocks have been cut, the
  IVA domain is woken but no response recieved until the peripheral
  clocks are reenabled. This triggers another race; when waking the
  dsp, clocks are reenabled and dsp starts its resume sequence,
  however dmtimer framework also resets the GPT clocks as part of
  its 'request' routine, which leaves the dsp without tick and unable
  to transition between power states.

It fixes the following future races, if IVA clock is enabled/disabled
in PM routines:

- Depending on timing it can cause an abort while accessing MMU
  registers from mpu side.

Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com>
---
 drivers/staging/tidspbridge/core/tiomap3430_pwr.c |   32 +++++++++++++++++++--
 1 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
index 95089ef..fdbf4eb 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
@@ -49,6 +49,8 @@
 
 #define PWRSTST_TIMEOUT          200
 
+DEFINE_SPINLOCK(pwr_lock);
+
 /*
  *  ======== handle_constraints_set ========
  *  	Sets new DSP constraint
@@ -91,6 +93,8 @@ int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
 	struct omap_dsp_platform_data *pdata =
 		omap_dspbridge_dev->dev.platform_data;
 
+	spin_lock_bh(&pwr_lock);
+
 	/* Wait for DSP to move into OFF state */
 	v = msecs_to_jiffies(PWRSTST_TIMEOUT) + jiffies;
 	do {
@@ -103,6 +107,7 @@ int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
 
 	if (!t) {
 		pr_err("%s: Timed out waiting for DSP off mode\n", __func__);
+		spin_unlock_bh(&pwr_lock);
 		return -ETIMEDOUT;
 	}
 
@@ -111,14 +116,19 @@ int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
 
 	/* Turn off DSP Peripheral clocks and DSP Load monitor timer */
 	status = dsp_clock_disable_all(dev_context->dsp_per_clks);
-	if (status)
+	if (status) {
+		spin_unlock_bh(&pwr_lock);
 		return status;
+	}
 
 	/* Disable wdt on hibernation. */
 	dsp_wdt_enable(false);
 
 	/* Update the Bridger Driver state */
 	dev_context->brd_state = BRD_DSP_HIBERNATION;
+
+	spin_unlock_bh(&pwr_lock);
+
 #ifdef CONFIG_TIDSPBRIDGE_DVFS
 	status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
 	if (!hio_mgr)
@@ -189,11 +199,15 @@ int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
 		return -EPERM;
 	}
 
+	spin_lock_bh(&pwr_lock);
+
 	omap_mbox_save_ctx(dev_context->mbox);
 
 	status = omap_mbox_msg_send(dev_context->mbox, mbx_msg);
-	if (status)
+	if (status) {
+		spin_unlock_bh(&pwr_lock);
 		return status;
+	}
 
 	/* Wait for DSP to move into target power state */
 	v = msecs_to_jiffies(PWRSTST_TIMEOUT) + jiffies;
@@ -212,6 +226,7 @@ int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
 		dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr);
 		bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0);
 #endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
+		spin_unlock_bh(&pwr_lock);
 		return -ETIMEDOUT;
 	}
 
@@ -226,8 +241,13 @@ int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
 
 	/* Turn off DSP Peripheral clocks */
 	status = dsp_clock_disable_all(dev_context->dsp_per_clks);
-	if (status)
+	if (status) {
+		spin_unlock_bh(&pwr_lock);
 		return status;
+	}
+
+	spin_unlock_bh(&pwr_lock);
+
 #ifdef CONFIG_TIDSPBRIDGE_DVFS
 	if (target_pwr_state == PWRDM_POWER_OFF) {
 		/*
@@ -259,8 +279,11 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
 	if (!dev_context->mbox || !resources)
 		return -EPERM;
 
+	spin_lock_bh(&pwr_lock);
+
 	switch (dev_context->brd_state) {
 	case BRD_STOPPED:
+		spin_unlock_bh(&pwr_lock);
 		return 0;
 	case BRD_RUNNING:
 		break;
@@ -318,12 +341,15 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
 	default:
 		pr_err("%s: unexpected state %x\n", __func__,
 						dev_context->brd_state);
+		spin_unlock_bh(&pwr_lock);
 		return -EINVAL;
 	}
 
 	/* Send a wakeup message to DSP */
 	status = omap_mbox_msg_send(dev_context->mbox, MBX_PM_DSPWAKEUP);
 
+	spin_unlock_bh(&pwr_lock);
+
 #endif /* CONFIG_PM */
 	return status;
 }
-- 
1.7.1


  parent reply	other threads:[~2011-03-23 19:01 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-23 18:49 [PATCH 0/8] staging: tidspbridge: PM routines cleanup Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 1/8] staging: tidspbridge: make wake_dsp to handle PM code Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 2/8] staging: tidspbridge: fix resume path from retention Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 3/8] staging: tidspbridge: remove msleep for dsp transition wait Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 4/8] staging: tidspbridge: send mbox PM command directly Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 5/8] staging: tidspbridge: send wake message even if dsp is running Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 6/8] staging: tidspbridge: remove redundant code from PM routines Omar Ramirez Luna
2011-03-23 18:49 ` [PATCH 7/8] staging: tidspbridge: remove redundant indentation in " Omar Ramirez Luna
2011-03-23 18:49 ` Omar Ramirez Luna [this message]
2011-04-29 19:20 ` [PATCH 0/8] staging: tidspbridge: PM routines cleanup Ramirez Luna, Omar

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=1300906193-1732-9-git-send-email-omar.ramirez@ti.com \
    --to=omar.ramirez@ti.com \
    --cc=felipe.contreras@gmail.com \
    --cc=fernando.lugo@ti.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=x0095078@ti.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 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).