ics-native.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * ICS backend for OPAL managed interrupts.
  4. *
  5. * Copyright 2011 IBM Corp.
  6. */
  7. //#define DEBUG
  8. #include <linux/types.h>
  9. #include <linux/kernel.h>
  10. #include <linux/irq.h>
  11. #include <linux/smp.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/init.h>
  14. #include <linux/cpu.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/msi.h>
  19. #include <linux/list.h>
  20. #include <asm/smp.h>
  21. #include <asm/machdep.h>
  22. #include <asm/irq.h>
  23. #include <asm/errno.h>
  24. #include <asm/xics.h>
  25. #include <asm/opal.h>
  26. #include <asm/firmware.h>
  27. struct ics_native {
  28. struct ics ics;
  29. struct device_node *node;
  30. void __iomem *base;
  31. u32 ibase;
  32. u32 icount;
  33. };
  34. #define to_ics_native(_ics) container_of(_ics, struct ics_native, ics)
  35. static void __iomem *ics_native_xive(struct ics_native *in, unsigned int vec)
  36. {
  37. return in->base + 0x800 + ((vec - in->ibase) << 2);
  38. }
  39. static void ics_native_unmask_irq(struct irq_data *d)
  40. {
  41. unsigned int vec = (unsigned int)irqd_to_hwirq(d);
  42. struct ics *ics = irq_data_get_irq_chip_data(d);
  43. struct ics_native *in = to_ics_native(ics);
  44. unsigned int server;
  45. pr_devel("ics-native: unmask virq %d [hw 0x%x]\n", d->irq, vec);
  46. if (vec < in->ibase || vec >= (in->ibase + in->icount))
  47. return;
  48. server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
  49. out_be32(ics_native_xive(in, vec), (server << 8) | DEFAULT_PRIORITY);
  50. }
  51. static unsigned int ics_native_startup(struct irq_data *d)
  52. {
  53. #ifdef CONFIG_PCI_MSI
  54. /*
  55. * The generic MSI code returns with the interrupt disabled on the
  56. * card, using the MSI mask bits. Firmware doesn't appear to unmask
  57. * at that level, so we do it here by hand.
  58. */
  59. if (irq_data_get_msi_desc(d))
  60. pci_msi_unmask_irq(d);
  61. #endif
  62. /* unmask it */
  63. ics_native_unmask_irq(d);
  64. return 0;
  65. }
  66. static void ics_native_do_mask(struct ics_native *in, unsigned int vec)
  67. {
  68. out_be32(ics_native_xive(in, vec), 0xff);
  69. }
  70. static void ics_native_mask_irq(struct irq_data *d)
  71. {
  72. unsigned int vec = (unsigned int)irqd_to_hwirq(d);
  73. struct ics *ics = irq_data_get_irq_chip_data(d);
  74. struct ics_native *in = to_ics_native(ics);
  75. pr_devel("ics-native: mask virq %d [hw 0x%x]\n", d->irq, vec);
  76. if (vec < in->ibase || vec >= (in->ibase + in->icount))
  77. return;
  78. ics_native_do_mask(in, vec);
  79. }
  80. static int ics_native_set_affinity(struct irq_data *d,
  81. const struct cpumask *cpumask,
  82. bool force)
  83. {
  84. unsigned int vec = (unsigned int)irqd_to_hwirq(d);
  85. struct ics *ics = irq_data_get_irq_chip_data(d);
  86. struct ics_native *in = to_ics_native(ics);
  87. int server;
  88. u32 xive;
  89. if (vec < in->ibase || vec >= (in->ibase + in->icount))
  90. return -EINVAL;
  91. server = xics_get_irq_server(d->irq, cpumask, 1);
  92. if (server == -1) {
  93. pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",
  94. __func__, cpumask_pr_args(cpumask), d->irq);
  95. return -1;
  96. }
  97. xive = in_be32(ics_native_xive(in, vec));
  98. xive = (xive & 0xff) | (server << 8);
  99. out_be32(ics_native_xive(in, vec), xive);
  100. return IRQ_SET_MASK_OK;
  101. }
  102. static struct irq_chip ics_native_irq_chip = {
  103. .name = "ICS",
  104. .irq_startup = ics_native_startup,
  105. .irq_mask = ics_native_mask_irq,
  106. .irq_unmask = ics_native_unmask_irq,
  107. .irq_eoi = NULL, /* Patched at init time */
  108. .irq_set_affinity = ics_native_set_affinity,
  109. .irq_set_type = xics_set_irq_type,
  110. .irq_retrigger = xics_retrigger,
  111. };
  112. static int ics_native_check(struct ics *ics, unsigned int hw_irq)
  113. {
  114. struct ics_native *in = to_ics_native(ics);
  115. pr_devel("%s: hw_irq=0x%x\n", __func__, hw_irq);
  116. if (hw_irq < in->ibase || hw_irq >= (in->ibase + in->icount))
  117. return -EINVAL;
  118. return 0;
  119. }
  120. static void ics_native_mask_unknown(struct ics *ics, unsigned long vec)
  121. {
  122. struct ics_native *in = to_ics_native(ics);
  123. if (vec < in->ibase || vec >= (in->ibase + in->icount))
  124. return;
  125. ics_native_do_mask(in, vec);
  126. }
  127. static long ics_native_get_server(struct ics *ics, unsigned long vec)
  128. {
  129. struct ics_native *in = to_ics_native(ics);
  130. u32 xive;
  131. if (vec < in->ibase || vec >= (in->ibase + in->icount))
  132. return -EINVAL;
  133. xive = in_be32(ics_native_xive(in, vec));
  134. return (xive >> 8) & 0xfff;
  135. }
  136. static int ics_native_host_match(struct ics *ics, struct device_node *node)
  137. {
  138. struct ics_native *in = to_ics_native(ics);
  139. return in->node == node;
  140. }
  141. static struct ics ics_native_template = {
  142. .check = ics_native_check,
  143. .mask_unknown = ics_native_mask_unknown,
  144. .get_server = ics_native_get_server,
  145. .host_match = ics_native_host_match,
  146. .chip = &ics_native_irq_chip,
  147. };
  148. static int __init ics_native_add_one(struct device_node *np)
  149. {
  150. struct ics_native *ics;
  151. u32 ranges[2];
  152. int rc, count;
  153. ics = kzalloc(sizeof(struct ics_native), GFP_KERNEL);
  154. if (!ics)
  155. return -ENOMEM;
  156. ics->node = of_node_get(np);
  157. memcpy(&ics->ics, &ics_native_template, sizeof(struct ics));
  158. ics->base = of_iomap(np, 0);
  159. if (!ics->base) {
  160. pr_err("Failed to map %pOFP\n", np);
  161. rc = -ENOMEM;
  162. goto fail;
  163. }
  164. count = of_property_count_u32_elems(np, "interrupt-ranges");
  165. if (count < 2 || count & 1) {
  166. pr_err("Failed to read interrupt-ranges of %pOFP\n", np);
  167. rc = -EINVAL;
  168. goto fail;
  169. }
  170. if (count > 2) {
  171. pr_warn("ICS %pOFP has %d ranges, only one supported\n",
  172. np, count >> 1);
  173. }
  174. rc = of_property_read_u32_array(np, "interrupt-ranges",
  175. ranges, 2);
  176. if (rc) {
  177. pr_err("Failed to read interrupt-ranges of %pOFP\n", np);
  178. goto fail;
  179. }
  180. ics->ibase = ranges[0];
  181. ics->icount = ranges[1];
  182. pr_info("ICS native initialized for sources %d..%d\n",
  183. ics->ibase, ics->ibase + ics->icount - 1);
  184. /* Register ourselves */
  185. xics_register_ics(&ics->ics);
  186. return 0;
  187. fail:
  188. of_node_put(ics->node);
  189. kfree(ics);
  190. return rc;
  191. }
  192. int __init ics_native_init(void)
  193. {
  194. struct device_node *ics;
  195. bool found_one = false;
  196. /* We need to patch our irq chip's EOI to point to the
  197. * right ICP
  198. */
  199. ics_native_irq_chip.irq_eoi = icp_ops->eoi;
  200. /* Find native ICS in the device-tree */
  201. for_each_compatible_node(ics, NULL, "openpower,xics-sources") {
  202. if (ics_native_add_one(ics) == 0)
  203. found_one = true;
  204. }
  205. if (found_one)
  206. pr_info("ICS native backend registered\n");
  207. return found_one ? 0 : -ENODEV;
  208. }