aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/phy-twl4030-usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/phy-twl4030-usb.c')
-rw-r--r--drivers/phy/phy-twl4030-usb.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 8882afbef688..6285f46f3ddb 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -144,6 +144,16 @@
#define PMBR1 0x0D
#define GPIO_USB_4PIN_ULPI_2430C (3 << 0)
+/*
+ * If VBUS is valid or ID is ground, then we know a
+ * cable is present and we need to be runtime-enabled
+ */
+static inline bool cable_present(enum omap_musb_vbus_id_status stat)
+{
+ return stat == OMAP_MUSB_VBUS_VALID ||
+ stat == OMAP_MUSB_ID_GROUND;
+}
+
struct twl4030_usb {
struct usb_phy phy;
struct device *dev;
@@ -536,8 +546,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
mutex_lock(&twl->lock);
if (status >= 0 && status != twl->linkstat) {
+ status_changed =
+ cable_present(twl->linkstat) !=
+ cable_present(status);
twl->linkstat = status;
- status_changed = true;
}
mutex_unlock(&twl->lock);
@@ -553,15 +565,11 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
* USB_LINK_VBUS state. musb_hdrc won't care until it
* starts to handle softconnect right.
*/
- if ((status == OMAP_MUSB_VBUS_VALID) ||
- (status == OMAP_MUSB_ID_GROUND)) {
- if (pm_runtime_suspended(twl->dev))
- pm_runtime_get_sync(twl->dev);
+ if (cable_present(status)) {
+ pm_runtime_get_sync(twl->dev);
} else {
- if (pm_runtime_active(twl->dev)) {
- pm_runtime_mark_last_busy(twl->dev);
- pm_runtime_put_autosuspend(twl->dev);
- }
+ pm_runtime_mark_last_busy(twl->dev);
+ pm_runtime_put_autosuspend(twl->dev);
}
omap_musb_mailbox(status);
}
@@ -766,6 +774,9 @@ static int twl4030_usb_remove(struct platform_device *pdev)
/* disable complete OTG block */
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
+
+ if (cable_present(twl->linkstat))
+ pm_runtime_put_noidle(twl->dev);
pm_runtime_mark_last_busy(twl->dev);
pm_runtime_put(twl->dev);