Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: mach-se: Convert SE7343 FPGA to dynamic IRQ allocation.

This gets rid of the arbitrary set of vectors used by the SE7722 FPGA
interrupt controller and switches over to a completely dynamic set.
No assumptions regarding a contiguous range are made, and the platform
resources themselves need to be filled in lazily.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+53 -50
+21 -14
arch/sh/boards/mach-se/7343/irq.c
··· 16 16 #include <linux/io.h> 17 17 #include <mach-se/mach/se7343.h> 18 18 19 + unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, }; 20 + 19 21 static void disable_se7343_irq(unsigned int irq) 20 22 { 21 - unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; 23 + unsigned int bit = (unsigned int)get_irq_chip_data(irq); 22 24 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); 23 25 } 24 26 25 27 static void enable_se7343_irq(unsigned int irq) 26 28 { 27 - unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; 29 + unsigned int bit = (unsigned int)get_irq_chip_data(irq); 28 30 ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); 29 31 } 30 32 ··· 40 38 static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) 41 39 { 42 40 unsigned short intv = ctrl_inw(PA_CPLD_ST); 43 - struct irq_desc *ext_desc; 44 - unsigned int ext_irq = SE7343_FPGA_IRQ_BASE; 41 + unsigned int ext_irq = 0; 45 42 46 43 intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; 47 44 48 - while (intv) { 49 - if (intv & 1) { 50 - ext_desc = irq_desc + ext_irq; 51 - handle_level_irq(ext_irq, ext_desc); 52 - } 53 - intv >>= 1; 54 - ext_irq++; 45 + for (; intv; intv >>= 1, ext_irq++) { 46 + if (!(intv & 1)) 47 + continue; 48 + 49 + generic_handle_irq(se7343_fpga_irq[ext_irq]); 55 50 } 56 51 } 57 52 ··· 57 58 */ 58 59 void __init init_7343se_IRQ(void) 59 60 { 60 - int i; 61 + int i, irq; 61 62 62 63 ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */ 63 64 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ 64 65 65 - for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) 66 - set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i, 66 + for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { 67 + irq = create_irq(); 68 + if (irq < 0) 69 + return; 70 + se7343_fpga_irq[i] = irq; 71 + 72 + set_irq_chip_and_handler_name(se7343_fpga_irq[i], 67 73 &se7343_irq_chip, 68 74 handle_level_irq, "level"); 75 + 76 + set_irq_chip_data(se7343_fpga_irq[i], (void *)i); 77 + } 69 78 70 79 set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux); 71 80 set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+10 -6
arch/sh/boards/mach-se/7343/setup.c
··· 82 82 .mapbase = 0x16000000, 83 83 .regshift = 1, 84 84 .flags = ST16C2550C_FLAGS, 85 - .irq = UARTA_IRQ, 86 85 .uartclk = 7372800, 87 86 }, 88 87 [1] = { ··· 89 90 .mapbase = 0x17000000, 90 91 .regshift = 1, 91 92 .flags = ST16C2550C_FLAGS, 92 - .irq = UARTB_IRQ, 93 93 .uartclk = 7372800, 94 94 }, 95 95 { }, ··· 119 121 .flags = IORESOURCE_MEM, 120 122 }, 121 123 [2] = { 122 - .start = USB_IRQ, 124 + /* Filled in later */ 123 125 .flags = IORESOURCE_IRQ, 124 126 }, 125 127 }; ··· 136 138 static struct platform_device usb_device = { 137 139 .name = "isp116x-hcd", 138 140 .id = -1, 139 - .num_resources = ARRAY_SIZE(usb_resources), 140 - .resource = usb_resources, 141 + .num_resources = ARRAY_SIZE(usb_resources), 142 + .resource = usb_resources, 141 143 .dev = { 142 144 .platform_data = &usb_platform_data, 143 145 }, ··· 153 155 154 156 static int __init sh7343se_devices_setup(void) 155 157 { 158 + /* Wire-up dynamic vectors */ 159 + serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA]; 160 + serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB]; 161 + 162 + usb_resources[2].start = usb_resources[2].end = 163 + se7343_fpga_irq[SE7343_FPGA_IRQ_USB]; 164 + 156 165 return platform_add_devices(sh7343se_platform_devices, 157 166 ARRAY_SIZE(sh7343se_platform_devices)); 158 167 } ··· 184 179 static struct sh_machine_vector mv_7343se __initmv = { 185 180 .mv_name = "SolutionEngine 7343", 186 181 .mv_setup = sh7343se_setup, 187 - .mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR, 188 182 .mv_init_irq = init_7343se_IRQ, 189 183 };
+22 -30
arch/sh/include/mach-se/mach/se7343.h
··· 94 94 95 95 #define PORT_DRVCR 0xA4050180 96 96 97 - #define PORT_PADR 0xA4050120 98 - #define PORT_PBDR 0xA4050122 99 - #define PORT_PCDR 0xA4050124 100 - #define PORT_PDDR 0xA4050126 101 - #define PORT_PEDR 0xA4050128 102 - #define PORT_PFDR 0xA405012A 103 - #define PORT_PGDR 0xA405012C 104 - #define PORT_PHDR 0xA405012E 105 - #define PORT_PJDR 0xA4050130 106 - #define PORT_PKDR 0xA4050132 107 - #define PORT_PLDR 0xA4050134 108 - #define PORT_PMDR 0xA4050136 109 - #define PORT_PNDR 0xA4050138 110 - #define PORT_PQDR 0xA405013A 111 - #define PORT_PRDR 0xA405013C 112 - #define PORT_PTDR 0xA4050160 113 - #define PORT_PUDR 0xA4050162 114 - #define PORT_PVDR 0xA4050164 115 - #define PORT_PWDR 0xA4050166 116 - #define PORT_PYDR 0xA4050168 97 + #define PORT_PADR 0xA4050120 98 + #define PORT_PBDR 0xA4050122 99 + #define PORT_PCDR 0xA4050124 100 + #define PORT_PDDR 0xA4050126 101 + #define PORT_PEDR 0xA4050128 102 + #define PORT_PFDR 0xA405012A 103 + #define PORT_PGDR 0xA405012C 104 + #define PORT_PHDR 0xA405012E 105 + #define PORT_PJDR 0xA4050130 106 + #define PORT_PKDR 0xA4050132 107 + #define PORT_PLDR 0xA4050134 108 + #define PORT_PMDR 0xA4050136 109 + #define PORT_PNDR 0xA4050138 110 + #define PORT_PQDR 0xA405013A 111 + #define PORT_PRDR 0xA405013C 112 + #define PORT_PTDR 0xA4050160 113 + #define PORT_PUDR 0xA4050162 114 + #define PORT_PVDR 0xA4050164 115 + #define PORT_PWDR 0xA4050166 116 + #define PORT_PYDR 0xA4050168 117 117 118 118 #define FPGA_IN 0xb1400000 119 119 #define FPGA_OUT 0xb1400002 ··· 133 133 #define SE7343_FPGA_IRQ_UARTB 11 134 134 135 135 #define SE7343_FPGA_IRQ_NR 12 136 - #define SE7343_FPGA_IRQ_BASE 120 137 - 138 - #define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3) 139 - #define MRSHPC_IRQ2 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2) 140 - #define MRSHPC_IRQ1 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1) 141 - #define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0) 142 - #define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC) 143 - #define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB) 144 - #define UARTA_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA) 145 - #define UARTB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB) 146 136 147 137 /* arch/sh/boards/se/7343/irq.c */ 138 + extern unsigned int se7343_fpga_irq[]; 139 + 148 140 void init_7343se_IRQ(void); 149 141 150 142 #endif /* __ASM_SH_HITACHI_SE7343_H */