aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
Commit message (Collapse)AuthorAgeFilesLines
* genirq: Fix long-term regression in genirq irq_set_irq_type() handlingRussell King2012-04-021-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | commit a09b659cd68c10ec6a30cb91ebd2c327fcd5bfe5 upstream. In 2008, commit 0c5d1eb77a8be ("genirq: record trigger type") modified the way set_irq_type() handles the 'no trigger' condition. However, this has an adverse effect on PCMCIA support on Intel StrongARM and probably PXA platforms. PCMCIA has several status signals on the socket which can trigger interrupts; some of these status signals depend on the card's mode (whether it is configured in memory or IO mode). For example, cards have a 'Ready/IRQ' signal: in memory mode, this provides an indication to PCMCIA that the card has finished its power up initialization. In IO mode, it provides the device interrupt signal. Other status signals switch between on-board battery status and loud speaker output. In classical PCMCIA implementations, where you have a specific socket controller, the controller provides a method to mask interrupts from the socket, and importantly ignore any state transitions on the pins which correspond with interrupts once masked. This masking prevents unwanted events caused by the removal and application of socket power being forwarded. However, on platforms where there is no socket controller, the PCMCIA status and interrupt signals are routed to standard edge-triggered GPIOs. These GPIOs can be configured to interrupt on rising edge, falling edge, or never. This is where the problems start. Edge triggered interrupts are required to record events while disabled via the usual methods of {free,request,disable,enable}_irq() to prevent problems with dropped interrupts (eg, the 8390 driver uses disable_irq() to defer the delivery of interrupts). As a result, these interfaces can not be used to implement the desired behaviour. The side effect of this is that if the 'Ready/IRQ' GPIO is disabled via disable_irq() on suspend, and enabled via enable_irq() after resume, we will record the state transitions caused by powering events as valid interrupts, and foward them to the card driver, which may attempt to access a card which is not powered up. This leads delays resume while drivers spin in their interrupt handlers, and complaints from drivers before they realize what's happened. Moreover, in the case of the 'Ready/IRQ' signal, this is requested and freed by the card driver itself; the PCMCIA core has no idea whether the interrupt is requested, and, therefore, whether a call to disable_irq() would be valid. (We tried this around 2.4.17 / 2.5.1 kernel era, and ended up throwing it out because of this problem.) Therefore, it was decided back in around 2002 to disable the edge triggering instead, resulting in all state transitions on the GPIO being ignored. That's what we actually need the hardware to do. The commit above changes this behaviour; it explicitly prevents the 'no trigger' state being selected. The reason that request_irq() does not accept the 'no trigger' state is for compatibility with existing drivers which do not provide their desired triggering configuration. The set_irq_type() function is 'new' and not used by non-trigger aware drivers. Therefore, revert this change, and restore previously working platforms back to their former state. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Cc: linux@arm.linux.org.uk Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* genirq: Handle pending irqs in irq_startup()Thomas Gleixner2012-02-291-7/+10
| | | | | | | | | | | | | | | | commit b4bc724e82e80478cba5fe9825b62e71ddf78757 upstream. An interrupt might be pending when irq_startup() is called, but the startup code does not invoke the resend logic. In some cases this prevents the device from issuing another interrupt which renders the device non functional. Call the resend function in irq_startup() to keep things going. Reported-and-tested-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* genirq: Unmask oneshot irqs when thread was not wokenThomas Gleixner2012-02-291-2/+23
| | | | | | | | | | | | | | | | | | | | | | | commit ac5637611150281f398bb7a47e3fcb69a09e7803 upstream. When the primary handler of an interrupt which is marked IRQ_ONESHOT returns IRQ_HANDLED or IRQ_NONE, then the interrupt thread is not woken and the unmask logic of the interrupt line is never invoked. This keeps the interrupt masked forever. This was not noticed as most IRQ_ONESHOT users wake the thread unconditionally (usually because they cannot access the underlying device from hard interrupt context). Though this behaviour was nowhere documented and not necessarily intentional. Some drivers can avoid the thread wakeup in certain cases and run into the situation where the interrupt line s kept masked. Handle it gracefully. Reported-and-tested-by: Lothar Wassmann <lw@karo-electronics.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* genirq: Make irq_shutdown() symmetric vs. irq_startup againGeert Uytterhoeven2011-10-031-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | commit ed585a651681e822089087b426e6ebfb6d3d9873 upstream. 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. 3b56f0585fd4c02d047dc406668cb40159b2d340 ("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 Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
* irq: Export functions to allow modular irq driversJonathan Cameron2011-05-181-0/+2
| | | | | | | | | | | | | | 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>
* genirq: Support per-IRQ thread disabling.Paul Mundt2011-04-231-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Fix common misspellingsLucas De Marchi2011-03-311-1/+1
| | | | | | Fixes generated by 'codespell' and manually reviewed. Signed-off-by: Lucas De Marchi <lucas.demarchi@profusion.mobi>
* genirq: fix CONFIG_IRQ_EDGE_EOI_HANDLER buildStephen Rothwell2011-03-291-1/+1
| | | | | | | | | | | 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>
* genirq: Remove compat codeThomas Gleixner2011-03-291-129/+0
| | | | Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq; Fix cleanup falloutThomas Gleixner2011-03-291-0/+2
| | | | | | | | | 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>
* genirq: Provide edge_eoi flow handlerThomas Gleixner2011-03-281-0/+45
| | | | | | | 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>
* genirq: Move INPROGRESS, MASKED and DISABLED state flags to irq_dataThomas Gleixner2011-03-281-21/+19
| | | | | | | | 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>
* genirq: Add chip flag for restricting cpu_on/offline callsThomas Gleixner2011-03-271-4/+6
| | | | | | | 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>
* genirq: Add chip hooks for taking CPUs on/off line.David Daney2011-03-271-0/+58
| | | | | | | | | | | [ 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>
* genirq: Add irq disabled flag to irq_data stateThomas Gleixner2011-03-271-2/+3
| | | | | | | | 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>
* genirq: Reserve the irq when calling irq_set_chip()David Daney2011-03-271-0/+6
| | | | | | | | | | | | | | | 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>
* genirq: Fixup fasteoi handler for oneshot modeThomas Gleixner2011-03-021-0/+4
| | | | | | | 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>
* genirq: Fix misplaced status update in irq_disable()Thomas Gleixner2011-02-211-1/+1
| | | | | | | 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>
* genirq; Add fasteoi irq_chip quirkThomas Gleixner2011-02-191-1/+8
| | | | | | | | | 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>
* genirq: Add preflow handler supportThomas Gleixner2011-02-191-0/+11
| | | | | | | | | 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>
* genirq: Consolidate set_chip_handler functionsThomas Gleixner2011-02-191-12/+4
| | | | | | No need to have separate functions if we have one plus inline wrappers. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Use irq_get/put functionsThomas Gleixner2011-02-191-67/+26
| | | | | | | Convert the management functions to use the common irq_get/put function. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Remove real old transition functionsThomas Gleixner2011-02-191-12/+4
| | | | | | These transition helpers are stale for years now. Remove them. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Reflect IRQ_MOVE_PCNTXT in irq_data stateThomas Gleixner2011-02-191-1/+3
| | | | | | Required by x86. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Add IRQCHIP_SET_TYPE_MASKED flagThomas Gleixner2011-02-191-2/+2
| | | | | | | | | | 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>
* genirq: Wrap the remaning IRQ_* flagsThomas Gleixner2011-02-191-1/+2
| | | | | | Use wrappers to keep them away from the core code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Mirror irq trigger type bits in irq_data.stateThomas Gleixner2011-02-191-1/+4
| | | | | | | | | | | | | | | | | 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>
* genirq: Mirror IRQ_PER_CPU and IRQ_NO_BALANCING in irq_data.stateThomas Gleixner2011-02-191-6/+9
| | | | | | | | | | | | | | 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>
* genirq: Move IRQ_MASKED to coreThomas Gleixner2011-02-191-8/+20
| | | | | | Keep status in sync until all users are fixed. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Move IRQ_PENDING flag to coreThomas Gleixner2011-02-191-4/+6
| | | | | | Keep status in sync until all users are fixed. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Move IRQ_DISABLED to coreThomas Gleixner2011-02-191-17/+31
| | | | | | Keep status in sync until all abusers are fixed. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Move IRQ_REPLAY and IRQ_WAITING to coreThomas Gleixner2011-02-191-5/+4
| | | | | | No users outside of core. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Move IRQ_ONESHOT to coreThomas Gleixner2011-02-191-1/+1
| | | | | | No users outside of core. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Add IRQ_INPROGRESS to coreThomas Gleixner2011-02-191-7/+9
| | | | | | | | | | | | | 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>
* genirq: Move IRQ_POLL_INPROGRESS to coreThomas Gleixner2011-02-191-1/+1
| | | | | | No users outside of core. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Use modify_status for set_irq_nested_threadThomas Gleixner2011-02-191-28/+0
| | | | | | No need for a separate function in the core code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Fixup core code namespace falloutThomas Gleixner2011-02-191-3/+3
| | | | Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Use handle_perpcu_event() in handle_percpu_irq()Thomas Gleixner2011-02-191-8/+6
| | | | Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Use handle_irq_event() in handle_edge_irq()Thomas Gleixner2011-02-191-14/+2
| | | | | | | 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>
* genirq: Use handle_irq_event() in handle_fasteoi_irq()Thomas Gleixner2011-02-191-17/+2
| | | | Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Use handle_irq_event() in handle_level_irq()Thomas Gleixner2011-02-191-14/+2
| | | | Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Use handle_irq_event() in handle_simple_irq()Thomas Gleixner2011-02-191-13/+2
| | | | Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Do not fiddle with IRQ_MASKED in handle_edge_irq()Thomas Gleixner2011-02-191-1/+1
| | | | | | | | | 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>
* genirq: Consolidate IRQ_DISABLEDThomas Gleixner2011-02-191-4/+10
| | | | | | Handle IRQ_DISABLED consistent. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Remove default magicThomas Gleixner2011-02-191-58/+15
| | | | | | | | | 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>
* genirq: Consolidate disable/enableThomas Gleixner2011-02-191-1/+11
| | | | | | Create irq_disable/enable and use them to keep the flags consistent. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
* genirq: Consolidate startup/shutdown of interruptsThomas Gleixner2011-02-191-17/+20
| | | | | | | | | | 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>
* genirq: Mark polled irqs and defer the real handlerThomas Gleixner2011-02-191-6/+20
| | | | | | | | | | | | | | 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>
* genirq: Namespace cleanupThomas Gleixner2011-02-191-14/+14
| | | | | | | | | | | | | | | | 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>
* genirq: Add missing buslock to set_irq_type(), set_irq_wake()Thomas Gleixner2011-02-191-0/+2
| | | | | | | | 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>