summaryrefslogtreecommitdiff
path: root/arch/arm/common/vic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 16:01:50 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 16:01:50 -0700
commitff8ce5f67ddca709fe59e6173f89260f0fdc2b22 (patch)
tree90d3ad380b290d251b54590be485b2ffb4528e5a /arch/arm/common/vic.c
parent4f6ade91532b5b05ea28219b891f12a3cec528cd (diff)
parent4ab1056766a4e49f6b9ef324313dd1583f8f8f4e (diff)
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull core ARM updates from Russell King: "This is the bulk of the core ARM updates for this merge window. Included in here is a different way to handle the VIVT cache flushing on context switch, which should allow scheduler folk to remove a special case in their core code. We have architectured timer support here, which is a set of timers specified by the ARM architecture for future SoCs. So we should see less variability in timer design going forward. The last big thing here is my cleanup to the way we handle PCI across ARM, fixing some oddities in some platforms which hadn't realised there was a way to deal with their private data already built in to our PCI backend. I've also removed support for the ARMv3 architecture; it hasn't worked properly for years so it seems pointless to keep it around." * 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (47 commits) ARM: PCI: remove per-pci_hw list of buses ARM: PCI: dove/kirkwood/mv78xx0: use sys->private_data ARM: PCI: provide a default bus scan implementation ARM: PCI: get rid of pci_std_swizzle() ARM: PCI: versatile: fix PCI interrupt setup ARM: PCI: integrator: use common PCI swizzle ARM: 7416/1: LPAE: Remove unused L_PTE_(BUFFERABLE|CACHEABLE) macros ARM: 7415/1: vfp: convert printk's to pr_*'s ARM: decompressor: avoid speculative prefetch from non-RAM areas ARM: Remove ARMv3 support from decompressor ARM: 7413/1: move read_{boot,persistent}_clock to the architecture level ARM: Remove support for ARMv3 ARM610 and ARM710 CPUs ARM: 7363/1: DEBUG_LL: limit early mapping to the minimum ARM: 7391/1: versatile: add some auxdata for device trees ARM: 7389/2: plat-versatile: modernize FPGA IRQ controller AMBA: get rid of last two uses of NO_IRQ ARM: 7408/1: cacheflush: return error to userspace when flushing syscall fails ARM: 7409/1: Do not call flush_cache_user_range with mmap_sem held ARM: 7404/1: cmpxchg64: use atomic64 and local64 routines for cmpxchg64 ARM: 7347/1: SCU: use cpu_logical_map for per-CPU low power mode ...
Diffstat (limited to 'arch/arm/common/vic.c')
-rw-r--r--arch/arm/common/vic.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 7e288f96cedf..e0d538803cc3 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -39,6 +39,7 @@
* struct vic_device - VIC PM device
* @irq: The IRQ number for the base of the VIC.
* @base: The register base for the VIC.
+ * @valid_sources: A bitmask of valid interrupts
* @resume_sources: A bitmask of interrupts for resume.
* @resume_irqs: The IRQs enabled for resume.
* @int_select: Save for VIC_INT_SELECT.
@@ -50,6 +51,7 @@
struct vic_device {
void __iomem *base;
int irq;
+ u32 valid_sources;
u32 resume_sources;
u32 resume_irqs;
u32 int_select;
@@ -164,10 +166,32 @@ static int __init vic_pm_init(void)
late_initcall(vic_pm_init);
#endif /* CONFIG_PM */
+static struct irq_chip vic_chip;
+
+static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct vic_device *v = d->host_data;
+
+ /* Skip invalid IRQs, only register handlers for the real ones */
+ if (!(v->valid_sources & (1 << hwirq)))
+ return -ENOTSUPP;
+ irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq);
+ irq_set_chip_data(irq, v->base);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+static struct irq_domain_ops vic_irqdomain_ops = {
+ .map = vic_irqdomain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
/**
* vic_register() - Register a VIC.
* @base: The base address of the VIC.
* @irq: The base IRQ for the VIC.
+ * @valid_sources: bitmask of valid interrupts
* @resume_sources: bitmask of interrupts allowed for resume sources.
* @node: The device tree node associated with the VIC.
*
@@ -178,7 +202,8 @@ late_initcall(vic_pm_init);
* This also configures the IRQ domain for the VIC.
*/
static void __init vic_register(void __iomem *base, unsigned int irq,
- u32 resume_sources, struct device_node *node)
+ u32 valid_sources, u32 resume_sources,
+ struct device_node *node)
{
struct vic_device *v;
@@ -189,11 +214,12 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
v = &vic_devices[vic_id];
v->base = base;
+ v->valid_sources = valid_sources;
v->resume_sources = resume_sources;
v->irq = irq;
vic_id++;
- v->domain = irq_domain_add_legacy(node, 32, irq, 0,
- &irq_domain_simple_ops, v);
+ v->domain = irq_domain_add_legacy(node, fls(valid_sources), irq, 0,
+ &vic_irqdomain_ops, v);
}
static void vic_ack_irq(struct irq_data *d)
@@ -287,23 +313,6 @@ static void __init vic_clear_interrupts(void __iomem *base)
}
}
-static void __init vic_set_irq_sources(void __iomem *base,
- unsigned int irq_start, u32 vic_sources)
-{
- unsigned int i;
-
- for (i = 0; i < 32; i++) {
- if (vic_sources & (1 << i)) {
- unsigned int irq = irq_start + i;
-
- irq_set_chip_and_handler(irq, &vic_chip,
- handle_level_irq);
- irq_set_chip_data(irq, base);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
- }
-}
-
/*
* The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
* The original cell has 32 interrupts, while the modified one has 64,
@@ -338,8 +347,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
writel(32, base + VIC_PL190_DEF_VECT_ADDR);
}
- vic_set_irq_sources(base, irq_start, vic_sources);
- vic_register(base, irq_start, 0, node);
+ vic_register(base, irq_start, vic_sources, 0, node);
}
void __init __vic_init(void __iomem *base, unsigned int irq_start,
@@ -379,9 +387,7 @@ void __init __vic_init(void __iomem *base, unsigned int irq_start,
vic_init2(base);
- vic_set_irq_sources(base, irq_start, vic_sources);
-
- vic_register(base, irq_start, resume_sources, node);
+ vic_register(base, irq_start, vic_sources, resume_sources, node);
}
/**