On Wed, Jan 08, 2014 at 05:06:21PM +0800, Li Jun wrote: > This patch adds OTG fsm timers initialization, which use controller's 1ms > interrupt as time out counter, also adds some local timers which are not timeout? > in otg_fsm_timer list. > > Signed-off-by: Li Jun <b47624@xxxxxxxxxxxxx> > --- > drivers/usb/chipidea/otg_fsm.c | 111 +++++++++++++++++++++++++++++++++++++++- > drivers/usb/chipidea/otg_fsm.h | 65 +++++++++++++++++++++++ > 2 files changed, 175 insertions(+), 1 deletions(-) > > diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c > index 31a046d..86bed68 100644 > --- a/drivers/usb/chipidea/otg_fsm.c > +++ b/drivers/usb/chipidea/otg_fsm.c > @@ -33,7 +33,23 @@ static struct list_head active_timers; > /* FSM timers */ > struct ci_otg_fsm_timer *a_wait_vrise_tmr, *a_wait_vfall_tmr, *a_wait_bcon_tmr, > *a_aidl_bdis_tmr, *a_bidl_adis_tmr, *b_ase0_brst_tmr, > - *b_se0_srp_tmr, *b_srp_fail_tmr, *b_data_pulse_tmr; > + *b_se0_srp_tmr, *b_srp_fail_tmr, *b_data_pulse_tmr, > + *b_ssend_srp_tmr, *b_sess_vld_tmr; > + > +inline struct ci_otg_fsm_timer *otg_timer_initializer > +(void (*function)(void *, unsigned long), unsigned long expires, > + unsigned long data) > +{ > + struct ci_otg_fsm_timer *timer; > + > + timer = kmalloc(sizeof(struct ci_otg_fsm_timer), GFP_KERNEL); Does devm_kzalloc can be used? Peter > + if (!timer) > + return NULL; > + timer->function = function; > + timer->expires = expires; > + timer->data = data; > + return timer; > +} > > /* Add timer to timer list */ > void ci_otg_add_timer(struct ci_hdrc *ci, struct ci_otg_fsm_timer *gtimer) > @@ -170,6 +186,89 @@ int ci_otg_tick_timer(struct ci_hdrc *ci) > return expired; > } > > +/* The timeout callback function to set time out bit */ > +void set_tmout(void *ptr, unsigned long indicator) > +{ > + *(int *)indicator = 1; > +} > + > +/* Initialize timers */ > +int ci_otg_init_timers(struct otg_fsm *fsm) > +{ > + /* FSM used timers */ > + a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, > + (unsigned long)&fsm->a_wait_vrise_tmout); > + if (a_wait_vrise_tmr == NULL) > + return -ENOMEM; > + > + a_wait_vfall_tmr = otg_timer_initializer(&set_tmout, > + TA_WAIT_VFALL, (unsigned long)&fsm->a_wait_vfall_tmout); > + if (a_wait_vfall_tmr == NULL) > + return -ENOMEM; > + > + a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, > + TA_WAIT_BCON, (unsigned long)&fsm->a_wait_bcon_tmout); > + if (a_wait_bcon_tmr == NULL) > + return -ENOMEM; > + > + a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, > + TA_AIDL_BDIS, (unsigned long)&fsm->a_aidl_bdis_tmout); > + if (a_aidl_bdis_tmr == NULL) > + return -ENOMEM; > + > + a_bidl_adis_tmr = otg_timer_initializer(&set_tmout, > + TA_BIDL_ADIS, (unsigned long)&fsm->a_bidl_adis_tmout); > + if (a_bidl_adis_tmr == NULL) > + return -ENOMEM; > + > + b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, > + (unsigned long)&fsm->b_ase0_brst_tmout); > + if (b_ase0_brst_tmr == NULL) > + return -ENOMEM; > + > + b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, > + (unsigned long)&fsm->b_se0_srp); > + if (b_se0_srp_tmr == NULL) > + return -ENOMEM; > + > + b_ssend_srp_tmr = otg_timer_initializer(&set_tmout, > + TB_SSEND_SRP, (unsigned long)&fsm->b_ssend_srp); > + if (b_ssend_srp_tmr == NULL) > + return -ENOMEM; > + > + b_srp_fail_tmr = otg_timer_initializer(&set_tmout, > + TB_SRP_FAIL, (unsigned long)&fsm->b_srp_done); > + if (b_srp_fail_tmr == NULL) > + return -ENOMEM; > + > + b_data_pulse_tmr = otg_timer_initializer(&set_tmout, TB_DATA_PLS, 0); > + if (b_data_pulse_tmr == NULL) > + return -ENOMEM; > + > + b_sess_vld_tmr = otg_timer_initializer(&set_tmout, TB_SESS_VLD, 0); > + if (b_sess_vld_tmr == NULL) > + return -ENOMEM; > + > + return 0; > +} > + > +/* Uninitialize timers */ > +void ci_otg_uninit_timers(void) > +{ > + /* FSM used timers */ > + kfree(a_wait_vrise_tmr); > + kfree(a_wait_vfall_tmr); > + kfree(a_wait_bcon_tmr); > + kfree(a_aidl_bdis_tmr); > + kfree(a_bidl_adis_tmr); > + kfree(b_ase0_brst_tmr); > + kfree(b_se0_srp_tmr); > + kfree(b_ssend_srp_tmr); > + kfree(b_srp_fail_tmr); > + kfree(b_data_pulse_tmr); > + kfree(b_sess_vld_tmr); > +} > + > /* -------------------------------------------------------------*/ > /* Operations that will be called from OTG Finite State Machine */ > > @@ -337,6 +436,8 @@ static struct otg_fsm_ops ci_otg_ops = { > > int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) > { > + int retval = 0; > + > if (ci->transceiver == NULL) > return -EPROBE_DEFER; > > @@ -366,6 +467,14 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) > > mutex_init(&ci->fsm->lock); > > + INIT_LIST_HEAD(&active_timers); > + retval = ci_otg_init_timers(ci->fsm); > + if (retval) { > + dev_err(ci->dev, "Couldn't init OTG timers\n"); > + ci_otg_uninit_timers(); > + return retval; > + } > + > /* enable ID and A vbus valid irq */ > hw_write(ci, OP_OTGSC, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS, > OTGSC_IDIE | OTGSC_AVVIE); > diff --git a/drivers/usb/chipidea/otg_fsm.h b/drivers/usb/chipidea/otg_fsm.h > index e1b45d7..6e8226a 100644 > --- a/drivers/usb/chipidea/otg_fsm.h > +++ b/drivers/usb/chipidea/otg_fsm.h > @@ -11,6 +11,71 @@ > #ifndef __DRIVERS_USB_CHIPIDEA_OTG_FSM_H > #define __DRIVERS_USB_CHIPIDEA_OTG_FSM_H > > +/* > + * A-DEVICE timing constants > + */ > + > +/* Wait for VBUS Rise */ > +#define TA_WAIT_VRISE (100) /* a_wait_vrise 100 ms, section: 6.6.5.1 */ > + > +/* Wait for VBUS Fall */ > +#define TA_WAIT_VFALL (1000) /* a_wait_vfall: Used by A device to wait > + * Vbus to fall below Votg_bus_lkg 7.4.5.2 > + * TSSEND_LKG 1 sec */ > +/* Wait for B-Connect */ > +#define TA_WAIT_BCON (10000) /* a_wait_bcon > 1 sec, section: 6.6.5.2 > + * This is only used to get out of > + * OTG_STATE_A_WAIT_BCON state if there was > + * no connection for these many milliseconds > + */ > + > +/* A-Idle to B-Disconnect */ > +/* It is necessary for this timer to be more than 750 ms because of a bug in OPT > + * test 5.4 in which B OPT disconnects after 750 ms instead of 75ms as stated > + * in the test description > + */ > +#define TA_AIDL_BDIS (5000) /* a_suspend minimum 200 ms, section: 6.6.5.3 */ > + > +/* B-Idle to A-Disconnect */ > +#define TA_BIDL_ADIS (500) /* 3 to 200 ms */ > + > +/* B-device timing constants */ > + > + > +/* Data-Line Pulse Time*/ > +#define TB_DATA_PLS (10) /* b_srp_init,continue 5~10ms, section:5.3.3 */ > +#define TB_DATA_PLS_MIN (5) /* minimum 5 ms */ > +#define TB_DATA_PLS_MAX (10) /* maximum 10 ms */ > + > +/* SRP Initiate Time */ > +#define TB_SRP_INIT (100) /* b_srp_init,maximum 100 ms, section:5.3.8 */ > + > +/* SRP Fail Time */ > +#define TB_SRP_FAIL (7000) /* b_srp_init,Fail time 5~30s, section:6.8.2.2*/ > + > +/* SRP result wait time */ > +#define TB_SRP_WAIT (60) > + > +/* VBus time */ > +#define TB_VBUS_PLS (30) /* time to keep vbus pulsing asserted */ > + > +/* Discharge time */ > +/* This time should be less than 10ms. It varies from system to system. */ > +#define TB_VBUS_DSCHRG (8) > + > +/* A-SE0 to B-Reset */ > +#define TB_ASE0_BRST (20) /* b_wait_acon, mini 3.125 ms,section:6.8.2.4 */ > + > +/* A bus suspend timer before we can switch to b_wait_aconn */ > +#define TB_A_SUSPEND (7) > +#define TB_BUS_RESUME (12) > + > +/* SE0 Time Before SRP */ > +#define TB_SE0_SRP (2) /* b_idle,minimum 2 ms, section:5.3.2 */ > +/* SSEND time before SRP, 1.5 sec min */ > +#define TB_SSEND_SRP (1500) /* Table 5-1, Session end to SRP init */ > +#define TB_SESS_VLD (1000) > + > struct ci_otg_fsm_timer { > unsigned long expires; /* Number of count increase to timeout */ > unsigned long count; /* Tick counter */ > -- > 1.7.8 > > -- Best Regards, Peter Chen -- 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