From f4afa00862b7db8a2da8c012843a286716c0a534 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 19 Jun 2012 14:48:56 +0000 Subject: add Moschip MSC814x support This target currently only supports Moschip's MCS8140 SoC, but support for other chips in the same family (MCS8142, MCS8144) will be easy to add. Target support is entirely using Device Tree for probing peripherals. Drivers support include: - PCI - USB 1 & 2 - watchdog - random number generator - UART - timer - internal Ethernet PHY - Ethernet MAC core Support for the following boards is included using Device Tree - Devolo dLAN USB Extender - Tigal RBT-832 SVN-Revision: 32462 --- .../mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c (limited to 'target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c') diff --git a/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c b/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c new file mode 100644 index 0000000000..cf86734afb --- /dev/null +++ b/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c @@ -0,0 +1,93 @@ +/* + * Moschip MCS814x generic interrupt controller routines + * + * Copyright (C) 2012, Florian Fainelli + * + * Licensed under the GPLv2 + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MCS814X_IRQ_ICR 0x00 +#define MCS814X_IRQ_ISR 0x04 +#define MCS814X_IRQ_MASK 0x20 +#define MCS814X_IRQ_STS0 0x40 + +static void __iomem *mcs814x_intc_base; + +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; + + gc = irq_alloc_generic_chip("mcs814x-intc", 1, + irq_start, base, handle_level_irq); + if (!gc) + panic("unable to allocate generic irq chip"); + + 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; + + irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST, 0); + + /* Clear all interrupts */ + __raw_writel(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_ICR); + /* call the generic handler */ + handle_IRQ(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"); + + irq_domain_add_simple(np, 0); + + of_node_put(np); + + mcs814x_alloc_gc(mcs814x_intc_base, 0, 32); +} + -- cgit v1.2.3