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 <av.tikhomirov@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
425d710172
commit
f6de27eed3
3 changed files with 87 additions and 25 deletions
|
@ -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)
|
||||||
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)
|
||||||
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 = {
|
||||||
.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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
* 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 @@
|
||||||
#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 {
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue