diff options
author | Li Jun <b47624@freescale.com> | 2014-06-23 16:11:12 +0800 |
---|---|---|
committer | Li Jun <B47624@freescale.com> | 2014-06-26 16:50:40 +0800 |
commit | f3dd2721c55fe5777ee2ba1e8c8317058a24173f (patch) | |
tree | 54304dec3775908d09d74db120a9816bfb2f0f3c /drivers/usb | |
parent | bc88a95b09a1b9aecbe0c1e21a04abf6c0821b4e (diff) |
ENGR00319720-6 usb: chipidea: otg_fsm: add HNP polling support
This patch adds HNP polling support for chipidea otg fsm driver, which
adds a SW timer to send HNP polling request.
Signed-off-by: Li Jun <b47624@freescale.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/chipidea/ci.h | 2 | ||||
-rw-r--r-- | drivers/usb/chipidea/otg_fsm.c | 33 | ||||
-rw-r--r-- | drivers/usb/chipidea/otg_fsm.h | 2 |
3 files changed, 35 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index cbd333edbec0..a52f9d38dc89 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -154,6 +154,8 @@ struct ci_hdrc { bool is_otg; struct otg_fsm fsm; struct ci_otg_fsm_timer_list *fsm_timer; + struct timer_list hnp_polling_timer; + bool hnp_polling_req; struct work_struct work; struct workqueue_struct *wq; diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index fc9d865d0f25..59454bfadf06 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -369,6 +369,14 @@ static void b_data_pulse_end(void *ptr, unsigned long indicator) ci_otg_queue_work(ci); } +static void hnp_polling_timer_work(unsigned long arg) +{ + struct ci_hdrc *ci = (struct ci_hdrc *)arg; + + ci->hnp_polling_req = true; + ci_otg_queue_work(ci); +} + /* Initialize timers */ static int ci_otg_init_timers(struct ci_hdrc *ci) { @@ -439,9 +447,17 @@ static int ci_otg_init_timers(struct ci_hdrc *ci) if (ci->fsm_timer->timer_list[B_SESS_VLD] == NULL) return -ENOMEM; + setup_timer(&ci->hnp_polling_timer, hnp_polling_timer_work, + (unsigned long)ci); return 0; } +static void ci_otg_add_hnp_polling_timer(struct ci_hdrc *ci) +{ + mod_timer(&ci->hnp_polling_timer, + jiffies + msecs_to_jiffies(T_HOST_REQ_POLL)); +} + /* -------------------------------------------------------------*/ /* Operations that will be called from OTG Finite State Machine */ /* -------------------------------------------------------------*/ @@ -449,8 +465,12 @@ static void ci_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) { struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); - if (t < NUM_OTG_FSM_TIMERS) - ci_otg_add_timer(ci, t); + if (t < NUM_OTG_FSM_TIMERS) { + if (t == HNP_POLLING) + ci_otg_add_hnp_polling_timer(ci); + else + ci_otg_add_timer(ci, t); + } return; } @@ -605,6 +625,14 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) } pm_runtime_get_sync(ci->dev); + if (ci->hnp_polling_req) { + ci->hnp_polling_req = false; + if (otg_hnp_polling(&ci->fsm) != HOST_REQUEST_FLAG) { + pm_runtime_put_sync(ci->dev); + return 0; + } + } + if (otg_statemachine(&ci->fsm)) { if (ci->transceiver->state == OTG_STATE_A_IDLE) { /* @@ -863,4 +891,5 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci) { sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group); + del_timer_sync(&ci->hnp_polling_timer); } diff --git a/drivers/usb/chipidea/otg_fsm.h b/drivers/usb/chipidea/otg_fsm.h index 94c085f456a9..2cfffb7061e1 100644 --- a/drivers/usb/chipidea/otg_fsm.h +++ b/drivers/usb/chipidea/otg_fsm.h @@ -64,6 +64,8 @@ #define TB_SESS_VLD (1000) +#define T_HOST_REQ_POLL (1500) /* HNP polling interval 1s~2s */ + enum ci_otg_fsm_timer_index { /* * CI specific timers, start from the end |