summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorNeil Zhang <zhangwm@marvell.com>2011-11-30 09:57:16 +0800
committerFelipe Balbi <balbi@ti.com>2011-12-12 11:45:24 +0200
commit5076ae5588e53da32fef697f604fec33fe5fada0 (patch)
tree2d6024f3bf035f86f89e3afac80a1c5bee93d714 /drivers/usb/gadget
parent85ff7bfb6e260d7cc6d675941f5569c9b7ad6b44 (diff)
downloadlinux-3.10-5076ae5588e53da32fef697f604fec33fe5fada0.tar.gz
linux-3.10-5076ae5588e53da32fef697f604fec33fe5fada0.tar.bz2
linux-3.10-5076ae5588e53da32fef697f604fec33fe5fada0.zip
usb: gadget: mv_udc: refine suspend/resume function
This patch impletments system suspend/resume functions for Marvell otg controller. If OTG is enabled, OTG driver will do most of the work. If not, we will check clock gating. If clock gating is enabled, the UDC will be start/stop automatically. If not, UDC will be start/stop in suspend/resume functions. Signed-off-by: Neil Zhang <zhangwm@marvell.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/mv_udc_core.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index 77e90655637..143925c6a18 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -2447,7 +2447,30 @@ static int mv_udc_suspend(struct device *_dev)
{
struct mv_udc *udc = the_controller;
- udc_stop(udc);
+ /* if OTG is enabled, the following will be done in OTG driver*/
+ if (udc->transceiver)
+ return 0;
+
+ if (udc->pdata->vbus && udc->pdata->vbus->poll)
+ if (udc->pdata->vbus->poll() == VBUS_HIGH) {
+ dev_info(&udc->dev->dev, "USB cable is connected!\n");
+ return -EAGAIN;
+ }
+
+ /*
+ * only cable is unplugged, udc can suspend.
+ * So do not care about clock_gating == 1.
+ */
+ if (!udc->clock_gating) {
+ udc_stop(udc);
+
+ spin_lock_irq(&udc->lock);
+ /* stop all usb activities */
+ stop_activity(udc, udc->driver);
+ spin_unlock_irq(&udc->lock);
+
+ mv_udc_disable_internal(udc);
+ }
return 0;
}
@@ -2457,20 +2480,22 @@ static int mv_udc_resume(struct device *_dev)
struct mv_udc *udc = the_controller;
int retval;
- if (udc->pdata->phy_init) {
- retval = udc->pdata->phy_init(udc->phy_regs);
- if (retval) {
- dev_err(&udc->dev->dev,
- "init phy error %d when resume back\n",
- retval);
+ /* if OTG is enabled, the following will be done in OTG driver*/
+ if (udc->transceiver)
+ return 0;
+
+ if (!udc->clock_gating) {
+ retval = mv_udc_enable_internal(udc);
+ if (retval)
return retval;
+
+ if (udc->driver && udc->softconnect) {
+ udc_reset(udc);
+ ep0_reset(udc);
+ udc_start(udc);
}
}
- udc_reset(udc);
- ep0_reset(udc);
- udc_start(udc);
-
return 0;
}