0006-irqchip-bcm2835-Add-FIQ-support.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. From 3e40206244596cbf6a8056c5e1f1c5aecd446452 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
  3. Date: Fri, 12 Jun 2015 19:01:05 +0200
  4. Subject: [PATCH 006/381] irqchip: bcm2835: Add FIQ support
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Add a duplicate irq range with an offset on the hwirq's so the
  9. driver can detect that enable_fiq() is used.
  10. Tested with downstream dwc_otg USB controller driver.
  11. Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
  12. Reviewed-by: Eric Anholt <eric@anholt.net>
  13. Acked-by: Stephen Warren <swarren@wwwdotorg.org>
  14. ---
  15. arch/arm/mach-bcm/Kconfig | 1 +
  16. drivers/irqchip/irq-bcm2835.c | 51 ++++++++++++++++++++++++++++++++++++++-----
  17. 2 files changed, 47 insertions(+), 5 deletions(-)
  18. --- a/arch/arm/mach-bcm/Kconfig
  19. +++ b/arch/arm/mach-bcm/Kconfig
  20. @@ -128,6 +128,7 @@ config ARCH_BCM2835
  21. select ARM_ERRATA_411920
  22. select ARM_TIMER_SP804
  23. select CLKSRC_OF
  24. + select FIQ
  25. select PINCTRL
  26. select PINCTRL_BCM2835
  27. help
  28. --- a/drivers/irqchip/irq-bcm2835.c
  29. +++ b/drivers/irqchip/irq-bcm2835.c
  30. @@ -55,7 +55,7 @@
  31. #include <asm/mach/irq.h>
  32. /* Put the bank and irq (32 bits) into the hwirq */
  33. -#define MAKE_HWIRQ(b, n) ((b << 5) | (n))
  34. +#define MAKE_HWIRQ(b, n) (((b) << 5) | (n))
  35. #define HWIRQ_BANK(i) (i >> 5)
  36. #define HWIRQ_BIT(i) BIT(i & 0x1f)
  37. @@ -71,9 +71,13 @@
  38. | SHORTCUT1_MASK | SHORTCUT2_MASK)
  39. #define REG_FIQ_CONTROL 0x0c
  40. +#define REG_FIQ_ENABLE 0x80
  41. +#define REG_FIQ_DISABLE 0
  42. #define NR_BANKS 3
  43. #define IRQS_PER_BANK 32
  44. +#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0)
  45. +#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0))
  46. static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 };
  47. static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 };
  48. @@ -98,14 +102,38 @@ static void __exception_irq_entry bcm283
  49. struct pt_regs *regs);
  50. static void bcm2836_chained_handle_irq(struct irq_desc *desc);
  51. +static inline unsigned int hwirq_to_fiq(unsigned long hwirq)
  52. +{
  53. + hwirq -= NUMBER_IRQS;
  54. + /*
  55. + * The hwirq numbering used in this driver is:
  56. + * BASE (0-7) GPU1 (32-63) GPU2 (64-95).
  57. + * This differ from the one used in the FIQ register:
  58. + * GPU1 (0-31) GPU2 (32-63) BASE (64-71)
  59. + */
  60. + if (hwirq >= 32)
  61. + return hwirq - 32;
  62. +
  63. + return hwirq + 64;
  64. +}
  65. +
  66. static void armctrl_mask_irq(struct irq_data *d)
  67. {
  68. - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]);
  69. + if (d->hwirq >= NUMBER_IRQS)
  70. + writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL);
  71. + else
  72. + writel_relaxed(HWIRQ_BIT(d->hwirq),
  73. + intc.disable[HWIRQ_BANK(d->hwirq)]);
  74. }
  75. static void armctrl_unmask_irq(struct irq_data *d)
  76. {
  77. - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]);
  78. + if (d->hwirq >= NUMBER_IRQS)
  79. + writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
  80. + intc.base + REG_FIQ_CONTROL);
  81. + else
  82. + writel_relaxed(HWIRQ_BIT(d->hwirq),
  83. + intc.enable[HWIRQ_BANK(d->hwirq)]);
  84. }
  85. static struct irq_chip armctrl_chip = {
  86. @@ -151,8 +179,9 @@ static int __init armctrl_of_init(struct
  87. panic("%s: unable to map IC registers\n",
  88. node->full_name);
  89. - intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
  90. - &armctrl_ops, NULL);
  91. + intc.base = base;
  92. + intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2,
  93. + &armctrl_ops, NULL);
  94. if (!intc.domain)
  95. panic("%s: unable to create IRQ domain\n", node->full_name);
  96. @@ -182,6 +211,18 @@ static int __init armctrl_of_init(struct
  97. set_handle_irq(bcm2835_handle_irq);
  98. }
  99. + /* Make a duplicate irq range which is used to enable FIQ */
  100. + for (b = 0; b < NR_BANKS; b++) {
  101. + for (i = 0; i < bank_irqs[b]; i++) {
  102. + irq = irq_create_mapping(intc.domain,
  103. + MAKE_HWIRQ(b, i) + NUMBER_IRQS);
  104. + BUG_ON(irq <= 0);
  105. + irq_set_chip(irq, &armctrl_chip);
  106. + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
  107. + }
  108. + }
  109. + init_FIQ(FIQ_START);
  110. +
  111. return 0;
  112. }