···4444config SH_7722_SOLUTION_ENGINE4545 bool "SolutionEngine7722"4646 select SOLUTION_ENGINE4747+ select GENERIC_IRQ_CHIP4848+ select IRQ_DOMAIN4749 depends on CPU_SUBTYPE_SH77224850 help4951 Select 7722 SolutionEngine if configuring for a Hitachi SH772···8280config SH_7343_SOLUTION_ENGINE8381 bool "SolutionEngine7343"8482 select SOLUTION_ENGINE8383+ select GENERIC_IRQ_CHIP8484+ select IRQ_DOMAIN8585 depends on CPU_SUBTYPE_SH73438686 help8787 Select 7343 SolutionEngine if configuring for a Hitachi···299295 bool "SH-X3 Prototype board"300296 depends on CPU_SUBTYPE_SHX3301297 select NO_IOPORT if !PCI298298+ select IRQ_DOMAIN302299303300config SH_MAGIC_PANEL_R2304301 bool "Magic Panel R2"
+12-22
arch/sh/boards/mach-dreamcast/irq.c
···88 * This file is part of the LinuxDC project (www.linuxdc.org)99 * Released under the terms of the GNU GPL v2.01010 */1111-1211#include <linux/irq.h>1312#include <linux/io.h>1414-#include <asm/irq.h>1313+#include <linux/irq.h>1414+#include <linux/export.h>1515+#include <linux/err.h>1516#include <mach/sysasic.h>16171718/*···142141143142void systemasic_irq_init(void)144143{145145- int i, nid = cpu_to_node(boot_cpu_data);144144+ int irq_base, i;146145147147- /* Assign all virtual IRQs to the System ASIC int. handler */148148- for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) {149149- unsigned int irq;150150-151151- irq = create_irq_nr(i, nid);152152- if (unlikely(irq == 0)) {153153- pr_err("%s: failed hooking irq %d for systemasic\n",154154- __func__, i);155155- return;156156- }157157-158158- if (unlikely(irq != i)) {159159- pr_err("%s: got irq %d but wanted %d, bailing.\n",160160- __func__, irq, i);161161- destroy_irq(irq);162162- return;163163- }164164-165165- irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq);146146+ irq_base = irq_alloc_descs(HW_EVENT_IRQ_BASE, HW_EVENT_IRQ_BASE,147147+ HW_EVENT_IRQ_MAX - HW_EVENT_IRQ_BASE, -1);148148+ if (IS_ERR_VALUE(irq_base)) {149149+ pr_err("%s: failed hooking irqs\n", __func__);150150+ return;166151 }152152+153153+ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)154154+ irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq);167155}
+95-52
arch/sh/boards/mach-se/7343/irq.c
···11/*22- * linux/arch/sh/boards/se/7343/irq.c22+ * Hitachi UL SolutionEngine 7343 FPGA IRQ Support.33 *44 * Copyright (C) 2008 Yoshihiro Shimoda55+ * Copyright (C) 2012 Paul Mundt56 *66- * Based on linux/arch/sh/boards/se/7722/irq.c77+ * Based on linux/arch/sh/boards/se/7343/irq.c78 * Copyright (C) 2007 Nobuhiro Iwamatsu89 *910 * This file is subject to the terms and conditions of the GNU General Public1011 * License. See the file "COPYING" in the main directory of this archive1112 * for more details.1213 */1414+#define DRV_NAME "SE7343-FPGA"1515+#define pr_fmt(fmt) DRV_NAME ": " fmt1616+1717+#define irq_reg_readl ioread161818+#define irq_reg_writel iowrite161919+1320#include <linux/init.h>1421#include <linux/irq.h>1522#include <linux/interrupt.h>2323+#include <linux/irqdomain.h>1624#include <linux/io.h>2525+#include <asm/sizes.h>1726#include <mach-se/mach/se7343.h>18271919-unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };2828+#define PA_CPLD_BASE_ADDR 0x114000002929+#define PA_CPLD_ST_REG 0x08 /* CPLD Interrupt status register */3030+#define PA_CPLD_IMSK_REG 0x0a /* CPLD Interrupt mask register */20312121-static void disable_se7343_irq(struct irq_data *data)2222-{2323- unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);2424- __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);2525-}2626-2727-static void enable_se7343_irq(struct irq_data *data)2828-{2929- unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);3030- __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);3131-}3232-3333-static struct irq_chip se7343_irq_chip __read_mostly = {3434- .name = "SE7343-FPGA",3535- .irq_mask = disable_se7343_irq,3636- .irq_unmask = enable_se7343_irq,3737-};3232+static void __iomem *se7343_irq_regs;3333+struct irq_domain *se7343_irq_domain;38343935static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)4036{4141- unsigned short intv = __raw_readw(PA_CPLD_ST);4242- unsigned int ext_irq = 0;3737+ struct irq_data *data = irq_get_irq_data(irq);3838+ struct irq_chip *chip = irq_data_get_irq_chip(data);3939+ unsigned long mask;4040+ int bit;43414444- intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;4242+ chip->irq_mask_ack(data);45434646- for (; intv; intv >>= 1, ext_irq++) {4747- if (!(intv & 1))4848- continue;4444+ mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG);49455050- generic_handle_irq(se7343_fpga_irq[ext_irq]);4646+ for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR)4747+ generic_handle_irq(irq_linear_revmap(se7343_irq_domain, bit));4848+4949+ chip->irq_unmask(data);5050+}5151+5252+static void __init se7343_domain_init(void)5353+{5454+ int i;5555+5656+ se7343_irq_domain = irq_domain_add_linear(NULL, SE7343_FPGA_IRQ_NR,5757+ &irq_domain_simple_ops, NULL);5858+ if (unlikely(!se7343_irq_domain)) {5959+ printk("Failed to get IRQ domain\n");6060+ return;5161 }6262+6363+ for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {6464+ int irq = irq_create_mapping(se7343_irq_domain, i);6565+6666+ if (unlikely(irq == 0)) {6767+ printk("Failed to allocate IRQ %d\n", i);6868+ return;6969+ }7070+ }7171+}7272+7373+static void __init se7343_gc_init(void)7474+{7575+ struct irq_chip_generic *gc;7676+ struct irq_chip_type *ct;7777+ unsigned int irq_base;7878+7979+ irq_base = irq_linear_revmap(se7343_irq_domain, 0);8080+8181+ gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7343_irq_regs,8282+ handle_level_irq);8383+ if (unlikely(!gc))8484+ return;8585+8686+ ct = gc->chip_types;8787+ ct->chip.irq_mask = irq_gc_mask_set_bit;8888+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;8989+9090+ ct->regs.mask = PA_CPLD_IMSK_REG;9191+9292+ irq_setup_generic_chip(gc, IRQ_MSK(SE7343_FPGA_IRQ_NR),9393+ IRQ_GC_INIT_MASK_CACHE,9494+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);9595+9696+ irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux);9797+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);9898+9999+ irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux);100100+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);101101+102102+ irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux);103103+ irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW);104104+105105+ irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux);106106+ irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW);52107}5310854109/*···11156 */11257void __init init_7343se_IRQ(void)11358{114114- int i, irq;115115-116116- __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */117117- __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */118118-119119- for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {120120- irq = create_irq();121121- if (irq < 0)122122- return;123123- se7343_fpga_irq[i] = irq;124124-125125- irq_set_chip_and_handler_name(se7343_fpga_irq[i],126126- &se7343_irq_chip,127127- handle_level_irq,128128- "level");129129-130130- irq_set_chip_data(se7343_fpga_irq[i], (void *)i);5959+ se7343_irq_regs = ioremap(PA_CPLD_BASE_ADDR, SZ_16);6060+ if (unlikely(!se7343_irq_regs)) {6161+ pr_err("Failed to remap CPLD\n");6262+ return;13163 }13264133133- irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux);134134- irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);135135- irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux);136136- irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);137137- irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux);138138- irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW);139139- irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux);140140- irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW);6565+ /*6666+ * All FPGA IRQs disabled by default6767+ */6868+ iowrite16(0, se7343_irq_regs + PA_CPLD_IMSK_REG);6969+7070+ __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */7171+7272+ se7343_domain_init();7373+ se7343_gc_init();14174}
···11-/*22- * Dynamic IRQ management33- *44- * Copyright (C) 2010 Paul Mundt55- *66- * Modelled after arch/x86/kernel/apic/io_apic.c77- *88- * This file is subject to the terms and conditions of the GNU General Public99- * License. See the file "COPYING" in the main directory of this archive1010- * for more details.1111- */1212-#define pr_fmt(fmt) "intc: " fmt1313-1414-#include <linux/irq.h>1515-#include <linux/bitmap.h>1616-#include <linux/spinlock.h>1717-#include <linux/module.h>1818-#include "internals.h" /* only for activate_irq() damage.. */1919-2020-/*2121- * The IRQ bitmap provides a global map of bound IRQ vectors for a2222- * given platform. Allocation of IRQs are either static through the CPU2323- * vector map, or dynamic in the case of board mux vectors or MSI.2424- *2525- * As this is a central point for all IRQ controllers on the system,2626- * each of the available sources are mapped out here. This combined with2727- * sparseirq makes it quite trivial to keep the vector map tightly packed2828- * when dynamically creating IRQs, as well as tying in to otherwise2929- * unused irq_desc positions in the sparse array.3030- */3131-3232-/*3333- * Dynamic IRQ allocation and deallocation3434- */3535-unsigned int create_irq_nr(unsigned int irq_want, int node)3636-{3737- int irq = irq_alloc_desc_at(irq_want, node);3838- if (irq < 0)3939- return 0;4040-4141- activate_irq(irq);4242- return irq;4343-}4444-4545-int create_irq(void)4646-{4747- int irq = irq_alloc_desc(numa_node_id());4848- if (irq >= 0)4949- activate_irq(irq);5050-5151- return irq;5252-}5353-5454-void destroy_irq(unsigned int irq)5555-{5656- irq_free_desc(irq);5757-}
+3-1
drivers/sh/intc/virq.c
···219219 if (radix_tree_deref_retry(entry))220220 goto restart;221221222222- irq = create_irq();222222+ irq = irq_alloc_desc(numa_node_id());223223 if (unlikely(irq < 0)) {224224 pr_err("no more free IRQs, bailing..\n");225225 break;226226 }227227+228228+ activate_irq(irq);227229228230 pr_info("Setting up a chained VIRQ from %d -> %d\n",229231 irq, entry->pirq);