summaryrefslogtreecommitdiff
path: root/recipes/linux/linux-mtx-1-2.4.24/08-usb-nonpci-2.4.24.patch
blob: 89ed24f2148d72374b2c855f8bc3891c1d79c371 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
diff -Naru linux/drivers/usb/host/Config.in linux-new/drivers/usb/host/Config.in
--- linux/drivers/usb/host/Config.in	2003-11-16 20:07:42.000000000 -0500
+++ linux-new/drivers/usb/host/Config.in	2003-12-18 14:19:37.000000000 -0500
@@ -17,3 +17,4 @@
    dep_tristate '  SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
    dep_tristate '  SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
+dep_tristate '    Non-PCI OHCI support' CONFIG_USB_NON_PCI_OHCI $CONFIG_USB_OHCI
diff -Naru linux/drivers/usb/host/usb-ohci.c linux-new/drivers/usb/host/usb-ohci.c
--- linux/drivers/usb/host/usb-ohci.c	2003-08-13 13:19:23.000000000 -0400
+++ linux-new/drivers/usb/host/usb-ohci.c	2003-12-18 14:19:53.000000000 -0500
@@ -2517,6 +2517,7 @@
 		hc_release_ohci (ohci);
 		return ret;
 	}
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	ohci->flags = id->driver_data;
 	
 	/* Check for NSC87560. We have to look at the bridge (fn1) to identify
@@ -2535,6 +2536,7 @@
 		printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
 	if (ohci->flags & OHCI_QUIRK_AMD756)
 		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
+#endif
 
 	if (hc_reset (ohci) < 0) {
 		hc_release_ohci (ohci);
@@ -2580,8 +2582,10 @@
 	int temp;
 	int i;
 
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	if (ohci->pci_latency)
 		pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
+#endif
 
 	ohci->disabled = 1;
 	ohci->sleeping = 0;
@@ -2611,6 +2615,7 @@
 
 /*-------------------------------------------------------------------------*/
 
+#ifndef CONFIG_USB_NON_PCI_OHCI
 /* configured so that an OHCI device is always provided */
 /* always called with process context; sleeping is OK */
 
@@ -2658,6 +2663,88 @@
 	}
 	return status;
 } 
+#else  /* CONFIG_USB_NON_PCI_OHCI */
+
+// Boot options
+static int ohci_base=0, ohci_len=0;
+static int ohci_irq=-1;
+
+MODULE_PARM(ohci_base, "i");
+MODULE_PARM(ohci_len, "i");
+MODULE_PARM(ohci_irq, "i");
+MODULE_PARM_DESC(ohci_base, "IO Base address of OHCI Oper. registers");
+MODULE_PARM_DESC(ohci_len, "IO length of OHCI Oper. registers");
+MODULE_PARM_DESC(ohci_irq, "IRQ for OHCI interrupts");
+
+// bogus pci_dev
+static struct pci_dev bogus_pcidev;
+
+static struct pci_driver ohci_pci_driver = {
+	name:		"usb-ohci",
+};
+
+static int __devinit
+ohci_non_pci_init (void)
+{
+	void *mem_base;
+
+	if (!ohci_base || !ohci_len || (ohci_irq < 0)) 
+		return -ENODEV;
+
+	if (!request_mem_region (ohci_base, ohci_len, ohci_pci_driver.name)) {
+		dbg ("controller already in use");
+		return -EBUSY;
+	}
+
+	mem_base = ioremap_nocache (ohci_base, ohci_len);
+	if (!mem_base) {
+		err("Error mapping OHCI memory");
+		return -EFAULT;
+	}
+
+	/*
+	* Fill in the bogus pci_dev. Only those members actually
+	* dereferenced in this driver are initialized.
+	*/
+	memset(&bogus_pcidev, 0, sizeof(struct pci_dev));
+	strcpy(bogus_pcidev.name, "non-PCI OHCI");
+	strcpy(bogus_pcidev.slot_name, "builtin");
+	bogus_pcidev.resource[0].name = "OHCI Operational Registers";
+	bogus_pcidev.resource[0].start = ohci_base;
+	bogus_pcidev.resource[0].end = ohci_base + ohci_len;
+	bogus_pcidev.resource[0].flags = 0;
+	bogus_pcidev.irq = ohci_irq;
+
+	return hc_found_ohci (&bogus_pcidev, bogus_pcidev.irq, mem_base, NULL);
+} 
+
+#ifndef MODULE
+
+static int __init
+ohci_setup (char* options)
+{
+	char* this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options,",");this_opt;this_opt=strtok(NULL,",")) {
+		if (!strncmp(this_opt, "base:", 5)) { 
+			ohci_base = simple_strtoul(this_opt+5, NULL, 0);
+		} else if (!strncmp(this_opt, "len:", 4)) { 
+			ohci_len = simple_strtoul(this_opt+4, NULL, 0);
+		} else if (!strncmp(this_opt, "irq:", 4)) { 
+			ohci_irq = simple_strtoul(this_opt+4, NULL, 0);
+		}
+	}
+	return 0;
+}
+
+__setup("usb_ohci=", ohci_setup);
+
+#endif  /* !MODULE */
+
+#endif  /* CONFIG_USB_NON_PCI_OHCI */
 
 /*-------------------------------------------------------------------------*/
 
@@ -2698,6 +2785,7 @@
 }
 
 
+#ifndef CONFIG_USB_NON_PCI_OHCI
 #ifdef	CONFIG_PM
 
 /*-------------------------------------------------------------------------*/
@@ -2936,20 +3024,29 @@
 	resume:		ohci_pci_resume,
 #endif	/* PM */
 };
+#endif /* CONFIG_USB_NON_PCI_OHCI */
 
  
 /*-------------------------------------------------------------------------*/
 
 static int __init ohci_hcd_init (void) 
 {
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	return pci_module_init (&ohci_pci_driver);
+#else
+	return ohci_non_pci_init();
+#endif
 }
 
 /*-------------------------------------------------------------------------*/
 
 static void __exit ohci_hcd_cleanup (void) 
 {	
+#ifndef CONFIG_USB_NON_PCI_OHCI
 	pci_unregister_driver (&ohci_pci_driver);
+#else
+	ohci_pci_remove(&bogus_pcidev);
+#endif
 }
 
 module_init (ohci_hcd_init);