-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/lin…
…ux/kernel/git/tip/tip Pull irq updates from Thomas Gleixner: "This lot provides: * Bugfixes for armada irq controller * Updates to renesas irq chip * Support for the TI-NSPIRE irq controller Not strictly a bug fix only pull request, but important updates for some of the arm Socs which I completely forgot to send last week. Seems like my obliviousness is getting worse, I just can't remember when it started" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip: Add support for TI-NSPIRE irqchip irqchip: renesas-irqc: Enable mask on suspend irqchip: renesas-irqc: Use lazy disable irqchip: armada-370-xp: fix MSI race condition irqchip: armada-370-xp: fix IPI race condition
- Loading branch information
Showing
4 changed files
with
148 additions
and
2 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
Documentation/devicetree/bindings/interrupt-controller/lsi,zevio-intc.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
TI-NSPIRE interrupt controller | ||
|
||
Required properties: | ||
- compatible: Compatible property value should be "lsi,zevio-intc". | ||
|
||
- reg: Physical base address of the controller and length of memory mapped | ||
region. | ||
|
||
- interrupt-controller : Identifies the node as an interrupt controller | ||
|
||
Example: | ||
|
||
interrupt-controller { | ||
compatible = "lsi,zevio-intc"; | ||
interrupt-controller; | ||
reg = <0xDC000000 0x1000>; | ||
#interrupt-cells = <1>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
* linux/drivers/irqchip/irq-zevio.c | ||
* | ||
* Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2, as | ||
* published by the Free Software Foundation. | ||
* | ||
*/ | ||
|
||
#include <linux/io.h> | ||
#include <linux/irq.h> | ||
#include <linux/of.h> | ||
#include <linux/of_address.h> | ||
#include <linux/of_irq.h> | ||
|
||
#include <asm/mach/irq.h> | ||
#include <asm/exception.h> | ||
|
||
#include "irqchip.h" | ||
|
||
#define IO_STATUS 0x000 | ||
#define IO_RAW_STATUS 0x004 | ||
#define IO_ENABLE 0x008 | ||
#define IO_DISABLE 0x00C | ||
#define IO_CURRENT 0x020 | ||
#define IO_RESET 0x028 | ||
#define IO_MAX_PRIOTY 0x02C | ||
|
||
#define IO_IRQ_BASE 0x000 | ||
#define IO_FIQ_BASE 0x100 | ||
|
||
#define IO_INVERT_SEL 0x200 | ||
#define IO_STICKY_SEL 0x204 | ||
#define IO_PRIORITY_SEL 0x300 | ||
|
||
#define MAX_INTRS 32 | ||
#define FIQ_START MAX_INTRS | ||
|
||
static struct irq_domain *zevio_irq_domain; | ||
static void __iomem *zevio_irq_io; | ||
|
||
static void zevio_irq_ack(struct irq_data *irqd) | ||
{ | ||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(irqd); | ||
struct irq_chip_regs *regs = | ||
&container_of(irqd->chip, struct irq_chip_type, chip)->regs; | ||
|
||
readl(gc->reg_base + regs->ack); | ||
} | ||
|
||
static asmlinkage void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) | ||
{ | ||
int irqnr; | ||
|
||
while (readl(zevio_irq_io + IO_STATUS)) { | ||
irqnr = readl(zevio_irq_io + IO_CURRENT); | ||
irqnr = irq_find_mapping(zevio_irq_domain, irqnr); | ||
handle_IRQ(irqnr, regs); | ||
}; | ||
} | ||
|
||
static void __init zevio_init_irq_base(void __iomem *base) | ||
{ | ||
/* Disable all interrupts */ | ||
writel(~0, base + IO_DISABLE); | ||
|
||
/* Accept interrupts of all priorities */ | ||
writel(0xF, base + IO_MAX_PRIOTY); | ||
|
||
/* Reset existing interrupts */ | ||
readl(base + IO_RESET); | ||
} | ||
|
||
static int __init zevio_of_init(struct device_node *node, | ||
struct device_node *parent) | ||
{ | ||
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
struct irq_chip_generic *gc; | ||
int ret; | ||
|
||
if (WARN_ON(zevio_irq_io || zevio_irq_domain)) | ||
return -EBUSY; | ||
|
||
zevio_irq_io = of_iomap(node, 0); | ||
BUG_ON(!zevio_irq_io); | ||
|
||
/* Do not invert interrupt status bits */ | ||
writel(~0, zevio_irq_io + IO_INVERT_SEL); | ||
|
||
/* Disable sticky interrupts */ | ||
writel(0, zevio_irq_io + IO_STICKY_SEL); | ||
|
||
/* We don't use IRQ priorities. Set each IRQ to highest priority. */ | ||
memset_io(zevio_irq_io + IO_PRIORITY_SEL, 0, MAX_INTRS * sizeof(u32)); | ||
|
||
/* Init IRQ and FIQ */ | ||
zevio_init_irq_base(zevio_irq_io + IO_IRQ_BASE); | ||
zevio_init_irq_base(zevio_irq_io + IO_FIQ_BASE); | ||
|
||
zevio_irq_domain = irq_domain_add_linear(node, MAX_INTRS, | ||
&irq_generic_chip_ops, NULL); | ||
BUG_ON(!zevio_irq_domain); | ||
|
||
ret = irq_alloc_domain_generic_chips(zevio_irq_domain, MAX_INTRS, 1, | ||
"zevio_intc", handle_level_irq, | ||
clr, 0, IRQ_GC_INIT_MASK_CACHE); | ||
BUG_ON(ret); | ||
|
||
gc = irq_get_domain_generic_chip(zevio_irq_domain, 0); | ||
gc->reg_base = zevio_irq_io; | ||
gc->chip_types[0].chip.irq_ack = zevio_irq_ack; | ||
gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg; | ||
gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg; | ||
gc->chip_types[0].regs.mask = IO_IRQ_BASE + IO_ENABLE; | ||
gc->chip_types[0].regs.enable = IO_IRQ_BASE + IO_ENABLE; | ||
gc->chip_types[0].regs.disable = IO_IRQ_BASE + IO_DISABLE; | ||
gc->chip_types[0].regs.ack = IO_IRQ_BASE + IO_RESET; | ||
|
||
set_handle_irq(zevio_handle_irq); | ||
|
||
pr_info("TI-NSPIRE classic IRQ controller\n"); | ||
return 0; | ||
} | ||
|
||
IRQCHIP_DECLARE(zevio_irq, "lsi,zevio-intc", zevio_of_init); |