From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- .../mcs814x/files-3.18/arch/arm/mach-mcs814x/irq.c | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/irq.c (limited to 'target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/irq.c') diff --git a/target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/irq.c b/target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/irq.c new file mode 100644 index 0000000..d1cab68 --- /dev/null +++ b/target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/irq.c @@ -0,0 +1,94 @@ +/* + * Moschip MCS814x generic interrupt controller routines + * + * Copyright (C) 2012, Florian Fainelli + * + * Licensed under the GPLv2 + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static void __iomem *mcs814x_intc_base; +static struct irq_domain *domain; + +static void __init mcs814x_alloc_gc(void __iomem *base, unsigned int irq_start, + unsigned int num) +{ + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + if (irq_alloc_domain_generic_chips(domain, num, 1, "mcs814x-intc", handle_level_irq, + IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 0)) + panic("unable to allocate domain generic irq chip"); + + gc = irq_get_domain_generic_chip(domain, irq_start); + if (!gc) + panic("unable to get generic irq chip"); + + gc->reg_base = base; + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_unmask_enable_reg; + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + ct->regs.mask = MCS814X_IRQ_MASK; + ct->regs.enable = MCS814X_IRQ_ICR; + + /* Clear all interrupts */ + writel_relaxed(0xffffffff, base + MCS814X_IRQ_ICR); +} + +asmlinkage void __exception_irq_entry mcs814x_handle_irq(struct pt_regs *regs) +{ + u32 status, irq; + + do { + /* read the status register */ + status = __raw_readl(mcs814x_intc_base + MCS814X_IRQ_STS0); + if (!status) + break; + + irq = ffs(status) - 1; + status |= (1 << irq); + /* clear the interrupt */ + __raw_writel(status, mcs814x_intc_base + MCS814X_IRQ_STS0); + /* call the generic handler */ + handle_domain_irq(domain, irq, regs); + + } while (1); +} + +static const struct of_device_id mcs814x_intc_ids[] = { + { .compatible = "moschip,mcs814x-intc" }, + { /* sentinel */ }, +}; + +void __init mcs814x_of_irq_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, mcs814x_intc_ids); + if (!np) + panic("unable to find compatible intc node in dtb\n"); + + mcs814x_intc_base = of_iomap(np, 0); + if (!mcs814x_intc_base) + panic("unable to map intc cpu registers\n"); + + domain = irq_domain_add_linear(np, 32, &irq_generic_chip_ops, NULL); + if (!domain) + panic("unable to add irq domain\n"); + irq_set_default_host(domain); + + of_node_put(np); + + mcs814x_alloc_gc(mcs814x_intc_base, 0, 32); +} + -- cgit v1.2.3