Commit Graph

141 Commits

Author SHA1 Message Date
Marc Zyngier 31d9d9b6d8 genirq: Add support for per-cpu dev_id interrupts
The ARM GIC interrupt controller offers per CPU interrupts (PPIs),
which are usually used to connect local timers to each core. Each CPU
has its own private interface to the GIC, and only sees the PPIs that
are directly connect to it.

While these timers are separate devices and have a separate interrupt
line to a core, they all use the same IRQ number.

For these devices, request_irq() is not the right API as it assumes
that an IRQ number is visible by a number of CPUs (through the
affinity setting), but makes it very awkward to express that an IRQ
number can be handled by all CPUs, and yet be a different interrupt
line on each CPU, requiring a different dev_id cookie to be passed
back to the handler.

The *_percpu_irq() functions is designed to overcome these
limitations, by providing a per-cpu dev_id vector:

int request_percpu_irq(unsigned int irq, irq_handler_t handler,
		   const char *devname, void __percpu *percpu_dev_id);
void free_percpu_irq(unsigned int, void __percpu *);
int setup_percpu_irq(unsigned int irq, struct irqaction *new);
void remove_percpu_irq(unsigned int irq, struct irqaction *act);
void enable_percpu_irq(unsigned int irq);
void disable_percpu_irq(unsigned int irq);

The API has a number of limitations:
- no interrupt sharing
- no threading
- common handler across all the CPUs

Once the interrupt is requested using setup_percpu_irq() or
request_percpu_irq(), it must be enabled by each core that wishes its
local interrupt to be delivered.

Based on an initial patch by Thomas Gleixner.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1316793788-14500-2-git-send-email-marc.zyngier@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-10-03 15:35:26 +02:00
Geert Uytterhoeven ed585a6516 genirq: Make irq_shutdown() symmetric vs. irq_startup again
If an irq_chip provides .irq_shutdown(), but neither of .irq_disable() or
.irq_mask(), free_irq() crashes when jumping to NULL.
Fix this by only trying .irq_disable() and .irq_mask() if there's no
.irq_shutdown() provided.

This revives the symmetry with irq_startup(), which tries .irq_startup(),
.irq_enable(), and irq_unmask(), and makes it consistent with the comment for
irq_chip.irq_shutdown() in <linux/irq.h>, which says:

 * @irq_shutdown:	shut down the interrupt (defaults to ->disable if NULL)

This is also how __free_irq() behaved before the big overhaul, cfr. e.g.
3b56f0585f ("genirq: Remove bogus conditional"),
where the core interrupt code always overrode .irq_shutdown() to
.irq_disable() if .irq_shutdown() was NULL.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
Link: http://lkml.kernel.org/r/1315742394-16036-2-git-send-email-geert@linux-m68k.org
Cc: stable@kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-09-12 09:38:53 +02:00
Jonathan Cameron edf76f8307 irq: Export functions to allow modular irq drivers
Export handle_simple_irq, irq_modify_status, irq_alloc_descs,
irq_free_descs and generic_handle_irq to allow their usage in
modules. First user is IIO, which wants to be built modular, but needs
to be able to create irq chips, allocate and configure interrupt
descriptors and handle demultiplexing interrupts.

[ tglx: Moved the uninlinig of generic_handle_irq to a separate patch ]

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Link: http://lkml.kernel.org/r/%3C1305711544-505-1-git-send-email-jic23%40cam.ac.uk%3E
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-05-18 14:59:08 +02:00
Paul Mundt 7f1b1244e1 genirq: Support per-IRQ thread disabling.
This adds support for disabling threading on a per-IRQ basis via the IRQ
status instead of the IRQ flow, which is necessary for interrupts that
don't follow the natural IRQ flow channels, such as those that are
virtually created.

The new APIs added are simply:

	irq_set_thread()
	irq_set_nothread()

which follow the rest of the IRQ status routines.

Chained handlers also have IRQ_NOTHREAD set on them automatically, making
the lack of threading explicit rather than implicit. Subsequently, the
nothread flag can be viewed through the standard genirq debugging
facilities.

