aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>2014-03-04 16:38:18 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:58:02 -0400
commit35519ea0d88a43e2ad2d99a08d524441571ec119 (patch)
tree2a0f3d884394992c648f634e0f7f39e6437201aa /drivers/usb/chipidea
parentfa82e467da1c2e44d0a80b57be6e9ff5ed8746cd (diff)
ENGR00299939-3 USB: imx6x: Add dummy LDO2p5 regulator for VBUS wakeup
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>
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 989857285130..ba9da1b3b4e0 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -15,6 +15,7 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/regmap.h> 17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
18 19
19#include "ci_hdrc_imx.h" 20#include "ci_hdrc_imx.h"
20 21
@@ -80,6 +81,7 @@ struct imx_usbmisc {
80}; 81};
81 82
82static struct imx_usbmisc *usbmisc; 83static struct imx_usbmisc *usbmisc;
84static struct regulator *vbus_wakeup_reg;
83 85
84static int usbmisc_imx25_post(struct imx_usbmisc_data *data) 86static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
85{ 87{
@@ -300,6 +302,7 @@ static int usbmisc_imx6q_set_wakeup
300{ 302{
301 unsigned long flags; 303 unsigned long flags;
302 u32 reg, val = MX6_BM_WAKEUP_ENABLE; 304 u32 reg, val = MX6_BM_WAKEUP_ENABLE;
305 int ret = 0;
303 306
304 if (data->index > 3) 307 if (data->index > 3)
305 return -EINVAL; 308 return -EINVAL;
@@ -309,16 +312,20 @@ static int usbmisc_imx6q_set_wakeup
309 if (enabled) { 312 if (enabled) {
310 val |= imx6q_finalize_wakeup_setting(data); 313 val |= imx6q_finalize_wakeup_setting(data);
311 writel(reg | val, usbmisc->base + data->index * 4); 314 writel(reg | val, usbmisc->base + data->index * 4);
315 if (vbus_wakeup_reg)
316 ret = regulator_enable(vbus_wakeup_reg);
312 } else { 317 } else {
313 if (reg & MX6_BM_WAKEUP_INTR) 318 if (reg & MX6_BM_WAKEUP_INTR)
314 pr_debug("wakeup int at ci_hdrc.%d\n", data->index); 319 pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
315 val = MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP 320 val = MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP
316 | MX6_BM_ID_WAKEUP; 321 | MX6_BM_ID_WAKEUP;
317 writel(reg & ~val, usbmisc->base + data->index * 4); 322 writel(reg & ~val, usbmisc->base + data->index * 4);
323 if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
324 regulator_disable(vbus_wakeup_reg);
318 } 325 }
319 spin_unlock_irqrestore(&usbmisc->lock, flags); 326 spin_unlock_irqrestore(&usbmisc->lock, flags);
320 327
321 return 0; 328 return ret;
322} 329}
323 330
324static const struct usbmisc_ops imx25_usbmisc_ops = { 331static const struct usbmisc_ops imx25_usbmisc_ops = {
@@ -439,6 +446,18 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
439 data->ops = (const struct usbmisc_ops *)tmp_dev->data; 446 data->ops = (const struct usbmisc_ops *)tmp_dev->data;
440 usbmisc = data; 447 usbmisc = data;
441 448
449 vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
450 if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
451 return -EPROBE_DEFER;
452 else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
453 /* no vbus regualator is needed */
454 vbus_wakeup_reg = NULL;
455 else if (IS_ERR(vbus_wakeup_reg)) {
456 dev_err(&pdev->dev, "Getting regulator error: %ld\n",
457 PTR_ERR(vbus_wakeup_reg));
458 return PTR_ERR(vbus_wakeup_reg);
459 }
460
442 return 0; 461 return 0;
443} 462}
444 463