tc-dwc-g210-pltfrm.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Synopsys G210 Test Chip driver
  4. *
  5. * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
  6. *
  7. * Authors: Joao Pinto <[email protected]>
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/of.h>
  13. #include <linux/delay.h>
  14. #include <linux/pm_runtime.h>
  15. #include "ufshcd-pltfrm.h"
  16. #include "ufshcd-dwc.h"
  17. #include "tc-dwc-g210.h"
  18. /*
  19. * UFS DWC specific variant operations
  20. */
  21. static struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = {
  22. .name = "tc-dwc-g210-pltfm",
  23. .link_startup_notify = ufshcd_dwc_link_startup_notify,
  24. .phy_initialization = tc_dwc_g210_config_20_bit,
  25. };
  26. static struct ufs_hba_variant_ops tc_dwc_g210_40bit_pltfm_hba_vops = {
  27. .name = "tc-dwc-g210-pltfm",
  28. .link_startup_notify = ufshcd_dwc_link_startup_notify,
  29. .phy_initialization = tc_dwc_g210_config_40_bit,
  30. };
  31. static const struct of_device_id tc_dwc_g210_pltfm_match[] = {
  32. {
  33. .compatible = "snps,g210-tc-6.00-20bit",
  34. .data = &tc_dwc_g210_20bit_pltfm_hba_vops,
  35. },
  36. {
  37. .compatible = "snps,g210-tc-6.00-40bit",
  38. .data = &tc_dwc_g210_40bit_pltfm_hba_vops,
  39. },
  40. { },
  41. };
  42. MODULE_DEVICE_TABLE(of, tc_dwc_g210_pltfm_match);
  43. /**
  44. * tc_dwc_g210_pltfm_probe()
  45. * @pdev: pointer to platform device structure
  46. *
  47. */
  48. static int tc_dwc_g210_pltfm_probe(struct platform_device *pdev)
  49. {
  50. int err;
  51. const struct of_device_id *of_id;
  52. struct ufs_hba_variant_ops *vops;
  53. struct device *dev = &pdev->dev;
  54. of_id = of_match_node(tc_dwc_g210_pltfm_match, dev->of_node);
  55. vops = (struct ufs_hba_variant_ops *)of_id->data;
  56. /* Perform generic probe */
  57. err = ufshcd_pltfrm_init(pdev, vops);
  58. if (err)
  59. dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
  60. return err;
  61. }
  62. /**
  63. * tc_dwc_g210_pltfm_remove()
  64. * @pdev: pointer to platform device structure
  65. *
  66. */
  67. static int tc_dwc_g210_pltfm_remove(struct platform_device *pdev)
  68. {
  69. struct ufs_hba *hba = platform_get_drvdata(pdev);
  70. pm_runtime_get_sync(&(pdev)->dev);
  71. ufshcd_remove(hba);
  72. return 0;
  73. }
  74. static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = {
  75. SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
  76. SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
  77. };
  78. static struct platform_driver tc_dwc_g210_pltfm_driver = {
  79. .probe = tc_dwc_g210_pltfm_probe,
  80. .remove = tc_dwc_g210_pltfm_remove,
  81. .shutdown = ufshcd_pltfrm_shutdown,
  82. .driver = {
  83. .name = "tc-dwc-g210-pltfm",
  84. .pm = &tc_dwc_g210_pltfm_pm_ops,
  85. .of_match_table = of_match_ptr(tc_dwc_g210_pltfm_match),
  86. },
  87. };
  88. module_platform_driver(tc_dwc_g210_pltfm_driver);
  89. MODULE_ALIAS("platform:tc-dwc-g210-pltfm");
  90. MODULE_DESCRIPTION("Synopsys Test Chip G210 platform glue driver");
  91. MODULE_AUTHOR("Joao Pinto <[email protected]>");
  92. MODULE_LICENSE("Dual BSD/GPL");