ohci-ps3.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * PS3 OHCI Host Controller driver
  4. *
  5. * Copyright (C) 2006 Sony Computer Entertainment Inc.
  6. * Copyright 2006 Sony Corp.
  7. */
  8. #include <asm/firmware.h>
  9. #include <asm/ps3.h>
  10. static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
  11. {
  12. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  13. ohci->flags |= OHCI_QUIRK_BE_MMIO;
  14. ohci_hcd_init(ohci);
  15. return ohci_init(ohci);
  16. }
  17. static int ps3_ohci_hc_start(struct usb_hcd *hcd)
  18. {
  19. int result;
  20. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  21. /* Handle root hub init quirk in spider south bridge. */
  22. /* Also set PwrOn2PwrGood to 0x7f (254ms). */
  23. ohci_writel(ohci, 0x7f000000 | RH_A_PSM | RH_A_OCPM,
  24. &ohci->regs->roothub.a);
  25. ohci_writel(ohci, 0x00060000, &ohci->regs->roothub.b);
  26. result = ohci_run(ohci);
  27. if (result < 0) {
  28. dev_err(hcd->self.controller, "can't start %s\n",
  29. hcd->self.bus_name);
  30. ohci_stop(hcd);
  31. }
  32. return result;
  33. }
  34. static const struct hc_driver ps3_ohci_hc_driver = {
  35. .description = hcd_name,
  36. .product_desc = "PS3 OHCI Host Controller",
  37. .hcd_priv_size = sizeof(struct ohci_hcd),
  38. .irq = ohci_irq,
  39. .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
  40. .reset = ps3_ohci_hc_reset,
  41. .start = ps3_ohci_hc_start,
  42. .stop = ohci_stop,
  43. .shutdown = ohci_shutdown,
  44. .urb_enqueue = ohci_urb_enqueue,
  45. .urb_dequeue = ohci_urb_dequeue,
  46. .endpoint_disable = ohci_endpoint_disable,
  47. .get_frame_number = ohci_get_frame,
  48. .hub_status_data = ohci_hub_status_data,
  49. .hub_control = ohci_hub_control,
  50. .start_port_reset = ohci_start_port_reset,
  51. #if defined(CONFIG_PM)
  52. .bus_suspend = ohci_bus_suspend,
  53. .bus_resume = ohci_bus_resume,
  54. #endif
  55. };
  56. static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
  57. {
  58. int result;
  59. struct usb_hcd *hcd;
  60. unsigned int virq;
  61. static u64 dummy_mask;
  62. if (usb_disabled()) {
  63. result = -ENODEV;
  64. goto fail_start;
  65. }
  66. result = ps3_open_hv_device(dev);
  67. if (result) {
  68. dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed: %s\n",
  69. __func__, __LINE__, ps3_result(result));
  70. result = -EPERM;
  71. goto fail_open;
  72. }
  73. result = ps3_dma_region_create(dev->d_region);
  74. if (result) {
  75. dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
  76. "(%d)\n", __func__, __LINE__, result);
  77. BUG_ON("check region type");
  78. goto fail_dma_region;
  79. }
  80. result = ps3_mmio_region_create(dev->m_region);
  81. if (result) {
  82. dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
  83. __func__, __LINE__);
  84. result = -EPERM;
  85. goto fail_mmio_region;
  86. }
  87. dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
  88. __LINE__, dev->m_region->lpar_addr);
  89. result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
  90. if (result) {
  91. dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
  92. __func__, __LINE__, virq);
  93. result = -EPERM;
  94. goto fail_irq;
  95. }
  96. dummy_mask = DMA_BIT_MASK(32);
  97. dev->core.dma_mask = &dummy_mask;
  98. dma_set_coherent_mask(&dev->core, dummy_mask);
  99. hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev_name(&dev->core));
  100. if (!hcd) {
  101. dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__,
  102. __LINE__);
  103. result = -ENOMEM;
  104. goto fail_create_hcd;
  105. }
  106. hcd->rsrc_start = dev->m_region->lpar_addr;
  107. hcd->rsrc_len = dev->m_region->len;
  108. if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
  109. dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
  110. __func__, __LINE__);
  111. hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
  112. if (!hcd->regs) {
  113. dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__,
  114. __LINE__);
  115. result = -EPERM;
  116. goto fail_ioremap;
  117. }
  118. dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__,
  119. (unsigned long)hcd->rsrc_start);
  120. dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__,
  121. (unsigned long)hcd->rsrc_len);
  122. dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__,
  123. (unsigned long)hcd->regs);
  124. dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__,
  125. (unsigned long)virq);
  126. ps3_system_bus_set_drvdata(dev, hcd);
  127. result = usb_add_hcd(hcd, virq, 0);
  128. if (result) {
  129. dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n",
  130. __func__, __LINE__, result);
  131. goto fail_add_hcd;
  132. }
  133. device_wakeup_enable(hcd->self.controller);
  134. return result;
  135. fail_add_hcd:
  136. iounmap(hcd->regs);
  137. fail_ioremap:
  138. release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  139. usb_put_hcd(hcd);
  140. fail_create_hcd:
  141. ps3_io_irq_destroy(virq);
  142. fail_irq:
  143. ps3_free_mmio_region(dev->m_region);
  144. fail_mmio_region:
  145. ps3_dma_region_free(dev->d_region);
  146. fail_dma_region:
  147. ps3_close_hv_device(dev);
  148. fail_open:
  149. fail_start:
  150. return result;
  151. }
  152. static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
  153. {
  154. unsigned int tmp;
  155. struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev);
  156. BUG_ON(!hcd);
  157. dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
  158. dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
  159. tmp = hcd->irq;
  160. ohci_shutdown(hcd);
  161. usb_remove_hcd(hcd);
  162. ps3_system_bus_set_drvdata(dev, NULL);
  163. BUG_ON(!hcd->regs);
  164. iounmap(hcd->regs);
  165. release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  166. usb_put_hcd(hcd);
  167. ps3_io_irq_destroy(tmp);
  168. ps3_free_mmio_region(dev->m_region);
  169. ps3_dma_region_free(dev->d_region);
  170. ps3_close_hv_device(dev);
  171. return 0;
  172. }
  173. static int __init ps3_ohci_driver_register(struct ps3_system_bus_driver *drv)
  174. {
  175. return firmware_has_feature(FW_FEATURE_PS3_LV1)
  176. ? ps3_system_bus_driver_register(drv)
  177. : 0;
  178. }
  179. static void ps3_ohci_driver_unregister(struct ps3_system_bus_driver *drv)
  180. {
  181. if (firmware_has_feature(FW_FEATURE_PS3_LV1))
  182. ps3_system_bus_driver_unregister(drv);
  183. }
  184. MODULE_ALIAS(PS3_MODULE_ALIAS_OHCI);
  185. static struct ps3_system_bus_driver ps3_ohci_driver = {
  186. .core.name = "ps3-ohci-driver",
  187. .core.owner = THIS_MODULE,
  188. .match_id = PS3_MATCH_ID_OHCI,
  189. .probe = ps3_ohci_probe,
  190. .remove = ps3_ohci_remove,
  191. .shutdown = ps3_ohci_remove,
  192. };