alcor_pci.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018 Oleksij Rempel <linux@rempel-privat.de>
  4. *
  5. * Driver for Alcor Micro AU6601 and AU6621 controllers
  6. */
  7. #include <linux/delay.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/io.h>
  10. #include <linux/irq.h>
  11. #include <linux/mfd/core.h>
  12. #include <linux/module.h>
  13. #include <linux/pci.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/pm.h>
  16. #include <linux/alcor_pci.h>
  17. static DEFINE_IDA(alcor_pci_idr);
  18. static struct mfd_cell alcor_pci_cells[] = {
  19. [ALCOR_SD_CARD] = {
  20. .name = DRV_NAME_ALCOR_PCI_SDMMC,
  21. },
  22. [ALCOR_MS_CARD] = {
  23. .name = DRV_NAME_ALCOR_PCI_MS,
  24. },
  25. };
  26. static const struct alcor_dev_cfg alcor_cfg = {
  27. .dma = 0,
  28. };
  29. static const struct alcor_dev_cfg au6621_cfg = {
  30. .dma = 1,
  31. };
  32. static const struct alcor_dev_cfg au6625_cfg = {
  33. .dma = 0,
  34. };
  35. static const struct pci_device_id pci_ids[] = {
  36. { PCI_DEVICE(PCI_ID_ALCOR_MICRO, PCI_ID_AU6601),
  37. .driver_data = (kernel_ulong_t)&alcor_cfg },
  38. { PCI_DEVICE(PCI_ID_ALCOR_MICRO, PCI_ID_AU6621),
  39. .driver_data = (kernel_ulong_t)&au6621_cfg },
  40. { PCI_DEVICE(PCI_ID_ALCOR_MICRO, PCI_ID_AU6625),
  41. .driver_data = (kernel_ulong_t)&au6625_cfg },
  42. {},
  43. };
  44. MODULE_DEVICE_TABLE(pci, pci_ids);
  45. void alcor_write8(struct alcor_pci_priv *priv, u8 val, unsigned int addr)
  46. {
  47. writeb(val, priv->iobase + addr);
  48. }
  49. EXPORT_SYMBOL_GPL(alcor_write8);
  50. void alcor_write16(struct alcor_pci_priv *priv, u16 val, unsigned int addr)
  51. {
  52. writew(val, priv->iobase + addr);
  53. }
  54. EXPORT_SYMBOL_GPL(alcor_write16);
  55. void alcor_write32(struct alcor_pci_priv *priv, u32 val, unsigned int addr)
  56. {
  57. writel(val, priv->iobase + addr);
  58. }
  59. EXPORT_SYMBOL_GPL(alcor_write32);
  60. void alcor_write32be(struct alcor_pci_priv *priv, u32 val, unsigned int addr)
  61. {
  62. iowrite32be(val, priv->iobase + addr);
  63. }
  64. EXPORT_SYMBOL_GPL(alcor_write32be);
  65. u8 alcor_read8(struct alcor_pci_priv *priv, unsigned int addr)
  66. {
  67. return readb(priv->iobase + addr);
  68. }
  69. EXPORT_SYMBOL_GPL(alcor_read8);
  70. u32 alcor_read32(struct alcor_pci_priv *priv, unsigned int addr)
  71. {
  72. return readl(priv->iobase + addr);
  73. }
  74. EXPORT_SYMBOL_GPL(alcor_read32);
  75. u32 alcor_read32be(struct alcor_pci_priv *priv, unsigned int addr)
  76. {
  77. return ioread32be(priv->iobase + addr);
  78. }
  79. EXPORT_SYMBOL_GPL(alcor_read32be);
  80. static int alcor_pci_probe(struct pci_dev *pdev,
  81. const struct pci_device_id *ent)
  82. {
  83. struct alcor_dev_cfg *cfg;
  84. struct alcor_pci_priv *priv;
  85. int ret, i, bar = 0;
  86. cfg = (void *)ent->driver_data;
  87. ret = pcim_enable_device(pdev);
  88. if (ret)
  89. return ret;
  90. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  91. if (!priv)
  92. return -ENOMEM;
  93. ret = ida_alloc(&alcor_pci_idr, GFP_KERNEL);
  94. if (ret < 0)
  95. return ret;
  96. priv->id = ret;
  97. priv->pdev = pdev;
  98. priv->parent_pdev = pdev->bus->self;
  99. priv->dev = &pdev->dev;
  100. priv->cfg = cfg;
  101. priv->irq = pdev->irq;
  102. ret = pcim_request_all_regions(pdev, DRV_NAME_ALCOR_PCI);
  103. if (ret) {
  104. dev_err(&pdev->dev, "Cannot request region\n");
  105. ret = -EBUSY;
  106. goto error_free_ida;
  107. }
  108. if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
  109. dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
  110. ret = -ENODEV;
  111. goto error_free_ida;
  112. }
  113. priv->iobase = pcim_iomap(pdev, bar, 0);
  114. if (!priv->iobase) {
  115. ret = -ENOMEM;
  116. goto error_free_ida;
  117. }
  118. /* make sure irqs are disabled */
  119. alcor_write32(priv, 0, AU6601_REG_INT_ENABLE);
  120. alcor_write32(priv, 0, AU6601_MS_INT_ENABLE);
  121. ret = dma_set_mask_and_coherent(priv->dev, AU6601_SDMA_MASK);
  122. if (ret) {
  123. dev_err(priv->dev, "Failed to set DMA mask\n");
  124. goto error_free_ida;
  125. }
  126. pci_set_master(pdev);
  127. pci_set_drvdata(pdev, priv);
  128. for (i = 0; i < ARRAY_SIZE(alcor_pci_cells); i++) {
  129. alcor_pci_cells[i].platform_data = priv;
  130. alcor_pci_cells[i].pdata_size = sizeof(*priv);
  131. }
  132. ret = mfd_add_devices(&pdev->dev, priv->id, alcor_pci_cells,
  133. ARRAY_SIZE(alcor_pci_cells), NULL, 0, NULL);
  134. if (ret < 0)
  135. goto error_clear_drvdata;
  136. pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
  137. return 0;
  138. error_clear_drvdata:
  139. pci_clear_master(pdev);
  140. pci_set_drvdata(pdev, NULL);
  141. error_free_ida:
  142. ida_free(&alcor_pci_idr, priv->id);
  143. return ret;
  144. }
  145. static void alcor_pci_remove(struct pci_dev *pdev)
  146. {
  147. struct alcor_pci_priv *priv;
  148. priv = pci_get_drvdata(pdev);
  149. mfd_remove_devices(&pdev->dev);
  150. ida_free(&alcor_pci_idr, priv->id);
  151. pci_clear_master(pdev);
  152. pci_set_drvdata(pdev, NULL);
  153. }
  154. #ifdef CONFIG_PM_SLEEP
  155. static int alcor_suspend(struct device *dev)
  156. {
  157. return 0;
  158. }
  159. static int alcor_resume(struct device *dev)
  160. {
  161. struct alcor_pci_priv *priv = dev_get_drvdata(dev);
  162. pci_disable_link_state(priv->pdev,
  163. PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
  164. return 0;
  165. }
  166. #endif /* CONFIG_PM_SLEEP */
  167. static SIMPLE_DEV_PM_OPS(alcor_pci_pm_ops, alcor_suspend, alcor_resume);
  168. static struct pci_driver alcor_driver = {
  169. .name = DRV_NAME_ALCOR_PCI,
  170. .id_table = pci_ids,
  171. .probe = alcor_pci_probe,
  172. .remove = alcor_pci_remove,
  173. .driver = {
  174. .pm = &alcor_pci_pm_ops
  175. },
  176. };
  177. module_pci_driver(alcor_driver);
  178. MODULE_AUTHOR("Oleksij Rempel <linux@rempel-privat.de>");
  179. MODULE_DESCRIPTION("PCI driver for Alcor Micro AU6601 Secure Digital Host Controller Interface");
  180. MODULE_LICENSE("GPL");