aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/chipidea/otg_fsm.c11
-rw-r--r--drivers/usb/chipidea/udc.c16
2 files changed, 25 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index fff809ca3a18..028f7687ad29 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -592,10 +592,18 @@ int ci_otg_fsm_work(struct ci_hdrc *ci)
592 /* 592 /*
593 * Don't do fsm transition for B device 593 * Don't do fsm transition for B device
594 * when there is no gadget class driver 594 * when there is no gadget class driver
595 * only handle charger notify
595 */ 596 */
596 if (ci->fsm.id && !(ci->driver) && 597 if (ci->fsm.id && !(ci->driver) &&
597 ci->transceiver->state < OTG_STATE_A_IDLE) 598 ci->transceiver->state < OTG_STATE_A_IDLE) {
599 if (ci->b_sess_valid_event) {
600 if (ci->fsm.b_sess_vld)
601 usb_gadget_vbus_connect(&ci->gadget);
602 else
603 usb_gadget_vbus_disconnect(&ci->gadget);
604 }
598 return 0; 605 return 0;
606 }
599 607
600 if (otg_statemachine(&ci->fsm)) { 608 if (otg_statemachine(&ci->fsm)) {
601 if (ci->transceiver->state == OTG_STATE_A_IDLE) { 609 if (ci->transceiver->state == OTG_STATE_A_IDLE) {
@@ -764,6 +772,7 @@ irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci)
764 } 772 }
765 } else if (otg_int_src & OTGSC_BSVIS) { 773 } else if (otg_int_src & OTGSC_BSVIS) {
766 hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS); 774 hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
775 ci->b_sess_valid_event = true;
767 if (otgsc & OTGSC_BSV) { 776 if (otgsc & OTGSC_BSV) {
768 fsm->b_sess_vld = 1; 777 fsm->b_sess_vld = 1;
769 ci_otg_del_timer(ci, B_SSEND_SRP); 778 ci_otg_del_timer(ci, B_SSEND_SRP);
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 5c20822160ea..a32c18cffd62 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1463,6 +1463,17 @@ static const struct usb_ep_ops usb_ep_ops = {
1463/****************************************************************************** 1463/******************************************************************************
1464 * GADGET block 1464 * GADGET block
1465 *****************************************************************************/ 1465 *****************************************************************************/
1466static bool ci_otg_fsm_charger_conn(struct ci_hdrc *ci)
1467{
1468 /*
1469 * OTG port is in fsm mode
1470 * only do charger notify for b sess valid event, or
1471 * when power up.
1472 */
1473 return !ci_otg_is_fsm_mode(ci) || ci->fsm.power_up ||
1474 ci->b_sess_valid_event;
1475}
1476
1466static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) 1477static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
1467{ 1478{
1468 struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); 1479 struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
@@ -1477,7 +1488,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
1477 spin_unlock_irqrestore(&ci->lock, flags); 1488 spin_unlock_irqrestore(&ci->lock, flags);
1478 1489
1479 /* Charger Detection */ 1490 /* Charger Detection */
1480 if (ci->platdata->notify_event) { 1491 if (ci->platdata->notify_event && ci_otg_fsm_charger_conn(ci)) {
1481 /* 1492 /*
1482 * Keep controller active when the cable is connected, 1493 * Keep controller active when the cable is connected,
1483 * It can make disconnect interrupt (BSV 1->0) occur when 1494 * It can make disconnect interrupt (BSV 1->0) occur when
@@ -1503,6 +1514,9 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
1503 } 1514 }
1504 } 1515 }
1505 1516
1517 if (ci_otg_is_fsm_mode(ci) && ci->b_sess_valid_event)
1518 ci->b_sess_valid_event = false;
1519
1506 if (gadget_ready) { 1520 if (gadget_ready) {
1507 if (is_active) { 1521 if (is_active) {
1508 pm_runtime_get_sync(&_gadget->dev); 1522 pm_runtime_get_sync(&_gadget->dev);