irq-uclass.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 <dm/device-internal.h>
  12. int irq_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
  13. {
  14. const struct irq_ops *ops = irq_get_ops(dev);
  15. if (!ops->route_pmc_gpio_gpe)
  16. return -ENOSYS;
  17. return ops->route_pmc_gpio_gpe(dev, pmc_gpe_num);
  18. }
  19. int irq_set_polarity(struct udevice *dev, uint irq, bool active_low)
  20. {
  21. const struct irq_ops *ops = irq_get_ops(dev);
  22. if (!ops->set_polarity)
  23. return -ENOSYS;
  24. return ops->set_polarity(dev, irq, active_low);
  25. }
  26. int irq_snapshot_polarities(struct udevice *dev)
  27. {
  28. const struct irq_ops *ops = irq_get_ops(dev);
  29. if (!ops->snapshot_polarities)
  30. return -ENOSYS;
  31. return ops->snapshot_polarities(dev);
  32. }
  33. int irq_restore_polarities(struct udevice *dev)
  34. {
  35. const struct irq_ops *ops = irq_get_ops(dev);
  36. if (!ops->restore_polarities)
  37. return -ENOSYS;
  38. return ops->restore_polarities(dev);
  39. }
  40. int irq_read_and_clear(struct irq *irq)
  41. {
  42. const struct irq_ops *ops = irq_get_ops(irq->dev);
  43. if (!ops->read_and_clear)
  44. return -ENOSYS;
  45. return ops->read_and_clear(irq);
  46. }
  47. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  48. int irq_get_by_index_platdata(struct udevice *dev, int index,
  49. struct phandle_1_arg *cells, struct irq *irq)
  50. {
  51. int ret;
  52. if (index != 0)
  53. return -ENOSYS;
  54. ret = uclass_get_device(UCLASS_IRQ, 0, &irq->dev);
  55. if (ret)
  56. return ret;
  57. irq->id = cells[0].arg[0];
  58. return 0;
  59. }
  60. #else
  61. static int irq_of_xlate_default(struct irq *irq,
  62. struct ofnode_phandle_args *args)
  63. {
  64. log_debug("(irq=%p)\n", irq);
  65. if (args->args_count > 1) {
  66. log_debug("Invaild args_count: %d\n", args->args_count);
  67. return -EINVAL;
  68. }
  69. if (args->args_count)
  70. irq->id = args->args[0];
  71. else
  72. irq->id = 0;
  73. return 0;
  74. }
  75. static int irq_get_by_index_tail(int ret, ofnode node,
  76. struct ofnode_phandle_args *args,
  77. const char *list_name, int index,
  78. struct irq *irq)
  79. {
  80. struct udevice *dev_irq;
  81. const struct irq_ops *ops;
  82. assert(irq);
  83. irq->dev = NULL;
  84. if (ret)
  85. goto err;
  86. ret = uclass_get_device_by_ofnode(UCLASS_IRQ, args->node, &dev_irq);
  87. if (ret) {
  88. log_debug("uclass_get_device_by_ofnode failed: err=%d\n", ret);
  89. return ret;
  90. }
  91. irq->dev = dev_irq;
  92. ops = irq_get_ops(dev_irq);
  93. if (ops->of_xlate)
  94. ret = ops->of_xlate(irq, args);
  95. else
  96. ret = irq_of_xlate_default(irq, args);
  97. if (ret) {
  98. log_debug("of_xlate() failed: %d\n", ret);
  99. return ret;
  100. }
  101. return irq_request(dev_irq, irq);
  102. err:
  103. log_debug("Node '%s', property '%s', failed to request IRQ index %d: %d\n",
  104. ofnode_get_name(node), list_name, index, ret);
  105. return ret;
  106. }
  107. int irq_get_by_index(struct udevice *dev, int index, struct irq *irq)
  108. {
  109. struct ofnode_phandle_args args;
  110. int ret;
  111. ret = dev_read_phandle_with_args(dev, "interrupts-extended",
  112. "#interrupt-cells", 0, index, &args);
  113. return irq_get_by_index_tail(ret, dev_ofnode(dev), &args,
  114. "interrupts-extended", index > 0, irq);
  115. }
  116. #endif /* OF_PLATDATA */
  117. int irq_request(struct udevice *dev, struct irq *irq)
  118. {
  119. const struct irq_ops *ops;
  120. log_debug("(dev=%p, irq=%p)\n", dev, irq);
  121. if (!irq)
  122. return 0;
  123. ops = irq_get_ops(dev);
  124. irq->dev = dev;
  125. if (!ops->request)
  126. return 0;
  127. return ops->request(irq);
  128. }
  129. int irq_first_device_type(enum irq_dev_t type, struct udevice **devp)
  130. {
  131. int ret;
  132. ret = uclass_first_device_drvdata(UCLASS_IRQ, type, devp);
  133. if (ret)
  134. return log_msg_ret("find", ret);
  135. return 0;
  136. }
  137. UCLASS_DRIVER(irq) = {
  138. .id = UCLASS_IRQ,
  139. .name = "irq",
  140. };