sdhci-pci.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-25 GuEe-GUI the first version
  9. */
  10. #define SDHCI_REG_BAR 0
  11. #include "../dev_sdio_dm.h"
  12. struct pci_sdhci_host
  13. {
  14. struct rt_sdhci_host parent;
  15. };
  16. static const struct rt_sdhci_ops pci_sdhci_ops =
  17. {
  18. .set_clock = rt_sdhci_set_clock,
  19. .set_bus_width = rt_sdhci_set_bus_width,
  20. .reset = rt_sdhci_reset,
  21. };
  22. static rt_err_t pci_sdhci_probe(struct rt_pci_device *pdev)
  23. {
  24. rt_err_t err;
  25. struct rt_sdhci_host *host;
  26. struct pci_sdhci_host *pci_host;
  27. host = rt_sdhci_alloc_host(&pdev->parent, sizeof(struct pci_sdhci_host));
  28. if (!host)
  29. {
  30. return -RT_ENOMEM;
  31. }
  32. pci_host = rt_container_of(host, struct pci_sdhci_host, parent);
  33. host->ioaddr = rt_pci_iomap(pdev, SDHCI_REG_BAR);
  34. if (!host->ioaddr)
  35. {
  36. err = -RT_EIO;
  37. goto _fail;
  38. }
  39. host->irq = pdev->irq;
  40. host->ops = &pci_sdhci_ops;
  41. rt_pci_irq_unmask(pdev);
  42. rt_pci_set_master(pdev);
  43. if ((err = rt_sdhci_set_and_add_host(host)))
  44. {
  45. goto _fail;
  46. }
  47. pdev->parent.user_data = pci_host;
  48. return RT_EOK;
  49. _fail:
  50. if (host->ioaddr)
  51. {
  52. rt_iounmap(host->ioaddr);
  53. }
  54. rt_sdhci_free_host(host);
  55. return err;
  56. }
  57. static rt_err_t pci_sdhci_remove(struct rt_pci_device *pdev)
  58. {
  59. rt_bool_t dead;
  60. struct rt_sdhci_host *host;
  61. struct pci_sdhci_host *pci_host = pdev->parent.user_data;
  62. host = &pci_host->parent;
  63. /* INTx is shared, don't mask all */
  64. rt_hw_interrupt_umask(pdev->irq);
  65. rt_pci_irq_mask(pdev);
  66. rt_pci_clear_master(pdev);
  67. dead = (HWREG32(host->ioaddr + RT_SDHCI_INT_STATUS) == 0xffffffff);
  68. rt_sdhci_uninit_host(host, dead);
  69. rt_iounmap(host->ioaddr);
  70. rt_sdhci_free_host(host);
  71. return RT_EOK;
  72. }
  73. static const struct rt_pci_device_id pci_sdhci_pci_ids[] =
  74. {
  75. { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0007), },
  76. { RT_PCI_DEVICE_CLASS(PCIS_SYSTEM_SDHCI, ~0) },
  77. { /* sentinel */ }
  78. };
  79. static struct rt_pci_driver pci_sdhci_driver =
  80. {
  81. .name = "sdhci-pci",
  82. .ids = pci_sdhci_pci_ids,
  83. .probe = pci_sdhci_probe,
  84. .remove = pci_sdhci_remove,
  85. };
  86. RT_PCI_DRIVER_EXPORT(pci_sdhci_driver);