core.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2024 Linaro Ltd.
  4. */
  5. #include <linux/device.h>
  6. #include <linux/export.h>
  7. #include <linux/kernel.h>
  8. #include <linux/pci.h>
  9. #include <linux/pci-pwrctl.h>
  10. #include <linux/property.h>
  11. #include <linux/slab.h>
  12. static int pci_pwrctl_notify(struct notifier_block *nb, unsigned long action,
  13. void *data)
  14. {
  15. struct pci_pwrctl *pwrctl = container_of(nb, struct pci_pwrctl, nb);
  16. struct device *dev = data;
  17. if (dev_fwnode(dev) != dev_fwnode(pwrctl->dev))
  18. return NOTIFY_DONE;
  19. switch (action) {
  20. case BUS_NOTIFY_ADD_DEVICE:
  21. /*
  22. * We will have two struct device objects bound to two different
  23. * drivers on different buses but consuming the same DT node. We
  24. * must not bind the pins twice in this case but only once for
  25. * the first device to be added.
  26. *
  27. * If we got here then the PCI device is the second after the
  28. * power control platform device. Mark its OF node as reused.
  29. */
  30. dev->of_node_reused = true;
  31. break;
  32. case BUS_NOTIFY_BOUND_DRIVER:
  33. pwrctl->link = device_link_add(dev, pwrctl->dev,
  34. DL_FLAG_AUTOREMOVE_CONSUMER);
  35. if (!pwrctl->link)
  36. dev_err(pwrctl->dev, "Failed to add device link\n");
  37. break;
  38. case BUS_NOTIFY_UNBOUND_DRIVER:
  39. if (pwrctl->link)
  40. device_link_remove(dev, pwrctl->dev);
  41. break;
  42. }
  43. return NOTIFY_DONE;
  44. }
  45. static void rescan_work_func(struct work_struct *work)
  46. {
  47. struct pci_pwrctl *pwrctl = container_of(work, struct pci_pwrctl, work);
  48. pci_lock_rescan_remove();
  49. pci_rescan_bus(to_pci_dev(pwrctl->dev->parent)->bus);
  50. pci_unlock_rescan_remove();
  51. }
  52. /**
  53. * pci_pwrctl_init() - Initialize the PCI power control context struct
  54. *
  55. * @pwrctl: PCI power control data
  56. * @dev: Parent device
  57. */
  58. void pci_pwrctl_init(struct pci_pwrctl *pwrctl, struct device *dev)
  59. {
  60. pwrctl->dev = dev;
  61. INIT_WORK(&pwrctl->work, rescan_work_func);
  62. }
  63. EXPORT_SYMBOL_GPL(pci_pwrctl_init);
  64. /**
  65. * pci_pwrctl_device_set_ready() - Notify the pwrctl subsystem that the PCI
  66. * device is powered-up and ready to be detected.
  67. *
  68. * @pwrctl: PCI power control data.
  69. *
  70. * Returns:
  71. * 0 on success, negative error number on error.
  72. *
  73. * Note:
  74. * This function returning 0 doesn't mean the device was detected. It means,
  75. * that the bus rescan was successfully started. The device will get bound to
  76. * its PCI driver asynchronously.
  77. */
  78. int pci_pwrctl_device_set_ready(struct pci_pwrctl *pwrctl)
  79. {
  80. int ret;
  81. if (!pwrctl->dev)
  82. return -ENODEV;
  83. pwrctl->nb.notifier_call = pci_pwrctl_notify;
  84. ret = bus_register_notifier(&pci_bus_type, &pwrctl->nb);
  85. if (ret)
  86. return ret;
  87. schedule_work(&pwrctl->work);
  88. return 0;
  89. }
  90. EXPORT_SYMBOL_GPL(pci_pwrctl_device_set_ready);
  91. /**
  92. * pci_pwrctl_device_unset_ready() - Notify the pwrctl subsystem that the PCI
  93. * device is about to be powered-down.
  94. *
  95. * @pwrctl: PCI power control data.
  96. */
  97. void pci_pwrctl_device_unset_ready(struct pci_pwrctl *pwrctl)
  98. {
  99. /*
  100. * We don't have to delete the link here. Typically, this function
  101. * is only called when the power control device is being detached. If
  102. * it is being detached then the child PCI device must have already
  103. * been unbound too or the device core wouldn't let us unbind.
  104. */
  105. bus_unregister_notifier(&pci_bus_type, &pwrctl->nb);
  106. }
  107. EXPORT_SYMBOL_GPL(pci_pwrctl_device_unset_ready);
  108. static void devm_pci_pwrctl_device_unset_ready(void *data)
  109. {
  110. struct pci_pwrctl *pwrctl = data;
  111. pci_pwrctl_device_unset_ready(pwrctl);
  112. }
  113. /**
  114. * devm_pci_pwrctl_device_set_ready - Managed variant of
  115. * pci_pwrctl_device_set_ready().
  116. *
  117. * @dev: Device managing this pwrctl provider.
  118. * @pwrctl: PCI power control data.
  119. *
  120. * Returns:
  121. * 0 on success, negative error number on error.
  122. */
  123. int devm_pci_pwrctl_device_set_ready(struct device *dev,
  124. struct pci_pwrctl *pwrctl)
  125. {
  126. int ret;
  127. ret = pci_pwrctl_device_set_ready(pwrctl);
  128. if (ret)
  129. return ret;
  130. return devm_add_action_or_reset(dev,
  131. devm_pci_pwrctl_device_unset_ready,
  132. pwrctl);
  133. }
  134. EXPORT_SYMBOL_GPL(devm_pci_pwrctl_device_set_ready);
  135. MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
  136. MODULE_DESCRIPTION("PCI Device Power Control core driver");
  137. MODULE_LICENSE("GPL");