From f6de27eed372f41646b7bd95d6903923f5308517 Mon Sep 17 00:00:00 2001 From: Anton Tikhomirov Date: Thu, 3 Oct 2013 12:42:04 +0900 Subject: [PATCH] usb: phy: Fix OTG FSM timer handling Get rid of using OTG driver specific timers by passing timer type to corresponding callbacks. Signed-off-by: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-fsl-usb.c | 60 +++++++++++++++++++++++++++++++++-- drivers/usb/phy/phy-fsm-usb.c | 28 ++++++++-------- drivers/usb/phy/phy-fsm-usb.h | 24 ++++++++------ 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index 8b34694ac48f..649586169be5 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -375,6 +375,40 @@ void fsl_otg_uninit_timers(void) kfree(b_vbus_pulse_tmr); } +static struct fsl_otg_timer *fsl_otg_get_timer(enum otg_fsm_timer t) +{ + struct fsl_otg_timer *timer; + + /* REVISIT: use array of pointers to timers instead */ + switch (t) { + case A_WAIT_VRISE: + timer = a_wait_vrise_tmr; + break; + case A_WAIT_BCON: + timer = a_wait_vrise_tmr; + break; + case A_AIDL_BDIS: + timer = a_wait_vrise_tmr; + break; + case B_ASE0_BRST: + timer = a_wait_vrise_tmr; + break; + case B_SE0_SRP: + timer = a_wait_vrise_tmr; + break; + case B_SRP_FAIL: + timer = a_wait_vrise_tmr; + break; + case A_WAIT_ENUM: + timer = a_wait_vrise_tmr; + break; + default: + timer = NULL; + } + + return timer; +} + /* Add timer to timer list */ void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) { @@ -394,6 +428,17 @@ void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) list_add_tail(&timer->list, &active_timers); } +static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) +{ + struct fsl_otg_timer *timer; + + timer = fsl_otg_get_timer(t); + if (!timer) + return; + + fsl_otg_add_timer(fsm, timer); +} + /* Remove timer from the timer list; clear timeout status */ void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) { @@ -405,6 +450,17 @@ void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) list_del(&timer->list); } +static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) +{ + struct fsl_otg_timer *timer; + + timer = fsl_otg_get_timer(t); + if (!timer) + return; + + fsl_otg_del_timer(fsm, timer); +} + /* * Reduce timer count by 1, and find timeout conditions. * Called by fsl_otg 1ms timer interrupt @@ -757,8 +813,8 @@ static struct otg_fsm_ops fsl_otg_ops = { .loc_sof = fsl_otg_loc_sof, .start_pulse = fsl_otg_start_pulse, - .add_timer = fsl_otg_add_timer, - .del_timer = fsl_otg_del_timer, + .add_timer = fsl_otg_fsm_add_timer, + .del_timer = fsl_otg_fsm_del_timer, .start_host = fsl_otg_start_host, .start_gadget = fsl_otg_start_gadget, diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c index 78984591ee74..f8fe7ec620e6 100644 --- a/drivers/usb/phy/phy-fsm-usb.c +++ b/drivers/usb/phy/phy-fsm-usb.c @@ -69,7 +69,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) { switch (old_state) { case OTG_STATE_B_IDLE: - otg_del_timer(fsm, b_se0_srp_tmr); + otg_del_timer(fsm, B_SE0_SRP); fsm->b_se0_srp = 0; break; case OTG_STATE_B_SRP_INIT: @@ -78,7 +78,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) case OTG_STATE_B_PERIPHERAL: break; case OTG_STATE_B_WAIT_ACON: - otg_del_timer(fsm, b_ase0_brst_tmr); + otg_del_timer(fsm, B_ASE0_BRST); fsm->b_ase0_brst_tmout = 0; break; case OTG_STATE_B_HOST: @@ -86,25 +86,25 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) case OTG_STATE_A_IDLE: break; case OTG_STATE_A_WAIT_VRISE: - otg_del_timer(fsm, a_wait_vrise_tmr); + otg_del_timer(fsm, A_WAIT_VRISE); fsm->a_wait_vrise_tmout = 0; break; case OTG_STATE_A_WAIT_BCON: - otg_del_timer(fsm, a_wait_bcon_tmr); + otg_del_timer(fsm, A_WAIT_BCON); fsm->a_wait_bcon_tmout = 0; break; case OTG_STATE_A_HOST: - otg_del_timer(fsm, a_wait_enum_tmr); + otg_del_timer(fsm, A_WAIT_ENUM); break; case OTG_STATE_A_SUSPEND: - otg_del_timer(fsm, a_aidl_bdis_tmr); + otg_del_timer(fsm, A_AIDL_BDIS); fsm->a_aidl_bdis_tmout = 0; fsm->a_suspend_req = 0; break; case OTG_STATE_A_PERIPHERAL: break; case OTG_STATE_A_WAIT_VFALL: - otg_del_timer(fsm, a_wait_vrise_tmr); + otg_del_timer(fsm, A_WAIT_VRISE); break; case OTG_STATE_A_VBUS_ERR: break; @@ -128,13 +128,13 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) otg_loc_conn(fsm, 0); otg_loc_sof(fsm, 0); otg_set_protocol(fsm, PROTO_UNDEF); - otg_add_timer(fsm, b_se0_srp_tmr); + otg_add_timer(fsm, B_SE0_SRP); break; case OTG_STATE_B_SRP_INIT: otg_start_pulse(fsm); otg_loc_sof(fsm, 0); otg_set_protocol(fsm, PROTO_UNDEF); - otg_add_timer(fsm, b_srp_fail_tmr); + otg_add_timer(fsm, B_SRP_FAIL); break; case OTG_STATE_B_PERIPHERAL: otg_chrg_vbus(fsm, 0); @@ -147,7 +147,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) otg_loc_conn(fsm, 0); otg_loc_sof(fsm, 0); otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, b_ase0_brst_tmr); + otg_add_timer(fsm, B_ASE0_BRST); fsm->a_bus_suspend = 0; break; case OTG_STATE_B_HOST: @@ -170,14 +170,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) otg_loc_conn(fsm, 0); otg_loc_sof(fsm, 0); otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_wait_vrise_tmr); + otg_add_timer(fsm, A_WAIT_VRISE); break; case OTG_STATE_A_WAIT_BCON: otg_drv_vbus(fsm, 1); otg_loc_conn(fsm, 0); otg_loc_sof(fsm, 0); otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_wait_bcon_tmr); + otg_add_timer(fsm, A_WAIT_BCON); break; case OTG_STATE_A_HOST: otg_drv_vbus(fsm, 1); @@ -189,14 +189,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) * suspend too fast to complete a_set_b_hnp_en */ if (!fsm->a_bus_req || fsm->a_suspend_req) - otg_add_timer(fsm, a_wait_enum_tmr); + otg_add_timer(fsm, A_WAIT_ENUM); break; case OTG_STATE_A_SUSPEND: otg_drv_vbus(fsm, 1); otg_loc_conn(fsm, 0); otg_loc_sof(fsm, 0); otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_aidl_bdis_tmr); + otg_add_timer(fsm, A_AIDL_BDIS); break; case OTG_STATE_A_PERIPHERAL: diff --git a/drivers/usb/phy/phy-fsm-usb.h b/drivers/usb/phy/phy-fsm-usb.h index 157f10672767..b47b32c6ed1f 100644 --- a/drivers/usb/phy/phy-fsm-usb.h +++ b/drivers/usb/phy/phy-fsm-usb.h @@ -34,6 +34,17 @@ #define PROTO_HOST (1) #define PROTO_GADGET (2) +enum otg_fsm_timer { + A_WAIT_VRISE, + A_WAIT_BCON, + A_AIDL_BDIS, + B_ASE0_BRST, + B_SE0_SRP, + B_SRP_FAIL, + A_WAIT_ENUM, + NUM_OTG_FSM_TIMERS, +}; + /* OTG state machine according to the OTG spec */ struct otg_fsm { /* Input */ @@ -88,8 +99,8 @@ struct otg_fsm_ops { void (*loc_conn)(struct otg_fsm *fsm, int on); void (*loc_sof)(struct otg_fsm *fsm, int on); void (*start_pulse)(struct otg_fsm *fsm); - void (*add_timer)(struct otg_fsm *fsm, void *timer); - void (*del_timer)(struct otg_fsm *fsm, void *timer); + void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); + void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); int (*start_host)(struct otg_fsm *fsm, int on); int (*start_gadget)(struct otg_fsm *fsm, int on); }; @@ -144,7 +155,7 @@ static inline int otg_start_pulse(struct otg_fsm *fsm) return 0; } -static inline int otg_add_timer(struct otg_fsm *fsm, void *timer) +static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer) { if (!fsm->ops->add_timer) return -EOPNOTSUPP; @@ -152,7 +163,7 @@ static inline int otg_add_timer(struct otg_fsm *fsm, void *timer) return 0; } -static inline int otg_del_timer(struct otg_fsm *fsm, void *timer) +static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer) { if (!fsm->ops->del_timer) return -EOPNOTSUPP; @@ -175,8 +186,3 @@ static inline int otg_start_gadget(struct otg_fsm *fsm, int on) } int otg_statemachine(struct otg_fsm *fsm); - -/* Defined by device specific driver, for different timer implementation */ -extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, - *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr, - *a_wait_enum_tmr; -- 2.30.2