diff options
| -rw-r--r-- | drivers/usb/chipidea/otg.c | 35 | ||||
| -rw-r--r-- | drivers/usb/chipidea/otg_fsm.c | 4 |
2 files changed, 22 insertions, 17 deletions
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index 7b9e417060e8..1850b034a4e5 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -57,22 +57,26 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci) return role; } -#define CI_VBUS_CONNECT_TIMEOUT_MS 500 +/* + * Handling vbus glitch + * We only need to consider glitch for without usb connection, + * With usb connection, we consider it as real disconnection. + * + * If the vbus can't be kept above B session valid for timeout value, + * we think it is a vbus glitch, otherwise it's a valid vbus. + */ +#define CI_VBUS_CONNECT_TIMEOUT_MS 300 static int ci_is_vbus_glitch(struct ci_hdrc *ci) { - /* - * Handling vbus glitch - * - * We only need to consider glitch for without usb connection, - * With usb connection, we consider it as real disconnection. - * - * If the vbus can't higher than AVV in timeout value, we think - * it is a vbus glitch - */ - if (hw_wait_reg(ci, OP_OTGSC, OTGSC_AVV, OTGSC_AVV, - CI_VBUS_CONNECT_TIMEOUT_MS)) { - dev_warn(ci->dev, "there is a vbus glitch\n"); - return 1; + int i; + for (i = 0; i < CI_VBUS_CONNECT_TIMEOUT_MS/20; i++) { + if (hw_read_otgsc(ci, OTGSC_AVV)) { + return 0; + } else if (!hw_read_otgsc(ci, OTGSC_BSV)) { + dev_warn(ci->dev, "there is a vbus glitch\n"); + return 1; + } + msleep(20); } return 0; @@ -141,8 +145,7 @@ static void ci_handle_vbus_glitch(struct ci_hdrc *ci) valid_vbus_change = true; } } else { - if (ci->vbus_active || (ci_otg_is_fsm_mode(ci) && - ci->fsm.b_sess_vld)) + if (ci->vbus_active && !ci_otg_is_fsm_mode(ci)) valid_vbus_change = true; } diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 34a4f3c53a61..7aa33e588f11 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -807,13 +807,15 @@ irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci) } } else if (otg_int_src & OTGSC_BSVIS) { hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS); - ci->vbus_glitch_check_event = true; if (!(otgsc & OTGSC_BSV) && fsm->b_sess_vld) { + ci->b_sess_valid_event = true; fsm->b_sess_vld = 0; if (fsm->id) ci_otg_add_timer(ci, B_SSEND_SRP); if (fsm->b_bus_req) fsm->b_bus_req = 0; + } else { + ci->vbus_glitch_check_event = true; } } else if (otg_int_src & OTGSC_AVVIS) { hw_write_otgsc(ci, OTGSC_AVVIS, OTGSC_AVVIS); |
