aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r--drivers/usb/core/driver.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 75b4bc0..e1f547e 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1181,6 +1181,19 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
udev->state == USB_STATE_SUSPENDED)
goto done;
+#ifdef CONFIG_MDM_HSIC_PM
+ /* when additional device attached at ehci hub, interface driver will
+ * goes to suspend , but hub will not goes to suspend.
+ * in hsic case, device modem cannot notice this change on host, so
+ * it does not try to send packet to host
+ *
+ * prevent suspend_both when it's parent has more child
+ */
+ if (udev->dev.parent) {
+ if (atomic_read(&udev->dev.parent->power.child_count) != 1)
+ return -EBUSY;
+ }
+#endif
/* Suspend all the interfaces and then udev itself */
if (udev->actconfig) {
n = udev->actconfig->desc.bNumInterfaces;
@@ -1332,6 +1345,9 @@ int usb_resume(struct device *dev, pm_message_t msg)
* Unbind the interfaces that will need rebinding later.
*/
} else {
+ #ifdef CONFIG_MDM_HSIC_PM
+ pm_runtime_get_sync(dev->parent);
+ #endif
status = usb_resume_both(udev, msg);
if (status == 0) {
pm_runtime_disable(dev);
@@ -1339,6 +1355,9 @@ int usb_resume(struct device *dev, pm_message_t msg)
pm_runtime_enable(dev);
do_unbind_rebind(udev, DO_REBIND);
}
+ #ifdef CONFIG_MDM_HSIC_PM
+ pm_runtime_put_sync(dev->parent);
+ #endif
}
/* Avoid PM error messages for devices disconnected while suspended