ohci-xls.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * OHCI HCD for Netlogic XLS processors.
  3. *
  4. * (C) Copyright 2011 Netlogic Microsystems Inc.
  5. *
  6. * Based on ohci-au1xxx.c, and other Linux OHCI drivers.
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file COPYING in the main directory of this archive for
  10. * more details.
  11. */
  12. #include <linux/platform_device.h>
  13. #include <linux/signal.h>
  14. static int ohci_xls_probe_internal(const struct hc_driver *driver,
  15. struct platform_device *dev)
  16. {
  17. struct resource *res;
  18. struct usb_hcd *hcd;
  19. int retval, irq;
  20. /* Get our IRQ from an earlier registered Platform Resource */
  21. irq = platform_get_irq(dev, 0);
  22. if (irq < 0) {
  23. dev_err(&dev->dev, "Found HC with no IRQ\n");
  24. return -ENODEV;
  25. }
  26. /* Get our Memory Handle */
  27. res = platform_get_resource(dev, IORESOURCE_MEM, 0);
  28. if (!res) {
  29. dev_err(&dev->dev, "MMIO Handle incorrect!\n");
  30. return -ENODEV;
  31. }
  32. hcd = usb_create_hcd(driver, &dev->dev, "XLS");
  33. if (!hcd) {
  34. retval = -ENOMEM;
  35. goto err1;
  36. }
  37. hcd->rsrc_start = res->start;
  38. hcd->rsrc_len = resource_size(res);
  39. if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
  40. driver->description)) {
  41. dev_dbg(&dev->dev, "Controller already in use\n");
  42. retval = -EBUSY;
  43. goto err2;
  44. }
  45. hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
  46. if (hcd->regs == NULL) {
  47. dev_dbg(&dev->dev, "error mapping memory\n");
  48. retval = -EFAULT;
  49. goto err3;
  50. }
  51. retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
  52. if (retval != 0)
  53. goto err4;
  54. return retval;
  55. err4:
  56. iounmap(hcd->regs);
  57. err3:
  58. release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  59. err2:
  60. usb_put_hcd(hcd);
  61. err1:
  62. dev_err(&dev->dev, "init fail, %d\n", retval);
  63. return retval;
  64. }
  65. static int ohci_xls_reset(struct usb_hcd *hcd)
  66. {
  67. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  68. ohci_hcd_init(ohci);
  69. return ohci_init(ohci);
  70. }
  71. static int __devinit ohci_xls_start(struct usb_hcd *hcd)
  72. {
  73. struct ohci_hcd *ohci;
  74. int ret;
  75. ohci = hcd_to_ohci(hcd);
  76. ret = ohci_run(ohci);
  77. if (ret < 0) {
  78. err("can't start %s", hcd->self.bus_name);
  79. ohci_stop(hcd);
  80. return ret;
  81. }
  82. return 0;
  83. }
  84. static struct hc_driver ohci_xls_hc_driver = {
  85. .description = hcd_name,
  86. .product_desc = "XLS OHCI Host Controller",
  87. .hcd_priv_size = sizeof(struct ohci_hcd),
  88. .irq = ohci_irq,
  89. .flags = HCD_MEMORY | HCD_USB11,
  90. .reset = ohci_xls_reset,
  91. .start = ohci_xls_start,
  92. .stop = ohci_stop,
  93. .shutdown = ohci_shutdown,
  94. .urb_enqueue = ohci_urb_enqueue,
  95. .urb_dequeue = ohci_urb_dequeue,
  96. .endpoint_disable = ohci_endpoint_disable,
  97. .get_frame_number = ohci_get_frame,
  98. .hub_status_data = ohci_hub_status_data,
  99. .hub_control = ohci_hub_control,
  100. #ifdef CONFIG_PM
  101. .bus_suspend = ohci_bus_suspend,
  102. .bus_resume = ohci_bus_resume,
  103. #endif
  104. .start_port_reset = ohci_start_port_reset,
  105. };
  106. static int ohci_xls_probe(struct platform_device *dev)
  107. {
  108. int ret;
  109. pr_debug("In ohci_xls_probe");
  110. if (usb_disabled())
  111. return -ENODEV;
  112. ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev);
  113. return ret;
  114. }
  115. static int ohci_xls_remove(struct platform_device *dev)
  116. {
  117. struct usb_hcd *hcd = platform_get_drvdata(dev);
  118. usb_remove_hcd(hcd);
  119. iounmap(hcd->regs);
  120. release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  121. usb_put_hcd(hcd);
  122. return 0;
  123. }
  124. static struct platform_driver ohci_xls_driver = {
  125. .probe = ohci_xls_probe,
  126. .remove = ohci_xls_remove,
  127. .shutdown = usb_hcd_platform_shutdown,
  128. .driver = {
  129. .name = "ohci-xls-0",
  130. .owner = THIS_MODULE,
  131. },
  132. };