diff options
| author | Peter Chen <peter.chen@freescale.com> | 2014-01-03 13:45:30 +0800 |
|---|---|---|
| committer | Li Jun <jun.li@freescale.com> | 2015-01-28 11:08:36 +0800 |
| commit | c20a133e64d3dcd6463823eb359b6aa9403ffded (patch) | |
| tree | 34c61af9be4a26af4fe53d91104515ec7c4d9fdf | |
| parent | dc31f1499797ff7b6d825c4a2871dfa39e2c2194 (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.c | 4 | ||||
| -rw-r--r-- | drivers/usb/chipidea/ci_hdrc_imx.h | 3 | ||||
| -rw-r--r-- | drivers/usb/chipidea/usbmisc_imx.c | 21 |
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); |
