summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2014-01-03 13:45:30 +0800
committerLi Jun <jun.li@freescale.com>2015-01-28 11:08:36 +0800
commitc20a133e64d3dcd6463823eb359b6aa9403ffded (patch)
tree34c61af9be4a26af4fe53d91104515ec7c4d9fdf
parentdc31f1499797ff7b6d825c4a2871dfa39e2c2194 (diff)
ENGR00292408-2 usb: chipidea: imx: enable different wakeup setting
We have different wakeup setting for different roles: For peripheral-only mode, we may only enable vbus wakeup. The Micro-AB cable should not be considered as wakeup source. For host-only mode, the ID change or vbus change should not be considered as wakeup source. For OTG mode, all wakeup setting should be considered as wakeup source. Signed-off-by: Peter Chen <peter.chen@freescale.com> (cherry picked from commit 632e2eda5d071781479e0e0a80496c9a198d614f)
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c4
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.h3
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c21
3 files changed, 22 insertions, 6 deletions
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 556bf700ce48..fb0a3acfa6df 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -418,6 +418,10 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
goto disable_device;
}
+ /* usbmisc needs to know dr mode to choose wakeup setting */
+ data->usbmisc_data->available_role =
+ ci_hdrc_query_available_role(data->ci_pdev);
+
if (data->supports_runtime_pm) {
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h
index 99765ef6a6d0..38f618527d8b 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.h
+++ b/drivers/usb/chipidea/ci_hdrc_imx.h
@@ -12,6 +12,8 @@
#ifndef __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
#define __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
+#include <linux/usb/otg.h>
+
struct imx_usbmisc_data {
struct device *dev;
int index;
@@ -24,6 +26,7 @@ struct imx_usbmisc_data {
*/
unsigned int osc_clkgate_delay;
struct regmap *anatop;
+ enum usb_dr_mode available_role;
};
int imx_usbmisc_init(struct imx_usbmisc_data *);
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index e9a253637523..803f1ec485d9 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -284,14 +284,23 @@ static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
return 0;
}
+static u32 imx6q_finalize_wakeup_setting(struct imx_usbmisc_data *data)
+{
+ if (data->available_role == USB_DR_MODE_PERIPHERAL)
+ return MX6_BM_VBUS_WAKEUP;
+ else if (data->available_role == USB_DR_MODE_OTG)
+ return MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
+
+ return 0;
+}
+
static int usbmisc_imx6q_set_wakeup
(struct imx_usbmisc_data *data, bool enabled)
{
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
unsigned long flags;
u32 val;
- u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE |
- MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP);
+ u32 wakeup_setting = MX6_BM_WAKEUP_ENABLE;
int ret = 0;
if (data->index > 3)
@@ -300,13 +309,13 @@ static int usbmisc_imx6q_set_wakeup
spin_lock_irqsave(&usbmisc->lock, flags);
val = readl(usbmisc->base + data->index * 4);
if (enabled) {
- val |= wakeup_setting;
- writel(val, usbmisc->base + data->index * 4);
+ wakeup_setting |= imx6q_finalize_wakeup_setting(data);
+ writel(val | wakeup_setting, usbmisc->base + data->index * 4);
} else {
if (val & MX6_BM_WAKEUP_INTR)
pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
- val &= ~wakeup_setting;
- writel(val, usbmisc->base + data->index * 4);
+ wakeup_setting |= MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
+ writel(val & ~wakeup_setting, usbmisc->base + data->index * 4);
}
spin_unlock_irqrestore(&usbmisc->lock, flags);