diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 06:42:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 06:42:04 -0400 |
commit | 782d59c5dfc5ac39ac8cfb4c6dd40597938dde9c (patch) | |
tree | 2d831c436a1962bfe5dfdb3afeaf87c7a3e82132 /kernel/irq | |
parent | 47137c6ba1bcde30215795f9594cea770946456b (diff) | |
parent | 2828c9cdb8bd30f49c48210c014ccdd4cb994931 (diff) |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"The irq departement delivers:
- a cleanup series to get rid of mindlessly copied code.
- another bunch of new pointlessly different interrupt chip drivers.
Adding homebrewn irq chips (and timers) to SoCs must provide a
value add which is beyond the imagination of mere mortals.
- the usual SoC irq controller updates, IOW my second cat herding
project"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits)
irqchip: gic-v3: Implement CPU PM notifier
irqchip: gic-v3: Refactor gic_enable_redist to support both enabling and disabling
irqchip: renesas-intc-irqpin: Add minimal runtime PM support
irqchip: renesas-intc-irqpin: Add helper variable dev = &pdev->dev
irqchip: atmel-aic5: Add sama5d4 support
irqchip: atmel-aic5: The sama5d3 has 48 IRQs
Documentation: bcm7120-l2: Add Broadcom BCM7120-style L2 binding
irqchip: bcm7120-l2: Add Broadcom BCM7120-style Level 2 interrupt controller
irqchip: renesas-irqc: Add binding docs for new R-Car Gen2 SoCs
irqchip: renesas-irqc: Add DT binding documentation
irqchip: renesas-intc-irqpin: Document SoC-specific bindings
openrisc: Get rid of handle_IRQ
arm64: Get rid of handle_IRQ
ARM: omap2: irq: Convert to handle_domain_irq
ARM: imx: tzic: Convert to handle_domain_irq
ARM: imx: avic: Convert to handle_domain_irq
irqchip: or1k-pic: Convert to handle_domain_irq
irqchip: atmel-aic5: Convert to handle_domain_irq
irqchip: atmel-aic: Convert to handle_domain_irq
irqchip: gic-v3: Convert to handle_domain_irq
...
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/Kconfig | 3 | ||||
-rw-r--r-- | kernel/irq/irqdesc.c | 42 |
2 files changed, 45 insertions, 0 deletions
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index d269cecdfbf0..225086b2652e 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig | |||
@@ -55,6 +55,9 @@ config GENERIC_IRQ_CHIP | |||
55 | config IRQ_DOMAIN | 55 | config IRQ_DOMAIN |
56 | bool | 56 | bool |
57 | 57 | ||
58 | config HANDLE_DOMAIN_IRQ | ||
59 | bool | ||
60 | |||
58 | config IRQ_DOMAIN_DEBUG | 61 | config IRQ_DOMAIN_DEBUG |
59 | bool "Expose hardware/virtual IRQ mapping via debugfs" | 62 | bool "Expose hardware/virtual IRQ mapping via debugfs" |
60 | depends on IRQ_DOMAIN && DEBUG_FS | 63 | depends on IRQ_DOMAIN && DEBUG_FS |
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 1487a123db5c..a1782f88f0af 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel_stat.h> | 14 | #include <linux/kernel_stat.h> |
15 | #include <linux/radix-tree.h> | 15 | #include <linux/radix-tree.h> |
16 | #include <linux/bitmap.h> | 16 | #include <linux/bitmap.h> |
17 | #include <linux/irqdomain.h> | ||
17 | 18 | ||
18 | #include "internals.h" | 19 | #include "internals.h" |
19 | 20 | ||
@@ -336,6 +337,47 @@ int generic_handle_irq(unsigned int irq) | |||
336 | } | 337 | } |
337 | EXPORT_SYMBOL_GPL(generic_handle_irq); | 338 | EXPORT_SYMBOL_GPL(generic_handle_irq); |
338 | 339 | ||
340 | #ifdef CONFIG_HANDLE_DOMAIN_IRQ | ||
341 | /** | ||
342 | * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain | ||
343 | * @domain: The domain where to perform the lookup | ||
344 | * @hwirq: The HW irq number to convert to a logical one | ||
345 | * @lookup: Whether to perform the domain lookup or not | ||
346 | * @regs: Register file coming from the low-level handling code | ||
347 | * | ||
348 | * Returns: 0 on success, or -EINVAL if conversion has failed | ||
349 | */ | ||
350 | int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, | ||
351 | bool lookup, struct pt_regs *regs) | ||
352 | { | ||
353 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
354 | unsigned int irq = hwirq; | ||
355 | int ret = 0; | ||
356 | |||
357 | irq_enter(); | ||
358 | |||
359 | #ifdef CONFIG_IRQ_DOMAIN | ||
360 | if (lookup) | ||
361 | irq = irq_find_mapping(domain, hwirq); | ||
362 | #endif | ||
363 | |||
364 | /* | ||
365 | * Some hardware gives randomly wrong interrupts. Rather | ||
366 | * than crashing, do something sensible. | ||
367 | */ | ||
368 | if (unlikely(!irq || irq >= nr_irqs)) { | ||
369 | ack_bad_irq(irq); | ||
370 | ret = -EINVAL; | ||
371 | } else { | ||
372 | generic_handle_irq(irq); | ||
373 | } | ||
374 | |||
375 | irq_exit(); | ||
376 | set_irq_regs(old_regs); | ||
377 | return ret; | ||
378 | } | ||
379 | #endif | ||
380 | |||
339 | /* Dynamic interrupt handling */ | 381 | /* Dynamic interrupt handling */ |
340 | 382 | ||
341 | /** | 383 | /** |