Commit f6de27ee authored by Anton Tikhomirov's avatar Anton Tikhomirov Committed by Felipe Balbi

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: default avatarAnton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 425d7101
...@@ -375,6 +375,40 @@ void fsl_otg_uninit_timers(void) ...@@ -375,6 +375,40 @@ void fsl_otg_uninit_timers(void)
kfree(b_vbus_pulse_tmr); 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 */ /* Add timer to timer list */
void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) 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) ...@@ -394,6 +428,17 @@ void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer)
list_add_tail(&timer->list, &active_timers); 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 */ /* Remove timer from the timer list; clear timeout status */
void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) 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) ...@@ -405,6 +450,17 @@ void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer)
list_del(&timer->list); 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. * Reduce timer count by 1, and find timeout conditions.
* Called by fsl_otg 1ms timer interrupt * Called by fsl_otg 1ms timer interrupt
...@@ -757,8 +813,8 @@ static struct otg_fsm_ops fsl_otg_ops = { ...@@ -757,8 +813,8 @@ static struct otg_fsm_ops fsl_otg_ops = {
.loc_sof = fsl_otg_loc_sof, .loc_sof = fsl_otg_loc_sof,
.start_pulse = fsl_otg_start_pulse, .start_pulse = fsl_otg_start_pulse,
.add_timer = fsl_otg_add_timer, .add_timer = fsl_otg_fsm_add_timer,
.del_timer = fsl_otg_del_timer, .del_timer = fsl_otg_fsm_del_timer,
.start_host = fsl_otg_start_host, .start_host = fsl_otg_start_host,
.start_gadget = fsl_otg_start_gadget, .start_gadget = fsl_otg_start_gadget,
......
...@@ -69,7 +69,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) ...@@ -69,7 +69,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
{ {
switch (old_state) { switch (old_state) {
case OTG_STATE_B_IDLE: 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; fsm->b_se0_srp = 0;
break; break;
case OTG_STATE_B_SRP_INIT: case OTG_STATE_B_SRP_INIT:
...@@ -78,7 +78,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) ...@@ -78,7 +78,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_PERIPHERAL:
break; break;
case OTG_STATE_B_WAIT_ACON: 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; fsm->b_ase0_brst_tmout = 0;
break; break;
case OTG_STATE_B_HOST: case OTG_STATE_B_HOST:
...@@ -86,25 +86,25 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) ...@@ -86,25 +86,25 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
case OTG_STATE_A_IDLE: case OTG_STATE_A_IDLE:
break; break;
case OTG_STATE_A_WAIT_VRISE: 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; fsm->a_wait_vrise_tmout = 0;
break; break;
case OTG_STATE_A_WAIT_BCON: 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; fsm->a_wait_bcon_tmout = 0;
break; break;
case OTG_STATE_A_HOST: case OTG_STATE_A_HOST:
otg_del_timer(fsm, a_wait_enum_tmr); otg_del_timer(fsm, A_WAIT_ENUM);
break; break;
case OTG_STATE_A_SUSPEND: 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_aidl_bdis_tmout = 0;
fsm->a_suspend_req = 0; fsm->a_suspend_req = 0;
break; break;
case OTG_STATE_A_PERIPHERAL: case OTG_STATE_A_PERIPHERAL:
break; break;
case OTG_STATE_A_WAIT_VFALL: case OTG_STATE_A_WAIT_VFALL:
otg_del_timer(fsm, a_wait_vrise_tmr); otg_del_timer(fsm, A_WAIT_VRISE);
break; break;
case OTG_STATE_A_VBUS_ERR: case OTG_STATE_A_VBUS_ERR:
break; break;
...@@ -128,13 +128,13 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) ...@@ -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_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_UNDEF); otg_set_protocol(fsm, PROTO_UNDEF);
otg_add_timer(fsm, b_se0_srp_tmr); otg_add_timer(fsm, B_SE0_SRP);
break; break;
case OTG_STATE_B_SRP_INIT: case OTG_STATE_B_SRP_INIT:
otg_start_pulse(fsm); otg_start_pulse(fsm);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_UNDEF); otg_set_protocol(fsm, PROTO_UNDEF);
otg_add_timer(fsm, b_srp_fail_tmr); otg_add_timer(fsm, B_SRP_FAIL);
break; break;
case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_PERIPHERAL:
otg_chrg_vbus(fsm, 0); otg_chrg_vbus(fsm, 0);
...@@ -147,7 +147,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) ...@@ -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_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_HOST); 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; fsm->a_bus_suspend = 0;
break; break;
case OTG_STATE_B_HOST: case OTG_STATE_B_HOST:
...@@ -170,14 +170,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) ...@@ -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_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_HOST); otg_set_protocol(fsm, PROTO_HOST);
otg_add_timer(fsm, a_wait_vrise_tmr); otg_add_timer(fsm, A_WAIT_VRISE);
break; break;
case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_BCON:
otg_drv_vbus(fsm, 1); otg_drv_vbus(fsm, 1);
otg_loc_conn(fsm, 0); otg_loc_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_HOST); otg_set_protocol(fsm, PROTO_HOST);
otg_add_timer(fsm, a_wait_bcon_tmr); otg_add_timer(fsm, A_WAIT_BCON);
break; break;
case OTG_STATE_A_HOST: case OTG_STATE_A_HOST:
otg_drv_vbus(fsm, 1); otg_drv_vbus(fsm, 1);
...@@ -189,14 +189,14 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) ...@@ -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 * suspend too fast to complete a_set_b_hnp_en
*/ */
if (!fsm->a_bus_req || fsm->a_suspend_req) 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; break;
case OTG_STATE_A_SUSPEND: case OTG_STATE_A_SUSPEND:
otg_drv_vbus(fsm, 1); otg_drv_vbus(fsm, 1);
otg_loc_conn(fsm, 0); otg_loc_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_HOST); otg_set_protocol(fsm, PROTO_HOST);
otg_add_timer(fsm, a_aidl_bdis_tmr); otg_add_timer(fsm, A_AIDL_BDIS);
break; break;
case OTG_STATE_A_PERIPHERAL: case OTG_STATE_A_PERIPHERAL:
......
...@@ -34,6 +34,17 @@ ...@@ -34,6 +34,17 @@
#define PROTO_HOST (1) #define PROTO_HOST (1)
#define PROTO_GADGET (2) #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 */ /* OTG state machine according to the OTG spec */
struct otg_fsm { struct otg_fsm {
/* Input */ /* Input */
...@@ -88,8 +99,8 @@ struct otg_fsm_ops { ...@@ -88,8 +99,8 @@ struct otg_fsm_ops {
void (*loc_conn)(struct otg_fsm *fsm, int on); void (*loc_conn)(struct otg_fsm *fsm, int on);
void (*loc_sof)(struct otg_fsm *fsm, int on); void (*loc_sof)(struct otg_fsm *fsm, int on);
void (*start_pulse)(struct otg_fsm *fsm); void (*start_pulse)(struct otg_fsm *fsm);
void (*add_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, void *timer); void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
int (*start_host)(struct otg_fsm *fsm, int on); int (*start_host)(struct otg_fsm *fsm, int on);
int (*start_gadget)(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) ...@@ -144,7 +155,7 @@ static inline int otg_start_pulse(struct otg_fsm *fsm)
return 0; 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) if (!fsm->ops->add_timer)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -152,7 +163,7 @@ static inline int otg_add_timer(struct otg_fsm *fsm, void *timer) ...@@ -152,7 +163,7 @@ static inline int otg_add_timer(struct otg_fsm *fsm, void *timer)
return 0; 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) if (!fsm->ops->del_timer)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -175,8 +186,3 @@ static inline int otg_start_gadget(struct otg_fsm *fsm, int on) ...@@ -175,8 +186,3 @@ static inline int otg_start_gadget(struct otg_fsm *fsm, int on)
} }
int otg_statemachine(struct otg_fsm *fsm); 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;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment