diff options
-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) | |||
485 | 485 | ||
486 | /* | 486 | /* |
487 | * Generate SOF by host. | 487 | * Generate SOF by host. |
488 | * This is controlled through suspend/resume the port. | ||
489 | * In host mode, controller will automatically send SOF. | 488 | * In host mode, controller will automatically send SOF. |
490 | * Suspend will block the data on the port. | 489 | * Suspend will block the data on the port. |
490 | * | ||
491 | * This is controlled through usbcore by usb autosuspend, | ||
492 | * so the usb device class driver need support autosuspend, | ||
493 | * otherwise the bus suspend will not happen. | ||
491 | */ | 494 | */ |
492 | static void ci_otg_loc_sof(struct otg_fsm *fsm, int on) | 495 | static void ci_otg_loc_sof(struct otg_fsm *fsm, int on) |
493 | { | 496 | { |
494 | struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); | 497 | struct usb_device *udev; |
495 | 498 | ||
496 | if (on) | 499 | if (!fsm->otg->host) |
497 | hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_FPR, | 500 | return; |
498 | PORTSC_FPR); | 501 | |
499 | else | 502 | udev = usb_hub_find_child(fsm->otg->host->root_hub, 1); |
500 | hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_SUSP, | 503 | if (!udev) |
501 | PORTSC_SUSP); | 504 | return; |
505 | |||
506 | if (on) { | ||
507 | usb_disable_autosuspend(udev); | ||
508 | } else { | ||
509 | pm_runtime_set_autosuspend_delay(&udev->dev, 0); | ||
510 | usb_enable_autosuspend(udev); | ||
511 | } | ||
502 | } | 512 | } |
503 | 513 | ||
504 | /* | 514 | /* |