pwm-lpss-pci.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Intel Low Power Subsystem PWM controller PCI driver
  4. *
  5. * Copyright (C) 2014, Intel Corporation
  6. *
  7. * Derived from the original pwm-lpss.c
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/pci.h>
  12. #include <linux/pm_runtime.h>
  13. #include "pwm-lpss.h"
  14. /* BayTrail */
  15. static const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
  16. .clk_rate = 25000000,
  17. .npwm = 1,
  18. .base_unit_bits = 16,
  19. };
  20. /* Braswell */
  21. static const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
  22. .clk_rate = 19200000,
  23. .npwm = 1,
  24. .base_unit_bits = 16,
  25. };
  26. /* Broxton */
  27. static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
  28. .clk_rate = 19200000,
  29. .npwm = 4,
  30. .base_unit_bits = 22,
  31. .bypass = true,
  32. };
  33. /* Tangier */
  34. static const struct pwm_lpss_boardinfo pwm_lpss_tng_info = {
  35. .clk_rate = 19200000,
  36. .npwm = 4,
  37. .base_unit_bits = 22,
  38. };
  39. static int pwm_lpss_probe_pci(struct pci_dev *pdev,
  40. const struct pci_device_id *id)
  41. {
  42. const struct pwm_lpss_boardinfo *info;
  43. struct pwm_lpss_chip *lpwm;
  44. int err;
  45. err = pcim_enable_device(pdev);
  46. if (err < 0)
  47. return err;
  48. info = (struct pwm_lpss_boardinfo *)id->driver_data;
  49. lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
  50. if (IS_ERR(lpwm))
  51. return PTR_ERR(lpwm);
  52. pci_set_drvdata(pdev, lpwm);
  53. pm_runtime_put(&pdev->dev);
  54. pm_runtime_allow(&pdev->dev);
  55. return 0;
  56. }
  57. static void pwm_lpss_remove_pci(struct pci_dev *pdev)
  58. {
  59. struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
  60. pm_runtime_forbid(&pdev->dev);
  61. pm_runtime_get_sync(&pdev->dev);
  62. pwm_lpss_remove(lpwm);
  63. }
  64. #ifdef CONFIG_PM
  65. static int pwm_lpss_runtime_suspend_pci(struct device *dev)
  66. {
  67. /*
  68. * The PCI core will handle transition to D3 automatically. We only
  69. * need to provide runtime PM hooks for that to happen.
  70. */
  71. return 0;
  72. }
  73. static int pwm_lpss_runtime_resume_pci(struct device *dev)
  74. {
  75. return 0;
  76. }
  77. #endif
  78. static const struct dev_pm_ops pwm_lpss_pci_pm = {
  79. SET_RUNTIME_PM_OPS(pwm_lpss_runtime_suspend_pci,
  80. pwm_lpss_runtime_resume_pci, NULL)
  81. };
  82. static const struct pci_device_id pwm_lpss_pci_ids[] = {
  83. { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
  84. { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
  85. { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
  86. { PCI_VDEVICE(INTEL, 0x11a5), (unsigned long)&pwm_lpss_tng_info},
  87. { PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bxt_info},
  88. { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
  89. { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
  90. { PCI_VDEVICE(INTEL, 0x31c8), (unsigned long)&pwm_lpss_bxt_info},
  91. { PCI_VDEVICE(INTEL, 0x5ac8), (unsigned long)&pwm_lpss_bxt_info},
  92. { },
  93. };
  94. MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
  95. static struct pci_driver pwm_lpss_driver_pci = {
  96. .name = "pwm-lpss",
  97. .id_table = pwm_lpss_pci_ids,
  98. .probe = pwm_lpss_probe_pci,
  99. .remove = pwm_lpss_remove_pci,
  100. .driver = {
  101. .pm = &pwm_lpss_pci_pm,
  102. },
  103. };
  104. module_pci_driver(pwm_lpss_driver_pci);
  105. MODULE_DESCRIPTION("PWM PCI driver for Intel LPSS");
  106. MODULE_LICENSE("GPL v2");