irq-uclass.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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_driver_info(struct udevice *dev,
  50. struct phandle_1_arg *cells, 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. return 0;
  58. }
  59. #else
  60. static int irq_of_xlate_default(struct irq *irq,
  61. struct ofnode_phandle_args *args)
  62. {
  63. log_debug("(irq=%p)\n", irq);
  64. if (args->args_count > 1) {
  65. log_debug("Invaild args_count: %d\n", args->args_count);
  66. return -EINVAL;
  67. }
  68. if (args->args_count)
  69. irq->id = args->args[0];
  70. else
  71. irq->id = 0;
  72. return 0;
  73. }
  74. static int irq_get_by_index_tail(int ret, ofnode node,
  75. struct ofnode_phandle_args *args,
  76. const char *list_name, int index,
  77. struct irq *irq)
  78. {
  79. struct udevice *dev_irq;
  80. const struct irq_ops *ops;
  81. assert(irq);
  82. irq->dev = NULL;
  83. if (ret)
  84. goto err;
  85. ret = uclass_get_device_by_ofnode(UCLASS_IRQ, args->node, &dev_irq);
  86. if (ret) {
  87. log_debug("uclass_get_device_by_ofnode failed: err=%d\n", ret);
  88. return ret;
  89. }
  90. irq->dev = dev_irq;
  91. ops = irq_get_ops(dev_irq);
  92. if (ops->of_xlate)
  93. ret = ops->of_xlate(irq, args);
  94. else
  95. ret = irq_of_xlate_default(irq, args);
  96. if (ret) {
  97. log_debug("of_xlate() failed: %d\n", ret);
  98. return ret;
  99. }
  100. return irq_request(dev_irq, irq);
  101. err:
  102. log_debug("Node '%s', property '%s', failed to request IRQ index %d: %d\n",
  103. ofnode_get_name(node), list_name, index, ret);
  104. return ret;
  105. }
  106. int irq_get_by_index(struct udevice *dev, int index, struct irq *irq)
  107. {
  108. struct ofnode_phandle_args args;
  109. int ret;
  110. ret = dev_read_phandle_with_args(dev, "interrupts-extended",
  111. "#interrupt-cells", 0, index, &args);
  112. return irq_get_by_index_tail(ret, dev_ofnode(dev), &args,
  113. "interrupts-extended", index > 0, irq);
  114. }
  115. #endif /* OF_PLATDATA */
  116. int irq_request(struct udevice *dev, struct irq *irq)
  117. {
  118. const struct irq_ops *ops;
  119. log_debug("(dev=%p, irq=%p)\n", dev, irq);
  120. ops = irq_get_ops(dev);
  121. irq->dev = dev;
  122. if (!ops->request)
  123. return 0;
  124. return ops->request(irq);
  125. }
  126. int irq_first_device_type(enum irq_dev_t type, struct udevice **devp)
  127. {
  128. int ret;
  129. ret = uclass_first_device_drvdata(UCLASS_IRQ, type, devp);
  130. if (ret)
  131. return ret;
  132. return 0;
  133. }
  134. #if CONFIG_IS_ENABLED(ACPIGEN)
  135. int irq_get_acpi(const struct irq *irq, struct acpi_irq *acpi_irq)
  136. {
  137. struct irq_ops *ops;
  138. if (!irq_is_valid(irq))
  139. return -EINVAL;
  140. ops = irq_get_ops(irq->dev);
  141. if (!ops->get_acpi)
  142. return -ENOSYS;
  143. return ops->get_acpi(irq, acpi_irq);
  144. }
  145. #endif
  146. UCLASS_DRIVER(irq) = {
  147. .id = UCLASS_IRQ,
  148. .name = "irq",
  149. };