aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp1760-if.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/isp1760-if.c')
-rw-r--r--drivers/usb/host/isp1760-if.c477
1 files changed, 0 insertions, 477 deletions
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
deleted file mode 100644
index 09254a43bc01..000000000000
--- a/drivers/usb/host/isp1760-if.c
+++ /dev/null
@@ -1,477 +0,0 @@
1/*
2 * Glue code for the ISP1760 driver and bus
3 * Currently there is support for
4 * - OpenFirmware
5 * - PCI
6 * - PDEV (generic platform device centralized driver model)
7 *
8 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
9 *
10 */
11
12#include <linux/usb.h>
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/usb/isp1760.h>
17#include <linux/usb/hcd.h>
18
19#include "isp1760-hcd.h"
20
21#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
22#include <linux/slab.h>
23#include <linux/of.h>
24#include <linux/of_platform.h>
25#include <linux/of_address.h>
26#include <linux/of_irq.h>
27#include <linux/of_gpio.h>
28#endif
29
30#ifdef CONFIG_PCI
31#include <linux/pci.h>
32#endif
33
34#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
35struct isp1760 {
36 struct usb_hcd *hcd;
37 int rst_gpio;
38};
39
40static int of_isp1760_probe(struct platform_device *dev)
41{
42 struct isp1760 *drvdata;
43 struct device_node *dp = dev->dev.of_node;
44 struct resource *res;
45 struct resource memory;
46 int virq;
47 resource_size_t res_len;
48 int ret;
49 unsigned int devflags = 0;
50 enum of_gpio_flags gpio_flags;
51 u32 bus_width = 0;
52
53 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
54 if (!drvdata)
55 return -ENOMEM;
56
57 ret = of_address_to_resource(dp, 0, &memory);
58 if (ret) {
59 ret = -ENXIO;
60 goto free_data;
61 }
62
63 res_len = resource_size(&memory);
64
65 res = request_mem_region(memory.start, res_len, dev_name(&dev->dev));
66 if (!res) {
67 ret = -EBUSY;
68 goto free_data;
69 }
70
71 virq = irq_of_parse_and_map(dp, 0);
72 if (!virq) {
73 ret = -ENODEV;
74 goto release_reg;
75 }
76
77 if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
78 devflags |= ISP1760_FLAG_ISP1761;
79
80 /* Some systems wire up only 16 of the 32 data lines */
81 of_property_read_u32(dp, "bus-width", &bus_width);
82 if (bus_width == 16)
83 devflags |= ISP1760_FLAG_BUS_WIDTH_16;
84
85 if (of_get_property(dp, "port1-otg", NULL) != NULL)
86 devflags |= ISP1760_FLAG_OTG_EN;
87
88 if (of_get_property(dp, "analog-oc", NULL) != NULL)
89 devflags |= ISP1760_FLAG_ANALOG_OC;
90
91 if (of_get_property(dp, "dack-polarity", NULL) != NULL)
92 devflags |= ISP1760_FLAG_DACK_POL_HIGH;
93
94 if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
95 devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
96
97 drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags);
98 if (gpio_is_valid(drvdata->rst_gpio)) {
99 ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev));
100 if (!ret) {
101 if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) {
102 devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH;
103 gpio_direction_output(drvdata->rst_gpio, 0);
104 } else {
105 gpio_direction_output(drvdata->rst_gpio, 1);
106 }
107 } else {
108 drvdata->rst_gpio = ret;
109 }
110 }
111
112 drvdata->hcd = isp1760_register(memory.start, res_len, virq,
113 IRQF_SHARED, drvdata->rst_gpio,
114 &dev->dev, dev_name(&dev->dev),
115 devflags);
116 if (IS_ERR(drvdata->hcd)) {
117 ret = PTR_ERR(drvdata->hcd);
118 goto free_gpio;
119 }
120
121 platform_set_drvdata(dev, drvdata);
122 return ret;
123
124free_gpio:
125 if (gpio_is_valid(drvdata->rst_gpio))
126 gpio_free(drvdata->rst_gpio);
127release_reg:
128 release_mem_region(memory.start, res_len);
129free_data:
130 kfree(drvdata);
131 return ret;
132}
133
134static int of_isp1760_remove(struct platform_device *dev)
135{
136 struct isp1760 *drvdata = platform_get_drvdata(dev);
137
138 usb_remove_hcd(drvdata->hcd);
139 iounmap(drvdata->hcd->regs);
140 release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len);
141 usb_put_hcd(drvdata->hcd);
142
143 if (gpio_is_valid(drvdata->rst_gpio))
144 gpio_free(drvdata->rst_gpio);
145
146 kfree(drvdata);
147 return 0;
148}
149
150static const struct of_device_id of_isp1760_match[] = {
151 {
152 .compatible = "nxp,usb-isp1760",
153 },
154 {
155 .compatible = "nxp,usb-isp1761",
156 },
157 { },
158};
159MODULE_DEVICE_TABLE(of, of_isp1760_match);
160
161static struct platform_driver isp1760_of_driver = {
162 .driver = {
163 .name = "nxp-isp1760",
164 .of_match_table = of_isp1760_match,
165 },
166 .probe = of_isp1760_probe,
167 .remove = of_isp1760_remove,
168};
169#endif
170
171#ifdef CONFIG_PCI
172static int isp1761_pci_probe(struct pci_dev *dev,
173 const struct pci_device_id *id)
174{
175 u8 latency, limit;
176 __u32 reg_data;
177 int retry_count;
178 struct usb_hcd *hcd;
179 unsigned int devflags = 0;
180 int ret_status = 0;
181
182 resource_size_t pci_mem_phy0;
183 resource_size_t memlength;
184
185 u8 __iomem *chip_addr;
186 u8 __iomem *iobase;
187 resource_size_t nxp_pci_io_base;
188 resource_size_t iolength;
189
190 if (usb_disabled())
191 return -ENODEV;
192
193 if (pci_enable_device(dev) < 0)
194 return -ENODEV;
195
196 if (!dev->irq)
197 return -ENODEV;
198
199 /* Grab the PLX PCI mem maped port start address we need */
200 nxp_pci_io_base = pci_resource_start(dev, 0);
201 iolength = pci_resource_len(dev, 0);
202
203 if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) {
204 printk(KERN_ERR "request region #1\n");
205 return -EBUSY;
206 }
207
208 iobase = ioremap_nocache(nxp_pci_io_base, iolength);
209 if (!iobase) {
210 printk(KERN_ERR "ioremap #1\n");
211 ret_status = -ENOMEM;
212 goto cleanup1;
213 }
214 /* Grab the PLX PCI shared memory of the ISP 1761 we need */
215 pci_mem_phy0 = pci_resource_start(dev, 3);
216 memlength = pci_resource_len(dev, 3);
217 if (memlength < 0xffff) {
218 printk(KERN_ERR "memory length for this resource is wrong\n");
219 ret_status = -ENOMEM;
220 goto cleanup2;
221 }
222
223 if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
224 printk(KERN_ERR "host controller already in use\n");
225 ret_status = -EBUSY;
226 goto cleanup2;
227 }
228
229 /* map available memory */
230 chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
231 if (!chip_addr) {
232 printk(KERN_ERR "Error ioremap failed\n");
233 ret_status = -ENOMEM;
234 goto cleanup3;
235 }
236
237 /* bad pci latencies can contribute to overruns */
238 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
239 if (latency) {
240 pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
241 if (limit && limit < latency)
242 pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
243 }
244
245 /* Try to check whether we can access Scratch Register of
246 * Host Controller or not. The initial PCI access is retried until
247 * local init for the PCI bridge is completed
248 */
249 retry_count = 20;
250 reg_data = 0;
251 while ((reg_data != 0xFACE) && retry_count) {
252 /*by default host is in 16bit mode, so
253 * io operations at this stage must be 16 bit
254 * */
255 writel(0xface, chip_addr + HC_SCRATCH_REG);
256 udelay(100);
257 reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
258 retry_count--;
259 }
260
261 iounmap(chip_addr);
262
263 /* Host Controller presence is detected by writing to scratch register
264 * and reading back and checking the contents are same or not
265 */
266 if (reg_data != 0xFACE) {
267 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
268 ret_status = -ENOMEM;
269 goto cleanup3;
270 }
271
272 pci_set_master(dev);
273
274 /* configure PLX PCI chip to pass interrupts */
275#define PLX_INT_CSR_REG 0x68
276 reg_data = readl(iobase + PLX_INT_CSR_REG);
277 reg_data |= 0x900;
278 writel(reg_data, iobase + PLX_INT_CSR_REG);
279
280 dev->dev.dma_mask = NULL;
281 hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
282 IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev),
283 devflags);
284 if (IS_ERR(hcd)) {
285 ret_status = -ENODEV;
286 goto cleanup3;
287 }
288
289 /* done with PLX IO access */
290 iounmap(iobase);
291 release_mem_region(nxp_pci_io_base, iolength);
292
293 pci_set_drvdata(dev, hcd);
294 return 0;
295
296cleanup3:
297 release_mem_region(pci_mem_phy0, memlength);
298cleanup2:
299 iounmap(iobase);
300cleanup1:
301 release_mem_region(nxp_pci_io_base, iolength);
302 return ret_status;
303}
304
305static void isp1761_pci_remove(struct pci_dev *dev)
306{
307 struct usb_hcd *hcd;
308
309 hcd = pci_get_drvdata(dev);
310
311 usb_remove_hcd(hcd);
312 iounmap(hcd->regs);
313 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
314 usb_put_hcd(hcd);
315
316 pci_disable_device(dev);
317}
318
319static void isp1761_pci_shutdown(struct pci_dev *dev)
320{
321 printk(KERN_ERR "ips1761_pci_shutdown\n");
322}
323
324static const struct pci_device_id isp1760_plx [] = {
325 {
326 .class = PCI_CLASS_BRIDGE_OTHER << 8,
327 .class_mask = ~0,
328 .vendor = PCI_VENDOR_ID_PLX,
329 .device = 0x5406,
330 .subvendor = PCI_VENDOR_ID_PLX,
331 .subdevice = 0x9054,
332 },
333 { }
334};
335MODULE_DEVICE_TABLE(pci, isp1760_plx);
336
337static struct pci_driver isp1761_pci_driver = {
338 .name = "isp1760",
339 .id_table = isp1760_plx,
340 .probe = isp1761_pci_probe,
341 .remove = isp1761_pci_remove,
342 .shutdown = isp1761_pci_shutdown,
343};
344#endif
345
346static int isp1760_plat_probe(struct platform_device *pdev)
347{
348 int ret = 0;
349 struct usb_hcd *hcd;
350 struct resource *mem_res;
351 struct resource *irq_res;
352 resource_size_t mem_size;
353 struct isp1760_platform_data *priv = dev_get_platdata(&pdev->dev);
354 unsigned int devflags = 0;
355 unsigned long irqflags = IRQF_SHARED;
356
357 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
358 if (!mem_res) {
359 pr_warning("isp1760: Memory resource not available\n");
360 ret = -ENODEV;
361 goto out;
362 }
363 mem_size = resource_size(mem_res);
364 if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
365 pr_warning("isp1760: Cannot reserve the memory resource\n");
366 ret = -EBUSY;
367 goto out;
368 }
369
370 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
371 if (!irq_res) {
372 pr_warning("isp1760: IRQ resource not available\n");
373 ret = -ENODEV;
374 goto cleanup;
375 }
376
377 irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
378
379 if (priv) {
380 if (priv->is_isp1761)
381 devflags |= ISP1760_FLAG_ISP1761;
382 if (priv->bus_width_16)
383 devflags |= ISP1760_FLAG_BUS_WIDTH_16;
384 if (priv->port1_otg)
385 devflags |= ISP1760_FLAG_OTG_EN;
386 if (priv->analog_oc)
387 devflags |= ISP1760_FLAG_ANALOG_OC;
388 if (priv->dack_polarity_high)
389 devflags |= ISP1760_FLAG_DACK_POL_HIGH;
390 if (priv->dreq_polarity_high)
391 devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
392 }
393
394 hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
395 irqflags, -ENOENT,
396 &pdev->dev, dev_name(&pdev->dev), devflags);
397
398 platform_set_drvdata(pdev, hcd);
399
400 if (IS_ERR(hcd)) {
401 pr_warning("isp1760: Failed to register the HCD device\n");
402 ret = -ENODEV;
403 goto cleanup;
404 }
405
406 pr_info("ISP1760 USB device initialised\n");
407 return ret;
408
409cleanup:
410 release_mem_region(mem_res->start, mem_size);
411out:
412 return ret;
413}
414
415static int isp1760_plat_remove(struct platform_device *pdev)
416{
417 struct resource *mem_res;
418 resource_size_t mem_size;
419 struct usb_hcd *hcd = platform_get_drvdata(pdev);
420
421 usb_remove_hcd(hcd);
422
423 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
424 mem_size = resource_size(mem_res);
425 release_mem_region(mem_res->start, mem_size);
426
427 usb_put_hcd(hcd);
428
429 return 0;
430}
431
432static struct platform_driver isp1760_plat_driver = {
433 .probe = isp1760_plat_probe,
434 .remove = isp1760_plat_remove,
435 .driver = {
436 .name = "isp1760",
437 },
438};
439
440static int __init isp1760_init(void)
441{
442 int ret, any_ret = -ENODEV;
443
444 init_kmem_once();
445
446 ret = platform_driver_register(&isp1760_plat_driver);
447 if (!ret)
448 any_ret = 0;
449#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
450 ret = platform_driver_register(&isp1760_of_driver);
451 if (!ret)
452 any_ret = 0;
453#endif
454#ifdef CONFIG_PCI
455 ret = pci_register_driver(&isp1761_pci_driver);
456 if (!ret)
457 any_ret = 0;
458#endif
459
460 if (any_ret)
461 deinit_kmem_cache();
462 return any_ret;
463}
464module_init(isp1760_init);
465
466static void __exit isp1760_exit(void)
467{
468 platform_driver_unregister(&isp1760_plat_driver);
469#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
470 platform_driver_unregister(&isp1760_of_driver);
471#endif
472#ifdef CONFIG_PCI
473 pci_unregister_driver(&isp1761_pci_driver);
474#endif
475 deinit_kmem_cache();
476}
477module_exit(isp1760_exit);