ci13xxx_pci.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * ci13xxx_pci.c - MIPS USB IP core family device controller
  3. *
  4. * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
  5. *
  6. * Author: David Lopo
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/pci.h>
  14. #include "ci13xxx_udc.c"
  15. /* driver name */
  16. #define UDC_DRIVER_NAME "ci13xxx_pci"
  17. /******************************************************************************
  18. * PCI block
  19. *****************************************************************************/
  20. /**
  21. * ci13xxx_pci_irq: interrut handler
  22. * @irq: irq number
  23. * @pdev: USB Device Controller interrupt source
  24. *
  25. * This function returns IRQ_HANDLED if the IRQ has been handled
  26. * This is an ISR don't trace, use attribute interface instead
  27. */
  28. static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev)
  29. {
  30. if (irq == 0) {
  31. dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!");
  32. return IRQ_HANDLED;
  33. }
  34. return udc_irq();
  35. }
  36. /**
  37. * ci13xxx_pci_probe: PCI probe
  38. * @pdev: USB device controller being probed
  39. * @id: PCI hotplug ID connecting controller to UDC framework
  40. *
  41. * This function returns an error code
  42. * Allocates basic PCI resources for this USB device controller, and then
  43. * invokes the udc_probe() method to start the UDC associated with it
  44. */
  45. static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
  46. const struct pci_device_id *id)
  47. {
  48. void __iomem *regs = NULL;
  49. int retval = 0;
  50. if (id == NULL)
  51. return -EINVAL;
  52. retval = pci_enable_device(pdev);
  53. if (retval)
  54. goto done;
  55. if (!pdev->irq) {
  56. dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!");
  57. retval = -ENODEV;
  58. goto disable_device;
  59. }
  60. retval = pci_request_regions(pdev, UDC_DRIVER_NAME);
  61. if (retval)
  62. goto disable_device;
  63. /* BAR 0 holds all the registers */
  64. regs = pci_iomap(pdev, 0, 0);
  65. if (!regs) {
  66. dev_err(&pdev->dev, "Error mapping memory!");
  67. retval = -EFAULT;
  68. goto release_regions;
  69. }
  70. pci_set_drvdata(pdev, (__force void *)regs);
  71. pci_set_master(pdev);
  72. pci_try_set_mwi(pdev);
  73. retval = udc_probe(&pdev->dev, regs, UDC_DRIVER_NAME);
  74. if (retval)
  75. goto iounmap;
  76. /* our device does not have MSI capability */
  77. retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED,
  78. UDC_DRIVER_NAME, pdev);
  79. if (retval)
  80. goto gadget_remove;
  81. return 0;
  82. gadget_remove:
  83. udc_remove();
  84. iounmap:
  85. pci_iounmap(pdev, regs);
  86. release_regions:
  87. pci_release_regions(pdev);
  88. disable_device:
  89. pci_disable_device(pdev);
  90. done:
  91. return retval;
  92. }
  93. /**
  94. * ci13xxx_pci_remove: PCI remove
  95. * @pdev: USB Device Controller being removed
  96. *
  97. * Reverses the effect of ci13xxx_pci_probe(),
  98. * first invoking the udc_remove() and then releases
  99. * all PCI resources allocated for this USB device controller
  100. */
  101. static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
  102. {
  103. free_irq(pdev->irq, pdev);
  104. udc_remove();
  105. pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev));
  106. pci_release_regions(pdev);
  107. pci_disable_device(pdev);
  108. }
  109. /**
  110. * PCI device table
  111. * PCI device structure
  112. *
  113. * Check "pci.h" for details
  114. */
  115. static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = {
  116. { PCI_DEVICE(0x153F, 0x1004) },
  117. { PCI_DEVICE(0x153F, 0x1006) },
  118. { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
  119. };
  120. MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table);
  121. static struct pci_driver ci13xxx_pci_driver = {
  122. .name = UDC_DRIVER_NAME,
  123. .id_table = ci13xxx_pci_id_table,
  124. .probe = ci13xxx_pci_probe,
  125. .remove = __devexit_p(ci13xxx_pci_remove),
  126. };
  127. /**
  128. * ci13xxx_pci_init: module init
  129. *
  130. * Driver load
  131. */
  132. static int __init ci13xxx_pci_init(void)
  133. {
  134. return pci_register_driver(&ci13xxx_pci_driver);
  135. }
  136. module_init(ci13xxx_pci_init);
  137. /**
  138. * ci13xxx_pci_exit: module exit
  139. *
  140. * Driver unload
  141. */
  142. static void __exit ci13xxx_pci_exit(void)
  143. {
  144. pci_unregister_driver(&ci13xxx_pci_driver);
  145. }
  146. module_exit(ci13xxx_pci_exit);
  147. MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
  148. MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
  149. MODULE_LICENSE("GPL");
  150. MODULE_VERSION("June 2008");