aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2012-07-11 11:22:53 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 19:56:47 -0400
commit32830f207691176234b4c4dd17f0d7ab6d87d94b (patch)
tree4b352a92dfc720418288c541d87e93594f97f859 /drivers/usb/host/ehci-hcd.c
parent3c273a056bf46167f0a1309c2ba72282a17d2541 (diff)
USB: EHCI: use hrtimer for unlinking empty async QHs
This patch (as1583) changes ehci-hcd to use an hrtimer event for unlinking empty (unused) async QHs instead of using a kernel timer. The check for empty QHs is moved to a new routine, where it doesn't require going through an entire scan of both the async and periodic schedules. And it can unlink multiple QHs at once, unlike the current code. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c16
1 files changed, 1 insertions, 15 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 86e8ee169c67..74ffd20edff8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -94,8 +94,6 @@ static const char hcd_name [] = "ehci_hcd";
94#define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */ 94#define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */
95 95
96#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ 96#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
97#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1)
98 /* 5-ms async qh unlink delay */
99 97
100/* Initial IRQ latency: faster than hw default */ 98/* Initial IRQ latency: faster than hw default */
101static int log2_irq_thresh = 0; // 0 to 6 99static int log2_irq_thresh = 0; // 0 to 6
@@ -130,15 +128,6 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
130static void 128static void
131timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) 129timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
132{ 130{
133 /* Don't override timeouts which shrink or (later) disable
134 * the async ring; just the I/O watchdog. Note that if a
135 * SHRINK were pending, OFF would never be requested.
136 */
137 if (timer_pending(&ehci->watchdog)
138 && (BIT(TIMER_ASYNC_SHRINK)
139 & ehci->actions))
140 return;
141
142 if (!test_and_set_bit(action, &ehci->actions)) { 131 if (!test_and_set_bit(action, &ehci->actions)) {
143 unsigned long t; 132 unsigned long t;
144 133
@@ -148,10 +137,6 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
148 return; 137 return;
149 t = EHCI_IO_JIFFIES; 138 t = EHCI_IO_JIFFIES;
150 break; 139 break;
151 /* case TIMER_ASYNC_SHRINK: */
152 default:
153 t = EHCI_SHRINK_JIFFIES;
154 break;
155 } 140 }
156 mod_timer(&ehci->watchdog, t + jiffies); 141 mod_timer(&ehci->watchdog, t + jiffies);
157 } 142 }
@@ -307,6 +292,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
307/*-------------------------------------------------------------------------*/ 292/*-------------------------------------------------------------------------*/
308 293
309static void end_unlink_async(struct ehci_hcd *ehci); 294static void end_unlink_async(struct ehci_hcd *ehci);
295static void unlink_empty_async(struct ehci_hcd *ehci);
310static void ehci_work(struct ehci_hcd *ehci); 296static void ehci_work(struct ehci_hcd *ehci);
311static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); 297static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
312static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); 298static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);