Commit 341eb5465f67437ad37ef2f6302b581beda4614a

Authored by Magnus Damm
Committed by Simon Horman
1 parent 1f4f11c671

ARM: shmobile: INTC External IRQ pin driver on sh73a0

Adjust the sh73a0 IRQ code to make use of the
INTC External IRQ pin driver for external
interrupt pins IRQ0 -> IRQ31.

This removes quite a bit of special-case code
in intc-sh73a0.c but the number of lines get
replaced with platform device information in
setup-sh73a0.c. The PFC code is also adjusted
to make gpio_to_irq() return the correct
interrupt number.

At this point the DT reference implementations
are not covered. In the future such code shall
tie in the INTC External IRQ pin driver via
DT, so this kind of verbose code is not needed
for the long term DT case.

Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

Showing 5 changed files with 137 additions and 127 deletions Side-by-side Diff

arch/arm/mach-shmobile/Kconfig
... ... @@ -16,6 +16,7 @@
16 16 select CPU_V7
17 17 select I2C
18 18 select SH_CLK_CPG
  19 + select RENESAS_INTC_IRQPIN
19 20  
20 21 config ARCH_R8A7740
21 22 bool "R-Mobile A1 (R8A77400)"
arch/arm/mach-shmobile/board-kzm9g.c
... ... @@ -81,7 +81,7 @@
81 81 .flags = IORESOURCE_MEM,
82 82 },
83 83 [1] = {
84   - .start = intcs_evt2irq(0x260), /* IRQ3 */
  84 + .start = irq_pin(3), /* IRQ3 */
85 85 .flags = IORESOURCE_IRQ,
86 86 },
87 87 };
... ... @@ -115,7 +115,7 @@
115 115 .flags = IORESOURCE_MEM,
116 116 },
117 117 [1] = {
118   - .start = intcs_evt2irq(0x220), /* IRQ1 */
  118 + .start = irq_pin(1), /* IRQ1 */
119 119 .flags = IORESOURCE_IRQ,
120 120 },
121 121 };
... ... @@ -138,7 +138,7 @@
138 138 struct renesas_usbhs_platform_info info;
139 139 };
140 140  
141   -#define IRQ15 intcs_evt2irq(0x03e0)
  141 +#define IRQ15 irq_pin(15)
