usb: phy: Add and use missed OTG FSM timers
authorAnton Tikhomirov <av.tikhomirov@samsung.com>
Thu, 3 Oct 2013 03:42:04 +0000 (12:42 +0900)
committerFelipe Balbi <balbi@ti.com>
Fri, 4 Oct 2013 14:44:47 +0000 (09:44 -0500)
a_bidl_adis_tmr and a_wait_vfall_tmr OTG timers missed in
current FSM implementation. This patch adds and makes use
of the timers as speicfied in OTG and EH supplement to USB2.0.

Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/phy/phy-fsm-usb.c
drivers/usb/phy/phy-fsm-usb.h

index f8fe7ec..5e899ed 100644 (file)
@@ -102,8 +102,12 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
                fsm->a_suspend_req = 0;
                break;
        case OTG_STATE_A_PERIPHERAL:
+               otg_del_timer(fsm, A_BIDL_ADIS);
+               fsm->a_bidl_adis_tmout = 0;
                break;
        case OTG_STATE_A_WAIT_VFALL:
+               otg_del_timer(fsm, A_WAIT_VFALL);
+               fsm->a_wait_vfall_tmout = 0;
                otg_del_timer(fsm, A_WAIT_VRISE);
                break;
        case OTG_STATE_A_VBUS_ERR:
@@ -204,12 +208,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_GADGET);
                otg_drv_vbus(fsm, 1);
+               otg_add_timer(fsm, A_BIDL_ADIS);
                break;
        case OTG_STATE_A_WAIT_VFALL:
                otg_drv_vbus(fsm, 0);
                otg_loc_conn(fsm, 0);
                otg_loc_sof(fsm, 0);
                otg_set_protocol(fsm, PROTO_HOST);
+               otg_add_timer(fsm, A_WAIT_VFALL);
                break;
        case OTG_STATE_A_VBUS_ERR:
                otg_drv_vbus(fsm, 0);
@@ -324,14 +330,14 @@ int otg_statemachine(struct otg_fsm *fsm)
        case OTG_STATE_A_PERIPHERAL:
                if (fsm->id || fsm->a_bus_drop)
                        otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
-               else if (fsm->b_bus_suspend)
+               else if (fsm->a_bidl_adis_tmout || fsm->b_bus_suspend)
                        otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
                else if (!fsm->a_vbus_vld)
                        otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
                break;
        case OTG_STATE_A_WAIT_VFALL:
-               if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld &&
-                                       !fsm->b_conn))
+               if (fsm->a_wait_vfall_tmout || fsm->id || fsm->a_bus_req ||
+                               (!fsm->a_sess_vld && !fsm->b_conn))
                        otg_set_state(fsm, OTG_STATE_A_IDLE);
                break;
        case OTG_STATE_A_VBUS_ERR:
index b47b32c..a74e14a 100644 (file)
 #define PROTO_GADGET   (2)
 
 enum otg_fsm_timer {
+       /* Standard OTG timers */
        A_WAIT_VRISE,
+       A_WAIT_VFALL,
        A_WAIT_BCON,
        A_AIDL_BDIS,
        B_ASE0_BRST,
+       A_BIDL_ADIS,
+
+       /* Auxiliary timers */
        B_SE0_SRP,
        B_SRP_FAIL,
        A_WAIT_ENUM,
+
        NUM_OTG_FSM_TIMERS,
 };
 
@@ -69,9 +75,11 @@ struct otg_fsm {
 
        /* Timeout indicator for timers */
        int a_wait_vrise_tmout;
+       int a_wait_vfall_tmout;
        int a_wait_bcon_tmout;
        int a_aidl_bdis_tmout;
        int b_ase0_brst_tmout;
+       int a_bidl_adis_tmout;
 
        /* Informative variables */
        int a_bus_drop;