diff options
author | Li Jun <b47624@freescale.com> | 2014-06-23 04:11:12 -0400 |
---|---|---|
committer | Li Jun <B47624@freescale.com> | 2014-06-26 04:50:40 -0400 |
commit | f3dd2721c55fe5777ee2ba1e8c8317058a24173f (patch) | |
tree | 54304dec3775908d09d74db120a9816bfb2f0f3c /drivers | |
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')
-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 { | |||
154 | bool is_otg; | 154 | bool is_otg; |
155 | struct otg_fsm fsm; | 155 | struct otg_fsm fsm; |
156 | struct ci_otg_fsm_timer_list *fsm_timer; | 156 | struct ci_otg_fsm_timer_list *fsm_timer; |
157 | struct timer_list hnp_polling_timer; | ||
158 | bool hnp_polling_req; | ||
157 | struct work_struct work; | 159 | struct work_struct work; |
158 | struct workqueue_struct *wq; | 160 | struct workqueue_struct *wq; |
159 | 161 | ||
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) | |||
369 | ci_otg_queue_work(ci); | 369 | ci_otg_queue_work(ci); |
370 | } | 370 | } |
371 | 371 | ||
372 | static void hnp_polling_timer_work(unsigned long arg) | ||
373 | { | ||
374 | struct ci_hdrc *ci = (struct ci_hdrc *)arg; | ||
375 | |||
376 | ci->hnp_polling_req = true; | ||
377 | ci_otg_queue_work(ci); | ||
378 | } | ||
379 | |||
372 | /* Initialize timers */ | 380 | /* Initialize timers */ |
373 | static int ci_otg_init_timers(struct ci_hdrc *ci) | 381 | static int ci_otg_init_timers(struct ci_hdrc *ci) |
374 | { | 382 | { |
@@ -439,9 +447,17 @@ static int ci_otg_init_timers(struct ci_hdrc *ci) | |||
439 | if (ci->fsm_timer->timer_list[B_SESS_VLD] == NULL) | 447 | if (ci->fsm_timer->timer_list[B_SESS_VLD] == NULL) |
440 | return -ENOMEM; | 448 | return -ENOMEM; |
441 | 449 | ||
450 | setup_timer(&ci->hnp_polling_timer, hnp_polling_timer_work, | ||
451 | (unsigned long)ci); | ||
442 | return 0; | 452 | return 0; |
443 | } | 453 | } |
444 | 454 | ||
455 | static void ci_otg_add_hnp_polling_timer(struct ci_hdrc *ci) | ||
456 | { | ||
457 | mod_timer(&ci->hnp_polling_timer, | ||
458 | jiffies + msecs_to_jiffies(T_HOST_REQ_POLL)); | ||
459 | } | ||
460 | |||
445 | /* -------------------------------------------------------------*/ | 461 | /* -------------------------------------------------------------*/ |
446 | /* Operations that will be called from OTG Finite State Machine */ | 462 | /* Operations that will be called from OTG Finite State Machine */ |
447 | /* -------------------------------------------------------------*/ | 463 | /* -------------------------------------------------------------*/ |
@@ -449,8 +465,12 @@ static void ci_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) | |||
449 | { | 465 | { |
450 | struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); | 466 | struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); |
451 | 467 | ||
452 | if (t < NUM_OTG_FSM_TIMERS) | 468 | if (t < NUM_OTG_FSM_TIMERS) { |
453 | ci_otg_add_timer(ci, t); | 469 | if (t == HNP_POLLING) |
470 | ci_otg_add_hnp_polling_timer(ci); | ||
471 | else | ||
472 | ci_otg_add_timer(ci, t); | ||
473 | } | ||
454 | return; | 474 | return; |
455 | } | 475 | } |
456 | 476 | ||
@@ -605,6 +625,14 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) | |||
605 | } | 625 | } |
606 | 626 | ||
607 | pm_runtime_get_sync(ci->dev); | 627 | pm_runtime_get_sync(ci->dev); |
628 | if (ci->hnp_polling_req) { | ||
629 | ci->hnp_polling_req = false; | ||
630 | if (otg_hnp_polling(&ci->fsm) != HOST_REQUEST_FLAG) { | ||
631 | pm_runtime_put_sync(ci->dev); | ||
632 | return 0; | ||
633 | } | ||
634 | } | ||
635 | |||
608 | if (otg_statemachine(&ci->fsm)) { | 636 | if (otg_statemachine(&ci->fsm)) { |
609 | if (ci->transceiver->state == OTG_STATE_A_IDLE) { | 637 | if (ci->transceiver->state == OTG_STATE_A_IDLE) { |
610 | /* | 638 | /* |
@@ -863,4 +891,5 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) | |||
863 | void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci) | 891 | void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci) |
864 | { | 892 | { |
865 | sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group); | 893 | sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group); |
894 | del_timer_sync(&ci->hnp_polling_timer); | ||
866 | } | 895 | } |
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 @@ | |||
64 | 64 | ||
65 | #define TB_SESS_VLD (1000) | 65 | #define TB_SESS_VLD (1000) |
66 | 66 | ||
67 | #define T_HOST_REQ_POLL (1500) /* HNP polling interval 1s~2s */ | ||
68 | |||
67 | enum ci_otg_fsm_timer_index { | 69 | enum ci_otg_fsm_timer_index { |
68 | /* | 70 | /* |
69 | * CI specific timers, start from the end | 71 | * CI specific timers, start from the end |