lkml.org 
[lkml]   [2018]   [Jun]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 3/3] usb: dwc2: host: do not schedule delayed QH unnecessarily
Date
When we are ready to retry the delayed QH, we do not need to manually
scan queues and schedule them if controller is already running; we only
need to do that if SOF interrupt is masked, otherwise we'll pick them up
at the next frame.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/usb/dwc2/hcd_queue.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index e34ad5e653501..db9e7c9d31554 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -1468,6 +1468,8 @@ static void dwc2_wait_timer_fn(struct timer_list *t)
{
struct dwc2_qh *qh = from_timer(qh, t, wait_timer);
struct dwc2_hsotg *hsotg = qh->hsotg;
+ enum dwc2_transaction_type tr_type;
+ u32 intr_mask;
unsigned long flags;

spin_lock_irqsave(&hsotg->lock, flags);
@@ -1476,19 +1478,22 @@ static void dwc2_wait_timer_fn(struct timer_list *t)
* We'll set wait_timer_cancel to true if we want to cancel this
* operation in dwc2_hcd_qh_unlink().
*/
- if (!qh->wait_timer_cancel) {
- enum dwc2_transaction_type tr_type;
+ if (qh->wait_timer_cancel)
+ goto out_unlock;

- qh->want_wait = false;
+ list_move(&qh->qh_list_entry, &hsotg->non_periodic_sched_inactive);

- list_move(&qh->qh_list_entry,
- &hsotg->non_periodic_sched_inactive);
+ /* See if we should kick the controller if it was idle */
+ intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
+ if (intr_mask & GINTSTS_SOF)
+ goto out_unlock;

- tr_type = dwc2_hcd_select_transactions(hsotg);
- if (tr_type != DWC2_TRANSACTION_NONE)
- dwc2_hcd_queue_transactions(hsotg, tr_type);
- }
+ /* The controller was idle, let's try queue our postponed work */
+ tr_type = dwc2_hcd_select_transactions(hsotg);
+ if (tr_type != DWC2_TRANSACTION_NONE)
+ dwc2_hcd_queue_transactions(hsotg, tr_type);

+out_unlock:
spin_unlock_irqrestore(&hsotg->lock, flags);
}

@@ -1722,10 +1727,6 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)

/* Add the new QH to the appropriate schedule */
if (dwc2_qh_is_non_per(qh)) {
- /* Schedule right away */
- qh->start_active_frame = hsotg->frame_number;
- qh->next_active_frame = qh->start_active_frame;
-
if (qh->want_wait) {
list_add_tail(&qh->qh_list_entry,
&hsotg->non_periodic_sched_waiting);
@@ -1733,6 +1734,10 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
mod_timer(&qh->wait_timer,
jiffies + DWC2_RETRY_WAIT_DELAY + 1);
} else {
+ /* Schedule right away */
+ qh->start_active_frame = hsotg->frame_number;
+ qh->next_active_frame = qh->start_active_frame;
+
list_add_tail(&qh->qh_list_entry,
&hsotg->non_periodic_sched_inactive);
}
--
2.18.0.rc1.244.gcf134e6275-goog
\
 
 \ /
  Last update: 2018-06-16 00:02    [W:2.284 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site