irq-uclass.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2019 Google, LLC
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #define LOG_CATEGORY UCLASS_IRQ
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <dt-structs.h>
  10. #include <irq.h>
  11. #include <log.h>
  12. #include <dm/device-internal.h>
  13. int irq_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
  14. {
  15. const struct irq_ops *ops = irq_get_ops(dev);
  16. if (!ops->route_pmc_gpio_gpe)
  17. return -ENOSYS;
  18. return ops->route_pmc_gpio_gpe(dev, pmc_gpe_num);
  19. }
  20. int irq_set_polarity(struct udevice *dev, uint irq, bool active_low)
  21. {
  22. const struct irq_ops *ops = irq_get_ops(dev);
  23. if (!ops->set_polarity)
  24. return -ENOSYS;
  25. return ops->set_polarity(dev, irq, active_low);
  26. }
  27. int irq_snapshot_polarities(struct udevice *dev)
  28. {
  29. const struct irq_ops *ops = irq_get_ops(dev);
  30. if (!ops->snapshot_polarities)
  31. return -ENOSYS;
  32. return ops->snapshot_polarities(dev);
  33. }
  34. int irq_restore_polarities(struct udevice *dev)
  35. {
  36. const struct irq_ops *ops = irq_get_ops(dev);
  37. if (!ops->restore_polarities)
  38. return -ENOSYS;
  39. return ops->restore_polarities(dev);
  40. }
  41. int irq_read_and_clear(struct irq *irq)
  42. {
  43. const struct irq_ops *ops = irq_get_ops(irq->dev);
  44. if (!ops->read_and_clear)
  45. return -ENOSYS;
  46. return ops->read_and_clear(irq);
  47. }
  48. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  49. int irq_get_by_phandle(struct udevice *dev, const struct phandle_2_arg *cells,
  50. struct irq *irq)
  51. {
  52. int ret;
  53. ret = device_get_by_ofplat_idx(cells->idx, &irq->dev);
  54. if (ret)
  55. return ret;
  56. irq->id = cells->arg[0];
  57. /*
  58. * Note: we could call irq_of_xlate_default() here to do this properly.
  59. * For now, this is good enough for existing cases.
  60. */
  61. irq->flags = cells->arg[1];
  62. return 0;
  63. }
  64. #else
  65. static int irq_of_xlate_default(struct irq *irq,
  66. struct ofnode_phandle_args *args)
  67. {
  68. log_debug("(irq=%p)\n", irq);
  69. if (args->args_count > 1) {
  70. log_debug("Invalid args_count: %d\n", args->args_count);
  71. return -EINVAL;
  72. }
  73. if (args->args_count)
  74. irq->id = args->args[0];
  75. else
  76. irq->id = 0;
  77. return 0;
  78. }
  79. static int irq_get_by_index_tail(int ret, ofnode node,
  80. struct ofnode_phandle_args *args,
  81. const char *list_name, int index,
  82. struct irq *irq)
  83. {
  84. struct udevice *dev_irq;
  85. const struct irq_ops *ops;
  86. assert(irq);
  87. irq->dev = NULL;
  88. if (ret)
  89. goto err;
  90. ret = uclass_get_device_by_ofnode(UCLASS_IRQ, args->node, &dev_irq);
  91. if (ret) {
  92. log_debug("uclass_get_device_by_ofnode failed: err=%d\n", ret);
  93. return ret;
  94. }
  95. irq->dev = dev_irq;
  96. ops = irq_get_ops(dev_irq);
  97. if (ops->of_xlate)
  98. ret = ops->of_xlate(irq, args);
  99. else
  100. ret = irq_of_xlate_default(irq, args);
  101. if (ret) {
  102. log_debug("of_xlate() failed: %d\n", ret);
  103. return ret;
  104. }
  105. return irq_request(dev_irq, irq);
  106. err:
  107. log_debug("Node '%s', property '%s', failed to request IRQ index %d: %d\n",
  108. ofnode_get_name(node), list_name, index, ret);
  109. return ret;
  110. }
  111. int irq_get_by_index(struct udevice *dev, int index, struct irq *irq)
  112. {
  113. struct ofnode_phandle_args args;
  114. int ret;
  115. ret = dev_read_phandle_with_args(dev, "interrupts-extended",
  116. "#interrupt-cells", 0, index, &args);
  117. return irq_get_by_index_tail(ret, dev_ofnode(dev), &args,
  118. "interrupts-extended", index > 0, irq);
  119. }
  120. #endif /* OF_PLATDATA */
  121. int irq_request(struct udevice *dev, struct irq *irq)
  122. {
  123. const struct irq_ops *ops;
  124. log_debug("(dev=%p, irq=%p)\n", dev, irq);
  125. ops = irq_get_ops(dev);
  126. irq->dev = dev;
  127. if (!ops->request)
  128. return 0;
  129. return ops->request(irq);
  130. }
  131. int irq_first_device_type(enum irq_dev_t type, struct udevice **devp)
  132. {
  133. int ret;
  134. ret = uclass_first_device_drvdata(UCLASS_IRQ, type, devp);
  135. if (ret)
  136. return ret;
  137. return 0;
  138. }
  139. #if CONFIG_IS_ENABLED(ACPIGEN)
  140. int irq_get_acpi(const struct irq *irq, struct acpi_irq *acpi_irq)
  141. {
  142. struct irq_ops *ops;
  143. if (!irq_is_valid(irq))
  144. return -EINVAL;
  145. ops = irq_get_ops(irq->dev);
  146. if (!ops->get_acpi)
  147. return -ENOSYS;
  148. return ops->get_acpi(irq, acpi_irq);
  149. }
  150. #endif
  151. UCLASS_DRIVER(irq) = {
  152. .id = UCLASS_IRQ,
  153. .name = "irq",
  154. };