ufs-pci.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (c) 2006-2023, 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. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #define UFS_REG_BAR 0
  13. struct pci_ufs_quirk
  14. {
  15. const struct rt_ufs_ops *ops;
  16. };
  17. struct pci_ufs_host
  18. {
  19. struct rt_ufs_host parent;
  20. const struct pci_ufs_quirk *quirk;
  21. };
  22. static const struct rt_ufs_ops pci_ufs_std_ops =
  23. {
  24. };
  25. static rt_err_t pci_ufs_probe(struct rt_pci_device *pdev)
  26. {
  27. rt_err_t err;
  28. struct rt_ufs_host *ufs;
  29. struct pci_ufs_host *pci_ufs = rt_calloc(1, sizeof(*pci_ufs));
  30. const struct pci_ufs_quirk *quirk = pdev->id->data;
  31. if (!pci_ufs)
  32. {
  33. return -RT_ENOMEM;
  34. }
  35. pci_ufs->quirk = quirk;
  36. ufs = &pci_ufs->parent;
  37. ufs->parent.dev = &pdev->parent;
  38. ufs->regs = rt_pci_iomap(pdev, UFS_REG_BAR);
  39. ufs->irq = pdev->irq;
  40. if (!ufs->regs)
  41. {
  42. err = -RT_EIO;
  43. goto _fail;
  44. }
  45. ufs->ops = quirk ? quirk->ops : &pci_ufs_std_ops;
  46. rt_pci_irq_unmask(pdev);
  47. rt_pci_set_master(pdev);
  48. if ((err = rt_ufs_host_register(ufs)))
  49. {
  50. goto _fail;
  51. }
  52. pdev->parent.user_data = pci_ufs;
  53. return RT_EOK;
  54. _fail:
  55. rt_free(pci_ufs);
  56. return err;
  57. }
  58. static rt_err_t pci_ufs_remove(struct rt_pci_device *pdev)
  59. {
  60. struct rt_ufs_host *ufs;
  61. struct pci_ufs_host *pci_ufs = pdev->parent.user_data;
  62. ufs = &pci_ufs->parent;
  63. rt_ufs_host_unregister(ufs);
  64. /* INTx is shared, don't mask all */
  65. rt_hw_interrupt_umask(pdev->irq);
  66. rt_pci_irq_mask(pdev);
  67. rt_pci_clear_master(pdev);
  68. rt_iounmap(ufs->regs);
  69. rt_free(pci_ufs);
  70. return RT_EOK;
  71. }
  72. static rt_err_t pci_ufs_shutdown(struct rt_pci_device *pdev)
  73. {
  74. return pci_ufs_remove(pdev);
  75. }
  76. static const struct rt_pci_device_id pci_ufs_ids[] =
  77. {
  78. { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0013), },
  79. { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_SAMSUNG, 0xc00c), },
  80. { /* sentinel */ }
  81. };
  82. static struct rt_pci_driver pci_ufs_driver =
  83. {
  84. .name = "ufs-pci",
  85. .ids = pci_ufs_ids,
  86. .probe = pci_ufs_probe,
  87. .remove = pci_ufs_remove,
  88. .shutdown = pci_ufs_shutdown,
  89. };
  90. RT_PCI_DRIVER_EXPORT(pci_ufs_driver);