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