0007-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. From 0d6484eb61b794ef795ff569f5f066922d554156 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
  3. Date: Fri, 23 Oct 2015 16:26:55 +0200
  4. Subject: [PATCH] irqchip: irq-bcm2835: Add 2836 FIQ support
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
  9. ---
  10. drivers/irqchip/irq-bcm2835.c | 42 ++++++++++++++++++++++++++++++++++++++++--
  11. 1 file changed, 40 insertions(+), 2 deletions(-)
  12. --- a/drivers/irqchip/irq-bcm2835.c
  13. +++ b/drivers/irqchip/irq-bcm2835.c
  14. @@ -50,6 +50,8 @@
  15. #include <linux/of_irq.h>
  16. #include <linux/irqchip.h>
  17. #include <linux/irqdomain.h>
  18. +#include <linux/mfd/syscon.h>
  19. +#include <linux/regmap.h>
  20. #include <asm/exception.h>
  21. #include <asm/mach/irq.h>
  22. @@ -70,6 +72,9 @@
  23. #define BANK0_VALID_MASK (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \
  24. | SHORTCUT1_MASK | SHORTCUT2_MASK)
  25. +#undef ARM_LOCAL_GPU_INT_ROUTING
  26. +#define ARM_LOCAL_GPU_INT_ROUTING 0x0c
  27. +
  28. #define REG_FIQ_CONTROL 0x0c
  29. #define REG_FIQ_ENABLE 0x80
  30. #define REG_FIQ_DISABLE 0
  31. @@ -95,6 +100,7 @@ struct armctrl_ic {
  32. void __iomem *enable[NR_BANKS];
  33. void __iomem *disable[NR_BANKS];
  34. struct irq_domain *domain;
  35. + struct regmap *local_regmap;
  36. };
  37. static struct armctrl_ic intc __read_mostly;
  38. @@ -128,12 +134,35 @@ static void armctrl_mask_irq(struct irq_
  39. static void armctrl_unmask_irq(struct irq_data *d)
  40. {
  41. - if (d->hwirq >= NUMBER_IRQS)
  42. + if (d->hwirq >= NUMBER_IRQS) {
  43. + if (num_online_cpus() > 1) {
  44. + unsigned int data;
  45. + int ret;
  46. +
  47. + if (!intc.local_regmap) {
  48. + pr_err("FIQ is disabled due to missing regmap\n");
  49. + return;
  50. + }
  51. +
  52. + ret = regmap_read(intc.local_regmap,
  53. + ARM_LOCAL_GPU_INT_ROUTING, &data);
  54. + if (ret) {
  55. + pr_err("Failed to read int routing %d\n", ret);
  56. + return;
  57. + }
  58. +
  59. + data &= ~0xc;
  60. + data |= (1 << 2);
  61. + regmap_write(intc.local_regmap,
  62. + ARM_LOCAL_GPU_INT_ROUTING, data);
  63. + }
  64. +
  65. writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
  66. intc.base + REG_FIQ_CONTROL);
  67. - else
  68. + } else {
  69. writel_relaxed(HWIRQ_BIT(d->hwirq),
  70. intc.enable[HWIRQ_BANK(d->hwirq)]);
  71. + }
  72. }
  73. static struct irq_chip armctrl_chip = {
  74. @@ -211,6 +240,15 @@ static int __init armctrl_of_init(struct
  75. set_handle_irq(bcm2835_handle_irq);
  76. }
  77. + if (is_2836) {
  78. + intc.local_regmap =
  79. + syscon_regmap_lookup_by_compatible("brcm,bcm2836-arm-local");
  80. + if (IS_ERR(intc.local_regmap)) {
  81. + pr_err("Failed to get local register map. FIQ is disabled for cpus > 1\n");
  82. + intc.local_regmap = NULL;
  83. + }
  84. + }
  85. +
  86. /* Make a duplicate irq range which is used to enable FIQ */
  87. for (b = 0; b < NR_BANKS; b++) {
  88. for (i = 0; i < bank_irqs[b]; i++) {