aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2015-10-20 09:23:51 -0400
committerThomas Gleixner <tglx@linutronix.de>2015-12-08 06:53:29 -0500
commitf0cb32207307e9d7b3ee8117078b7a37f8d0166e (patch)
tree1c9f4d3b4286147fc70b6221ac980e42a67713a9
parenta946e8c717f9355d1abd5408ed0adc0002d1aed1 (diff)
genirq: Implement irq_percpu_is_enabled()
Certain interrupt controller drivers have a register set that does not make it easy to save/restore the mask of enabled/disabled interrupts at suspend/resume time. At resume time, such drivers rely on the core kernel irq subsystem to tell whether such or such interrupt is enabled or not, in order to restore the proper state in the interrupt controller register. While the irqd_irq_disabled() provides the relevant information for global interrupts, there is no similar function to query the enabled/disabled state of a per-CPU interrupt. Therefore, this commit complements the percpu_irq API with an irq_percpu_is_enabled() function. [ tglx: Simplified the implementation and added kerneldoc ] Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Cc: linux-arm-kernel@lists.infradead.org Cc: Tawfik Bayouk <tawfik@marvell.com> Cc: Nadav Haklai <nadavh@marvell.com> Cc: Lior Amsalem <alior@marvell.com> Cc: Andrew Lunn <andrew@lunn.ch> Cc: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Cc: Gregory Clement <gregory.clement@free-electrons.com> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Marc Zyngier <marc.zyngier@arm.com> Link: http://lkml.kernel.org/r/1445347435-2333-2-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/interrupt.h1
-rw-r--r--kernel/irq/manage.c25
2 files changed, 26 insertions, 0 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index ad16809c8596..cb30edbfe9fc 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -195,6 +195,7 @@ extern void disable_irq(unsigned int irq);
195extern void disable_percpu_irq(unsigned int irq); 195extern void disable_percpu_irq(unsigned int irq);
196extern void enable_irq(unsigned int irq); 196extern void enable_irq(unsigned int irq);
197extern void enable_percpu_irq(unsigned int irq, unsigned int type); 197extern void enable_percpu_irq(unsigned int irq, unsigned int type);
198extern bool irq_percpu_is_enabled(unsigned int irq);
198extern void irq_wake_thread(unsigned int irq, void *dev_id); 199extern void irq_wake_thread(unsigned int irq, void *dev_id);
199 200
200/* The following three functions are for the core kernel use only. */ 201/* The following three functions are for the core kernel use only. */
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 0eebaeef317b..c84670c373f9 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1743,6 +1743,31 @@ out:
1743} 1743}
1744EXPORT_SYMBOL_GPL(enable_percpu_irq); 1744EXPORT_SYMBOL_GPL(enable_percpu_irq);
1745 1745
1746/**
1747 * irq_percpu_is_enabled - Check whether the per cpu irq is enabled
1748 * @irq: Linux irq number to check for
1749 *
1750 * Must be called from a non migratable context. Returns the enable
1751 * state of a per cpu interrupt on the current cpu.
1752 */
1753bool irq_percpu_is_enabled(unsigned int irq)
1754{
1755 unsigned int cpu = smp_processor_id();
1756 struct irq_desc *desc;
1757 unsigned long flags;
1758 bool is_enabled;
1759
1760 desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
1761 if (!desc)
1762 return false;
1763
1764 is_enabled = cpumask_test_cpu(cpu, desc->percpu_enabled);
1765 irq_put_desc_unlock(desc, flags);
1766
1767 return is_enabled;
1768}
1769EXPORT_SYMBOL_GPL(irq_percpu_is_enabled);
1770
1746void disable_percpu_irq(unsigned int irq) 1771void disable_percpu_irq(unsigned int irq)
1747{ 1772{
1748 unsigned int cpu = smp_processor_id(); 1773 unsigned int cpu = smp_processor_id();