0050-BCM2708-armctrl-Add-IRQ-Device-Tree-support.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. From 6be3809614db2d52724eb4b5193c27d2466142be Mon Sep 17 00:00:00 2001
  2. From: notro <notro@tronnes.org>
  3. Date: Wed, 9 Jul 2014 14:47:48 +0200
  4. Subject: [PATCH 050/114] BCM2708: armctrl: Add IRQ Device Tree support
  5. Add Device Tree IRQ support for BCM2708.
  6. Usage is the same as for irq-bcm2835.
  7. See binding document: brcm,bcm2835-armctrl-ic.txt
  8. A bank 3 is added to handle GPIO interrupts. This is done because
  9. armctrl also handles GPIO interrupts.
  10. Signed-off-by: Noralf Tronnes <notro@tronnes.org>
  11. BCM2708: armctrl: remove irq bank 3
  12. irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio
  13. combination. It is no longer required.
  14. Signed-off-by: Noralf Tronnes <notro@tronnes.org>
  15. ---
  16. arch/arm/boot/dts/bcm2708.dtsi | 9 ++++
  17. arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++
  18. 2 files changed, 105 insertions(+)
  19. --- a/arch/arm/boot/dts/bcm2708.dtsi
  20. +++ b/arch/arm/boot/dts/bcm2708.dtsi
  21. @@ -4,6 +4,8 @@
  22. compatible = "brcm,bcm2708";
  23. model = "BCM2708";
  24. + interrupt-parent = <&intc>;
  25. +
  26. chosen {
  27. /*
  28. bootargs must be 1024 characters long because the
  29. @@ -17,6 +19,13 @@
  30. #address-cells = <1>;
  31. #size-cells = <1>;
  32. ranges = <0x7e000000 0x20000000 0x02000000>;
  33. +
  34. + intc: interrupt-controller {
  35. + compatible = "brcm,bcm2708-armctrl-ic";
  36. + reg = <0x7e00b200 0x200>;
  37. + interrupt-controller;
  38. + #interrupt-cells = <2>;
  39. + };
  40. };
  41. clocks {
  42. --- a/arch/arm/mach-bcm2708/armctrl.c
  43. +++ b/arch/arm/mach-bcm2708/armctrl.c
  44. @@ -23,6 +23,8 @@
  45. #include <linux/version.h>
  46. #include <linux/syscore_ops.h>
  47. #include <linux/interrupt.h>
  48. +#include <linux/irqdomain.h>
  49. +#include <linux/of.h>
  50. #include <asm/mach/irq.h>
  51. #include <mach/hardware.h>
  52. @@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct ir
  53. }
  54. }
  55. +#ifdef CONFIG_OF
  56. +
  57. +#define NR_IRQS_BANK0 21
  58. +#define NR_BANKS 3
  59. +#define IRQS_PER_BANK 32
  60. +
  61. +/* from drivers/irqchip/irq-bcm2835.c */
  62. +static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
  63. + const u32 *intspec, unsigned int intsize,
  64. + unsigned long *out_hwirq, unsigned int *out_type)
  65. +{
  66. + if (WARN_ON(intsize != 2))
  67. + return -EINVAL;
  68. +
  69. + if (WARN_ON(intspec[0] >= NR_BANKS))
  70. + return -EINVAL;
  71. +
  72. + if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
  73. + return -EINVAL;
  74. +
  75. + if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
  76. + return -EINVAL;
  77. +
  78. + if (intspec[0] == 0)
  79. + *out_hwirq = ARM_IRQ0_BASE + intspec[1];
  80. + else if (intspec[0] == 1)
  81. + *out_hwirq = ARM_IRQ1_BASE + intspec[1];
  82. + else
  83. + *out_hwirq = ARM_IRQ2_BASE + intspec[1];
  84. +
  85. + /* reverse remap_irqs[] */
  86. + switch (*out_hwirq) {
  87. + case INTERRUPT_VC_JPEG:
  88. + *out_hwirq = INTERRUPT_JPEG;
  89. + break;
  90. + case INTERRUPT_VC_USB:
  91. + *out_hwirq = INTERRUPT_USB;
  92. + break;
  93. + case INTERRUPT_VC_3D:
  94. + *out_hwirq = INTERRUPT_3D;
  95. + break;
  96. + case INTERRUPT_VC_DMA2:
  97. + *out_hwirq = INTERRUPT_DMA2;
  98. + break;
  99. + case INTERRUPT_VC_DMA3:
  100. + *out_hwirq = INTERRUPT_DMA3;
  101. + break;
  102. + case INTERRUPT_VC_I2C:
  103. + *out_hwirq = INTERRUPT_I2C;
  104. + break;
  105. + case INTERRUPT_VC_SPI:
  106. + *out_hwirq = INTERRUPT_SPI;
  107. + break;
  108. + case INTERRUPT_VC_I2SPCM:
  109. + *out_hwirq = INTERRUPT_I2SPCM;
  110. + break;
  111. + case INTERRUPT_VC_SDIO:
  112. + *out_hwirq = INTERRUPT_SDIO;
  113. + break;
  114. + case INTERRUPT_VC_UART:
  115. + *out_hwirq = INTERRUPT_UART;
  116. + break;
  117. + case INTERRUPT_VC_ARASANSDIO:
  118. + *out_hwirq = INTERRUPT_ARASANSDIO;
  119. + break;
  120. + }
  121. +
  122. + *out_type = IRQ_TYPE_NONE;
  123. + return 0;
  124. +}
  125. +
  126. +static struct irq_domain_ops armctrl_ops = {
  127. + .xlate = armctrl_xlate
  128. +};
  129. +
  130. +void __init armctrl_dt_init(void)
  131. +{
  132. + struct device_node *np;
  133. + struct irq_domain *domain;
  134. +
  135. + np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
  136. + if (!np)
  137. + return;
  138. +
  139. + domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
  140. + IRQ_ARMCTRL_START, 0,
  141. + &armctrl_ops, NULL);
  142. + WARN_ON(!domain);
  143. +}
  144. +#else
  145. +void __init armctrl_dt_init(void) { }
  146. +#endif /* CONFIG_OF */
  147. +
  148. #if defined(CONFIG_PM)
  149. /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
  150. @@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * b
  151. armctrl_pm_register(base, irq_start, resume_sources);
  152. init_FIQ(FIQ_START);
  153. + armctrl_dt_init();
  154. return 0;
  155. }