MLK-11340-38 usb: chipidea: imx: enable different wakeup setting
authorPeter Chen <peter.chen@freescale.com>
Fri, 3 Jan 2014 05:45:30 +0000 (13:45 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:47:01 +0000 (14:47 -0500)
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)

drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/chipidea/ci_hdrc_imx.h
drivers/usb/chipidea/usbmisc_imx.c

index 20a6a20..4247667 100644 (file)
@@ -592,6 +592,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);
index 5d96152..3be2cbe 100644 (file)
@@ -52,6 +52,7 @@ struct imx_usbmisc_data {
         * and release the clock to the digital logic inside the analog block
         */
        unsigned int osc_clkgate_delay;
+       enum usb_dr_mode available_role;
 };
 
 int imx_usbmisc_init(struct imx_usbmisc_data *);
index 09b31a0..a92ac17 100644 (file)
@@ -311,15 +311,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);
        int ret = 0;
+       u32 val, wakeup_setting = MX6_BM_WAKEUP_ENABLE;
 
        if (data->index > 3)
                return -EINVAL;
@@ -327,13 +335,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);