[ tglx: Fixed cleanup fallout ]

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Link: http://lkml.kernel.org/r/%3C20110406210135.GF18426%40linux-sh.org%3E
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-04-23 15:56:24 +02:00
Lucas De Marchi 25985edced Fix common misspellings
Fixes generated by 'codespell' and manually reviewed.

Signed-off-by: Lucas De Marchi <lucas.demarchi@profusion.mobi>
2011-03-31 11:26:23 -03:00
Stephen Rothwell ac0e0447be genirq: fix CONFIG_IRQ_EDGE_EOI_HANDLER build
Fixes these errors:

  kernel/irq/chip.c: In function 'handle_edge_eoi_irq':
  kernel/irq/chip.c:517: warning: label 'out_unlock' defined but not used
  kernel/irq/chip.c:503: error: label 'out_eoi' used but not defined

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-03-29 17:04:39 -07:00
Thomas Gleixner 0c6f8a8b91 genirq: Remove compat code
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-29 14:48:19 +02:00
Thomas Gleixner 0ef5ca1e1f genirq; Fix cleanup fallout
I missed the CONFIG_GENERIC_PENDING_IRQ dependency in the affinity
related functions and the IRQ_LEVEL propagation into irq_data
state. Did not pop up on my main test platforms. :(

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: David Daney <ddaney@caviumnetworks.com>
2011-03-29 01:41:22 +02:00
Thomas Gleixner 0521c8fbb3 genirq: Provide edge_eoi flow handler
This is a replacment for the cell flow handler which is in the way of
cleanups. Must be selected to avoid general bloat.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-28 16:55:11 +02:00
Thomas Gleixner 32f4125ebf genirq: Move INPROGRESS, MASKED and DISABLED state flags to irq_data
We really need these flags for some of the interrupt chips. Move it
from internal state to irq_data and provide proper accessors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: David Daney <ddaney@caviumnetworks.com>
2011-03-28 16:55:10 +02:00
Thomas Gleixner b3d422329f genirq: Add chip flag for restricting cpu_on/offline calls
Add a flag which indicates that the on/offline callback should only be
called on enabled interrupts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-27 17:45:58 +02:00
David Daney 0fdb4b259e genirq: Add chip hooks for taking CPUs on/off line.
[ tglx: Removed the enabled argument as this is now available in
irq_data ]

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
Cc: ralf@linux-mips.org
LKML-Reference: <1301081931-11240-3-git-send-email-ddaney@caviumnetworks.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-27 17:45:58 +02:00
Thomas Gleixner 801a0e9ae3 genirq: Add irq disabled flag to irq_data state
Some irq_chip implementation require to know the disabled state of the
interrupt in certain callbacks. Add a state flag and accessor to
irq_data.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-27 17:45:58 +02:00
David Daney d72274e589 genirq: Reserve the irq when calling irq_set_chip()
The helper macros and functions like for_each_active_irq() don't work
unless the irq is in the allocated_irqs set.

In the case of !CONFIG_SPARSE_IRQ, instead of forcing all users of the
irq infrastructure to explicitly call irq_reserve_irq(), do it for
them.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
Cc: ralf@linux-mips.org
LKML-Reference: <1301081931-11240-2-git-send-email-ddaney@caviumnetworks.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-27 17:45:58 +02:00
Thomas Gleixner c69e3758ff genirq: Fixup fasteoi handler for oneshot mode
The fasteoi handler must mask the interrupt line in oneshot mode
otherwise we end up with an irq storm.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-03-02 11:49:21 +01:00
Thomas Gleixner a61d825808 genirq: Fix misplaced status update in irq_disable()
We lazy disable interrupt lines, so only mark the line masked, when
the chip provides an irq_disable callback.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-21 21:19:59 +01:00
Thomas Gleixner 77694b408a genirq; Add fasteoi irq_chip quirk
Some chips want irq_eoi() only called when an interrupt is actually
handled. So they have checks for INPROGRESS and DISABLED in their
irq_eoi callbacks. Add a chip flag, which allows to handle that in the
generic code. No impact on the fastpath.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:24 +01:00
Thomas Gleixner 781295762d genirq: Add preflow handler support
sparc64 needs to call a preflow handler on certain interrupts befor
calling the action chain. Integrate it into handle_fasteoi_irq. Must
be enabled via CONFIG_IRQ_FASTEOI_PREFLOW. No impact when disabled.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: David S. Miller <davem@davemloft.net>
2011-02-19 12:58:24 +01:00
Thomas Gleixner 3836ca08aa genirq: Consolidate set_chip_handler functions
No need to have separate functions if we have one plus inline wrappers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:23 +01:00
Thomas Gleixner 02725e7471 genirq: Use irq_get/put functions
Convert the management functions to use the common irq_get/put
function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:23 +01:00
Thomas Gleixner 091738a266 genirq: Remove real old transition functions
These transition helpers are stale for years now. Remove them.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:23 +01:00
Thomas Gleixner e1ef824146 genirq: Reflect IRQ_MOVE_PCNTXT in irq_data state
Required by x86.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:22 +01:00
Thomas Gleixner d4d5e08960 genirq: Add IRQCHIP_SET_TYPE_MASKED flag
irq_chips, which require to mask the chip before changing the trigger
type should set this flag. So the core takes care of it and the
requirement for looking into desc->status in the chip goes away.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
2011-02-19 12:58:22 +01:00
Thomas Gleixner 1ccb4e612f genirq: Wrap the remaning IRQ_* flags
Use wrappers to keep them away from the core code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:21 +01:00
Thomas Gleixner 876dbd4cc1 genirq: Mirror irq trigger type bits in irq_data.state
That's the data structure chip functions get provided. Also allow them
to signal the core code that they updated the flags in irq_data.state
by returning IRQ_SET_MASK_OK_NOCOPY. The default is unchanged.

The type bits should be accessed via:

val = irqd_get_trigger_type(irqdata);
and
irqd_set_trigger_type(irqdata, val);

Coders who access them directly will be tracked down and slapped with
stinking trouts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:20 +01:00
Thomas Gleixner a005677b3d genirq: Mirror IRQ_PER_CPU and IRQ_NO_BALANCING in irq_data.state
That's the right data structure to look at for arch code.

Accessor functions are provided.

	 irqd_is_per_cpu(irqdata);
	 irqd_can_balance(irqdata);

Coders who access them directly will be tracked down and slapped with
stinking trouts.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:20 +01:00
Thomas Gleixner 6e40262ea4 genirq: Move IRQ_MASKED to core
Keep status in sync until all users are fixed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:17 +01:00
Thomas Gleixner 2a0d6fb335 genirq: Move IRQ_PENDING flag to core
Keep status in sync until all users are fixed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:17 +01:00
Thomas Gleixner c1594b77e4 genirq: Move IRQ_DISABLED to core
Keep status in sync until all abusers are fixed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:17 +01:00
Thomas Gleixner 163ef30911 genirq: Move IRQ_REPLAY and IRQ_WAITING to core
No users outside of core.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:16 +01:00
Thomas Gleixner 3d67baec7f genirq: Move IRQ_ONESHOT to core
No users outside of core.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:16 +01:00
Thomas Gleixner 009b4c3b8a genirq: Add IRQ_INPROGRESS to core
We need to maintain the flag for now in both fields status and istate.
Add a CONFIG_GENERIC_HARDIRQS_NO_COMPAT switch to allow testing w/o
the status one. Wrap the access to status IRQ_INPROGRESS in a inline
which can be turned of with CONFIG_GENERIC_HARDIRQS_NO_COMPAT along
with the define.

There is no reason that anything outside of core looks at this. That
needs some modifications, but we'll get there.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:16 +01:00
Thomas Gleixner 6954b75b48 genirq: Move IRQ_POLL_INPROGRESS to core
No users outside of core.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:15 +01:00
Thomas Gleixner 6f91a52d9b genirq: Use modify_status for set_irq_nested_thread
No need for a separate function in the core code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:15 +01:00
Thomas Gleixner 35e857cbeb genirq: Fixup core code namespace fallout
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:13 +01:00
Thomas Gleixner 849f061c25 genirq: Use handle_perpcu_event() in handle_percpu_irq()
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:12 +01:00
Thomas Gleixner a60a5dc2db genirq: Use handle_irq_event() in handle_edge_irq()
It's safe to drop the IRQ_INPROGRESS flag between action chain walks
as we are protected by desc->lock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:12 +01:00
Thomas Gleixner a7ae4de5c8 genirq: Use handle_irq_event() in handle_fasteoi_irq()
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:12 +01:00
Thomas Gleixner 1529866c63 genirq: Use handle_irq_event() in handle_level_irq()
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:12 +01:00
Thomas Gleixner 107781e721 genirq: Use handle_irq_event() in handle_simple_irq()
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:11 +01:00
Thomas Gleixner d78f8dd36b genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq()
IRQ_MASKED is set in mask_ack_irq() anyway. Remove it from
handle_edge_irq() to allow simpler ab^HHreuse of that function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110202212551.918484270@linutronix.de>
2011-02-19 12:58:11 +01:00
Thomas Gleixner 3aae994fb0 genirq: Consolidate IRQ_DISABLED
Handle IRQ_DISABLED consistent.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:11 +01:00
Thomas Gleixner 50f7c03275 genirq: Remove default magic
Now that everything uses the wrappers, we can remove the default
functions. None of those functions is performance critical.

That makes the IRQ_MASKED flag tracking fully consistent.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:10 +01:00
Thomas Gleixner 87923470c7 genirq: Consolidate disable/enable
Create irq_disable/enable and use them to keep the flags consistent.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:10 +01:00
Thomas Gleixner 4699923861 genirq: Consolidate startup/shutdown of interrupts
Aside of duplicated code some of the startup/shutdown sites do not
handle the MASKED/DISABLED flags and the depth field at all. Move that
to a helper function and take care of it there.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110202212551.787481468@linutronix.de>
2011-02-19 12:58:10 +01:00
Thomas Gleixner fe200ae48e genirq: Mark polled irqs and defer the real handler
With the chip.end() function gone we might run into a situation where
a poll call runs and the real interrupt comes in, sees IRQ_INPROGRESS
and disables the line. That might be a perfect working one, which will
then be masked forever.

So mark them polled while the poll runs. When the real handler sees
IRQ_INPROGRESS it checks the poll flag and waits for the polling to
complete. Add the necessary amount of sanity checks to it to avoid
deadlocks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:09 +01:00
Thomas Gleixner a0cd9ca2b9 genirq: Namespace cleanup
The irq namespace has become quite convoluted. My bad.  Clean it up
and deprecate the old functions. All new functions follow the scheme:

irq number based:
    irq_set/get/xxx/_xxx(unsigned int irq, ...)

irq_data based:
	 irq_data_set/get/xxx/_xxx(struct irq_data *d, ....)

irq_desc based:
	 irq_desc_get_xxx(struct irq_desc *desc)

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:06 +01:00
Thomas Gleixner 43abe43ce0 genirq: Add missing buslock to set_irq_type(), set_irq_wake()
chips behind a slow bus cannot update the chip under desc->lock, but
we miss the chip_buslock/chip_bus_sync_unlock() calls around the set
type and set wake functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2011-02-19 12:58:06 +01:00
Thomas Gleixner b7b29338dc genirq: Sanitize dynamic irq handling
Use the cleanup functions of the dynamic allocator. No need to have
separate implementations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
2010-10-12 16:53:44 +02:00
Thomas Gleixner 1318a481fc genirq: Provide default irq init flags
Arch code sets it's own irq_desc.status flags right after boot and for
dynamically allocated interrupts. That might involve iterating over a
huge array.

Allow ARCH_IRQ_INIT_FLAGS to set separate flags aside of IRQ_DISABLED
which is the default.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
2010-10-12 16:39:06 +02:00