diff options
Diffstat (limited to 'drivers/usb/chipidea/otg_fsm.c')
-rw-r--r-- | drivers/usb/chipidea/otg_fsm.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 00ab59d45da1..ba90dc66703d 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -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); + } } /* |