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

Merge branch 'sh/dynamic-irq-cleanup' into sh-latest

Conflicts:
drivers/sh/intc/dynamic.c

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

+273 -272
+5
arch/sh/boards/Kconfig
··· 44 44 config SH_7722_SOLUTION_ENGINE 45 45 bool "SolutionEngine7722" 46 46 select SOLUTION_ENGINE 47 + select GENERIC_IRQ_CHIP 48 + select IRQ_DOMAIN 47 49 depends on CPU_SUBTYPE_SH7722 48 50 help 49 51 Select 7722 SolutionEngine if configuring for a Hitachi SH772 ··· 82 80 config SH_7343_SOLUTION_ENGINE 83 81 bool "SolutionEngine7343" 84 82 select SOLUTION_ENGINE 83 + select GENERIC_IRQ_CHIP 84 + select IRQ_DOMAIN 85 85 depends on CPU_SUBTYPE_SH7343 86 86 help 87 87 Select 7343 SolutionEngine if configuring for a Hitachi ··· 299 295 bool "SH-X3 Prototype board" 300 296 depends on CPU_SUBTYPE_SHX3 301 297 select NO_IOPORT if !PCI 298 + select IRQ_DOMAIN 302 299 303 300 config SH_MAGIC_PANEL_R2 304 301 bool "Magic Panel R2"
+12 -22
arch/sh/boards/mach-dreamcast/irq.c
··· 8 8 * This file is part of the LinuxDC project (www.linuxdc.org) 9 9 * Released under the terms of the GNU GPL v2.0 10 10 */ 11 - 12 11 #include <linux/irq.h> 13 12 #include <linux/io.h> 14 - #include <asm/irq.h> 13 + #include <linux/irq.h> 14 + #include <linux/export.h> 15 + #include <linux/err.h> 15 16 #include <mach/sysasic.h> 16 17 17 18 /* ··· 142 141 143 142 void systemasic_irq_init(void) 144 143 { 145 - int i, nid = cpu_to_node(boot_cpu_data); 144 + int irq_base, i; 146 145 147 - /* Assign all virtual IRQs to the System ASIC int. handler */ 148 - for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) { 149 - unsigned int irq; 150 - 151 - irq = create_irq_nr(i, nid); 152 - if (unlikely(irq == 0)) { 153 - pr_err("%s: failed hooking irq %d for systemasic\n", 154 - __func__, i); 155 - return; 156 - } 157 - 158 - if (unlikely(irq != i)) { 159 - pr_err("%s: got irq %d but wanted %d, bailing.\n", 160 - __func__, irq, i); 161 - destroy_irq(irq); 162 - return; 163 - } 164 - 165 - irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq); 146 + irq_base = irq_alloc_descs(HW_EVENT_IRQ_BASE, HW_EVENT_IRQ_BASE, 147 + HW_EVENT_IRQ_MAX - HW_EVENT_IRQ_BASE, -1); 148 + if (IS_ERR_VALUE(irq_base)) { 149 + pr_err("%s: failed hooking irqs\n", __func__); 150 + return; 166 151 } 152 + 153 + for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) 154 + irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq); 167 155 }
+95 -52
arch/sh/boards/mach-se/7343/irq.c
··· 1 1 /* 2 - * linux/arch/sh/boards/se/7343/irq.c 2 + * Hitachi UL SolutionEngine 7343 FPGA IRQ Support. 3 3 * 4 4 * Copyright (C) 2008 Yoshihiro Shimoda 5 + * Copyright (C) 2012 Paul Mundt 5 6 * 6 - * Based on linux/arch/sh/boards/se/7722/irq.c 7 + * Based on linux/arch/sh/boards/se/7343/irq.c 7 8 * Copyright (C) 2007 Nobuhiro Iwamatsu 8 9 * 9 10 * This file is subject to the terms and conditions of the GNU General Public 10 11 * License. See the file "COPYING" in the main directory of this archive 11 12 * for more details. 12 13 */ 14 + #define DRV_NAME "SE7343-FPGA" 15 + #define pr_fmt(fmt) DRV_NAME ": " fmt 16 + 17 + #define irq_reg_readl ioread16 18 + #define irq_reg_writel iowrite16 19 + 13 20 #include <linux/init.h> 14 21 #include <linux/irq.h> 15 22 #include <linux/interrupt.h> 23 + #include <linux/irqdomain.h> 16 24 #include <linux/io.h> 25 + #include <asm/sizes.h> 17 26 #include <mach-se/mach/se7343.h> 18 27 19 - unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, }; 28 + #define PA_CPLD_BASE_ADDR 0x11400000 29 + #define PA_CPLD_ST_REG 0x08 /* CPLD Interrupt status register */ 30 + #define PA_CPLD_IMSK_REG 0x0a /* CPLD Interrupt mask register */ 20 31 21 - static void disable_se7343_irq(struct irq_data *data) 22 - { 23 - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); 24 - __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); 25 - } 26 - 27 - static void enable_se7343_irq(struct irq_data *data) 28 - { 29 - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); 30 - __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); 31 - } 32 - 33 - static struct irq_chip se7343_irq_chip __read_mostly = { 34 - .name = "SE7343-FPGA", 35 - .irq_mask = disable_se7343_irq, 36 - .irq_unmask = enable_se7343_irq, 37 - }; 32 + static void __iomem *se7343_irq_regs; 33 + struct irq_domain *se7343_irq_domain; 38 34 39 35 static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) 40 36 { 41 - unsigned short intv = __raw_readw(PA_CPLD_ST); 42 - unsigned int ext_irq = 0; 37 + struct irq_data *data = irq_get_irq_data(irq); 38 + struct irq_chip *chip = irq_data_get_irq_chip(data); 39 + unsigned long mask; 40 + int bit; 43 41 44 - intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; 42 + chip->irq_mask_ack(data); 45 43 46 - for (; intv; intv >>= 1, ext_irq++) { 47 - if (!(intv & 1)) 48 - continue; 44 + mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG); 49 45 50 - generic_handle_irq(se7343_fpga_irq[ext_irq]); 46 + for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR) 47 + generic_handle_irq(irq_linear_revmap(se7343_irq_domain, bit)); 48 + 49 + chip->irq_unmask(data); 50 + } 51 + 52 + static void __init se7343_domain_init(void) 53 + { 54 + int i; 55 + 56 + se7343_irq_domain = irq_domain_add_linear(NULL, SE7343_FPGA_IRQ_NR, 57 + &irq_domain_simple_ops, NULL); 58 + if (unlikely(!se7343_irq_domain)) { 59 + printk("Failed to get IRQ domain\n"); 60 + return; 51 61 } 62 + 63 + for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { 64 + int irq = irq_create_mapping(se7343_irq_domain, i); 65 + 66 + if (unlikely(irq == 0)) { 67 + printk("Failed to allocate IRQ %d\n", i); 68 + return; 69 + } 70 + } 71 + } 72 + 73 + static void __init se7343_gc_init(void) 74 + { 75 + struct irq_chip_generic *gc; 76 + struct irq_chip_type *ct; 77 + unsigned int irq_base; 78 + 79 + irq_base = irq_linear_revmap(se7343_irq_domain, 0); 80 + 81 + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7343_irq_regs, 82 + handle_level_irq); 83 + if (unlikely(!gc)) 84 + return; 85 + 86 + ct = gc->chip_types; 87 + ct->chip.irq_mask = irq_gc_mask_set_bit; 88 + ct->chip.irq_unmask = irq_gc_mask_clr_bit; 89 + 90 + ct->regs.mask = PA_CPLD_IMSK_REG; 91 + 92 + irq_setup_generic_chip(gc, IRQ_MSK(SE7343_FPGA_IRQ_NR), 93 + IRQ_GC_INIT_MASK_CACHE, 94 + IRQ_NOREQUEST | IRQ_NOPROBE, 0); 95 + 96 + irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux); 97 + irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); 98 + 99 + irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux); 100 + irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); 101 + 102 + irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux); 103 + irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW); 104 + 105 + irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux); 106 + irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW); 52 107 } 53 108 54 109 /* ··· 111 56 */ 112 57 void __init init_7343se_IRQ(void) 113 58 { 114 - int i, irq; 115 - 116 - __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */ 117 - __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ 118 - 119 - for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { 120 - irq = create_irq(); 121 - if (irq < 0) 122 - return; 123 - se7343_fpga_irq[i] = irq; 124 - 125 - irq_set_chip_and_handler_name(se7343_fpga_irq[i], 126 - &se7343_irq_chip, 127 - handle_level_irq, 128 - "level"); 129 - 130 - irq_set_chip_data(se7343_fpga_irq[i], (void *)i); 59 + se7343_irq_regs = ioremap(PA_CPLD_BASE_ADDR, SZ_16); 60 + if (unlikely(!se7343_irq_regs)) { 61 + pr_err("Failed to remap CPLD\n"); 62 + return; 131 63 } 132 64 133 - irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux); 134 - irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); 135 - irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux); 136 - irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); 137 - irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux); 138 - irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW); 139 - irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux); 140 - irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW); 65 + /* 66 + * All FPGA IRQs disabled by default 67 + */ 68 + iowrite16(0, se7343_irq_regs + PA_CPLD_IMSK_REG); 69 + 70 + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ 71 + 72 + se7343_domain_init(); 73 + se7343_gc_init(); 141 74 }
+6 -4
arch/sh/boards/mach-se/7343/setup.c
··· 5 5 #include <linux/serial_reg.h> 6 6 #include <linux/usb/isp116x.h> 7 7 #include <linux/delay.h> 8 + #include <linux/irqdomain.h> 8 9 #include <asm/machvec.h> 9 10 #include <mach-se/mach/se7343.h> 10 11 #include <asm/heartbeat.h> ··· 146 145 static int __init sh7343se_devices_setup(void) 147 146 { 148 147 /* Wire-up dynamic vectors */ 149 - serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA]; 150 - serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB]; 151 - 148 + serial_platform_data[0].irq = irq_find_mapping(se7343_irq_domain, 149 + SE7343_FPGA_IRQ_UARTA); 150 + serial_platform_data[1].irq = irq_find_mapping(se7343_irq_domain, 151 + SE7343_FPGA_IRQ_UARTB); 152 152 usb_resources[2].start = usb_resources[2].end = 153 - se7343_fpga_irq[SE7343_FPGA_IRQ_USB]; 153 + irq_find_mapping(se7343_irq_domain, SE7343_FPGA_IRQ_USB); 154 154 155 155 return platform_add_devices(sh7343se_platform_devices, 156 156 ARRAY_SIZE(sh7343se_platform_devices));
+87 -48
arch/sh/boards/mach-se/7722/irq.c
··· 1 1 /* 2 - * linux/arch/sh/boards/se/7722/irq.c 2 + * Hitachi UL SolutionEngine 7722 FPGA IRQ Support. 3 3 * 4 4 * Copyright (C) 2007 Nobuhiro Iwamatsu 5 - * 6 - * Hitachi UL SolutionEngine 7722 Support. 5 + * Copyright (C) 2012 Paul Mundt 7 6 * 8 7 * This file is subject to the terms and conditions of the GNU General Public 9 8 * License. See the file "COPYING" in the main directory of this archive 10 9 * for more details. 11 10 */ 11 + #define DRV_NAME "SE7722-FPGA" 12 + #define pr_fmt(fmt) DRV_NAME ": " fmt 13 + 14 + #define irq_reg_readl ioread16 15 + #define irq_reg_writel iowrite16 16 + 12 17 #include <linux/init.h> 13 18 #include <linux/irq.h> 14 19 #include <linux/interrupt.h> 15 - #include <asm/irq.h> 16 - #include <asm/io.h> 20 + #include <linux/irqdomain.h> 21 + #include <linux/io.h> 22 + #include <linux/err.h> 23 + #include <asm/sizes.h> 17 24 #include <mach-se/mach/se7722.h> 18 25 19 - unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; 26 + #define IRQ01_BASE_ADDR 0x11800000 27 + #define IRQ01_MODE_REG 0 28 + #define IRQ01_STS_REG 4 29 + #define IRQ01_MASK_REG 8 20 30 21 - static void disable_se7722_irq(struct irq_data *data) 22 - { 23 - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); 24 - __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); 25 - } 26 - 27 - static void enable_se7722_irq(struct irq_data *data) 28 - { 29 - unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); 30 - __raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); 31 - } 32 - 33 - static struct irq_chip se7722_irq_chip __read_mostly = { 34 - .name = "SE7722-FPGA", 35 - .irq_mask = disable_se7722_irq, 36 - .irq_unmask = enable_se7722_irq, 37 - }; 31 + static void __iomem *se7722_irq_regs; 32 + struct irq_domain *se7722_irq_domain; 38 33 39 34 static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) 40 35 { 41 - unsigned short intv = __raw_readw(IRQ01_STS); 42 - unsigned int ext_irq = 0; 36 + struct irq_data *data = irq_get_irq_data(irq); 37 + struct irq_chip *chip = irq_data_get_irq_chip(data); 38 + unsigned long mask; 39 + int bit; 43 40 44 - intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; 41 + chip->irq_mask_ack(data); 45 42 46 - for (; intv; intv >>= 1, ext_irq++) { 47 - if (!(intv & 1)) 48 - continue; 43 + mask = ioread16(se7722_irq_regs + IRQ01_STS_REG); 49 44 50 - generic_handle_irq(se7722_fpga_irq[ext_irq]); 45 + for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR) 46 + generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit)); 47 + 48 + chip->irq_unmask(data); 49 + } 50 + 51 + static void __init se7722_domain_init(void) 52 + { 53 + int i; 54 + 55 + se7722_irq_domain = irq_domain_add_linear(NULL, SE7722_FPGA_IRQ_NR, 56 + &irq_domain_simple_ops, NULL); 57 + if (unlikely(!se7722_irq_domain)) { 58 + printk("Failed to get IRQ domain\n"); 59 + return; 60 + } 61 + 62 + for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { 63 + int irq = irq_create_mapping(se7722_irq_domain, i); 64 + 65 + if (unlikely(irq == 0)) { 66 + printk("Failed to allocate IRQ %d\n", i); 67 + return; 68 + } 51 69 } 52 70 } 53 71 54 - /* 55 - * Initialize IRQ setting 56 - */ 57 - void __init init_se7722_IRQ(void) 72 + static void __init se7722_gc_init(void) 58 73 { 59 - int i, irq; 74 + struct irq_chip_generic *gc; 75 + struct irq_chip_type *ct; 76 + unsigned int irq_base; 60 77 61 - __raw_writew(0, IRQ01_MASK); /* disable all irqs */ 62 - __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ 78 + irq_base = irq_linear_revmap(se7722_irq_domain, 0); 63 79 64 - for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { 65 - irq = create_irq(); 66 - if (irq < 0) 67 - return; 68 - se7722_fpga_irq[i] = irq; 80 + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs, 81 + handle_level_irq); 82 + if (unlikely(!gc)) 83 + return; 69 84 70 - irq_set_chip_and_handler_name(se7722_fpga_irq[i], 71 - &se7722_irq_chip, 72 - handle_level_irq, 73 - "level"); 85 + ct = gc->chip_types; 86 + ct->chip.irq_mask = irq_gc_mask_set_bit; 87 + ct->chip.irq_unmask = irq_gc_mask_clr_bit; 74 88 75 - irq_set_chip_data(se7722_fpga_irq[i], (void *)i); 76 - } 89 + ct->regs.mask = IRQ01_MASK_REG; 90 + 91 + irq_setup_generic_chip(gc, IRQ_MSK(SE7722_FPGA_IRQ_NR), 92 + IRQ_GC_INIT_MASK_CACHE, 93 + IRQ_NOREQUEST | IRQ_NOPROBE, 0); 77 94 78 95 irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux); 79 96 irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); 80 97 81 98 irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux); 82 99 irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); 100 + } 101 + 102 + /* 103 + * Initialize FPGA IRQs 104 + */ 105 + void __init init_se7722_IRQ(void) 106 + { 107 + se7722_irq_regs = ioremap(IRQ01_BASE_ADDR, SZ_16); 108 + if (unlikely(!se7722_irq_regs)) { 109 + printk("Failed to remap IRQ01 regs\n"); 110 + return; 111 + } 112 + 113 + /* 114 + * All FPGA IRQs disabled by default 115 + */ 116 + iowrite16(0, se7722_irq_regs + IRQ01_MASK_REG); 117 + 118 + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ 119 + 120 + se7722_domain_init(); 121 + se7722_gc_init(); 83 122 }
+4 -2
arch/sh/boards/mach-se/7722/setup.c
··· 2 2 * linux/arch/sh/boards/se/7722/setup.c 3 3 * 4 4 * Copyright (C) 2007 Nobuhiro Iwamatsu 5 + * Copyright (C) 2012 Paul Mundt 5 6 * 6 7 * Hitachi UL SolutionEngine 7722 Support. 7 8 * ··· 16 15 #include <linux/ata_platform.h> 17 16 #include <linux/input.h> 18 17 #include <linux/input/sh_keysc.h> 18 + #include <linux/irqdomain.h> 19 19 #include <linux/smc91x.h> 20 20 #include <linux/sh_intc.h> 21 21 #include <mach-se/mach/se7722.h> ··· 145 143 146 144 /* Wire-up dynamic vectors */ 147 145 cf_ide_resources[2].start = cf_ide_resources[2].end = 148 - se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0]; 146 + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_MRSHPC0); 149 147 150 148 smc91x_eth_resources[1].start = smc91x_eth_resources[1].end = 151 - se7722_fpga_irq[SE7722_FPGA_IRQ_SMC]; 149 + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_SMC); 152 150 153 151 return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); 154 152 }
+14 -24
arch/sh/boards/mach-se/7724/irq.c
··· 17 17 #include <linux/init.h> 18 18 #include <linux/irq.h> 19 19 #include <linux/interrupt.h> 20 - #include <asm/irq.h> 21 - #include <asm/io.h> 20 + #include <linux/export.h> 21 + #include <linux/topology.h> 22 + #include <linux/io.h> 23 + #include <linux/err.h> 22 24 #include <mach-se/mach/se7724.h> 23 25 24 26 struct fpga_irq { ··· 113 111 */ 114 112 void __init init_se7724_IRQ(void) 115 113 { 116 - int i, nid = cpu_to_node(boot_cpu_data); 114 + int irq_base, i; 117 115 118 116 __raw_writew(0xffff, IRQ0_MR); /* mask all */ 119 117 __raw_writew(0xffff, IRQ1_MR); /* mask all */ ··· 123 121 __raw_writew(0x0000, IRQ2_SR); /* clear irq */ 124 122 __raw_writew(0x002a, IRQ_MODE); /* set irq type */ 125 123 126 - for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) { 127 - int irq, wanted; 128 - 129 - wanted = SE7724_FPGA_IRQ_BASE + i; 130 - 131 - irq = create_irq_nr(wanted, nid); 132 - if (unlikely(irq == 0)) { 133 - pr_err("%s: failed hooking irq %d for FPGA\n", 134 - __func__, wanted); 135 - return; 136 - } 137 - 138 - if (unlikely(irq != wanted)) { 139 - pr_err("%s: got irq %d but wanted %d, bailing.\n", 140 - __func__, irq, wanted); 141 - destroy_irq(irq); 142 - return; 143 - } 144 - 145 - irq_set_chip_and_handler_name(irq, &se7724_irq_chip, 146 - handle_level_irq, "level"); 124 + irq_base = irq_alloc_descs(SE7724_FPGA_IRQ_BASE, SE7724_FPGA_IRQ_BASE, 125 + SE7724_FPGA_IRQ_NR, numa_node_id()); 126 + if (IS_ERR_VALUE(irq_base)) { 127 + pr_err("%s: failed hooking irqs for FPGA\n", __func__); 128 + return; 147 129 } 130 + 131 + for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) 132 + irq_set_chip_and_handler_name(irq_base + i, &se7724_irq_chip, 133 + handle_level_irq, "level"); 148 134 149 135 irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux); 150 136 irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+31 -26
arch/sh/boards/mach-x3proto/gpio.c
··· 3 3 * 4 4 * Renesas SH-X3 Prototype Baseboard GPIO Support. 5 5 * 6 - * Copyright (C) 2010 Paul Mundt 6 + * Copyright (C) 2010 - 2012 Paul Mundt 7 7 * 8 8 * This file is subject to the terms and conditions of the GNU General Public 9 9 * License. See the file "COPYING" in the main directory of this archive ··· 17 17 #include <linux/irq.h> 18 18 #include <linux/kernel.h> 19 19 #include <linux/spinlock.h> 20 + #include <linux/irqdomain.h> 20 21 #include <linux/io.h> 21 22 #include <mach/ilsel.h> 22 23 #include <mach/hardware.h> ··· 27 26 #define KEYDETR 0xb81c0004 28 27 29 28 static DEFINE_SPINLOCK(x3proto_gpio_lock); 30 - static unsigned int x3proto_gpio_irq_map[NR_BASEBOARD_GPIOS] = { 0, }; 29 + static struct irq_domain *x3proto_irq_domain; 31 30 32 31 static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 33 32 { ··· 50 49 51 50 static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) 52 51 { 53 - return x3proto_gpio_irq_map[gpio]; 52 + int virq; 53 + 54 + if (gpio < chip->ngpio) 55 + virq = irq_create_mapping(x3proto_irq_domain, gpio); 56 + else 57 + virq = -ENXIO; 58 + 59 + return virq; 54 60 } 55 61 56 62 static void x3proto_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ··· 70 62 chip->irq_mask_ack(data); 71 63 72 64 mask = __raw_readw(KEYDETR); 73 - 74 65 for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS) 75 - generic_handle_irq(x3proto_gpio_to_irq(NULL, pin)); 66 + generic_handle_irq(irq_linear_revmap(x3proto_irq_domain, pin)); 76 67 77 68 chip->irq_unmask(data); 78 69 } ··· 85 78 .ngpio = NR_BASEBOARD_GPIOS, 86 79 }; 87 80 81 + static int x3proto_gpio_irq_map(struct irq_domain *domain, unsigned int virq, 82 + irq_hw_number_t hwirq) 83 + { 84 + irq_set_chip_and_handler_name(virq, &dummy_irq_chip, handle_simple_irq, 85 + "gpio"); 86 + 87 + return 0; 88 + } 89 + 90 + static struct irq_domain_ops x3proto_gpio_irq_ops = { 91 + .map = x3proto_gpio_irq_map, 92 + .xlate = irq_domain_xlate_twocell, 93 + }; 94 + 88 95 int __init x3proto_gpio_setup(void) 89 96 { 90 - int ilsel; 91 - int ret, i; 97 + int ilsel, ret; 92 98 93 99 ilsel = ilsel_enable(ILSEL_KEY); 94 100 if (unlikely(ilsel < 0)) ··· 111 91 if (unlikely(ret)) 112 92 goto err_gpio; 113 93 114 - for (i = 0; i < NR_BASEBOARD_GPIOS; i++) { 115 - unsigned long flags; 116 - int irq = create_irq(); 117 - 118 - if (unlikely(irq < 0)) { 119 - ret = -EINVAL; 120 - goto err_irq; 121 - } 122 - 123 - spin_lock_irqsave(&x3proto_gpio_lock, flags); 124 - x3proto_gpio_irq_map[i] = irq; 125 - irq_set_chip_and_handler_name(irq, &dummy_irq_chip, 126 - handle_simple_irq, "gpio"); 127 - spin_unlock_irqrestore(&x3proto_gpio_lock, flags); 128 - } 94 + x3proto_irq_domain = irq_domain_add_linear(NULL, NR_BASEBOARD_GPIOS, 95 + &x3proto_gpio_irq_ops, NULL); 96 + if (unlikely(!x3proto_irq_domain)) 97 + goto err_irq; 129 98 130 99 pr_info("registering '%s' support, handling GPIOs %u -> %u, " 131 100 "bound to IRQ %u\n", ··· 128 119 return 0; 129 120 130 121 err_irq: 131 - for (; i >= 0; --i) 132 - if (x3proto_gpio_irq_map[i]) 133 - destroy_irq(x3proto_gpio_irq_map[i]); 134 - 135 122 ret = gpiochip_remove(&x3proto_gpio_chip); 136 123 if (unlikely(ret)) 137 124 pr_err("Failed deregistering GPIO\n");
+9 -24
arch/sh/cchips/hd6446x/hd64461.c
··· 73 73 74 74 int __init setup_hd64461(void) 75 75 { 76 - int i, nid = cpu_to_node(boot_cpu_data); 77 - 78 - if (!MACH_HD64461) 79 - return 0; 76 + int irq_base, i; 80 77 81 78 printk(KERN_INFO 82 79 "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n", ··· 86 89 #endif 87 90 __raw_writew(0xffff, HD64461_NIMR); 88 91 89 - /* IRQ 80 -> 95 belongs to HD64461 */ 90 - for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { 91 - unsigned int irq; 92 - 93 - irq = create_irq_nr(i, nid); 94 - if (unlikely(irq == 0)) { 95 - pr_err("%s: failed hooking irq %d for HD64461\n", 96 - __func__, i); 97 - return -EBUSY; 98 - } 99 - 100 - if (unlikely(irq != i)) { 101 - pr_err("%s: got irq %d but wanted %d, bailing.\n", 102 - __func__, irq, i); 103 - destroy_irq(irq); 104 - return -EINVAL; 105 - } 106 - 107 - irq_set_chip_and_handler(i, &hd64461_irq_chip, 108 - handle_level_irq); 92 + irq_base = irq_alloc_descs(HD64461_IRQBASE, HD64461_IRQBASE, 16, -1); 93 + if (IS_ERR_VALUE(irq_base)) { 94 + pr_err("%s: failed hooking irqs for HD64461\n", __func__); 95 + return irq_base; 109 96 } 97 + 98 + for (i = 0; i < 16; i++) 99 + irq_set_chip_and_handler(irq_base + i, &hd64461_irq_chip, 100 + handle_level_irq); 110 101 111 102 irq_set_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); 112 103 irq_set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
+3 -4
arch/sh/include/mach-se/mach/se7343.h
··· 50 50 #define PA_LED 0xb0C00000 /* LED */ 51 51 #define LED_SHIFT 0 52 52 #define PA_DIPSW 0xb0900000 /* Dip switch 31 */ 53 - #define PA_CPLD_MODESET 0xb1400004 /* CPLD Mode set register */ 54 - #define PA_CPLD_ST 0xb1400008 /* CPLD Interrupt status register */ 55 - #define PA_CPLD_IMSK 0xb140000a /* CPLD Interrupt mask register */ 56 53 /* Area 5 */ 57 54 #define PA_EXT5 0x14000000 58 55 #define PA_EXT5_SIZE 0x04000000 ··· 132 135 133 136 #define SE7343_FPGA_IRQ_NR 12 134 137 138 + struct irq_domain; 139 + 135 140 /* arch/sh/boards/se/7343/irq.c */ 136 - extern unsigned int se7343_fpga_irq[]; 141 + extern struct irq_domain *se7343_irq_domain; 137 142 138 143 void init_7343se_IRQ(void); 139 144
+3 -7
arch/sh/include/mach-se/mach/se7722.h
··· 81 81 #define IRQ0_IRQ evt2irq(0x600) 82 82 #define IRQ1_IRQ evt2irq(0x620) 83 83 84 - #define IRQ01_MODE 0xb1800000 85 - #define IRQ01_STS 0xb1800004 86 - #define IRQ01_MASK 0xb1800008 87 - 88 - /* Bits in IRQ01_* registers */ 89 - 90 84 #define SE7722_FPGA_IRQ_USB 0 /* IRQ0 */ 91 85 #define SE7722_FPGA_IRQ_SMC 1 /* IRQ0 */ 92 86 #define SE7722_FPGA_IRQ_MRSHPC0 2 /* IRQ1 */ ··· 89 95 #define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ 90 96 #define SE7722_FPGA_IRQ_NR 6 91 97 98 + struct irq_domain; 99 + 92 100 /* arch/sh/boards/se/7722/irq.c */ 93 - extern unsigned int se7722_fpga_irq[]; 101 + extern struct irq_domain *se7722_irq_domain; 94 102 95 103 void init_se7722_IRQ(void); 96 104
+1 -1
drivers/sh/intc/Makefile
··· 1 - obj-y := access.o chip.o core.o dynamic.o handle.o virq.o 1 + obj-y := access.o chip.o core.o handle.o virq.o 2 2 3 3 obj-$(CONFIG_INTC_BALANCING) += balancing.o 4 4 obj-$(CONFIG_INTC_USERIMASK) += userimask.o
-57
drivers/sh/intc/dynamic.c
··· 1 - /* 2 - * Dynamic IRQ management 3 - * 4 - * Copyright (C) 2010 Paul Mundt 5 - * 6 - * Modelled after arch/x86/kernel/apic/io_apic.c 7 - * 8 - * This file is subject to the terms and conditions of the GNU General Public 9 - * License. See the file "COPYING" in the main directory of this archive 10 - * for more details. 11 - */ 12 - #define pr_fmt(fmt) "intc: " fmt 13 - 14 - #include <linux/irq.h> 15 - #include <linux/bitmap.h> 16 - #include <linux/spinlock.h> 17 - #include <linux/module.h> 18 - #include "internals.h" /* only for activate_irq() damage.. */ 19 - 20 - /* 21 - * The IRQ bitmap provides a global map of bound IRQ vectors for a 22 - * given platform. Allocation of IRQs are either static through the CPU 23 - * vector map, or dynamic in the case of board mux vectors or MSI. 24 - * 25 - * As this is a central point for all IRQ controllers on the system, 26 - * each of the available sources are mapped out here. This combined with 27 - * sparseirq makes it quite trivial to keep the vector map tightly packed 28 - * when dynamically creating IRQs, as well as tying in to otherwise 29 - * unused irq_desc positions in the sparse array. 30 - */ 31 - 32 - /* 33 - * Dynamic IRQ allocation and deallocation 34 - */ 35 - unsigned int create_irq_nr(unsigned int irq_want, int node) 36 - { 37 - int irq = irq_alloc_desc_at(irq_want, node); 38 - if (irq < 0) 39 - return 0; 40 - 41 - activate_irq(irq); 42 - return irq; 43 - } 44 - 45 - int create_irq(void) 46 - { 47 - int irq = irq_alloc_desc(numa_node_id()); 48 - if (irq >= 0) 49 - activate_irq(irq); 50 - 51 - return irq; 52 - } 53 - 54 - void destroy_irq(unsigned int irq) 55 - { 56 - irq_free_desc(irq); 57 - }
+3 -1
drivers/sh/intc/virq.c
··· 219 219 if (radix_tree_deref_retry(entry)) 220 220 goto restart; 221 221 222 - irq = create_irq(); 222 + irq = irq_alloc_desc(numa_node_id()); 223 223 if (unlikely(irq < 0)) { 224 224 pr_err("no more free IRQs, bailing..\n"); 225 225 break; 226 226 } 227 + 228 + activate_irq(irq); 227 229 228 230 pr_info("Setting up a chained VIRQ from %d -> %d\n", 229 231 irq, entry->pirq);