|
@@ -485,20 +485,30 @@ static void ci_otg_loc_conn(struct otg_fsm *fsm, int on)
|
|
|
|
|
|
/*
|
|
|
* Generate SOF by host.
|
|
|
- * This is controlled through suspend/resume the port.
|
|
|
* In host mode, controller will automatically send SOF.
|
|
|
* Suspend will block the data on the port.
|
|
|
+ *
|
|
|
+ * This is controlled through usbcore by usb autosuspend,
|
|
|
+ * so the usb device class driver need support autosuspend,
|
|
|
+ * otherwise the bus suspend will not happen.
|
|
|
*/
|
|
|
static void ci_otg_loc_sof(struct otg_fsm *fsm, int on)
|
|
|
{
|
|
|
- struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
|
|
|
+ struct usb_device *udev;
|
|
|
|
|
|
- if (on)
|
|
|
- hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_FPR,
|
|
|
- PORTSC_FPR);
|
|
|
- else
|
|
|
- hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_SUSP,
|
|
|
- PORTSC_SUSP);
|
|
|
+ if (!fsm->otg->host)
|
|
|
+ return;
|
|
|
+
|
|
|
+ udev = usb_hub_find_child(fsm->otg->host->root_hub, 1);
|
|
|
+ if (!udev)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (on) {
|
|
|
+ usb_disable_autosuspend(udev);
|
|
|
+ } else {
|
|
|
+ pm_runtime_set_autosuspend_delay(&udev->dev, 0);
|
|
|
+ usb_enable_autosuspend(udev);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|