From 00ad106a7b28019587065f49895f94dc46e94e09 Mon Sep 17 00:00:00 2001
From: mbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Fri, 7 Apr 2006 20:39:49 +0000
Subject: [PATCH] fixes ehci problems with the ap70

git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3598 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../aruba-2.6/patches/012-ehci_softirq.patch  | 70 +++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 target/linux/aruba-2.6/patches/012-ehci_softirq.patch

diff --git a/target/linux/aruba-2.6/patches/012-ehci_softirq.patch b/target/linux/aruba-2.6/patches/012-ehci_softirq.patch
new file mode 100644
index 000000000..ae7f9f26c
--- /dev/null
+++ b/target/linux/aruba-2.6/patches/012-ehci_softirq.patch
@@ -0,0 +1,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.
+
-- 
2.20.1