summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2012-08-14 15:16:49 +0800
committerPeter Chen <peter.chen@freescale.com>2012-08-16 17:44:47 +0800
commit3b509358a976bc43041930485fd7f644980b62b4 (patch)
tree564ca3be95e39e14872307c0cb559a900d637407 /arch
parentdabdd1704ce8dc11a6476daccf739d92a45ab112 (diff)
ENGR00220341-1 usb: add spin_lock_irqsave protect for pdata->lowpower
pdata->lowpower may be accessed at two drivers together, assumed the situation that host/device set phy to low power mode but still not set the flag lowpower, at this time the wakeup occurs, as the flag lowpower is still not set, the interrupt will be infinite loop as no one will serve it. This commit is for MSL code and add protect at wakeup interrupt. Signed-off-by: Peter Chen <peter.chen@freescale.com>
Diffstat (limited to 'arch')
-rwxr-xr-xarch/arm/plat-mxc/usb_wakeup.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c
index e67c2219e52d..5d31d3621205 100755
--- a/arch/arm/plat-mxc/usb_wakeup.c
+++ b/arch/arm/plat-mxc/usb_wakeup.c
@@ -47,6 +47,20 @@ static void wakeup_clk_gate(struct fsl_usb2_wakeup_platform_data *pdata, bool on
if (pdata->usb_clock_for_pm)
pdata->usb_clock_for_pm(on);
}
+static bool phy_in_lowpower_mode(struct fsl_usb2_platform_data *pdata)
+{
+ unsigned long flags;
+ bool ret = true;
+
+ spin_lock_irqsave(&pdata->lock, flags);
+
+ if (!pdata->lowpower)
+ ret = false;
+
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
+ return ret;
+}
static bool usb2_is_in_lowpower(struct wakeup_ctrl *ctrl)
{
@@ -54,8 +68,8 @@ static bool usb2_is_in_lowpower(struct wakeup_ctrl *ctrl)
struct fsl_usb2_wakeup_platform_data *pdata = ctrl->pdata;
/* all the usb module related the wakeup is in lowpower mode */
for (i = 0; i < 3; i++) {
- if (pdata->usb_pdata[i]) {
- if (pdata->usb_pdata[i]->phy_lowpower_suspend && !pdata->usb_pdata[i]->lowpower)
+ if (pdata->usb_pdata[i] && pdata->usb_pdata[i]->phy_lowpower_suspend) {
+ if (!phy_in_lowpower_mode(pdata->usb_pdata[i]))
return false;
}
}