From c20a133e64d3dcd6463823eb359b6aa9403ffded Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 3 Jan 2014 13:45:30 +0800 Subject: 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 (cherry picked from commit 632e2eda5d071781479e0e0a80496c9a198d614f) --- drivers/usb/chipidea/ci_hdrc_imx.c | 4 ++++ drivers/usb/chipidea/ci_hdrc_imx.h | 3 +++ 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 + 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); -- cgit v1.2.3