142 142 #define USB_PHY_MODE (1 << 4)
143 143 #define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
144 144 #define USB_PHY_ON (1 << 1)
145 145  
146 146  
147 147  
... ... @@ -563,25 +563,25 @@
563 563 },
564 564 {
565 565 I2C_BOARD_INFO("ak8975", 0x0c),
566   - .irq = intcs_evt2irq(0x3380), /* IRQ28 */
  566 + .irq = irq_pin(28), /* IRQ28 */
567 567 },
568 568 {
569 569 I2C_BOARD_INFO("adxl34x", 0x1d),
570   - .irq = intcs_evt2irq(0x3340), /* IRQ26 */
  570 + .irq = irq_pin(26), /* IRQ26 */
571 571 },
572 572 };
573 573  
574 574 static struct i2c_board_info i2c1_devices[] = {
575 575 {
576 576 I2C_BOARD_INFO("st1232-ts", 0x55),
577   - .irq = intcs_evt2irq(0x300), /* IRQ8 */
  577 + .irq = irq_pin(8), /* IRQ8 */
578 578 },
579 579 };
580 580  
581 581 static struct i2c_board_info i2c3_devices[] = {
582 582 {
583 583 I2C_BOARD_INFO("pcf8575", 0x20),
584   - .irq = intcs_evt2irq(0x3260), /* IRQ19 */
  584 + .irq = irq_pin(19), /* IRQ19 */
585 585 .platform_data = &pcf8575_pdata,
586 586 },
587 587 };
arch/arm/mach-shmobile/intc-sh73a0.c
... ... @@ -260,108 +260,6 @@
260 260 return 0; /* always allow wakeup */
261 261 }
262 262  
263   -#define RELOC_BASE 0x1200
264   -
265   -/* INTCA IRQ pins at INTCS + RELOC_BASE to make space for GIC+INTC handling */
266   -#define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE)
267   -
268   -INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
269   - INTCS_VECT_RELOC, "sh73a0-intca-irq-pins");
270   -
271   -static int to_gic_irq(struct irq_data *data)
272   -{
273   - unsigned int vect = irq2evt(data->irq) - INTCS_VECT_BASE;
274   -
275   - if (vect >= 0x3200)
276   - vect -= 0x3000;
277   - else
278   - vect -= 0x0200;
279   -
280   - return gic_spi((vect >> 5) + 1);
281   -}
282   -
283   -static int to_intca_reloc_irq(struct irq_data *data)
284   -{
285   - return data->irq + (RELOC_BASE >> 5);
286   -}
287   -
288   -#define irq_cb(cb, irq) irq_get_chip(irq)->cb(irq_get_irq_data(irq))
289   -#define irq_cbp(cb, irq, p...) irq_get_chip(irq)->cb(irq_get_irq_data(irq), p)
290   -
291   -static void intca_gic_enable(struct irq_data *data)
292   -{
293   - irq_cb(irq_unmask, to_intca_reloc_irq(data));
294   - irq_cb(irq_unmask, to_gic_irq(data));
295   -}
296   -
297   -static void intca_gic_disable(struct irq_data *data)
298   -{
299   - irq_cb(irq_mask, to_gic_irq(data));
300   - irq_cb(irq_mask, to_intca_reloc_irq(data));
301   -}
302   -
303   -static void intca_gic_mask_ack(struct irq_data *data)
304   -{
305   - irq_cb(irq_mask, to_gic_irq(data));
306   - irq_cb(irq_mask_ack, to_intca_reloc_irq(data));
307   -}
308   -
309   -static void intca_gic_eoi(struct irq_data *data)
310   -{
311   - irq_cb(irq_eoi, to_gic_irq(data));
312   -}
313   -
314   -static int intca_gic_set_type(struct irq_data *data, unsigned int type)
315   -{
316   - return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type);
317   -}
318   -
319   -#ifdef CONFIG_SMP
320   -static int intca_gic_set_affinity(struct irq_data *data,
321   - const struct cpumask *cpumask,
322   - bool force)
323   -{
324   - return irq_cbp(irq_set_affinity, to_gic_irq(data), cpumask, force);
325   -}
326   -#endif
327   -
328   -struct irq_chip intca_gic_irq_chip = {
329   - .name = "INTCA-GIC",
330   - .irq_mask = intca_gic_disable,
331   - .irq_unmask = intca_gic_enable,
332   - .irq_mask_ack = intca_gic_mask_ack,
333   - .irq_eoi = intca_gic_eoi,
334   - .irq_enable = intca_gic_enable,
335   - .irq_disable = intca_gic_disable,
336   - .irq_shutdown = intca_gic_disable,
337   - .irq_set_type = intca_gic_set_type,
338   - .irq_set_wake = sh73a0_set_wake,
339   -#ifdef CONFIG_SMP
340   - .irq_set_affinity = intca_gic_set_affinity,
341   -#endif
342   -};
343   -
344   -static int to_intc_vect(int irq)
345   -{
346   - unsigned int irq_pin = irq - gic_spi(1);
347   - unsigned int offs;
348   -
349   - if (irq_pin < 16)
350   - offs = 0x0200;
351   - else
352   - offs = 0x3000;
353   -
354   - return offs + (irq_pin << 5);
355   -}
356   -
357   -static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id)
358   -{
359   - generic_handle_irq(intcs_evt2irq(to_intc_vect(irq)));
360   - return IRQ_HANDLED;
361   -}
362   -
363   -static struct irqaction sh73a0_irq_pin_cascade[32];
364   -
365 263 #define PINTER0_PHYS 0xe69000a0
366 264 #define PINTER1_PHYS 0xe69000a4
367 265 #define PINTER0_VIRT IOMEM(0xe69000a0)
368 266  
... ... @@ -422,13 +320,11 @@
422 320 void __iomem *gic_dist_base = IOMEM(0xf0001000);
423 321 void __iomem *gic_cpu_base = IOMEM(0xf0000100);
424 322 void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
425   - int k, n;
426 323  
427 324 gic_init(0, 29, gic_dist_base, gic_cpu_base);
428 325 gic_arch_extn.irq_set_wake = sh73a0_set_wake;
429 326  
430 327 register_intc_controller(&intcs_desc);
431   - register_intc_controller(&intca_irq_pins_desc);
432 328 register_intc_controller(&intc_pint0_desc);
433 329 register_intc_controller(&intc_pint1_desc);
434 330  
... ... @@ -437,19 +333,6 @@
437 333 sh73a0_intcs_cascade.handler = sh73a0_intcs_demux;
438 334 sh73a0_intcs_cascade.dev_id = intevtsa;
439 335 setup_irq(gic_spi(50), &sh73a0_intcs_cascade);
440   -
441   - /* IRQ pins require special handling through INTCA and GIC */
442   - for (k = 0; k < 32; k++) {
443   - sh73a0_irq_pin_cascade[k].name = "INTCA-GIC cascade";
444   - sh73a0_irq_pin_cascade[k].handler = sh73a0_irq_pin_demux;
445   - setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]);
446   -
447   - n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k)));
448   - WARN_ON(irq_alloc_desc_at(n, numa_node_id()) != n);
449   - irq_set_chip_and_handler_name(n, &intca_gic_irq_chip,
450   - handle_level_irq, "level");
451   - set_irq_flags(n, IRQF_VALID); /* yuck */
452   - }
453 336  
454 337 /* PINT pins are sanely tied to the GIC as SPI */
455 338 sh73a0_pint0_cascade.name = "PINT0 cascade";
arch/arm/mach-shmobile/setup-sh73a0.c
... ... @@ -33,6 +33,7 @@
33 33 #include <linux/sh_intc.h>
34 34 #include <linux/sh_timer.h>
35 35 #include <linux/platform_data/sh_ipmmu.h>
  36 +#include <linux/platform_data/irq-renesas-intc-irqpin.h>
