diff options
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/Kconfig | 9 | ||||
-rw-r--r-- | drivers/irqchip/Makefile | 5 | ||||
-rw-r--r-- | drivers/irqchip/irq-bcm2835.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-sunxi.c | 151 | ||||
-rw-r--r-- | drivers/irqchip/irq-versatile-fpga.c | 203 | ||||
-rw-r--r-- | drivers/irqchip/spear-shirq.c | 316 |
6 files changed, 684 insertions, 3 deletions
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 1bb8bf6d7fd..62ca575701d 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -1 +1,8 @@ -# empty +config VERSATILE_FPGA_IRQ + bool + select IRQ_DOMAIN + +config VERSATILE_FPGA_IRQ_NR + int + default 4 + depends on VERSATILE_FPGA_IRQ diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 054321db435..bf4609a5bd9 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -1 +1,4 @@ -obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o +obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o +obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o +obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o +obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index dc670ccc697..16c78f1c5ef 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c @@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node, } static struct of_device_id irq_of_match[] __initconst = { - { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } + { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, + { } }; void __init bcm2835_init_irq(void) diff --git a/drivers/irqchip/irq-sunxi.c b/drivers/irqchip/irq-sunxi.c new file mode 100644 index 00000000000..10974fa4265 --- /dev/null +++ b/drivers/irqchip/irq-sunxi.c @@ -0,0 +1,151 @@ +/* + * Allwinner A1X SoCs IRQ chip driver. + * + * Copyright (C) 2012 Maxime Ripard + * + * Maxime Ripard <maxime.ripard@free-electrons.com> + * + * Based on code from + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> + * Benn Huang <benn@allwinnertech.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> + +#include <linux/irqchip/sunxi.h> + +#define SUNXI_IRQ_VECTOR_REG 0x00 +#define SUNXI_IRQ_PROTECTION_REG 0x08 +#define SUNXI_IRQ_NMI_CTRL_REG 0x0c +#define SUNXI_IRQ_PENDING_REG(x) (0x10 + 0x4 * x) +#define SUNXI_IRQ_FIQ_PENDING_REG(x) (0x20 + 0x4 * x) +#define SUNXI_IRQ_ENABLE_REG(x) (0x40 + 0x4 * x) +#define SUNXI_IRQ_MASK_REG(x) (0x50 + 0x4 * x) + +static void __iomem *sunxi_irq_base; +static struct irq_domain *sunxi_irq_domain; + +void sunxi_irq_ack(struct irq_data *irqd) +{ + unsigned int irq = irqd_to_hwirq(irqd); + unsigned int irq_off = irq % 32; + int reg = irq / 32; + u32 val; + + val = readl(sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg)); + writel(val | (1 << irq_off), + sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg)); +} + +static void sunxi_irq_mask(struct irq_data *irqd) +{ + unsigned int irq = irqd_to_hwirq(irqd); + unsigned int irq_off = irq % 32; + int reg = irq / 32; + u32 val; + + val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); + writel(val & ~(1 << irq_off), + sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); +} + +static void sunxi_irq_unmask(struct irq_data *irqd) +{ + unsigned int irq = irqd_to_hwirq(irqd); + unsigned int irq_off = irq % 32; + int reg = irq / 32; + u32 val; + + val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); + writel(val | (1 << irq_off), + sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); +} + +static struct irq_chip sunxi_irq_chip = { + .name = "sunxi_irq", + .irq_ack = sunxi_irq_ack, + .irq_mask = sunxi_irq_mask, + .irq_unmask = sunxi_irq_unmask, +}; + +static int sunxi_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(virq, &sunxi_irq_chip, + handle_level_irq); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + + return 0; +} + +static struct irq_domain_ops sunxi_irq_ops = { + .map = sunxi_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int __init sunxi_of_init(struct device_node *node, + struct device_node *parent) +{ + sunxi_irq_base = of_iomap(node, 0); + if (!sunxi_irq_base) + panic("%s: unable to map IC registers\n", + node->full_name); + + /* Disable all interrupts */ + writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(0)); + writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(1)); + writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(2)); + + /* Mask all the interrupts */ + writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(0)); + writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(1)); + writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(2)); + + /* Clear all the pending interrupts */ + writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(0)); + writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(1)); + writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(2)); + + /* Enable protection mode */ + writel(0x01, sunxi_irq_base + SUNXI_IRQ_PROTECTION_REG); + + /* Configure the external interrupt source type */ + writel(0x00, sunxi_irq_base + SUNXI_IRQ_NMI_CTRL_REG); + + sunxi_irq_domain = irq_domain_add_linear(node, 3 * 32, + &sunxi_irq_ops, NULL); + if (!sunxi_irq_domain) + panic("%s: unable to create IRQ domain\n", node->full_name); + + return 0; +} + +static struct of_device_id sunxi_irq_dt_ids[] __initconst = { + { .compatible = "allwinner,sunxi-ic", .data = sunxi_of_init }, + { } +}; + +void __init sunxi_init_irq(void) +{ + of_irq_init(sunxi_irq_dt_ids); +} + +asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) +{ + u32 irq, hwirq; + + hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2; + while (hwirq != 0) { + irq = irq_find_mapping(sunxi_irq_domain, hwirq); + handle_IRQ(irq, regs); + hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2; + } +} diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c new file mode 100644 index 00000000000..9dbd82b716d --- /dev/null +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -0,0 +1,203 @@ +/* + * Support for Versatile FPGA-based IRQ controllers + */ +#include <linux/bitops.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/irqchip/versatile-fpga.h> +#include <linux/irqdomain.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/exception.h> +#include <asm/mach/irq.h> + +#define IRQ_STATUS 0x00 +#define IRQ_RAW_STATUS 0x04 +#define IRQ_ENABLE_SET 0x08 +#define IRQ_ENABLE_CLEAR 0x0c +#define INT_SOFT_SET 0x10 +#define INT_SOFT_CLEAR 0x14 +#define FIQ_STATUS 0x20 +#define FIQ_RAW_STATUS 0x24 +#define FIQ_ENABLE 0x28 +#define FIQ_ENABLE_SET 0x28 +#define FIQ_ENABLE_CLEAR 0x2C + +/** + * struct fpga_irq_data - irq data container for the FPGA IRQ controller + * @base: memory offset in virtual memory + * @chip: chip container for this instance + * @domain: IRQ domain for this instance + * @valid: mask for valid IRQs on this controller + * @used_irqs: number of active IRQs on this controller + */ +struct fpga_irq_data { + void __iomem *base; + struct irq_chip chip; + u32 valid; + struct irq_domain *domain; + u8 used_irqs; +}; + +/* we cannot allocate memory when the controllers are initially registered */ +static struct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR]; +static int fpga_irq_id; + +static void fpga_irq_mask(struct irq_data *d) +{ + struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); + u32 mask = 1 << d->hwirq; + + writel(mask, f->base + IRQ_ENABLE_CLEAR); +} + +static void fpga_irq_unmask(struct irq_data *d) +{ + struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); + u32 mask = 1 << d->hwirq; + + writel(mask, f->base + IRQ_ENABLE_SET); +} + +static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) +{ + struct fpga_irq_data *f = irq_desc_get_handler_data(desc); + u32 status = readl(f->base + IRQ_STATUS); + + if (status == 0) { + do_bad_IRQ(irq, desc); + return; + } + + do { + irq = ffs(status) - 1; + status &= ~(1 << irq); + generic_handle_irq(irq_find_mapping(f->domain, irq)); + } while (status); +} + +/* + * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero + * if we've handled at least one interrupt. This does a single read of the + * status register and handles all interrupts in order from LSB first. + */ +static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs) +{ + int handled = 0; + int irq; + u32 status; + + while ((status = readl(f->base + IRQ_STATUS))) { + irq = ffs(status) - 1; + handle_IRQ(irq_find_mapping(f->domain, irq), regs); + handled = 1; + } + + return handled; +} + +/* + * Keep iterating over all registered FPGA IRQ controllers until there are + * no pending interrupts. + */ +asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs) +{ + int i, handled; + + do { + for (i = 0, handled = 0; i < fpga_irq_id; ++i) + handled |= handle_one_fpga(&fpga_irq_devices[i], regs); + } while (handled); +} + +static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) +{ + struct fpga_irq_data *f = d->host_data; + + /* Skip invalid IRQs, only register handlers for the real ones */ + if (!(f->valid & BIT(hwirq))) + return -ENOTSUPP; + irq_set_chip_data(irq, f); + irq_set_chip_and_handler(irq, &f->chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + return 0; +} + +static struct irq_domain_ops fpga_irqdomain_ops = { + .map = fpga_irqdomain_map, + .xlate = irq_domain_xlate_onetwocell, +}; + +void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, + int parent_irq, u32 valid, struct device_node *node) +{ + struct fpga_irq_data *f; + int i; + + if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { + pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); + return; + } + f = &fpga_irq_devices[fpga_irq_id]; + f->base = base; + f->chip.name = name; + f->chip.irq_ack = fpga_irq_mask; + f->chip.irq_mask = fpga_irq_mask; + f->chip.irq_unmask = fpga_irq_unmask; + f->valid = valid; + + if (parent_irq != -1) { + irq_set_handler_data(parent_irq, f); + irq_set_chained_handler(parent_irq, fpga_irq_handle); + } + + /* This will also allocate irq descriptors */ + f->domain = irq_domain_add_simple(node, fls(valid), irq_start, + &fpga_irqdomain_ops, f); + + /* This will allocate all valid descriptors in the linear case */ + for (i = 0; i < fls(valid); i++) + if (valid & BIT(i)) { + if (!irq_start) + irq_create_mapping(f->domain, i); + f->used_irqs++; + } + + pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", + fpga_irq_id, name, base, f->used_irqs); + + fpga_irq_id++; +} + +#ifdef CONFIG_OF +int __init fpga_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + void __iomem *base; + u32 clear_mask; + u32 valid_mask; + + if (WARN_ON(!node)) + return -ENODEV; + + base = of_iomap(node, 0); + WARN(!base, "unable to map fpga irq registers\n"); + + if (of_property_read_u32(node, "clear-mask", &clear_mask)) + clear_mask = 0; + + if (of_property_read_u32(node, "valid-mask", &valid_mask)) + valid_mask = 0; + + fpga_irq_init(base, node->name, 0, -1, valid_mask, node); + + writel(clear_mask, base + IRQ_ENABLE_CLEAR); + writel(clear_mask, base + FIQ_ENABLE_CLEAR); + + return 0; +} +#endif diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c new file mode 100644 index 00000000000..80e1d2fd9d4 --- /dev/null +++ b/drivers/irqchip/spear-shirq.c @@ -0,0 +1,316 @@ +/* + * SPEAr platform shared irq layer source file + * + * Copyright (C) 2009-2012 ST Microelectronics + * Viresh Kumar <viresh.linux@gmail.com> + * + * Copyright (C) 2012 ST Microelectronics + * Shiraz Hashim <shiraz.hashim@st.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/err.h> +#include <linux/export.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/irqchip/spear-shirq.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/spinlock.h> + +static DEFINE_SPINLOCK(lock); + +/* spear300 shared irq registers offsets and masks */ +#define SPEAR300_INT_ENB_MASK_REG 0x54 +#define SPEAR300_INT_STS_MASK_REG 0x58 + +static struct spear_shirq spear300_shirq_ras1 = { + .irq_nr = 9, + .irq_bit_off = 0, + .regs = { + .enb_reg = SPEAR300_INT_ENB_MASK_REG, + .status_reg = SPEAR300_INT_STS_MASK_REG, + .clear_reg = -1, + }, +}; + +static struct spear_shirq *spear300_shirq_blocks[] = { + &spear300_shirq_ras1, +}; + +/* spear310 shared irq registers offsets and masks */ +#define SPEAR310_INT_STS_MASK_REG 0x04 + +static struct spear_shirq spear310_shirq_ras1 = { + .irq_nr = 8, + .irq_bit_off = 0, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR310_INT_STS_MASK_REG, + .clear_reg = -1, + }, +}; + +static struct spear_shirq spear310_shirq_ras2 = { + .irq_nr = 5, + .irq_bit_off = 8, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR310_INT_STS_MASK_REG, + .clear_reg = -1, + }, +}; + +static struct spear_shirq spear310_shirq_ras3 = { + .irq_nr = 1, + .irq_bit_off = 13, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR310_INT_STS_MASK_REG, + .clear_reg = -1, + }, +}; + +static struct spear_shirq spear310_shirq_intrcomm_ras = { + .irq_nr = 3, + .irq_bit_off = 14, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR310_INT_STS_MASK_REG, + .clear_reg = -1, + }, +}; + +static struct spear_shirq *spear310_shirq_blocks[] = { + &spear310_shirq_ras1, + &spear310_shirq_ras2, + &spear310_shirq_ras3, + &spear310_shirq_intrcomm_ras, +}; + +/* spear320 shared irq registers offsets and masks */ +#define SPEAR320_INT_STS_MASK_REG 0x04 +#define SPEAR320_INT_CLR_MASK_REG 0x04 +#define SPEAR320_INT_ENB_MASK_REG 0x08 + +static struct spear_shirq spear320_shirq_ras1 = { + .irq_nr = 3, + .irq_bit_off = 7, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR320_INT_STS_MASK_REG, + .clear_reg = SPEAR320_INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + +static struct spear_shirq spear320_shirq_ras2 = { + .irq_nr = 1, + .irq_bit_off = 10, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR320_INT_STS_MASK_REG, + .clear_reg = SPEAR320_INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + +static struct spear_shirq spear320_shirq_ras3 = { + .irq_nr = 3, + .irq_bit_off = 0, + .invalid_irq = 1, + .regs = { + .enb_reg = SPEAR320_INT_ENB_MASK_REG, + .reset_to_enb = 1, + .status_reg = SPEAR320_INT_STS_MASK_REG, + .clear_reg = SPEAR320_INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + +static struct spear_shirq spear320_shirq_intrcomm_ras = { + .irq_nr = 11, + .irq_bit_off = 11, + .regs = { + .enb_reg = -1, + .status_reg = SPEAR320_INT_STS_MASK_REG, + .clear_reg = SPEAR320_INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + +static struct spear_shirq *spear320_shirq_blocks[] = { + &spear320_shirq_ras3, + &spear320_shirq_ras1, + &spear320_shirq_ras2, + &spear320_shirq_intrcomm_ras, +}; + +static void shirq_irq_mask_unmask(struct irq_data *d, bool mask) +{ + struct spear_shirq *shirq = irq_data_get_irq_chip_data(d); + u32 val, offset = d->irq - shirq->irq_base; + unsigned long flags; + + if (shirq->regs.enb_reg == -1) + return; + + spin_lock_irqsave(&lock, flags); + val = readl(shirq->base + shirq->regs.enb_reg); + + if (mask ^ shirq->regs.reset_to_enb) + val &= ~(0x1 << shirq->irq_bit_off << offset); + else + val |= 0x1 << shirq->irq_bit_off << offset; + + writel(val, shirq->base + shirq->regs.enb_reg); + spin_unlock_irqrestore(&lock, flags); + +} + +static void shirq_irq_mask(struct irq_data *d) +{ + shirq_irq_mask_unmask(d, 1); +} + +static void shirq_irq_unmask(struct irq_data *d) +{ + shirq_irq_mask_unmask(d, 0); +} + +static struct irq_chip shirq_chip = { + .name = "spear-shirq", + .irq_ack = shirq_irq_mask, + .irq_mask = shirq_irq_mask, + .irq_unmask = shirq_irq_unmask, +}; + +static void shirq_handler(unsigned irq, struct irq_desc *desc) +{ + u32 i, j, val, mask, tmp; + struct irq_chip *chip; + struct spear_shirq *shirq = irq_get_handler_data(irq); + + chip = irq_get_chip(irq); + chip->irq_ack(&desc->irq_data); + + mask = ((0x1 << shirq->irq_nr) - 1) << shirq->irq_bit_off; + while ((val = readl(shirq->base + shirq->regs.status_reg) & + mask)) { + + val >>= shirq->irq_bit_off; + for (i = 0, j = 1; i < shirq->irq_nr; i++, j <<= 1) { + + if (!(j & val)) + continue; + + generic_handle_irq(shirq->irq_base + i); + + /* clear interrupt */ + if (shirq->regs.clear_reg == -1) + continue; + + tmp = readl(shirq->base + shirq->regs.clear_reg); + if (shirq->regs.reset_to_clear) + tmp &= ~(j << shirq->irq_bit_off); + else + tmp |= (j << shirq->irq_bit_off); + writel(tmp, shirq->base + shirq->regs.clear_reg); + } + } + chip->irq_unmask(&desc->irq_data); +} + +static void __init spear_shirq_register(struct spear_shirq *shirq) +{ + int i; + + if (shirq->invalid_irq) + return; + + irq_set_chained_handler(shirq->irq, shirq_handler); + for (i = 0; i < shirq->irq_nr; i++) { + irq_set_chip_and_handler(shirq->irq_base + i, + &shirq_chip, handle_simple_irq); + set_irq_flags(shirq->irq_base + i, IRQF_VALID); + irq_set_chip_data(shirq->irq_base + i, shirq); + } + + irq_set_handler_data(shirq->irq, shirq); +} + +static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr, + struct device_node *np) +{ + int i, irq_base, hwirq = 0, irq_nr = 0; + static struct irq_domain *shirq_domain; + void __iomem *base; + + base = of_iomap(np, 0); + if (!base) { + pr_err("%s: failed to map shirq registers\n", __func__); + return -ENXIO; + } + + for (i = 0; i < block_nr; i++) + irq_nr += shirq_blocks[i]->irq_nr; + + irq_base = irq_alloc_descs(-1, 0, irq_nr, 0); + if (IS_ERR_VALUE(irq_base)) { + pr_err("%s: irq desc alloc failed\n", __func__); + goto err_unmap; + } + + shirq_domain = irq_domain_add_legacy(np, irq_nr, irq_base, 0, + &irq_domain_simple_ops, NULL); + if (WARN_ON(!shirq_domain)) { + pr_warn("%s: irq domain init failed\n", __func__); + goto err_free_desc; + } + + for (i = 0; i < block_nr; i++) { + shirq_blocks[i]->base = base; + shirq_blocks[i]->irq_base = irq_find_mapping(shirq_domain, + hwirq); + shirq_blocks[i]->irq = irq_of_parse_and_map(np, i); + + spear_shirq_register(shirq_blocks[i]); + hwirq += shirq_blocks[i]->irq_nr; + } + + return 0; + +err_free_desc: + irq_free_descs(irq_base, irq_nr); +err_unmap: + iounmap(base); + return -ENXIO; +} + +int __init spear300_shirq_of_init(struct device_node *np, + struct device_node *parent) +{ + return shirq_init(spear300_shirq_blocks, + ARRAY_SIZE(spear300_shirq_blocks), np); +} + +int __init spear310_shirq_of_init(struct device_node *np, + struct device_node *parent) +{ + return shirq_init(spear310_shirq_blocks, + ARRAY_SIZE(spear310_shirq_blocks), np); +} + +int __init spear320_shirq_of_init(struct device_node *np, + struct device_node *parent) +{ + return shirq_init(spear320_shirq_blocks, + ARRAY_SIZE(spear320_shirq_blocks), np); +} |