aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/otg_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea/otg_fsm.c')
-rw-r--r--drivers/usb/chipidea/otg_fsm.c33
1 files changed, 31 insertions, 2 deletions
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
372static 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 */
373static int ci_otg_init_timers(struct ci_hdrc *ci) 381static 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
455static 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)
863void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci) 891void 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}