From: Hao Wu <hao.wu@xxxxxxxxx> The patch updated the OTG state machine for HNP. Main change: - Update events in OTG state machine. - Update show_hsm function for debug. Signed-off-by: Hao Wu <hao.wu@xxxxxxxxx> Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx> --- drivers/usb/otg/langwell_otg.c | 31 +++++++++++++++++++++---------- 1 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index 0811fb7..618b84d 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -977,7 +977,8 @@ static void langwell_otg_work(struct work_struct *work) "client driver has been removed.\n"); lnw->otg.state = OTG_STATE_B_IDLE; - } else if (lnw->hsm.b_bus_req && lnw->hsm.b_hnp_enable + } else if (lnw->hsm.b_bus_req && lnw->otg.gadget + && lnw->otg.gadget->b_hnp_enable && lnw->hsm.a_bus_suspend) { if (lnw->client_ops) { @@ -1007,6 +1008,7 @@ static void langwell_otg_work(struct work_struct *work) if (!lnw->hsm.id) { /* delete hsm timer for b_ase0_brst_tmr */ del_timer_sync(&lnw->hsm_timer); + lnw->otg.default_a = 1; lnw->hsm.a_srp_det = 0; @@ -1025,6 +1027,7 @@ static void langwell_otg_work(struct work_struct *work) } else if (!lnw->hsm.b_sess_vld) { /* delete hsm timer for b_ase0_brst_tmr */ del_timer_sync(&lnw->hsm_timer); + lnw->hsm.b_hnp_enable = 0; lnw->hsm.b_bus_req = 0; langwell_otg_chrg_vbus(0); @@ -1077,6 +1080,7 @@ static void langwell_otg_work(struct work_struct *work) lnw->hsm.a_srp_det = 0; langwell_otg_chrg_vbus(0); + if (lnw->host_ops) lnw->host_ops->remove(lnw->pdev); else @@ -1136,19 +1140,19 @@ static void langwell_otg_work(struct work_struct *work) (lnw->hsm.a_srp_det || lnw->hsm.a_bus_req)) { langwell_otg_phy_low_power(0); langwell_otg_drv_vbus(1); - lnw->hsm.a_srp_det = 1; + lnw->hsm.vbus_srp_up = 0; lnw->hsm.a_wait_vrise_tmout = 0; langwell_otg_add_timer(a_wait_vrise_tmr); lnw->otg.state = OTG_STATE_A_WAIT_VRISE; queue_work(lnw->qwork, &lnw->work); - } else if (lnw->hsm.a_sess_vld) { + } else if (!lnw->hsm.a_bus_drop && lnw->hsm.a_sess_vld) { lnw->hsm.vbus_srp_up = 1; - } else if (!lnw->hsm.a_sess_vld && - lnw->hsm.vbus_srp_up) { + } else if (!lnw->hsm.a_sess_vld && lnw->hsm.vbus_srp_up) { msleep(10); langwell_otg_phy_low_power(0); langwell_otg_drv_vbus(1); lnw->hsm.a_srp_det = 1; + lnw->hsm.vbus_srp_up = 0; lnw->hsm.a_wait_vrise_tmout = 0; langwell_otg_add_timer(a_wait_vrise_tmr); lnw->otg.state = OTG_STATE_A_WAIT_VRISE; @@ -1166,10 +1170,10 @@ static void langwell_otg_work(struct work_struct *work) langwell_otg_drv_vbus(0); set_client_mode(); langwell_otg_phy_low_power_wait(1); - lnw->otg.state = OTG_STATE_B_IDLE; } else if (lnw->hsm.a_vbus_vld) { langwell_otg_del_timer(a_wait_vrise_tmr); + lnw->hsm.b_conn = 0; if (lnw->host_ops) lnw->host_ops->probe(lnw->pdev, lnw->host_ops->id_table); @@ -1178,10 +1182,11 @@ static void langwell_otg_work(struct work_struct *work) "host driver not loaded.\n"); break; } - lnw->hsm.b_conn = 0; + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); lnw->otg.state = OTG_STATE_A_WAIT_BCON; } else if (lnw->hsm.a_wait_vrise_tmout) { + lnw->hsm.b_conn = 0; if (lnw->hsm.a_vbus_vld) { if (lnw->host_ops) lnw->host_ops->probe( @@ -1192,7 +1197,6 @@ static void langwell_otg_work(struct work_struct *work) "host driver not loaded.\n"); break; } - lnw->hsm.b_conn = 0; langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); lnw->otg.state = OTG_STATE_A_WAIT_BCON; } else { @@ -1256,7 +1260,7 @@ static void langwell_otg_work(struct work_struct *work) lnw->hsm.a_bus_req = 1; lnw->hsm.a_srp_det = 0; } else if (!lnw->hsm.a_bus_req && - lnw->hsm.a_set_b_hnp_en) { + lnw->otg.host->b_hnp_enable) { /* It is not safe enough to do a fast * transistion from A_WAIT_BCON to * A_SUSPEND */ @@ -1407,7 +1411,6 @@ static void langwell_otg_work(struct work_struct *work) lnw->hsm.b_bus_suspend = 0; lnw->hsm.b_bus_suspend_vld = 0; - lnw->hsm.b_bus_suspend_tmout = 0; /* msleep(200); */ if (lnw->client_ops) @@ -1607,6 +1610,12 @@ show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) next = buf; size = PAGE_SIZE; + if (lnw->otg.host) + lnw->hsm.a_set_b_hnp_en = lnw->otg.host->b_hnp_enable; + + if (lnw->otg.gadget) + lnw->hsm.b_hnp_enable = lnw->otg.gadget->b_hnp_enable; + t = scnprintf(next, size, "\n" "current state = %s\n" @@ -1623,6 +1632,7 @@ show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) "b_sess_end = \t%d\n" "b_sess_vld = \t%d\n" "id = \t%d\n" + "a_set_b_hnp_en = \t%d\n" "b_srp_done = \t%d\n" "b_hnp_enable = \t%d\n" "a_wait_vrise_tmout = \t%d\n" @@ -1650,6 +1660,7 @@ show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) lnw->hsm.b_sess_end, lnw->hsm.b_sess_vld, lnw->hsm.id, + lnw->hsm.a_set_b_hnp_en, lnw->hsm.b_srp_done, lnw->hsm.b_hnp_enable, lnw->hsm.a_wait_vrise_tmout, -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html