On Wed, May 28, 2014 at 03:09:17PM +0800, Li Jun wrote:
> From: Li Jun <b47...@freescale.com>
> 
> 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 <b47...@freescale.com>
> ---
>  drivers/usb/chipidea/ci.h      |    2 ++
>  drivers/usb/chipidea/otg_fsm.c |   32 ++++++++++++++++++++++++++++++--
>  drivers/usb/chipidea/otg_fsm.h |    2 ++
>  3 files changed, 34 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index 9563cb5..9a7f1fd 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -179,6 +179,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 8d4c33d..923b789 100644
> --- a/drivers/usb/chipidea/otg_fsm.c
> +++ b/drivers/usb/chipidea/otg_fsm.c
> @@ -369,6 +369,15 @@ static void b_data_pulse_end(void *ptr, unsigned long 
> indicator)
>       queue_work(ci->wq, &ci->work);
>  }
>  
> +static void hnp_polling_timer_work(unsigned long arg)
> +{
> +     struct ci_hdrc *ci = (struct ci_hdrc *)arg;
> +
> +     ci->hnp_polling_req = true;
> +     disable_irq_nosync(ci->irq);
> +     queue_work(ci->wq, &ci->work);
> +}
> +
>  /* Initialize timers */
>  static int ci_otg_init_timers(struct ci_hdrc *ci)
>  {
> @@ -439,9 +448,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 +466,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;
>  }
>  
> @@ -596,6 +617,12 @@ int ci_otg_fsm_work(struct ci_hdrc *ci)
>               ci->transceiver->state < OTG_STATE_A_IDLE)
>               return 0;
>  
> +     if (ci->hnp_polling_req) {
> +             ci->hnp_polling_req = false;
> +             if (otg_hnp_polling(&ci->fsm) != HOST_REQUEST_FLAG)
> +                     return 0;
> +     }
> +
>       if (otg_statemachine(&ci->fsm)) {
>               if (ci->transceiver->state == OTG_STATE_A_IDLE) {
>                       /*
> @@ -862,4 +889,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 94c085f..b33d8fe 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
> -- 
> 1.7.9.5
> 

I suggest we have a patch to use hrtimer to instead of hardware
1ms timer first, drivers/usb/host/ehci-timer.c is an good example.
After that, we don't need to differentiate kinds of timers, and
we may not need to consider some low power condition in future.

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to