]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00299939-3 USB: imx6x: Add dummy LDO2p5 regulator for VBUS wakeup
authorRanjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
Tue, 4 Mar 2014 21:38:18 +0000 (15:38 -0600)
committerBai Ping <b51503@freescale.com>
Mon, 2 Feb 2015 18:06:03 +0000 (02:06 +0800)
LDO2p5 cannot be disabled in low power idle mode when the USB driver
enables VBUS wakeup. To identify when LDO2p5 can be disabled add a dummy
regulator that the USB driver will enable when VBUS wakeup is required.

Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
(cherry picked from commit 7d849e4d9ebca3c3c045deca0a12559f84ad6fa1)

drivers/usb/chipidea/usbmisc_imx.c

index 803f1ec485d997a0b4b95b2303ef63508e3969a5..4c49d5405a1bb699de5b38f5e74d2842967ee075 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 
 #include "ci_hdrc_imx.h"
 
@@ -110,6 +111,8 @@ struct imx_usbmisc {
        const struct usbmisc_ops *ops;
 };
 
+static struct regulator *vbus_wakeup_reg;
+
 static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
 {
        struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
@@ -311,13 +314,18 @@ static int usbmisc_imx6q_set_wakeup
        if (enabled) {
                wakeup_setting |= imx6q_finalize_wakeup_setting(data);
                writel(val | wakeup_setting, usbmisc->base + data->index * 4);
+               spin_unlock_irqrestore(&usbmisc->lock, flags);
+               if (vbus_wakeup_reg)
+                       ret = regulator_enable(vbus_wakeup_reg);
        } else {
                if (val & MX6_BM_WAKEUP_INTR)
                        pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
                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);
+               if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
+                       regulator_disable(vbus_wakeup_reg);
        }
-       spin_unlock_irqrestore(&usbmisc->lock, flags);
 
        return ret;
 }
@@ -619,6 +627,18 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
        data->ops = (const struct usbmisc_ops *)tmp_dev->data;
        platform_set_drvdata(pdev, data);
 
+       vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
+       if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+       else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
+               /* no vbus regualator is needed */
+               vbus_wakeup_reg = NULL;
+       else if (IS_ERR(vbus_wakeup_reg)) {
+               dev_err(&pdev->dev, "Getting regulator error: %ld\n",
+                       PTR_ERR(vbus_wakeup_reg));
+               return PTR_ERR(vbus_wakeup_reg);
+       }
+
        return 0;
 }