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
next prev 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).