aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/aruba-2.6/patches/012-ehci_softirq.patch
blob: ae7f9f26c856b2594db76ec12b2cbfcce399ee80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
diff -Nurb linux-2.6.16.1/drivers/usb/host/ehci.h linux-patched/drivers/usb/host/ehci.h
--- linux-2.6.16.1/drivers/usb/host/ehci.h	2006-03-27 22:49:02.000000000 -0800
+++ linux-patched/drivers/usb/host/ehci.h	2006-04-07 12:07:30.000000000 -0700
@@ -82,6 +82,7 @@
 	struct dma_pool		*sitd_pool;	/* sitd per split iso urb */
 
 	struct timer_list	watchdog;
+	struct timer_list	softirq;
 	struct notifier_block	reboot_notifier;
 	unsigned long		actions;
 	unsigned		stamp;
diff -Nurb linux-2.6.16.1/drivers/usb/host/ehci-hcd.c linux-patched/drivers/usb/host/ehci-hcd.c
--- linux-2.6.16.1/drivers/usb/host/ehci-hcd.c	2006-03-27 22:49:02.000000000 -0800
+++ linux-patched/drivers/usb/host/ehci-hcd.c	2006-04-07 13:20:13.000000000 -0700
@@ -116,6 +116,7 @@
 #define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */
 #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
 #define EHCI_SHRINK_JIFFIES	(HZ/200)	/* async qh unlink delay */
+#define EHCI_SOFTIRQ		(HZ/400)
 
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;		// 0 to 6
@@ -263,6 +264,16 @@
 #include "ehci-sched.c"
 
 /*-------------------------------------------------------------------------*/
+static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs);
+
+static void ehci_softirq (unsigned long param)
+{
+	struct ehci_hcd         *ehci = (struct ehci_hcd *) param;
+
+	if (ehci_irq(ehci_to_hcd(ehci),0) != IRQ_NONE)
+		set_bit(HCD_FLAG_SAW_IRQ, &(ehci_to_hcd(ehci))->flags);
+	mod_timer (&ehci->softirq, jiffies + EHCI_SOFTIRQ);
+}
 
 static void ehci_watchdog (unsigned long param)
 {
@@ -280,6 +291,10 @@
 			COUNT (ehci->stats.lost_iaa);
 			writel (STS_IAA, &ehci->regs->status);
 			ehci->reclaim_ready = 1;
+			if (!timer_pending(&ehci->softirq)) {
+				ehci_info(ehci, "switching to softirq\n");
+				mod_timer (&ehci->softirq, jiffies + EHCI_SOFTIRQ);
+			}
 		}
 	}
 
@@ -371,6 +388,7 @@
 
 	/* no more interrupts ... */
 	del_timer_sync (&ehci->watchdog);
+	del_timer_sync (&ehci->softirq);
 
 	spin_lock_irq(&ehci->lock);
 	if (HC_IS_RUNNING (hcd->state))
@@ -418,6 +436,10 @@
 	ehci->watchdog.function = ehci_watchdog;
 	ehci->watchdog.data = (unsigned long) ehci;
 
+	init_timer(&ehci->softirq);
+	ehci->softirq.function = ehci_softirq;
+	ehci->softirq.data = (unsigned long) ehci;
+
 	/*
 	 * hw default: 1K periodic list heads, one per frame.
 	 * periodic_size can shrink by USBCMD update if hcc_params allows.