disable usbip; patch to 2.6.28.10
[kernel-power] / usbhost / usb / host / isp1760-if.c
1 /*
2  * Glue code for the ISP1760 driver and bus
3  * Currently there is support for
4  * - OpenFirmware
5  * - PCI
6  *
7  * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
8  *
9  */
10
11 #include <linux/usb.h>
12 #include <linux/io.h>
13
14 #include "../core/hcd.h"
15 #include "isp1760-hcd.h"
16
17 #ifdef CONFIG_PPC_OF
18 #include <linux/of.h>
19 #include <linux/of_platform.h>
20 #endif
21
22 #ifdef CONFIG_PCI
23 #include <linux/pci.h>
24 #endif
25
26 #ifdef CONFIG_PPC_OF
27 static int of_isp1760_probe(struct of_device *dev,
28                 const struct of_device_id *match)
29 {
30         struct usb_hcd *hcd;
31         struct device_node *dp = dev->node;
32         struct resource *res;
33         struct resource memory;
34         struct of_irq oirq;
35         int virq;
36         u64 res_len;
37         int ret;
38         const unsigned int *prop;
39         unsigned int devflags = 0;
40
41         ret = of_address_to_resource(dp, 0, &memory);
42         if (ret)
43                 return -ENXIO;
44
45         res = request_mem_region(memory.start, memory.end - memory.start + 1,
46                         dev_name(&dev->dev));
47         if (!res)
48                 return -EBUSY;
49
50         res_len = memory.end - memory.start + 1;
51
52         if (of_irq_map_one(dp, 0, &oirq)) {
53                 ret = -ENODEV;
54                 goto release_reg;
55         }
56
57         virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
58                         oirq.size);
59
60         if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
61                 devflags |= ISP1760_FLAG_ISP1761;
62
63         if (of_get_property(dp, "port1-disable", NULL) != NULL)
64                 devflags |= ISP1760_FLAG_PORT1_DIS;
65
66         /* Some systems wire up only 16 of the 32 data lines */
67         prop = of_get_property(dp, "bus-width", NULL);
68         if (prop && *prop == 16)
69                 devflags |= ISP1760_FLAG_BUS_WIDTH_16;
70
71         if (of_get_property(dp, "port1-otg", NULL) != NULL)
72                 devflags |= ISP1760_FLAG_OTG_EN;
73
74         if (of_get_property(dp, "analog-oc", NULL) != NULL)
75                 devflags |= ISP1760_FLAG_ANALOG_OC;
76
77         if (of_get_property(dp, "dack-polarity", NULL) != NULL)
78                 devflags |= ISP1760_FLAG_DACK_POL_HIGH;
79
80         if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
81                 devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
82
83         hcd = isp1760_register(memory.start, res_len, virq,
84                 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
85                 devflags);
86         if (IS_ERR(hcd)) {
87                 ret = PTR_ERR(hcd);
88                 goto release_reg;
89         }
90
91         dev_set_drvdata(&dev->dev, hcd);
92         return ret;
93
94 release_reg:
95         release_mem_region(memory.start, memory.end - memory.start + 1);
96         return ret;
97 }
98
99 static int of_isp1760_remove(struct of_device *dev)
100 {
101         struct usb_hcd *hcd = dev_get_drvdata(&dev->dev);
102
103         dev_set_drvdata(&dev->dev, NULL);
104
105         usb_remove_hcd(hcd);
106         iounmap(hcd->regs);
107         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
108         usb_put_hcd(hcd);
109         return 0;
110 }
111
112 static struct of_device_id of_isp1760_match[] = {
113         {
114                 .compatible = "nxp,usb-isp1760",
115         },
116         {
117                 .compatible = "nxp,usb-isp1761",
118         },
119         { },
120 };
121 MODULE_DEVICE_TABLE(of, of_isp1760_match);
122
123 static struct of_platform_driver isp1760_of_driver = {
124         .name           = "nxp-isp1760",
125         .match_table    = of_isp1760_match,
126         .probe          = of_isp1760_probe,
127         .remove         = of_isp1760_remove,
128 };
129 #endif
130
131 #ifdef CONFIG_PCI
132 static int __devinit isp1761_pci_probe(struct pci_dev *dev,
133                 const struct pci_device_id *id)
134 {
135         u8 latency, limit;
136         __u32 reg_data;
137         int retry_count;
138         struct usb_hcd *hcd;
139         unsigned int devflags = 0;
140         int ret_status = 0;
141
142         resource_size_t pci_mem_phy0;
143         resource_size_t memlength;
144
145         u8 __iomem *chip_addr;
146         u8 __iomem *iobase;
147         resource_size_t nxp_pci_io_base;
148         resource_size_t iolength;
149
150         if (usb_disabled())
151                 return -ENODEV;
152
153         if (pci_enable_device(dev) < 0)
154                 return -ENODEV;
155
156         if (!dev->irq)
157                 return -ENODEV;
158
159         /* Grab the PLX PCI mem maped port start address we need  */
160         nxp_pci_io_base = pci_resource_start(dev, 0);
161         iolength = pci_resource_len(dev, 0);
162
163         if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) {
164                 printk(KERN_ERR "request region #1\n");
165                 return -EBUSY;
166         }
167
168         iobase = ioremap_nocache(nxp_pci_io_base, iolength);
169         if (!iobase) {
170                 printk(KERN_ERR "ioremap #1\n");
171                 ret_status = -ENOMEM;
172                 goto cleanup1;
173         }
174         /* Grab the PLX PCI shared memory of the ISP 1761 we need  */
175         pci_mem_phy0 = pci_resource_start(dev, 3);
176         memlength = pci_resource_len(dev, 3);
177         if (memlength < 0xffff) {
178                 printk(KERN_ERR "memory length for this resource is wrong\n");
179                 ret_status = -ENOMEM;
180                 goto cleanup2;
181         }
182
183         if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
184                 printk(KERN_ERR "host controller already in use\n");
185                 ret_status = -EBUSY;
186                 goto cleanup2;
187         }
188
189         /* map available memory */
190         chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
191         if (!chip_addr) {
192                 printk(KERN_ERR "Error ioremap failed\n");
193                 ret_status = -ENOMEM;
194                 goto cleanup3;
195         }
196
197         /* bad pci latencies can contribute to overruns */
198         pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
199         if (latency) {
200                 pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
201                 if (limit && limit < latency)
202                         pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
203         }
204
205         /* Try to check whether we can access Scratch Register of
206          * Host Controller or not. The initial PCI access is retried until
207          * local init for the PCI bridge is completed
208          */
209         retry_count = 20;
210         reg_data = 0;
211         while ((reg_data != 0xFACE) && retry_count) {
212                 /*by default host is in 16bit mode, so
213                  * io operations at this stage must be 16 bit
214                  * */
215                 writel(0xface, chip_addr + HC_SCRATCH_REG);
216                 udelay(100);
217                 reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
218                 retry_count--;
219         }
220
221         iounmap(chip_addr);
222
223         /* Host Controller presence is detected by writing to scratch register
224          * and reading back and checking the contents are same or not
225          */
226         if (reg_data != 0xFACE) {
227                 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
228                 ret_status = -ENOMEM;
229                 goto cleanup3;
230         }
231
232         pci_set_master(dev);
233
234         /* configure PLX PCI chip to pass interrupts */
235 #define PLX_INT_CSR_REG 0x68
236         reg_data = readl(iobase + PLX_INT_CSR_REG);
237         reg_data |= 0x900;
238         writel(reg_data, iobase + PLX_INT_CSR_REG);
239
240         dev->dev.dma_mask = NULL;
241         hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
242                 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
243                 devflags);
244         if (IS_ERR(hcd)) {
245                 ret_status = -ENODEV;
246                 goto cleanup3;
247         }
248
249         /* done with PLX IO access */
250         iounmap(iobase);
251         release_mem_region(nxp_pci_io_base, iolength);
252
253         pci_set_drvdata(dev, hcd);
254         return 0;
255
256 cleanup3:
257         release_mem_region(pci_mem_phy0, memlength);
258 cleanup2:
259         iounmap(iobase);
260 cleanup1:
261         release_mem_region(nxp_pci_io_base, iolength);
262         return ret_status;
263 }
264
265 static void isp1761_pci_remove(struct pci_dev *dev)
266 {
267         struct usb_hcd *hcd;
268
269         hcd = pci_get_drvdata(dev);
270
271         usb_remove_hcd(hcd);
272         iounmap(hcd->regs);
273         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
274         usb_put_hcd(hcd);
275
276         pci_disable_device(dev);
277 }
278
279 static void isp1761_pci_shutdown(struct pci_dev *dev)
280 {
281         printk(KERN_ERR "ips1761_pci_shutdown\n");
282 }
283
284 static const struct pci_device_id isp1760_plx [] = {
285         {
286                 .class          = PCI_CLASS_BRIDGE_OTHER << 8,
287                 .class_mask     = ~0,
288                 .vendor         = PCI_VENDOR_ID_PLX,
289                 .device         = 0x5406,
290                 .subvendor      = PCI_VENDOR_ID_PLX,
291                 .subdevice      = 0x9054,
292         },
293         { }
294 };
295 MODULE_DEVICE_TABLE(pci, isp1760_plx);
296
297 static struct pci_driver isp1761_pci_driver = {
298         .name =         "isp1760",
299         .id_table =     isp1760_plx,
300         .probe =        isp1761_pci_probe,
301         .remove =       isp1761_pci_remove,
302         .shutdown =     isp1761_pci_shutdown,
303 };
304 #endif
305
306 static int __init isp1760_init(void)
307 {
308         int ret;
309
310         init_kmem_once();
311
312 #ifdef CONFIG_PPC_OF
313         ret = of_register_platform_driver(&isp1760_of_driver);
314         if (ret) {
315                 deinit_kmem_cache();
316                 return ret;
317         }
318 #endif
319 #ifdef CONFIG_PCI
320         ret = pci_register_driver(&isp1761_pci_driver);
321         if (ret)
322                 goto unreg_of;
323 #endif
324         return ret;
325
326 #ifdef CONFIG_PCI
327 unreg_of:
328 #endif
329 #ifdef CONFIG_PPC_OF
330         of_unregister_platform_driver(&isp1760_of_driver);
331 #endif
332         deinit_kmem_cache();
333         return ret;
334 }
335 module_init(isp1760_init);
336
337 static void __exit isp1760_exit(void)
338 {
339 #ifdef CONFIG_PPC_OF
340         of_unregister_platform_driver(&isp1760_of_driver);
341 #endif
342 #ifdef CONFIG_PCI
343         pci_unregister_driver(&isp1761_pci_driver);
344 #endif
345         deinit_kmem_cache();
346 }
347 module_exit(isp1760_exit);