36 37 #include <mach/dma-register.h>
37 38 #include <mach/hardware.h>
38 39 #include <mach/irqs.h>
... ... @@ -811,6 +812,127 @@
811 812 .num_resources = ARRAY_SIZE(ipmmu_resources),
812 813 };
813 814  
  815 +struct renesas_intc_irqpin_config irqpin0_platform_data = {
  816 + .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
  817 +};
  818 +
  819 +static struct resource irqpin0_resources[] = {
  820 + DEFINE_RES_MEM(0xe6900000, 4), /* ICR1A */
  821 + DEFINE_RES_MEM(0xe6900010, 4), /* INTPRI00A */
  822 + DEFINE_RES_MEM(0xe6900020, 1), /* INTREQ00A */
  823 + DEFINE_RES_MEM(0xe6900040, 1), /* INTMSK00A */
  824 + DEFINE_RES_MEM(0xe6900060, 1), /* INTMSKCLR00A */
  825 + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ0 */
  826 + DEFINE_RES_IRQ(gic_spi(2)), /* IRQ1 */
  827 + DEFINE_RES_IRQ(gic_spi(3)), /* IRQ2 */
  828 + DEFINE_RES_IRQ(gic_spi(4)), /* IRQ3 */
  829 + DEFINE_RES_IRQ(gic_spi(5)), /* IRQ4 */
  830 + DEFINE_RES_IRQ(gic_spi(6)), /* IRQ5 */
  831 + DEFINE_RES_IRQ(gic_spi(7)), /* IRQ6 */
  832 + DEFINE_RES_IRQ(gic_spi(8)), /* IRQ7 */
  833 +};
  834 +
  835 +static struct platform_device irqpin0_device = {
  836 + .name = "renesas_intc_irqpin",
  837 + .id = 0,
  838 + .resource = irqpin0_resources,
  839 + .num_resources = ARRAY_SIZE(irqpin0_resources),
  840 + .dev = {
  841 + .platform_data = &irqpin0_platform_data,
  842 + },
  843 +};
  844 +
  845 +struct renesas_intc_irqpin_config irqpin1_platform_data = {
  846 + .irq_base = irq_pin(8), /* IRQ8 -> IRQ15 */
  847 + .control_parent = true, /* Disable spurious IRQ10 */
  848 +};
  849 +
  850 +static struct resource irqpin1_resources[] = {
  851 + DEFINE_RES_MEM(0xe6900004, 4), /* ICR2A */
  852 + DEFINE_RES_MEM(0xe6900014, 4), /* INTPRI10A */
  853 + DEFINE_RES_MEM(0xe6900024, 1), /* INTREQ10A */
  854 + DEFINE_RES_MEM(0xe6900044, 1), /* INTMSK10A */
  855 + DEFINE_RES_MEM(0xe6900064, 1), /* INTMSKCLR10A */
  856 + DEFINE_RES_IRQ(gic_spi(9)), /* IRQ8 */
  857 + DEFINE_RES_IRQ(gic_spi(10)), /* IRQ9 */
  858 + DEFINE_RES_IRQ(gic_spi(11)), /* IRQ10 */
  859 + DEFINE_RES_IRQ(gic_spi(12)), /* IRQ11 */
  860 + DEFINE_RES_IRQ(gic_spi(13)), /* IRQ12 */
  861 + DEFINE_RES_IRQ(gic_spi(14)), /* IRQ13 */
  862 + DEFINE_RES_IRQ(gic_spi(15)), /* IRQ14 */
  863 + DEFINE_RES_IRQ(gic_spi(16)), /* IRQ15 */
  864 +};
  865 +
  866 +static struct platform_device irqpin1_device = {
  867 + .name = "renesas_intc_irqpin",
  868 + .id = 1,
  869 + .resource = irqpin1_resources,
  870 + .num_resources = ARRAY_SIZE(irqpin1_resources),
  871 + .dev = {
  872 + .platform_data = &irqpin1_platform_data,
  873 + },
  874 +};
  875 +
  876 +struct renesas_intc_irqpin_config irqpin2_platform_data = {
  877 + .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
  878 +};
  879 +
  880 +static struct resource irqpin2_resources[] = {
  881 + DEFINE_RES_MEM(0xe6900008, 4), /* ICR3A */
  882 + DEFINE_RES_MEM(0xe6900018, 4), /* INTPRI20A */
  883 + DEFINE_RES_MEM(0xe6900028, 1), /* INTREQ20A */
  884 + DEFINE_RES_MEM(0xe6900048, 1), /* INTMSK20A */
  885 + DEFINE_RES_MEM(0xe6900068, 1), /* INTMSKCLR20A */
  886 + DEFINE_RES_IRQ(gic_spi(17)), /* IRQ16 */
  887 + DEFINE_RES_IRQ(gic_spi(18)), /* IRQ17 */
  888 + DEFINE_RES_IRQ(gic_spi(19)), /* IRQ18 */
  889 + DEFINE_RES_IRQ(gic_spi(20)), /* IRQ19 */
  890 + DEFINE_RES_IRQ(gic_spi(21)), /* IRQ20 */
  891 + DEFINE_RES_IRQ(gic_spi(22)), /* IRQ21 */
  892 + DEFINE_RES_IRQ(gic_spi(23)), /* IRQ22 */
  893 + DEFINE_RES_IRQ(gic_spi(24)), /* IRQ23 */
  894 +};
  895 +
  896 +static struct platform_device irqpin2_device = {
  897 + .name = "renesas_intc_irqpin",
  898 + .id = 2,
  899 + .resource = irqpin2_resources,
  900 + .num_resources = ARRAY_SIZE(irqpin2_resources),
  901 + .dev = {
  902 + .platform_data = &irqpin2_platform_data,
  903 + },
  904 +};
  905 +
  906 +struct renesas_intc_irqpin_config irqpin3_platform_data = {
  907 + .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
  908 +};
  909 +
  910 +static struct resource irqpin3_resources[] = {
  911 + DEFINE_RES_MEM(0xe690000c, 4), /* ICR4A */
  912 + DEFINE_RES_MEM(0xe690001c, 4), /* INTPRI30A */
  913 + DEFINE_RES_MEM(0xe690002c, 1), /* INTREQ30A */
  914 + DEFINE_RES_MEM(0xe690004c, 1), /* INTMSK30A */
  915 + DEFINE_RES_MEM(0xe690006c, 1), /* INTMSKCLR30A */
  916 + DEFINE_RES_IRQ(gic_spi(25)), /* IRQ24 */
  917 + DEFINE_RES_IRQ(gic_spi(26)), /* IRQ25 */
  918 + DEFINE_RES_IRQ(gic_spi(27)), /* IRQ26 */
  919 + DEFINE_RES_IRQ(gic_spi(28)), /* IRQ27 */
  920 + DEFINE_RES_IRQ(gic_spi(29)), /* IRQ28 */
  921 + DEFINE_RES_IRQ(gic_spi(30)), /* IRQ29 */
  922 + DEFINE_RES_IRQ(gic_spi(31)), /* IRQ30 */
  923 + DEFINE_RES_IRQ(gic_spi(32)), /* IRQ31 */
  924 +};
  925 +
  926 +static struct platform_device irqpin3_device = {
  927 + .name = "renesas_intc_irqpin",
  928 + .id = 3,
  929 + .resource = irqpin3_resources,
  930 + .num_resources = ARRAY_SIZE(irqpin3_resources),
  931 + .dev = {
  932 + .platform_data = &irqpin3_platform_data,
  933 + },
  934 +};
  935 +
814 936 static struct platform_device *sh73a0_devices_dt[] __initdata = {
815 937 &scif0_device,
816 938 &scif1_device,
... ... @@ -839,6 +961,10 @@
839 961 &dma0_device,
840 962 &mpdma0_device,
841 963 &pmu_device,
  964 + &irqpin0_device,
  965 + &irqpin1_device,
  966 + &irqpin2_device,
  967 + &irqpin3_device,
842 968 };
843 969  
844 970 #define SRCR2 IOMEM(0xe61580b0)
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
... ... @@ -2733,9 +2733,9 @@
2733 2733 { },
2734 2734 };
2735 2735  
2736   -/* IRQ pins through INTCS with IRQ0->15 from 0x200 and IRQ16-31 from 0x3200 */
2737   -#define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5))
2738   -#define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5))
  2736 +/* External IRQ pins mapped at IRQPIN_BASE */
  2737 +#define EXT_IRQ16L(n) irq_pin(n)
  2738 +#define EXT_IRQ16H(n) irq_pin(n)
2739 2739  
2740 2740 static struct pinmux_irq pinmux_irqs[] = {
2741 2741 PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0),