1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
206fcb0c6SIngo Molnar #ifndef _LINUX_IRQ_H
306fcb0c6SIngo Molnar #define _LINUX_IRQ_H
41da177e4SLinus Torvalds
51da177e4SLinus Torvalds /*
61da177e4SLinus Torvalds * Please do not include this file in generic code. There is currently
71da177e4SLinus Torvalds * no requirement for any architecture to implement anything held
81da177e4SLinus Torvalds * within this file.
91da177e4SLinus Torvalds *
101da177e4SLinus Torvalds * Thanks. --rmk
111da177e4SLinus Torvalds */
121da177e4SLinus Torvalds
131da177e4SLinus Torvalds #include <linux/cache.h>
141da177e4SLinus Torvalds #include <linux/spinlock.h>
151da177e4SLinus Torvalds #include <linux/cpumask.h>
1675ffc007SThomas Gleixner #include <linux/irqhandler.h>
17908dcecdSJan Beulich #include <linux/irqreturn.h>
18dd3a1db9SThomas Gleixner #include <linux/irqnr.h>
19503e5763SRalf Baechle #include <linux/topology.h>
20332fd7c4SKevin Cernekee #include <linux/io.h>
21707188f5SBartosz Golaszewski #include <linux/slab.h>
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds #include <asm/irq.h>
241da177e4SLinus Torvalds #include <asm/ptrace.h>
257d12e780SDavid Howells #include <asm/irq_regs.h>
261da177e4SLinus Torvalds
27ab7798ffSThomas Gleixner struct seq_file;
28ec53cf23SPaul Gortmaker struct module;
29515085efSJiang Liu struct msi_msg;
30bec04037SDou Liyang struct irq_affinity_desc;
311b7047edSMarc Zyngier enum irqchip_irq_state;
3257a58a94SDavid Howells
331da177e4SLinus Torvalds /*
341da177e4SLinus Torvalds * IRQ line status.
356e213616SThomas Gleixner *
365d4d8fc9SThomas Gleixner * Bits 0-7 are the same as the IRQF_* bits in linux/interrupt.h
376e213616SThomas Gleixner *
385d4d8fc9SThomas Gleixner * IRQ_TYPE_NONE - default, unspecified type
395d4d8fc9SThomas Gleixner * IRQ_TYPE_EDGE_RISING - rising edge triggered
405d4d8fc9SThomas Gleixner * IRQ_TYPE_EDGE_FALLING - falling edge triggered
415d4d8fc9SThomas Gleixner * IRQ_TYPE_EDGE_BOTH - rising and falling edge triggered
425d4d8fc9SThomas Gleixner * IRQ_TYPE_LEVEL_HIGH - high level triggered
435d4d8fc9SThomas Gleixner * IRQ_TYPE_LEVEL_LOW - low level triggered
445d4d8fc9SThomas Gleixner * IRQ_TYPE_LEVEL_MASK - Mask to filter out the level bits
455d4d8fc9SThomas Gleixner * IRQ_TYPE_SENSE_MASK - Mask for all the above bits
463fca40c7SBenjamin Herrenschmidt * IRQ_TYPE_DEFAULT - For use by some PICs to ask irq_set_type
473fca40c7SBenjamin Herrenschmidt * to setup the HW to a sane default (used
483fca40c7SBenjamin Herrenschmidt * by irqdomain map() callbacks to synchronize
493fca40c7SBenjamin Herrenschmidt * the HW state and SW flags for a newly
503fca40c7SBenjamin Herrenschmidt * allocated descriptor).
513fca40c7SBenjamin Herrenschmidt *
525d4d8fc9SThomas Gleixner * IRQ_TYPE_PROBE - Special flag for probing in progress
535d4d8fc9SThomas Gleixner *
545d4d8fc9SThomas Gleixner * Bits which can be modified via irq_set/clear/modify_status_flags()
555d4d8fc9SThomas Gleixner * IRQ_LEVEL - Interrupt is level type. Will be also
565d4d8fc9SThomas Gleixner * updated in the code when the above trigger
570911f124SGeert Uytterhoeven * bits are modified via irq_set_irq_type()
585d4d8fc9SThomas Gleixner * IRQ_PER_CPU - Mark an interrupt PER_CPU. Will protect
595d4d8fc9SThomas Gleixner * it from affinity setting
605d4d8fc9SThomas Gleixner * IRQ_NOPROBE - Interrupt cannot be probed by autoprobing
615d4d8fc9SThomas Gleixner * IRQ_NOREQUEST - Interrupt cannot be requested via
625d4d8fc9SThomas Gleixner * request_irq()
637f1b1244SPaul Mundt * IRQ_NOTHREAD - Interrupt cannot be threaded
645d4d8fc9SThomas Gleixner * IRQ_NOAUTOEN - Interrupt is not automatically enabled in
655d4d8fc9SThomas Gleixner * request/setup_irq()
665d4d8fc9SThomas Gleixner * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
675d4d8fc9SThomas Gleixner * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
6892068d17SMika Westerberg * IRQ_NESTED_THREAD - Interrupt nests into another thread
6931d9d9b6SMarc Zyngier * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
70b39898cdSThomas Gleixner * IRQ_IS_POLLED - Always polled by another interrupt. Exclude
71b39898cdSThomas Gleixner * it from the spurious interrupt detection
72b39898cdSThomas Gleixner * mechanism and from core side polling.
73e9849777SThomas Gleixner * IRQ_DISABLE_UNLAZY - Disable lazy irq disable
7483cfac95SMarc Zyngier * IRQ_HIDDEN - Don't show up in /proc/interrupts
75c2b1063eSThomas Gleixner * IRQ_NO_DEBUG - Exclude from note_interrupt() debugging
761da177e4SLinus Torvalds */
775d4d8fc9SThomas Gleixner enum {
785d4d8fc9SThomas Gleixner IRQ_TYPE_NONE = 0x00000000,
795d4d8fc9SThomas Gleixner IRQ_TYPE_EDGE_RISING = 0x00000001,
805d4d8fc9SThomas Gleixner IRQ_TYPE_EDGE_FALLING = 0x00000002,
815d4d8fc9SThomas Gleixner IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
825d4d8fc9SThomas Gleixner IRQ_TYPE_LEVEL_HIGH = 0x00000004,
835d4d8fc9SThomas Gleixner IRQ_TYPE_LEVEL_LOW = 0x00000008,
845d4d8fc9SThomas Gleixner IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),
855d4d8fc9SThomas Gleixner IRQ_TYPE_SENSE_MASK = 0x0000000f,
863fca40c7SBenjamin Herrenschmidt IRQ_TYPE_DEFAULT = IRQ_TYPE_SENSE_MASK,
87876dbd4cSThomas Gleixner
885d4d8fc9SThomas Gleixner IRQ_TYPE_PROBE = 0x00000010,
896e213616SThomas Gleixner
905d4d8fc9SThomas Gleixner IRQ_LEVEL = (1 << 8),
915d4d8fc9SThomas Gleixner IRQ_PER_CPU = (1 << 9),
925d4d8fc9SThomas Gleixner IRQ_NOPROBE = (1 << 10),
935d4d8fc9SThomas Gleixner IRQ_NOREQUEST = (1 << 11),
945d4d8fc9SThomas Gleixner IRQ_NOAUTOEN = (1 << 12),
955d4d8fc9SThomas Gleixner IRQ_NO_BALANCING = (1 << 13),
965d4d8fc9SThomas Gleixner IRQ_MOVE_PCNTXT = (1 << 14),
975d4d8fc9SThomas Gleixner IRQ_NESTED_THREAD = (1 << 15),
987f1b1244SPaul Mundt IRQ_NOTHREAD = (1 << 16),
9931d9d9b6SMarc Zyngier IRQ_PER_CPU_DEVID = (1 << 17),
100b39898cdSThomas Gleixner IRQ_IS_POLLED = (1 << 18),
101e9849777SThomas Gleixner IRQ_DISABLE_UNLAZY = (1 << 19),
10283cfac95SMarc Zyngier IRQ_HIDDEN = (1 << 20),
103c2b1063eSThomas Gleixner IRQ_NO_DEBUG = (1 << 21),
1045d4d8fc9SThomas Gleixner };
105950f4427SThomas Gleixner
10644247184SThomas Gleixner #define IRQF_MODIFY_MASK \
10744247184SThomas Gleixner (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
108872434d6SThomas Gleixner IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
109b39898cdSThomas Gleixner IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \
11083cfac95SMarc Zyngier IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_HIDDEN)
11144247184SThomas Gleixner
112950f4427SThomas Gleixner #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
1131da177e4SLinus Torvalds
1143b8249e7SThomas Gleixner /*
1153b8249e7SThomas Gleixner * Return value for chip->irq_set_affinity()
1163b8249e7SThomas Gleixner *
1179df872faSJiang Liu * IRQ_SET_MASK_OK - OK, core updates irq_common_data.affinity
1189df872faSJiang Liu * IRQ_SET_MASK_NOCPY - OK, chip did update irq_common_data.affinity
1192cb62547SJiang Liu * IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to
1202cb62547SJiang Liu * support stacked irqchips, which indicates skipping
121a359f757SIngo Molnar * all descendant irqchips.
1223b8249e7SThomas Gleixner */
1233b8249e7SThomas Gleixner enum {
1243b8249e7SThomas Gleixner IRQ_SET_MASK_OK = 0,
1253b8249e7SThomas Gleixner IRQ_SET_MASK_OK_NOCOPY,
1262cb62547SJiang Liu IRQ_SET_MASK_OK_DONE,
1273b8249e7SThomas Gleixner };
1283b8249e7SThomas Gleixner
1295b912c10SEric W. Biederman struct msi_desc;
13008a543adSGrant Likely struct irq_domain;
1316a6de9efSThomas Gleixner
1328fee5c36SIngo Molnar /**
1330d0b4c86SJiang Liu * struct irq_common_data - per irq data shared by all irqchips
1340d0b4c86SJiang Liu * @state_use_accessors: status information for irq chip functions.
1350d0b4c86SJiang Liu * Use accessor functions to deal with it
136449e9caeSJiang Liu * @node: node index useful for balancing
137af7080e0SJiang Liu * @handler_data: per-IRQ data for the irq_chip methods
138955bfe59SQais Yousef * @affinity: IRQ affinity on SMP. If this is an IPI
139955bfe59SQais Yousef * related irq, then this is the mask of the
140955bfe59SQais Yousef * CPUs to which an IPI can be sent.
1410d3f5425SThomas Gleixner * @effective_affinity: The effective IRQ affinity on SMP as some irq
1420d3f5425SThomas Gleixner * chips do not allow multi CPU destinations.
1430d3f5425SThomas Gleixner * A subset of @affinity.
144b237721cSJiang Liu * @msi_desc: MSI descriptor
145f256c9a0SQais Yousef * @ipi_offset: Offset of first IPI target cpu in @affinity. Optional.
1460d0b4c86SJiang Liu */
1470d0b4c86SJiang Liu struct irq_common_data {
148b354286eSBoqun Feng unsigned int __private state_use_accessors;
149449e9caeSJiang Liu #ifdef CONFIG_NUMA
150449e9caeSJiang Liu unsigned int node;
151449e9caeSJiang Liu #endif
152af7080e0SJiang Liu void *handler_data;
153b237721cSJiang Liu struct msi_desc *msi_desc;
154aa081358SSamuel Holland #ifdef CONFIG_SMP
1559df872faSJiang Liu cpumask_var_t affinity;
156aa081358SSamuel Holland #endif
1570d3f5425SThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
1580d3f5425SThomas Gleixner cpumask_var_t effective_affinity;
1590d3f5425SThomas Gleixner #endif
160f256c9a0SQais Yousef #ifdef CONFIG_GENERIC_IRQ_IPI
161f256c9a0SQais Yousef unsigned int ipi_offset;
162f256c9a0SQais Yousef #endif
1630d0b4c86SJiang Liu };
1640d0b4c86SJiang Liu
1650d0b4c86SJiang Liu /**
1660d0b4c86SJiang Liu * struct irq_data - per irq chip data passed down to chip functions
167966dc736SThomas Gleixner * @mask: precomputed bitmask for accessing the chip registers
168ff7dcd44SThomas Gleixner * @irq: interrupt number
16908a543adSGrant Likely * @hwirq: hardware interrupt number, local to the interrupt domain
1700d0b4c86SJiang Liu * @common: point to data shared by all irqchips
171ff7dcd44SThomas Gleixner * @chip: low level interrupt hardware access
17208a543adSGrant Likely * @domain: Interrupt translation domain; responsible for mapping
17308a543adSGrant Likely * between hwirq number and linux irq number.
174f8264e34SJiang Liu * @parent_data: pointer to parent struct irq_data to support hierarchy
175f8264e34SJiang Liu * irq_domain
176ff7dcd44SThomas Gleixner * @chip_data: platform-specific per-chip private data for the chip
177ff7dcd44SThomas Gleixner * methods, to allow shared chip implementations
178ff7dcd44SThomas Gleixner */
179ff7dcd44SThomas Gleixner struct irq_data {
180966dc736SThomas Gleixner u32 mask;
181ff7dcd44SThomas Gleixner unsigned int irq;
18208a543adSGrant Likely unsigned long hwirq;
1830d0b4c86SJiang Liu struct irq_common_data *common;
184ff7dcd44SThomas Gleixner struct irq_chip *chip;
18508a543adSGrant Likely struct irq_domain *domain;
186f8264e34SJiang Liu #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
187f8264e34SJiang Liu struct irq_data *parent_data;
188f8264e34SJiang Liu #endif
189ff7dcd44SThomas Gleixner void *chip_data;
190ff7dcd44SThomas Gleixner };
191ff7dcd44SThomas Gleixner
192f230b6d5SThomas Gleixner /*
1930d0b4c86SJiang Liu * Bit masks for irq_common_data.state_use_accessors
194f230b6d5SThomas Gleixner *
195876dbd4cSThomas Gleixner * IRQD_TRIGGER_MASK - Mask for the trigger type bits
196f230b6d5SThomas Gleixner * IRQD_SETAFFINITY_PENDING - Affinity setting is pending
19708d85f3eSMarc Zyngier * IRQD_ACTIVATED - Interrupt has already been activated
198a005677bSThomas Gleixner * IRQD_NO_BALANCING - Balancing disabled for this IRQ
199a005677bSThomas Gleixner * IRQD_PER_CPU - Interrupt is per cpu
2002bdd1055SThomas Gleixner * IRQD_AFFINITY_SET - Interrupt affinity was set
201876dbd4cSThomas Gleixner * IRQD_LEVEL - Interrupt is level triggered
2027f94226fSThomas Gleixner * IRQD_WAKEUP_STATE - Interrupt is configured for wakeup
2037f94226fSThomas Gleixner * from suspend
204551417afSPeter Xu * IRQD_MOVE_PCNTXT - Interrupt can be moved in process
205e1ef8241SThomas Gleixner * context
20632f4125eSThomas Gleixner * IRQD_IRQ_DISABLED - Disabled state of the interrupt
20732f4125eSThomas Gleixner * IRQD_IRQ_MASKED - Masked state of the interrupt
20832f4125eSThomas Gleixner * IRQD_IRQ_INPROGRESS - In progress state of the interrupt
209b76f1674SThomas Gleixner * IRQD_WAKEUP_ARMED - Wakeup mode armed
210fc569712SThomas Gleixner * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU
2119c255583SThomas Gleixner * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel
2121bb04016SThomas Gleixner * IRQD_IRQ_STARTED - Startup state of the interrupt
21354fdf6a0SThomas Gleixner * IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity
21454fdf6a0SThomas Gleixner * mask. Applies only to affinity managed irqs.
215d52dd441SThomas Gleixner * IRQD_SINGLE_TARGET - IRQ allows only a single affinity target
2164f8413a3SMarc Zyngier * IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set
21769790ba9SThomas Gleixner * IRQD_CAN_RESERVE - Can use reservation mode
218c16816acSThomas Gleixner * IRQD_HANDLE_ENFORCE_IRQCTX - Enforce that handle_irq_*() is only invoked
219c16816acSThomas Gleixner * from actual interrupt context.
220f0c7bacaSThomas Gleixner * IRQD_AFFINITY_ON_ACTIVATE - Affinity is set on activation. Don't call
221f0c7bacaSThomas Gleixner * irq_chip::irq_set_affinity() when deactivated.
22290428a8eSMaulik Shah * IRQD_IRQ_ENABLED_ON_SUSPEND - Interrupt is enabled on suspend by irq pm if
22390428a8eSMaulik Shah * irqchip have flag IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND set.
2249c15eeb5SJames Gowans * IRQD_RESEND_WHEN_IN_PROGRESS - Interrupt may fire when already in progress in which
2259c15eeb5SJames Gowans * case it must be resent at the next available opportunity.
226f230b6d5SThomas Gleixner */
227f230b6d5SThomas Gleixner enum {
228876dbd4cSThomas Gleixner IRQD_TRIGGER_MASK = 0xf,
2290cfb4a1aSMarc Zyngier IRQD_SETAFFINITY_PENDING = BIT(8),
2300cfb4a1aSMarc Zyngier IRQD_ACTIVATED = BIT(9),
2310cfb4a1aSMarc Zyngier IRQD_NO_BALANCING = BIT(10),
2320cfb4a1aSMarc Zyngier IRQD_PER_CPU = BIT(11),
2330cfb4a1aSMarc Zyngier IRQD_AFFINITY_SET = BIT(12),
2340cfb4a1aSMarc Zyngier IRQD_LEVEL = BIT(13),
2350cfb4a1aSMarc Zyngier IRQD_WAKEUP_STATE = BIT(14),
2360cfb4a1aSMarc Zyngier IRQD_MOVE_PCNTXT = BIT(15),
2370cfb4a1aSMarc Zyngier IRQD_IRQ_DISABLED = BIT(16),
2380cfb4a1aSMarc Zyngier IRQD_IRQ_MASKED = BIT(17),
2390cfb4a1aSMarc Zyngier IRQD_IRQ_INPROGRESS = BIT(18),
2400cfb4a1aSMarc Zyngier IRQD_WAKEUP_ARMED = BIT(19),
2410cfb4a1aSMarc Zyngier IRQD_FORWARDED_TO_VCPU = BIT(20),
2420cfb4a1aSMarc Zyngier IRQD_AFFINITY_MANAGED = BIT(21),
2430cfb4a1aSMarc Zyngier IRQD_IRQ_STARTED = BIT(22),
2440cfb4a1aSMarc Zyngier IRQD_MANAGED_SHUTDOWN = BIT(23),
2450cfb4a1aSMarc Zyngier IRQD_SINGLE_TARGET = BIT(24),
2460cfb4a1aSMarc Zyngier IRQD_DEFAULT_TRIGGER_SET = BIT(25),
2470cfb4a1aSMarc Zyngier IRQD_CAN_RESERVE = BIT(26),
248*119f7373SKoichiro Den IRQD_HANDLE_ENFORCE_IRQCTX = BIT(27),
249*119f7373SKoichiro Den IRQD_AFFINITY_ON_ACTIVATE = BIT(28),
250*119f7373SKoichiro Den IRQD_IRQ_ENABLED_ON_SUSPEND = BIT(29),
251*119f7373SKoichiro Den IRQD_RESEND_WHEN_IN_PROGRESS = BIT(30),
252f230b6d5SThomas Gleixner };
253f230b6d5SThomas Gleixner
254b354286eSBoqun Feng #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
2550d0b4c86SJiang Liu
irqd_is_setaffinity_pending(struct irq_data * d)256f230b6d5SThomas Gleixner static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
257f230b6d5SThomas Gleixner {
2580d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
259f230b6d5SThomas Gleixner }
260f230b6d5SThomas Gleixner
irqd_is_per_cpu(struct irq_data * d)261a005677bSThomas Gleixner static inline bool irqd_is_per_cpu(struct irq_data *d)
262a005677bSThomas Gleixner {
2630d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_PER_CPU;
264a005677bSThomas Gleixner }
265a005677bSThomas Gleixner
irqd_can_balance(struct irq_data * d)266a005677bSThomas Gleixner static inline bool irqd_can_balance(struct irq_data *d)
267a005677bSThomas Gleixner {
2680d0b4c86SJiang Liu return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
269a005677bSThomas Gleixner }
270a005677bSThomas Gleixner
irqd_affinity_was_set(struct irq_data * d)2712bdd1055SThomas Gleixner static inline bool irqd_affinity_was_set(struct irq_data *d)
2722bdd1055SThomas Gleixner {
2730d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_AFFINITY_SET;
2742bdd1055SThomas Gleixner }
2752bdd1055SThomas Gleixner
irqd_mark_affinity_was_set(struct irq_data * d)276ee38c04bSThomas Gleixner static inline void irqd_mark_affinity_was_set(struct irq_data *d)
277ee38c04bSThomas Gleixner {
2780d0b4c86SJiang Liu __irqd_to_state(d) |= IRQD_AFFINITY_SET;
279ee38c04bSThomas Gleixner }
280ee38c04bSThomas Gleixner
irqd_trigger_type_was_set(struct irq_data * d)2814f8413a3SMarc Zyngier static inline bool irqd_trigger_type_was_set(struct irq_data *d)
2824f8413a3SMarc Zyngier {
2834f8413a3SMarc Zyngier return __irqd_to_state(d) & IRQD_DEFAULT_TRIGGER_SET;
2844f8413a3SMarc Zyngier }
2854f8413a3SMarc Zyngier
irqd_get_trigger_type(struct irq_data * d)286876dbd4cSThomas Gleixner static inline u32 irqd_get_trigger_type(struct irq_data *d)
287876dbd4cSThomas Gleixner {
2880d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
289876dbd4cSThomas Gleixner }
290876dbd4cSThomas Gleixner
291876dbd4cSThomas Gleixner /*
2924f8413a3SMarc Zyngier * Must only be called inside irq_chip.irq_set_type() functions or
2934f8413a3SMarc Zyngier * from the DT/ACPI setup code.
294876dbd4cSThomas Gleixner */
irqd_set_trigger_type(struct irq_data * d,u32 type)295876dbd4cSThomas Gleixner static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
296876dbd4cSThomas Gleixner {
2970d0b4c86SJiang Liu __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
2980d0b4c86SJiang Liu __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
2994f8413a3SMarc Zyngier __irqd_to_state(d) |= IRQD_DEFAULT_TRIGGER_SET;
300876dbd4cSThomas Gleixner }
301876dbd4cSThomas Gleixner
irqd_is_level_type(struct irq_data * d)302876dbd4cSThomas Gleixner static inline bool irqd_is_level_type(struct irq_data *d)
303876dbd4cSThomas Gleixner {
3040d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_LEVEL;
305876dbd4cSThomas Gleixner }
306876dbd4cSThomas Gleixner
307d52dd441SThomas Gleixner /*
308d52dd441SThomas Gleixner * Must only be called of irqchip.irq_set_affinity() or low level
309a359f757SIngo Molnar * hierarchy domain allocation functions.
310d52dd441SThomas Gleixner */
irqd_set_single_target(struct irq_data * d)311d52dd441SThomas Gleixner static inline void irqd_set_single_target(struct irq_data *d)
312d52dd441SThomas Gleixner {
313d52dd441SThomas Gleixner __irqd_to_state(d) |= IRQD_SINGLE_TARGET;
314d52dd441SThomas Gleixner }
315d52dd441SThomas Gleixner
irqd_is_single_target(struct irq_data * d)316d52dd441SThomas Gleixner static inline bool irqd_is_single_target(struct irq_data *d)
317d52dd441SThomas Gleixner {
318d52dd441SThomas Gleixner return __irqd_to_state(d) & IRQD_SINGLE_TARGET;
319d52dd441SThomas Gleixner }
320d52dd441SThomas Gleixner
irqd_set_handle_enforce_irqctx(struct irq_data * d)321c16816acSThomas Gleixner static inline void irqd_set_handle_enforce_irqctx(struct irq_data *d)
322c16816acSThomas Gleixner {
323c16816acSThomas Gleixner __irqd_to_state(d) |= IRQD_HANDLE_ENFORCE_IRQCTX;
324c16816acSThomas Gleixner }
325c16816acSThomas Gleixner
irqd_is_handle_enforce_irqctx(struct irq_data * d)326c16816acSThomas Gleixner static inline bool irqd_is_handle_enforce_irqctx(struct irq_data *d)
327c16816acSThomas Gleixner {
328c16816acSThomas Gleixner return __irqd_to_state(d) & IRQD_HANDLE_ENFORCE_IRQCTX;
329c16816acSThomas Gleixner }
330c16816acSThomas Gleixner
irqd_is_enabled_on_suspend(struct irq_data * d)33190428a8eSMaulik Shah static inline bool irqd_is_enabled_on_suspend(struct irq_data *d)
33290428a8eSMaulik Shah {
33390428a8eSMaulik Shah return __irqd_to_state(d) & IRQD_IRQ_ENABLED_ON_SUSPEND;
33490428a8eSMaulik Shah }
33590428a8eSMaulik Shah
irqd_is_wakeup_set(struct irq_data * d)3367f94226fSThomas Gleixner static inline bool irqd_is_wakeup_set(struct irq_data *d)
3377f94226fSThomas Gleixner {
3380d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
3397f94226fSThomas Gleixner }
3407f94226fSThomas Gleixner
irqd_can_move_in_process_context(struct irq_data * d)341e1ef8241SThomas Gleixner static inline bool irqd_can_move_in_process_context(struct irq_data *d)
342e1ef8241SThomas Gleixner {
3430d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
344e1ef8241SThomas Gleixner }
345e1ef8241SThomas Gleixner
irqd_irq_disabled(struct irq_data * d)346801a0e9aSThomas Gleixner static inline bool irqd_irq_disabled(struct irq_data *d)
347801a0e9aSThomas Gleixner {
3480d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
349801a0e9aSThomas Gleixner }
350801a0e9aSThomas Gleixner
irqd_irq_masked(struct irq_data * d)35132f4125eSThomas Gleixner static inline bool irqd_irq_masked(struct irq_data *d)
35232f4125eSThomas Gleixner {
3530d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_IRQ_MASKED;
35432f4125eSThomas Gleixner }
35532f4125eSThomas Gleixner
irqd_irq_inprogress(struct irq_data * d)35632f4125eSThomas Gleixner static inline bool irqd_irq_inprogress(struct irq_data *d)
35732f4125eSThomas Gleixner {
3580d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
35932f4125eSThomas Gleixner }
36032f4125eSThomas Gleixner
irqd_is_wakeup_armed(struct irq_data * d)361b76f1674SThomas Gleixner static inline bool irqd_is_wakeup_armed(struct irq_data *d)
362b76f1674SThomas Gleixner {
3630d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
364b76f1674SThomas Gleixner }
365b76f1674SThomas Gleixner
irqd_is_forwarded_to_vcpu(struct irq_data * d)366fc569712SThomas Gleixner static inline bool irqd_is_forwarded_to_vcpu(struct irq_data *d)
367fc569712SThomas Gleixner {
368fc569712SThomas Gleixner return __irqd_to_state(d) & IRQD_FORWARDED_TO_VCPU;
369fc569712SThomas Gleixner }
370fc569712SThomas Gleixner
irqd_set_forwarded_to_vcpu(struct irq_data * d)371fc569712SThomas Gleixner static inline void irqd_set_forwarded_to_vcpu(struct irq_data *d)
372fc569712SThomas Gleixner {
373fc569712SThomas Gleixner __irqd_to_state(d) |= IRQD_FORWARDED_TO_VCPU;
374fc569712SThomas Gleixner }
375fc569712SThomas Gleixner
irqd_clr_forwarded_to_vcpu(struct irq_data * d)376fc569712SThomas Gleixner static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d)
377fc569712SThomas Gleixner {
378fc569712SThomas Gleixner __irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU;
379fc569712SThomas Gleixner }
380b76f1674SThomas Gleixner
irqd_affinity_is_managed(struct irq_data * d)3819c255583SThomas Gleixner static inline bool irqd_affinity_is_managed(struct irq_data *d)
3829c255583SThomas Gleixner {
3839c255583SThomas Gleixner return __irqd_to_state(d) & IRQD_AFFINITY_MANAGED;
3849c255583SThomas Gleixner }
3859c255583SThomas Gleixner
irqd_is_activated(struct irq_data * d)38608d85f3eSMarc Zyngier static inline bool irqd_is_activated(struct irq_data *d)
38708d85f3eSMarc Zyngier {
38808d85f3eSMarc Zyngier return __irqd_to_state(d) & IRQD_ACTIVATED;
38908d85f3eSMarc Zyngier }
39008d85f3eSMarc Zyngier
irqd_set_activated(struct irq_data * d)39108d85f3eSMarc Zyngier static inline void irqd_set_activated(struct irq_data *d)
39208d85f3eSMarc Zyngier {
39308d85f3eSMarc Zyngier __irqd_to_state(d) |= IRQD_ACTIVATED;
39408d85f3eSMarc Zyngier }
39508d85f3eSMarc Zyngier
irqd_clr_activated(struct irq_data * d)39608d85f3eSMarc Zyngier static inline void irqd_clr_activated(struct irq_data *d)
39708d85f3eSMarc Zyngier {
39808d85f3eSMarc Zyngier __irqd_to_state(d) &= ~IRQD_ACTIVATED;
39908d85f3eSMarc Zyngier }
40008d85f3eSMarc Zyngier
irqd_is_started(struct irq_data * d)401201d7f47SThomas Gleixner static inline bool irqd_is_started(struct irq_data *d)
402201d7f47SThomas Gleixner {
403201d7f47SThomas Gleixner return __irqd_to_state(d) & IRQD_IRQ_STARTED;
404201d7f47SThomas Gleixner }
405201d7f47SThomas Gleixner
irqd_is_managed_and_shutdown(struct irq_data * d)406761ea388SThomas Gleixner static inline bool irqd_is_managed_and_shutdown(struct irq_data *d)
40754fdf6a0SThomas Gleixner {
40854fdf6a0SThomas Gleixner return __irqd_to_state(d) & IRQD_MANAGED_SHUTDOWN;
40954fdf6a0SThomas Gleixner }
41054fdf6a0SThomas Gleixner
irqd_set_can_reserve(struct irq_data * d)41169790ba9SThomas Gleixner static inline void irqd_set_can_reserve(struct irq_data *d)
41269790ba9SThomas Gleixner {
41369790ba9SThomas Gleixner __irqd_to_state(d) |= IRQD_CAN_RESERVE;
41469790ba9SThomas Gleixner }
41569790ba9SThomas Gleixner
irqd_clr_can_reserve(struct irq_data * d)41669790ba9SThomas Gleixner static inline void irqd_clr_can_reserve(struct irq_data *d)
41769790ba9SThomas Gleixner {
41869790ba9SThomas Gleixner __irqd_to_state(d) &= ~IRQD_CAN_RESERVE;
41969790ba9SThomas Gleixner }
42069790ba9SThomas Gleixner
irqd_can_reserve(struct irq_data * d)42169790ba9SThomas Gleixner static inline bool irqd_can_reserve(struct irq_data *d)
42269790ba9SThomas Gleixner {
42369790ba9SThomas Gleixner return __irqd_to_state(d) & IRQD_CAN_RESERVE;
42469790ba9SThomas Gleixner }
42569790ba9SThomas Gleixner
irqd_set_affinity_on_activate(struct irq_data * d)426f0c7bacaSThomas Gleixner static inline void irqd_set_affinity_on_activate(struct irq_data *d)
427f0c7bacaSThomas Gleixner {
428f0c7bacaSThomas Gleixner __irqd_to_state(d) |= IRQD_AFFINITY_ON_ACTIVATE;
429f0c7bacaSThomas Gleixner }
430f0c7bacaSThomas Gleixner
irqd_affinity_on_activate(struct irq_data * d)431f0c7bacaSThomas Gleixner static inline bool irqd_affinity_on_activate(struct irq_data *d)
432f0c7bacaSThomas Gleixner {
433f0c7bacaSThomas Gleixner return __irqd_to_state(d) & IRQD_AFFINITY_ON_ACTIVATE;
434f0c7bacaSThomas Gleixner }
435f0c7bacaSThomas Gleixner
irqd_set_resend_when_in_progress(struct irq_data * d)4369c15eeb5SJames Gowans static inline void irqd_set_resend_when_in_progress(struct irq_data *d)
4379c15eeb5SJames Gowans {
4389c15eeb5SJames Gowans __irqd_to_state(d) |= IRQD_RESEND_WHEN_IN_PROGRESS;
4399c15eeb5SJames Gowans }
4409c15eeb5SJames Gowans
irqd_needs_resend_when_in_progress(struct irq_data * d)4419c15eeb5SJames Gowans static inline bool irqd_needs_resend_when_in_progress(struct irq_data *d)
4429c15eeb5SJames Gowans {
4439c15eeb5SJames Gowans return __irqd_to_state(d) & IRQD_RESEND_WHEN_IN_PROGRESS;
4449c15eeb5SJames Gowans }
4459c15eeb5SJames Gowans
446b354286eSBoqun Feng #undef __irqd_to_state
447b354286eSBoqun Feng
irqd_to_hwirq(struct irq_data * d)448a699e4e4SGrant Likely static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
449a699e4e4SGrant Likely {
450a699e4e4SGrant Likely return d->hwirq;
451a699e4e4SGrant Likely }
452a699e4e4SGrant Likely
453ff7dcd44SThomas Gleixner /**
4546a6de9efSThomas Gleixner * struct irq_chip - hardware interrupt chip descriptor
4558fee5c36SIngo Molnar *
4568fee5c36SIngo Molnar * @name: name for /proc/interrupts
457f8822657SThomas Gleixner * @irq_startup: start up the interrupt (defaults to ->enable if NULL)
458f8822657SThomas Gleixner * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL)
459f8822657SThomas Gleixner * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL)
460f8822657SThomas Gleixner * @irq_disable: disable the interrupt
461f8822657SThomas Gleixner * @irq_ack: start of a new interrupt
462f8822657SThomas Gleixner * @irq_mask: mask an interrupt source
463f8822657SThomas Gleixner * @irq_mask_ack: ack and mask an interrupt source
464f8822657SThomas Gleixner * @irq_unmask: unmask an interrupt source
465f8822657SThomas Gleixner * @irq_eoi: end of interrupt
46683979133SThomas Gleixner * @irq_set_affinity: Set the CPU affinity on SMP machines. If the force
46783979133SThomas Gleixner * argument is true, it tells the driver to
46883979133SThomas Gleixner * unconditionally apply the affinity setting. Sanity
46983979133SThomas Gleixner * checks against the supplied affinity mask are not
47083979133SThomas Gleixner * required. This is used for CPU hotplug where the
47183979133SThomas Gleixner * target CPU is not yet set in the cpu_online_mask.
472f8822657SThomas Gleixner * @irq_retrigger: resend an IRQ to the CPU
473f8822657SThomas Gleixner * @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
474f8822657SThomas Gleixner * @irq_set_wake: enable/disable power-management wake-on of an IRQ
475f8822657SThomas Gleixner * @irq_bus_lock: function to lock access to slow bus (i2c) chips
476f8822657SThomas Gleixner * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
4770fdb4b25SDavid Daney * @irq_cpu_online: configure an interrupt source for a secondary CPU
4780fdb4b25SDavid Daney * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU
479be9b22b6SBrian Norris * @irq_suspend: function called from core code on suspend once per
480be9b22b6SBrian Norris * chip, when one or more interrupts are installed
481be9b22b6SBrian Norris * @irq_resume: function called from core code on resume once per chip,
482be9b22b6SBrian Norris * when one ore more interrupts are installed
483cfefd21eSThomas Gleixner * @irq_pm_shutdown: function called from core code on shutdown once per chip
484d0051816SThomas Gleixner * @irq_calc_mask: Optional function to set irq_data.mask for special cases
485ab7798ffSThomas Gleixner * @irq_print_chip: optional to print special chip info in show_interrupts
486c1bacbaeSThomas Gleixner * @irq_request_resources: optional to request resources before calling
487c1bacbaeSThomas Gleixner * any other callback related to this irq
488c1bacbaeSThomas Gleixner * @irq_release_resources: optional to release resources acquired with
489c1bacbaeSThomas Gleixner * irq_request_resources
490515085efSJiang Liu * @irq_compose_msi_msg: optional to compose message content for MSI
4919dde55b7SJiang Liu * @irq_write_msi_msg: optional to write message content for MSI
4921b7047edSMarc Zyngier * @irq_get_irqchip_state: return the internal state of an interrupt
4931b7047edSMarc Zyngier * @irq_set_irqchip_state: set the internal state of a interrupt
4940a4377deSJiang Liu * @irq_set_vcpu_affinity: optional to target a vCPU in a virtual machine
49534dc1ae1SQais Yousef * @ipi_send_single: send a single IPI to destination cpus
49634dc1ae1SQais Yousef * @ipi_send_mask: send an IPI to destination cpus in cpumask
497b525903cSJulien Thierry * @irq_nmi_setup: function called from core code before enabling an NMI
498b525903cSJulien Thierry * @irq_nmi_teardown: function called from core code after disabling an NMI
4992bff17adSThomas Gleixner * @flags: chip specific flags
5001da177e4SLinus Torvalds */
5016a6de9efSThomas Gleixner struct irq_chip {
5026a6de9efSThomas Gleixner const char *name;
503f8822657SThomas Gleixner unsigned int (*irq_startup)(struct irq_data *data);
504f8822657SThomas Gleixner void (*irq_shutdown)(struct irq_data *data);
505f8822657SThomas Gleixner void (*irq_enable)(struct irq_data *data);
506f8822657SThomas Gleixner void (*irq_disable)(struct irq_data *data);
507f8822657SThomas Gleixner
508f8822657SThomas Gleixner void (*irq_ack)(struct irq_data *data);
509f8822657SThomas Gleixner void (*irq_mask)(struct irq_data *data);
510f8822657SThomas Gleixner void (*irq_mask_ack)(struct irq_data *data);
511f8822657SThomas Gleixner void (*irq_unmask)(struct irq_data *data);
512f8822657SThomas Gleixner void (*irq_eoi)(struct irq_data *data);
513f8822657SThomas Gleixner
514f8822657SThomas Gleixner int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force);
515f8822657SThomas Gleixner int (*irq_retrigger)(struct irq_data *data);
516f8822657SThomas Gleixner int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);
517f8822657SThomas Gleixner int (*irq_set_wake)(struct irq_data *data, unsigned int on);
518f8822657SThomas Gleixner
519f8822657SThomas Gleixner void (*irq_bus_lock)(struct irq_data *data);
520f8822657SThomas Gleixner void (*irq_bus_sync_unlock)(struct irq_data *data);
521f8822657SThomas Gleixner
5228d15a729SMarc Zyngier #ifdef CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE
5230fdb4b25SDavid Daney void (*irq_cpu_online)(struct irq_data *data);
5240fdb4b25SDavid Daney void (*irq_cpu_offline)(struct irq_data *data);
5258d15a729SMarc Zyngier #endif
526cfefd21eSThomas Gleixner void (*irq_suspend)(struct irq_data *data);
527cfefd21eSThomas Gleixner void (*irq_resume)(struct irq_data *data);
528cfefd21eSThomas Gleixner void (*irq_pm_shutdown)(struct irq_data *data);
529cfefd21eSThomas Gleixner
530d0051816SThomas Gleixner void (*irq_calc_mask)(struct irq_data *data);
531d0051816SThomas Gleixner
532ab7798ffSThomas Gleixner void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
533c1bacbaeSThomas Gleixner int (*irq_request_resources)(struct irq_data *data);
534c1bacbaeSThomas Gleixner void (*irq_release_resources)(struct irq_data *data);
535ab7798ffSThomas Gleixner
536515085efSJiang Liu void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg);
5379dde55b7SJiang Liu void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg);
538515085efSJiang Liu
5391b7047edSMarc Zyngier int (*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state);
5401b7047edSMarc Zyngier int (*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state);
5411b7047edSMarc Zyngier
5420a4377deSJiang Liu int (*irq_set_vcpu_affinity)(struct irq_data *data, void *vcpu_info);
5430a4377deSJiang Liu
54434dc1ae1SQais Yousef void (*ipi_send_single)(struct irq_data *data, unsigned int cpu);
54534dc1ae1SQais Yousef void (*ipi_send_mask)(struct irq_data *data, const struct cpumask *dest);
54634dc1ae1SQais Yousef
547b525903cSJulien Thierry int (*irq_nmi_setup)(struct irq_data *data);
548b525903cSJulien Thierry void (*irq_nmi_teardown)(struct irq_data *data);
549b525903cSJulien Thierry
5502bff17adSThomas Gleixner unsigned long flags;
5511da177e4SLinus Torvalds };
5521da177e4SLinus Torvalds
553d4d5e089SThomas Gleixner /*
554d4d5e089SThomas Gleixner * irq_chip specific flags
555d4d5e089SThomas Gleixner *
556d4d5e089SThomas Gleixner * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type()
55777694b40SThomas Gleixner * IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled
558d209a699SThomas Gleixner * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path
559b3d42232SThomas Gleixner * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks
560b3d42232SThomas Gleixner * when irq enabled
56160f96b41SSantosh Shilimkar * IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
5624f6e4f71SThomas Gleixner * IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask
563328a4978SThomas Gleixner * IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode
56490428a8eSMaulik Shah * IRQCHIP_SUPPORTS_LEVEL_MSI: Chip can provide two doorbells for Level MSIs
565b525903cSJulien Thierry * IRQCHIP_SUPPORTS_NMI: Chip can deliver NMIs, only for root irqchips
56690428a8eSMaulik Shah * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs
56790428a8eSMaulik Shah * in the suspend path if they are in disabled state
568826da771SThomas Gleixner * IRQCHIP_AFFINITY_PRE_STARTUP: Default affinity update before startup
5696c846d02SMarc Zyngier * IRQCHIP_IMMUTABLE: Don't ever change anything in this chip
570d4d5e089SThomas Gleixner */
571d4d5e089SThomas Gleixner enum {
572d4d5e089SThomas Gleixner IRQCHIP_SET_TYPE_MASKED = (1 << 0),
57377694b40SThomas Gleixner IRQCHIP_EOI_IF_HANDLED = (1 << 1),
574d209a699SThomas Gleixner IRQCHIP_MASK_ON_SUSPEND = (1 << 2),
575b3d42232SThomas Gleixner IRQCHIP_ONOFFLINE_ENABLED = (1 << 3),
57660f96b41SSantosh Shilimkar IRQCHIP_SKIP_SET_WAKE = (1 << 4),
577dc9b229aSThomas Gleixner IRQCHIP_ONESHOT_SAFE = (1 << 5),
578328a4978SThomas Gleixner IRQCHIP_EOI_THREADED = (1 << 6),
5796988e0e0SMarc Zyngier IRQCHIP_SUPPORTS_LEVEL_MSI = (1 << 7),
580b525903cSJulien Thierry IRQCHIP_SUPPORTS_NMI = (1 << 8),
58190428a8eSMaulik Shah IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = (1 << 9),
582826da771SThomas Gleixner IRQCHIP_AFFINITY_PRE_STARTUP = (1 << 10),
5836c846d02SMarc Zyngier IRQCHIP_IMMUTABLE = (1 << 11),
584d4d5e089SThomas Gleixner };
585d4d5e089SThomas Gleixner
586e144710bSThomas Gleixner #include <linux/irqdesc.h>
587c6b7674fSThomas Gleixner
58834ffdb72SIngo Molnar /*
58934ffdb72SIngo Molnar * Pick up the arch-dependent methods:
59034ffdb72SIngo Molnar */
59134ffdb72SIngo Molnar #include <asm/hw_irq.h>
5921da177e4SLinus Torvalds
593b683de2bSThomas Gleixner #ifndef NR_IRQS_LEGACY
594b683de2bSThomas Gleixner # define NR_IRQS_LEGACY 0
595b683de2bSThomas Gleixner #endif
596b683de2bSThomas Gleixner
5971318a481SThomas Gleixner #ifndef ARCH_IRQ_INIT_FLAGS
5981318a481SThomas Gleixner # define ARCH_IRQ_INIT_FLAGS 0
5991318a481SThomas Gleixner #endif
6001318a481SThomas Gleixner
601c1594b77SThomas Gleixner #define IRQ_DEFAULT_INIT_FLAGS ARCH_IRQ_INIT_FLAGS
6021318a481SThomas Gleixner
603e144710bSThomas Gleixner struct irqaction;
60431d9d9b6SMarc Zyngier extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
60531d9d9b6SMarc Zyngier extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
6061da177e4SLinus Torvalds
6078d15a729SMarc Zyngier #ifdef CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE
6080fdb4b25SDavid Daney extern void irq_cpu_online(void);
6090fdb4b25SDavid Daney extern void irq_cpu_offline(void);
6108d15a729SMarc Zyngier #endif
61101f8fa4fSThomas Gleixner extern int irq_set_affinity_locked(struct irq_data *data,
61201f8fa4fSThomas Gleixner const struct cpumask *cpumask, bool force);
6130a4377deSJiang Liu extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
6140fdb4b25SDavid Daney
615c5cb83bbSThomas Gleixner #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_IRQ_MIGRATION)
616f1e0bb0aSYang Yingliang extern void irq_migrate_all_off_this_cpu(void);
617c5cb83bbSThomas Gleixner extern int irq_affinity_online_cpu(unsigned int cpu);
618c5cb83bbSThomas Gleixner #else
619c5cb83bbSThomas Gleixner # define irq_affinity_online_cpu NULL
620c5cb83bbSThomas Gleixner #endif
621f1e0bb0aSYang Yingliang
6223a3856d0SThomas Gleixner #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
623d340ebd6SThomas Gleixner void __irq_move_irq(struct irq_data *data);
irq_move_irq(struct irq_data * data)624d340ebd6SThomas Gleixner static inline void irq_move_irq(struct irq_data *data)
625d340ebd6SThomas Gleixner {
626d340ebd6SThomas Gleixner if (unlikely(irqd_is_setaffinity_pending(data)))
627d340ebd6SThomas Gleixner __irq_move_irq(data);
628d340ebd6SThomas Gleixner }
629a439520fSThomas Gleixner void irq_move_masked_irq(struct irq_data *data);
630f0383c24SThomas Gleixner void irq_force_complete_move(struct irq_desc *desc);
631e144710bSThomas Gleixner #else
irq_move_irq(struct irq_data * data)632a439520fSThomas Gleixner static inline void irq_move_irq(struct irq_data *data) { }
irq_move_masked_irq(struct irq_data * data)633a439520fSThomas Gleixner static inline void irq_move_masked_irq(struct irq_data *data) { }
irq_force_complete_move(struct irq_desc * desc)634f0383c24SThomas Gleixner static inline void irq_force_complete_move(struct irq_desc *desc) { }
635e144710bSThomas Gleixner #endif
63654d5d424SAshok Raj
6371da177e4SLinus Torvalds extern int no_irq_affinity;
6381da177e4SLinus Torvalds
639293a7a0aSThomas Gleixner #ifdef CONFIG_HARDIRQS_SW_RESEND
640293a7a0aSThomas Gleixner int irq_set_parent(int irq, int parent_irq);
641293a7a0aSThomas Gleixner #else
irq_set_parent(int irq,int parent_irq)642293a7a0aSThomas Gleixner static inline int irq_set_parent(int irq, int parent_irq)
643293a7a0aSThomas Gleixner {
644293a7a0aSThomas Gleixner return 0;
645293a7a0aSThomas Gleixner }
646293a7a0aSThomas Gleixner #endif
647293a7a0aSThomas Gleixner
6482e60bbb6SIngo Molnar /*
6496a6de9efSThomas Gleixner * Built-in IRQ handlers for various IRQ types,
650bebd04ccSKrzysztof Halasa * callable via desc->handle_irq()
6516a6de9efSThomas Gleixner */
652bd0b9ac4SThomas Gleixner extern void handle_level_irq(struct irq_desc *desc);
653bd0b9ac4SThomas Gleixner extern void handle_fasteoi_irq(struct irq_desc *desc);
654bd0b9ac4SThomas Gleixner extern void handle_edge_irq(struct irq_desc *desc);
655bd0b9ac4SThomas Gleixner extern void handle_edge_eoi_irq(struct irq_desc *desc);
656bd0b9ac4SThomas Gleixner extern void handle_simple_irq(struct irq_desc *desc);
657edd14cfeSKeith Busch extern void handle_untracked_irq(struct irq_desc *desc);
658bd0b9ac4SThomas Gleixner extern void handle_percpu_irq(struct irq_desc *desc);
659bd0b9ac4SThomas Gleixner extern void handle_percpu_devid_irq(struct irq_desc *desc);
660bd0b9ac4SThomas Gleixner extern void handle_bad_irq(struct irq_desc *desc);
66131b47cf7SMark Brown extern void handle_nested_irq(unsigned int irq);
6626a6de9efSThomas Gleixner
6632dcf1fbcSJulien Thierry extern void handle_fasteoi_nmi(struct irq_desc *desc);
6642dcf1fbcSJulien Thierry extern void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc);
6652dcf1fbcSJulien Thierry
666515085efSJiang Liu extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
667be45beb2SJon Hunter extern int irq_chip_pm_get(struct irq_data *data);
668be45beb2SJon Hunter extern int irq_chip_pm_put(struct irq_data *data);
66985f08c17SJiang Liu #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
6707703b08cSDavid Daney extern void handle_fasteoi_ack_irq(struct irq_desc *desc);
6717703b08cSDavid Daney extern void handle_fasteoi_mask_irq(struct irq_desc *desc);
6724a169a95SMaulik Shah extern int irq_chip_set_parent_state(struct irq_data *data,
6734a169a95SMaulik Shah enum irqchip_irq_state which,
6744a169a95SMaulik Shah bool val);
6754a169a95SMaulik Shah extern int irq_chip_get_parent_state(struct irq_data *data,
6764a169a95SMaulik Shah enum irqchip_irq_state which,
6774a169a95SMaulik Shah bool *state);
6783cfeffc2SStefan Agner extern void irq_chip_enable_parent(struct irq_data *data);
6793cfeffc2SStefan Agner extern void irq_chip_disable_parent(struct irq_data *data);
68085f08c17SJiang Liu extern void irq_chip_ack_parent(struct irq_data *data);
68185f08c17SJiang Liu extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
68256e8ababSYingjoe Chen extern void irq_chip_mask_parent(struct irq_data *data);
6835aa5bd56SLinus Walleij extern void irq_chip_mask_ack_parent(struct irq_data *data);
68456e8ababSYingjoe Chen extern void irq_chip_unmask_parent(struct irq_data *data);
68556e8ababSYingjoe Chen extern void irq_chip_eoi_parent(struct irq_data *data);
68656e8ababSYingjoe Chen extern int irq_chip_set_affinity_parent(struct irq_data *data,
68756e8ababSYingjoe Chen const struct cpumask *dest,
68856e8ababSYingjoe Chen bool force);
68908b55e2aSMarc Zyngier extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
6900a4377deSJiang Liu extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
6910a4377deSJiang Liu void *vcpu_info);
692b7560de1SGrygorii Strashko extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
6932bd1298aSLokesh Vutla extern int irq_chip_request_resources_parent(struct irq_data *data);
6942bd1298aSLokesh Vutla extern void irq_chip_release_resources_parent(struct irq_data *data);
69585f08c17SJiang Liu #endif
69685f08c17SJiang Liu
6976a6de9efSThomas Gleixner /* Handling of unhandled and spurious interrupts: */
6980dcdbc97SJiang Liu extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
6991da177e4SLinus Torvalds
700a4633adcSThomas Gleixner
7016a6de9efSThomas Gleixner /* Enable/disable irq debugging output: */
7026a6de9efSThomas Gleixner extern int noirqdebug_setup(char *str);
7031da177e4SLinus Torvalds
7046a6de9efSThomas Gleixner /* Checks whether the interrupt can be requested by request_irq(): */
7056a6de9efSThomas Gleixner extern int can_request_irq(unsigned int irq, unsigned long irqflags);
7066a6de9efSThomas Gleixner
707f8b5473fSThomas Gleixner /* Dummy irq-chip implementations: */
7086a6de9efSThomas Gleixner extern struct irq_chip no_irq_chip;
709f8b5473fSThomas Gleixner extern struct irq_chip dummy_irq_chip;
7106a6de9efSThomas Gleixner
7116a6de9efSThomas Gleixner extern void
712393e1280SMarc Zyngier irq_set_chip_and_handler_name(unsigned int irq, const struct irq_chip *chip,
713a460e745SIngo Molnar irq_flow_handler_t handle, const char *name);
714a460e745SIngo Molnar
irq_set_chip_and_handler(unsigned int irq,const struct irq_chip * chip,irq_flow_handler_t handle)715393e1280SMarc Zyngier static inline void irq_set_chip_and_handler(unsigned int irq,
716393e1280SMarc Zyngier const struct irq_chip *chip,
7173836ca08SThomas Gleixner irq_flow_handler_t handle)
7183836ca08SThomas Gleixner {
7193836ca08SThomas Gleixner irq_set_chip_and_handler_name(irq, chip, handle, NULL);
7203836ca08SThomas Gleixner }
7213836ca08SThomas Gleixner
72231d9d9b6SMarc Zyngier extern int irq_set_percpu_devid(unsigned int irq);
723222df54fSMarc Zyngier extern int irq_set_percpu_devid_partition(unsigned int irq,
724222df54fSMarc Zyngier const struct cpumask *affinity);
725222df54fSMarc Zyngier extern int irq_get_percpu_devid_partition(unsigned int irq,
726222df54fSMarc Zyngier struct cpumask *affinity);
72731d9d9b6SMarc Zyngier
7286a6de9efSThomas Gleixner extern void
7293836ca08SThomas Gleixner __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
730a460e745SIngo Molnar const char *name);
7316a6de9efSThomas Gleixner
7326a6de9efSThomas Gleixner static inline void
irq_set_handler(unsigned int irq,irq_flow_handler_t handle)7333836ca08SThomas Gleixner irq_set_handler(unsigned int irq, irq_flow_handler_t handle)
7346a6de9efSThomas Gleixner {
7353836ca08SThomas Gleixner __irq_set_handler(irq, handle, 0, NULL);
7366a6de9efSThomas Gleixner }
7376a6de9efSThomas Gleixner
7386a6de9efSThomas Gleixner /*
7396a6de9efSThomas Gleixner * Set a highlevel chained flow handler for a given IRQ.
7406a6de9efSThomas Gleixner * (a chained handler is automatically enabled and set to
7417f1b1244SPaul Mundt * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
7426a6de9efSThomas Gleixner */
7436a6de9efSThomas Gleixner static inline void
irq_set_chained_handler(unsigned int irq,irq_flow_handler_t handle)7443836ca08SThomas Gleixner irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle)
7456a6de9efSThomas Gleixner {
7463836ca08SThomas Gleixner __irq_set_handler(irq, handle, 1, NULL);
7476a6de9efSThomas Gleixner }
7486a6de9efSThomas Gleixner
7493b0f95beSRussell King /*
7503b0f95beSRussell King * Set a highlevel chained flow handler and its data for a given IRQ.
7513b0f95beSRussell King * (a chained handler is automatically enabled and set to
7523b0f95beSRussell King * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
7533b0f95beSRussell King */
7543b0f95beSRussell King void
7553b0f95beSRussell King irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
7563b0f95beSRussell King void *data);
7573b0f95beSRussell King
75844247184SThomas Gleixner void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
75944247184SThomas Gleixner
irq_set_status_flags(unsigned int irq,unsigned long set)76044247184SThomas Gleixner static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
76144247184SThomas Gleixner {
76244247184SThomas Gleixner irq_modify_status(irq, 0, set);
76344247184SThomas Gleixner }
76444247184SThomas Gleixner
irq_clear_status_flags(unsigned int irq,unsigned long clr)76544247184SThomas Gleixner static inline void irq_clear_status_flags(unsigned int irq, unsigned long clr)
76644247184SThomas Gleixner {
76744247184SThomas Gleixner irq_modify_status(irq, clr, 0);
76844247184SThomas Gleixner }
76944247184SThomas Gleixner
irq_set_noprobe(unsigned int irq)770a0cd9ca2SThomas Gleixner static inline void irq_set_noprobe(unsigned int irq)
77144247184SThomas Gleixner {
77244247184SThomas Gleixner irq_modify_status(irq, 0, IRQ_NOPROBE);
77344247184SThomas Gleixner }
77444247184SThomas Gleixner
irq_set_probe(unsigned int irq)775a0cd9ca2SThomas Gleixner static inline void irq_set_probe(unsigned int irq)
77644247184SThomas Gleixner {
77744247184SThomas Gleixner irq_modify_status(irq, IRQ_NOPROBE, 0);
77844247184SThomas Gleixner }
77946f4f8f6SRalf Baechle
irq_set_nothread(unsigned int irq)7807f1b1244SPaul Mundt static inline void irq_set_nothread(unsigned int irq)
7817f1b1244SPaul Mundt {
7827f1b1244SPaul Mundt irq_modify_status(irq, 0, IRQ_NOTHREAD);
7837f1b1244SPaul Mundt }
7847f1b1244SPaul Mundt
irq_set_thread(unsigned int irq)7857f1b1244SPaul Mundt static inline void irq_set_thread(unsigned int irq)
7867f1b1244SPaul Mundt {
7877f1b1244SPaul Mundt irq_modify_status(irq, IRQ_NOTHREAD, 0);
7887f1b1244SPaul Mundt }
7897f1b1244SPaul Mundt
irq_set_nested_thread(unsigned int irq,bool nest)7906f91a52dSThomas Gleixner static inline void irq_set_nested_thread(unsigned int irq, bool nest)
7916f91a52dSThomas Gleixner {
7926f91a52dSThomas Gleixner if (nest)
7936f91a52dSThomas Gleixner irq_set_status_flags(irq, IRQ_NESTED_THREAD);
7946f91a52dSThomas Gleixner else
7956f91a52dSThomas Gleixner irq_clear_status_flags(irq, IRQ_NESTED_THREAD);
7966f91a52dSThomas Gleixner }
7976f91a52dSThomas Gleixner
irq_set_percpu_devid_flags(unsigned int irq)79831d9d9b6SMarc Zyngier static inline void irq_set_percpu_devid_flags(unsigned int irq)
79931d9d9b6SMarc Zyngier {
80031d9d9b6SMarc Zyngier irq_set_status_flags(irq,
80131d9d9b6SMarc Zyngier IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD |
80231d9d9b6SMarc Zyngier IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
80331d9d9b6SMarc Zyngier }
80431d9d9b6SMarc Zyngier
8053a16d713SEric W. Biederman /* Set/get chip/data for an IRQ: */
806393e1280SMarc Zyngier extern int irq_set_chip(unsigned int irq, const struct irq_chip *chip);
807a0cd9ca2SThomas Gleixner extern int irq_set_handler_data(unsigned int irq, void *data);
808a0cd9ca2SThomas Gleixner extern int irq_set_chip_data(unsigned int irq, void *data);
809a0cd9ca2SThomas Gleixner extern int irq_set_irq_type(unsigned int irq, unsigned int type);
810a0cd9ca2SThomas Gleixner extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry);
81151906e77SAlexander Gordeev extern int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset,
81251906e77SAlexander Gordeev struct msi_desc *entry);
813f303a6ddSThomas Gleixner extern struct irq_data *irq_get_irq_data(unsigned int irq);
814dd87eb3aSThomas Gleixner
irq_get_chip(unsigned int irq)815a0cd9ca2SThomas Gleixner static inline struct irq_chip *irq_get_chip(unsigned int irq)
816f303a6ddSThomas Gleixner {
817f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
818f303a6ddSThomas Gleixner return d ? d->chip : NULL;
819f303a6ddSThomas Gleixner }
820f303a6ddSThomas Gleixner
irq_data_get_irq_chip(struct irq_data * d)821f303a6ddSThomas Gleixner static inline struct irq_chip *irq_data_get_irq_chip(struct irq_data *d)
822f303a6ddSThomas Gleixner {
823f303a6ddSThomas Gleixner return d->chip;
824f303a6ddSThomas Gleixner }
825f303a6ddSThomas Gleixner
irq_get_chip_data(unsigned int irq)826a0cd9ca2SThomas Gleixner static inline void *irq_get_chip_data(unsigned int irq)
827f303a6ddSThomas Gleixner {
828f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
829f303a6ddSThomas Gleixner return d ? d->chip_data : NULL;
830f303a6ddSThomas Gleixner }
831f303a6ddSThomas Gleixner
irq_data_get_irq_chip_data(struct irq_data * d)832f303a6ddSThomas Gleixner static inline void *irq_data_get_irq_chip_data(struct irq_data *d)
833f303a6ddSThomas Gleixner {
834f303a6ddSThomas Gleixner return d->chip_data;
835f303a6ddSThomas Gleixner }
836f303a6ddSThomas Gleixner
irq_get_handler_data(unsigned int irq)837a0cd9ca2SThomas Gleixner static inline void *irq_get_handler_data(unsigned int irq)
838f303a6ddSThomas Gleixner {
839f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
840af7080e0SJiang Liu return d ? d->common->handler_data : NULL;
841f303a6ddSThomas Gleixner }
842f303a6ddSThomas Gleixner
irq_data_get_irq_handler_data(struct irq_data * d)843a0cd9ca2SThomas Gleixner static inline void *irq_data_get_irq_handler_data(struct irq_data *d)
844f303a6ddSThomas Gleixner {
845af7080e0SJiang Liu return d->common->handler_data;
846f303a6ddSThomas Gleixner }
847f303a6ddSThomas Gleixner
irq_get_msi_desc(unsigned int irq)848a0cd9ca2SThomas Gleixner static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
849f303a6ddSThomas Gleixner {
850f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
851b237721cSJiang Liu return d ? d->common->msi_desc : NULL;
852f303a6ddSThomas Gleixner }
853f303a6ddSThomas Gleixner
irq_data_get_msi_desc(struct irq_data * d)854c391f262SJiang Liu static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d)
855f303a6ddSThomas Gleixner {
856b237721cSJiang Liu return d->common->msi_desc;
857f303a6ddSThomas Gleixner }
858f303a6ddSThomas Gleixner
irq_get_trigger_type(unsigned int irq)8591f6236bfSJavier Martinez Canillas static inline u32 irq_get_trigger_type(unsigned int irq)
8601f6236bfSJavier Martinez Canillas {
8611f6236bfSJavier Martinez Canillas struct irq_data *d = irq_get_irq_data(irq);
8621f6236bfSJavier Martinez Canillas return d ? irqd_get_trigger_type(d) : 0;
8631f6236bfSJavier Martinez Canillas }
8641f6236bfSJavier Martinez Canillas
irq_common_data_get_node(struct irq_common_data * d)865449e9caeSJiang Liu static inline int irq_common_data_get_node(struct irq_common_data *d)
866449e9caeSJiang Liu {
867449e9caeSJiang Liu #ifdef CONFIG_NUMA
868449e9caeSJiang Liu return d->node;
869449e9caeSJiang Liu #else
870449e9caeSJiang Liu return 0;
871449e9caeSJiang Liu #endif
872449e9caeSJiang Liu }
873449e9caeSJiang Liu
irq_data_get_node(struct irq_data * d)8746783011bSJiang Liu static inline int irq_data_get_node(struct irq_data *d)
8756783011bSJiang Liu {
876449e9caeSJiang Liu return irq_common_data_get_node(d->common);
8776783011bSJiang Liu }
8786783011bSJiang Liu
8794d0b8298SSamuel Holland static inline
irq_data_get_affinity_mask(struct irq_data * d)8804d0b8298SSamuel Holland const struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
881961343d7SSamuel Holland {
882aa081358SSamuel Holland #ifdef CONFIG_SMP
883961343d7SSamuel Holland return d->common->affinity;
884aa081358SSamuel Holland #else
885aa081358SSamuel Holland return cpumask_of(0);
886aa081358SSamuel Holland #endif
887961343d7SSamuel Holland }
888961343d7SSamuel Holland
irq_data_update_affinity(struct irq_data * d,const struct cpumask * m)889073352e9SSamuel Holland static inline void irq_data_update_affinity(struct irq_data *d,
890073352e9SSamuel Holland const struct cpumask *m)
891073352e9SSamuel Holland {
892aa081358SSamuel Holland #ifdef CONFIG_SMP
893073352e9SSamuel Holland cpumask_copy(d->common->affinity, m);
894aa081358SSamuel Holland #endif
895073352e9SSamuel Holland }
896073352e9SSamuel Holland
irq_get_affinity_mask(int irq)8974d0b8298SSamuel Holland static inline const struct cpumask *irq_get_affinity_mask(int irq)
898c64301a2SJiang Liu {
899c64301a2SJiang Liu struct irq_data *d = irq_get_irq_data(irq);
900c64301a2SJiang Liu
901961343d7SSamuel Holland return d ? irq_data_get_affinity_mask(d) : NULL;
902c64301a2SJiang Liu }
903c64301a2SJiang Liu
9040d3f5425SThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
9050d3f5425SThomas Gleixner static inline
irq_data_get_effective_affinity_mask(struct irq_data * d)9064d0b8298SSamuel Holland const struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d)
9070d3f5425SThomas Gleixner {
9080d3f5425SThomas Gleixner return d->common->effective_affinity;
9090d3f5425SThomas Gleixner }
irq_data_update_effective_affinity(struct irq_data * d,const struct cpumask * m)9100d3f5425SThomas Gleixner static inline void irq_data_update_effective_affinity(struct irq_data *d,
9110d3f5425SThomas Gleixner const struct cpumask *m)
9120d3f5425SThomas Gleixner {
9130d3f5425SThomas Gleixner cpumask_copy(d->common->effective_affinity, m);
9140d3f5425SThomas Gleixner }
9150d3f5425SThomas Gleixner #else
irq_data_update_effective_affinity(struct irq_data * d,const struct cpumask * m)9160d3f5425SThomas Gleixner static inline void irq_data_update_effective_affinity(struct irq_data *d,
9170d3f5425SThomas Gleixner const struct cpumask *m)
9180d3f5425SThomas Gleixner {
9190d3f5425SThomas Gleixner }
9200d3f5425SThomas Gleixner static inline
irq_data_get_effective_affinity_mask(struct irq_data * d)9214d0b8298SSamuel Holland const struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d)
9220d3f5425SThomas Gleixner {
923961343d7SSamuel Holland return irq_data_get_affinity_mask(d);
9240d3f5425SThomas Gleixner }
9250d3f5425SThomas Gleixner #endif
9260d3f5425SThomas Gleixner
9274d0b8298SSamuel Holland static inline
irq_get_effective_affinity_mask(unsigned int irq)9284d0b8298SSamuel Holland const struct cpumask *irq_get_effective_affinity_mask(unsigned int irq)
9293e238012SThomas Gleixner {
9303e238012SThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
9313e238012SThomas Gleixner
9323e238012SThomas Gleixner return d ? irq_data_get_effective_affinity_mask(d) : NULL;
9333e238012SThomas Gleixner }
9343e238012SThomas Gleixner
93562a08ae2SThomas Gleixner unsigned int arch_dynirq_lower_bound(unsigned int from);
93662a08ae2SThomas Gleixner
937b6873807SSebastian Andrzej Siewior int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
938bec04037SDou Liyang struct module *owner,
939bec04037SDou Liyang const struct irq_affinity_desc *affinity);
940b6873807SSebastian Andrzej Siewior
9412b5e7730SBartosz Golaszewski int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
9422b5e7730SBartosz Golaszewski unsigned int cnt, int node, struct module *owner,
943bec04037SDou Liyang const struct irq_affinity_desc *affinity);
9442b5e7730SBartosz Golaszewski
945ec53cf23SPaul Gortmaker /* use macros to avoid needing export.h for THIS_MODULE */
946ec53cf23SPaul Gortmaker #define irq_alloc_descs(irq, from, cnt, node) \
94706ee6d57SThomas Gleixner __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL)
948ec53cf23SPaul Gortmaker
949ec53cf23SPaul Gortmaker #define irq_alloc_desc(node) \
9504c7bcb51SHans de Goede irq_alloc_descs(-1, 1, 1, node)
951ec53cf23SPaul Gortmaker
952ec53cf23SPaul Gortmaker #define irq_alloc_desc_at(at, node) \
953ec53cf23SPaul Gortmaker irq_alloc_descs(at, at, 1, node)
954ec53cf23SPaul Gortmaker
955ec53cf23SPaul Gortmaker #define irq_alloc_desc_from(from, node) \
956ec53cf23SPaul Gortmaker irq_alloc_descs(-1, from, 1, node)
957b6873807SSebastian Andrzej Siewior
95851906e77SAlexander Gordeev #define irq_alloc_descs_from(from, cnt, node) \
95951906e77SAlexander Gordeev irq_alloc_descs(-1, from, cnt, node)
96051906e77SAlexander Gordeev
9612b5e7730SBartosz Golaszewski #define devm_irq_alloc_descs(dev, irq, from, cnt, node) \
9622b5e7730SBartosz Golaszewski __devm_irq_alloc_descs(dev, irq, from, cnt, node, THIS_MODULE, NULL)
9632b5e7730SBartosz Golaszewski
9642b5e7730SBartosz Golaszewski #define devm_irq_alloc_desc(dev, node) \
9654c7bcb51SHans de Goede devm_irq_alloc_descs(dev, -1, 1, 1, node)
9662b5e7730SBartosz Golaszewski
9672b5e7730SBartosz Golaszewski #define devm_irq_alloc_desc_at(dev, at, node) \
9682b5e7730SBartosz Golaszewski devm_irq_alloc_descs(dev, at, at, 1, node)
9692b5e7730SBartosz Golaszewski
9702b5e7730SBartosz Golaszewski #define devm_irq_alloc_desc_from(dev, from, node) \
9712b5e7730SBartosz Golaszewski devm_irq_alloc_descs(dev, -1, from, 1, node)
9722b5e7730SBartosz Golaszewski
9732b5e7730SBartosz Golaszewski #define devm_irq_alloc_descs_from(dev, from, cnt, node) \
9742b5e7730SBartosz Golaszewski devm_irq_alloc_descs(dev, -1, from, cnt, node)
9752b5e7730SBartosz Golaszewski
9761f5a5b87SThomas Gleixner void irq_free_descs(unsigned int irq, unsigned int cnt);
irq_free_desc(unsigned int irq)9771f5a5b87SThomas Gleixner static inline void irq_free_desc(unsigned int irq)
9781f5a5b87SThomas Gleixner {
9791f5a5b87SThomas Gleixner irq_free_descs(irq, 1);
9801f5a5b87SThomas Gleixner }
9811f5a5b87SThomas Gleixner
982c940e01cSThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_LEGACY
983c940e01cSThomas Gleixner void irq_init_desc(unsigned int irq);
984c940e01cSThomas Gleixner #endif
985c940e01cSThomas Gleixner
9867d828062SThomas Gleixner /**
9877d828062SThomas Gleixner * struct irq_chip_regs - register offsets for struct irq_gci
9887d828062SThomas Gleixner * @enable: Enable register offset to reg_base
9897d828062SThomas Gleixner * @disable: Disable register offset to reg_base
9907d828062SThomas Gleixner * @mask: Mask register offset to reg_base
9917d828062SThomas Gleixner * @ack: Ack register offset to reg_base
9927d828062SThomas Gleixner * @eoi: Eoi register offset to reg_base
9937d828062SThomas Gleixner * @type: Type configuration register offset to reg_base
9947d828062SThomas Gleixner * @polarity: Polarity configuration register offset to reg_base
9957d828062SThomas Gleixner */
9967d828062SThomas Gleixner struct irq_chip_regs {
9977d828062SThomas Gleixner unsigned long enable;
9987d828062SThomas Gleixner unsigned long disable;
9997d828062SThomas Gleixner unsigned long mask;
10007d828062SThomas Gleixner unsigned long ack;
10017d828062SThomas Gleixner unsigned long eoi;
10027d828062SThomas Gleixner unsigned long type;
10037d828062SThomas Gleixner unsigned long polarity;
10047d828062SThomas Gleixner };
10057d828062SThomas Gleixner
10067d828062SThomas Gleixner /**
10077d828062SThomas Gleixner * struct irq_chip_type - Generic interrupt chip instance for a flow type
10087d828062SThomas Gleixner * @chip: The real interrupt chip which provides the callbacks
10097d828062SThomas Gleixner * @regs: Register offsets for this chip
10107d828062SThomas Gleixner * @handler: Flow handler associated with this chip
10117d828062SThomas Gleixner * @type: Chip can handle these flow types
1012899f0e66SGerlando Falauto * @mask_cache_priv: Cached mask register private to the chip type
1013899f0e66SGerlando Falauto * @mask_cache: Pointer to cached mask register
10147d828062SThomas Gleixner *
10157d828062SThomas Gleixner * A irq_generic_chip can have several instances of irq_chip_type when
10167d828062SThomas Gleixner * it requires different functions and register offsets for different
10177d828062SThomas Gleixner * flow types.
10187d828062SThomas Gleixner */
10197d828062SThomas Gleixner struct irq_chip_type {
10207d828062SThomas Gleixner struct irq_chip chip;
10217d828062SThomas Gleixner struct irq_chip_regs regs;
10227d828062SThomas Gleixner irq_flow_handler_t handler;
10237d828062SThomas Gleixner u32 type;
1024899f0e66SGerlando Falauto u32 mask_cache_priv;
1025899f0e66SGerlando Falauto u32 *mask_cache;
10267d828062SThomas Gleixner };
10277d828062SThomas Gleixner
10287d828062SThomas Gleixner /**
10297d828062SThomas Gleixner * struct irq_chip_generic - Generic irq chip data structure
10307d828062SThomas Gleixner * @lock: Lock to protect register and cache data access
10317d828062SThomas Gleixner * @reg_base: Register base address (virtual)
10322b280376SKevin Cernekee * @reg_readl: Alternate I/O accessor (defaults to readl if NULL)
10332b280376SKevin Cernekee * @reg_writel: Alternate I/O accessor (defaults to writel if NULL)
1034be9b22b6SBrian Norris * @suspend: Function called from core code on suspend once per
1035be9b22b6SBrian Norris * chip; can be useful instead of irq_chip::suspend to
1036be9b22b6SBrian Norris * handle chip details even when no interrupts are in use
1037be9b22b6SBrian Norris * @resume: Function called from core code on resume once per chip;
1038be9b22b6SBrian Norris * can be useful instead of irq_chip::suspend to handle
1039be9b22b6SBrian Norris * chip details even when no interrupts are in use
10407d828062SThomas Gleixner * @irq_base: Interrupt base nr for this chip
10417d828062SThomas Gleixner * @irq_cnt: Number of interrupts handled by this chip
1042899f0e66SGerlando Falauto * @mask_cache: Cached mask register shared between all chip types
10437d828062SThomas Gleixner * @type_cache: Cached type register
10447d828062SThomas Gleixner * @polarity_cache: Cached polarity register
10457d828062SThomas Gleixner * @wake_enabled: Interrupt can wakeup from suspend
10467d828062SThomas Gleixner * @wake_active: Interrupt is marked as an wakeup from suspend source
10477d828062SThomas Gleixner * @num_ct: Number of available irq_chip_type instances (usually 1)
10487d828062SThomas Gleixner * @private: Private data for non generic chip callbacks
1049088f40b7SThomas Gleixner * @installed: bitfield to denote installed interrupts
1050e8bd834fSGrant Likely * @unused: bitfield to denote unused interrupts
1051088f40b7SThomas Gleixner * @domain: irq domain pointer
1052cfefd21eSThomas Gleixner * @list: List head for keeping track of instances
10537d828062SThomas Gleixner * @chip_types: Array of interrupt irq_chip_types
10547d828062SThomas Gleixner *
10557d828062SThomas Gleixner * Note, that irq_chip_generic can have multiple irq_chip_type
10567d828062SThomas Gleixner * implementations which can be associated to a particular irq line of
10577d828062SThomas Gleixner * an irq_chip_generic instance. That allows to share and protect
10587d828062SThomas Gleixner * state in an irq_chip_generic instance when we need to implement
10597d828062SThomas Gleixner * different flow mechanisms (level/edge) for it.
10607d828062SThomas Gleixner */
10617d828062SThomas Gleixner struct irq_chip_generic {
10627d828062SThomas Gleixner raw_spinlock_t lock;
10637d828062SThomas Gleixner void __iomem *reg_base;
10642b280376SKevin Cernekee u32 (*reg_readl)(void __iomem *addr);
10652b280376SKevin Cernekee void (*reg_writel)(u32 val, void __iomem *addr);
1066be9b22b6SBrian Norris void (*suspend)(struct irq_chip_generic *gc);
1067be9b22b6SBrian Norris void (*resume)(struct irq_chip_generic *gc);
10687d828062SThomas Gleixner unsigned int irq_base;
10697d828062SThomas Gleixner unsigned int irq_cnt;
10707d828062SThomas Gleixner u32 mask_cache;
10717d828062SThomas Gleixner u32 type_cache;
10727d828062SThomas Gleixner u32 polarity_cache;
10737d828062SThomas Gleixner u32 wake_enabled;
10747d828062SThomas Gleixner u32 wake_active;
10757d828062SThomas Gleixner unsigned int num_ct;
10767d828062SThomas Gleixner void *private;
1077088f40b7SThomas Gleixner unsigned long installed;
1078e8bd834fSGrant Likely unsigned long unused;
1079088f40b7SThomas Gleixner struct irq_domain *domain;
1080cfefd21eSThomas Gleixner struct list_head list;
10817856e9f1SGustavo A. R. Silva struct irq_chip_type chip_types[];
10827d828062SThomas Gleixner };
10837d828062SThomas Gleixner
10847d828062SThomas Gleixner /**
10857d828062SThomas Gleixner * enum irq_gc_flags - Initialization flags for generic irq chips
10867d828062SThomas Gleixner * @IRQ_GC_INIT_MASK_CACHE: Initialize the mask_cache by reading mask reg
10877d828062SThomas Gleixner * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for
10887d828062SThomas Gleixner * irq chips which need to call irq_set_wake() on
10897d828062SThomas Gleixner * the parent irq. Usually GPIO implementations
1090af80b0feSGerlando Falauto * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private
1091966dc736SThomas Gleixner * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask
1092b7905595SKevin Cernekee * @IRQ_GC_BE_IO: Use big-endian register accesses (default: LE)
10937d828062SThomas Gleixner */
10947d828062SThomas Gleixner enum irq_gc_flags {
10957d828062SThomas Gleixner IRQ_GC_INIT_MASK_CACHE = 1 << 0,
10967d828062SThomas Gleixner IRQ_GC_INIT_NESTED_LOCK = 1 << 1,
1097af80b0feSGerlando Falauto IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2,
1098966dc736SThomas Gleixner IRQ_GC_NO_MASK = 1 << 3,
1099b7905595SKevin Cernekee IRQ_GC_BE_IO = 1 << 4,
11007d828062SThomas Gleixner };
11017d828062SThomas Gleixner
1102088f40b7SThomas Gleixner /*
1103088f40b7SThomas Gleixner * struct irq_domain_chip_generic - Generic irq chip data structure for irq domains
1104088f40b7SThomas Gleixner * @irqs_per_chip: Number of interrupts per chip
1105088f40b7SThomas Gleixner * @num_chips: Number of chips
1106088f40b7SThomas Gleixner * @irq_flags_to_set: IRQ* flags to set on irq setup
1107088f40b7SThomas Gleixner * @irq_flags_to_clear: IRQ* flags to clear on irq setup
1108088f40b7SThomas Gleixner * @gc_flags: Generic chip specific setup flags
1109088f40b7SThomas Gleixner * @gc: Array of pointers to generic interrupt chips
1110088f40b7SThomas Gleixner */
1111088f40b7SThomas Gleixner struct irq_domain_chip_generic {
1112088f40b7SThomas Gleixner unsigned int irqs_per_chip;
1113088f40b7SThomas Gleixner unsigned int num_chips;
1114088f40b7SThomas Gleixner unsigned int irq_flags_to_clear;
1115088f40b7SThomas Gleixner unsigned int irq_flags_to_set;
1116088f40b7SThomas Gleixner enum irq_gc_flags gc_flags;
11177856e9f1SGustavo A. R. Silva struct irq_chip_generic *gc[];
1118088f40b7SThomas Gleixner };
1119088f40b7SThomas Gleixner
11207d828062SThomas Gleixner /* Generic chip callback functions */
11217d828062SThomas Gleixner void irq_gc_noop(struct irq_data *d);
11227d828062SThomas Gleixner void irq_gc_mask_disable_reg(struct irq_data *d);
11237d828062SThomas Gleixner void irq_gc_mask_set_bit(struct irq_data *d);
11247d828062SThomas Gleixner void irq_gc_mask_clr_bit(struct irq_data *d);
11257d828062SThomas Gleixner void irq_gc_unmask_enable_reg(struct irq_data *d);
1126659fb32dSSimon Guinot void irq_gc_ack_set_bit(struct irq_data *d);
1127659fb32dSSimon Guinot void irq_gc_ack_clr_bit(struct irq_data *d);
112820608924SDoug Berger void irq_gc_mask_disable_and_ack_set(struct irq_data *d);
11297d828062SThomas Gleixner void irq_gc_eoi(struct irq_data *d);
11307d828062SThomas Gleixner int irq_gc_set_wake(struct irq_data *d, unsigned int on);
11317d828062SThomas Gleixner
11327d828062SThomas Gleixner /* Setup functions for irq_chip_generic */
1133a5152c8aSBoris BREZILLON int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
1134a5152c8aSBoris BREZILLON irq_hw_number_t hw_irq);
1135d319a299SJianmin Lv void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq);
11367d828062SThomas Gleixner struct irq_chip_generic *
11377d828062SThomas Gleixner irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base,
11387d828062SThomas Gleixner void __iomem *reg_base, irq_flow_handler_t handler);
11397d828062SThomas Gleixner void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
11407d828062SThomas Gleixner enum irq_gc_flags flags, unsigned int clr,
11417d828062SThomas Gleixner unsigned int set);
11427d828062SThomas Gleixner int irq_setup_alt_chip(struct irq_data *d, unsigned int type);
1143cfefd21eSThomas Gleixner void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
1144cfefd21eSThomas Gleixner unsigned int clr, unsigned int set);
11457d828062SThomas Gleixner
11461c3e3630SBartosz Golaszewski struct irq_chip_generic *
11471c3e3630SBartosz Golaszewski devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct,
11481c3e3630SBartosz Golaszewski unsigned int irq_base, void __iomem *reg_base,
11491c3e3630SBartosz Golaszewski irq_flow_handler_t handler);
115030fd8fc5SBartosz Golaszewski int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
115130fd8fc5SBartosz Golaszewski u32 msk, enum irq_gc_flags flags,
115230fd8fc5SBartosz Golaszewski unsigned int clr, unsigned int set);
11531c3e3630SBartosz Golaszewski
1154088f40b7SThomas Gleixner struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
1155f88eecfeSSebastian Frias
1156f88eecfeSSebastian Frias int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
1157088f40b7SThomas Gleixner int num_ct, const char *name,
1158088f40b7SThomas Gleixner irq_flow_handler_t handler,
1159088f40b7SThomas Gleixner unsigned int clr, unsigned int set,
1160088f40b7SThomas Gleixner enum irq_gc_flags flags);
1161088f40b7SThomas Gleixner
1162f88eecfeSSebastian Frias #define irq_alloc_domain_generic_chips(d, irqs_per_chip, num_ct, name, \
1163f88eecfeSSebastian Frias handler, clr, set, flags) \
1164f88eecfeSSebastian Frias ({ \
1165f88eecfeSSebastian Frias MAYBE_BUILD_BUG_ON(irqs_per_chip > 32); \
1166f88eecfeSSebastian Frias __irq_alloc_domain_generic_chips(d, irqs_per_chip, num_ct, name,\
1167f88eecfeSSebastian Frias handler, clr, set, flags); \
1168f88eecfeSSebastian Frias })
1169088f40b7SThomas Gleixner
irq_free_generic_chip(struct irq_chip_generic * gc)1170707188f5SBartosz Golaszewski static inline void irq_free_generic_chip(struct irq_chip_generic *gc)
1171707188f5SBartosz Golaszewski {
1172707188f5SBartosz Golaszewski kfree(gc);
1173707188f5SBartosz Golaszewski }
1174707188f5SBartosz Golaszewski
irq_destroy_generic_chip(struct irq_chip_generic * gc,u32 msk,unsigned int clr,unsigned int set)117532bb6cbbSBartosz Golaszewski static inline void irq_destroy_generic_chip(struct irq_chip_generic *gc,
117632bb6cbbSBartosz Golaszewski u32 msk, unsigned int clr,
117732bb6cbbSBartosz Golaszewski unsigned int set)
117832bb6cbbSBartosz Golaszewski {
117932bb6cbbSBartosz Golaszewski irq_remove_generic_chip(gc, msk, clr, set);
118032bb6cbbSBartosz Golaszewski irq_free_generic_chip(gc);
118132bb6cbbSBartosz Golaszewski }
118232bb6cbbSBartosz Golaszewski
irq_data_get_chip_type(struct irq_data * d)11837d828062SThomas Gleixner static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d)
11847d828062SThomas Gleixner {
11857d828062SThomas Gleixner return container_of(d->chip, struct irq_chip_type, chip);
11867d828062SThomas Gleixner }
11877d828062SThomas Gleixner
11887d828062SThomas Gleixner #define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX)
11897d828062SThomas Gleixner
11907d828062SThomas Gleixner #ifdef CONFIG_SMP
irq_gc_lock(struct irq_chip_generic * gc)11917d828062SThomas Gleixner static inline void irq_gc_lock(struct irq_chip_generic *gc)
11927d828062SThomas Gleixner {
11937d828062SThomas Gleixner raw_spin_lock(&gc->lock);
11947d828062SThomas Gleixner }
11957d828062SThomas Gleixner
irq_gc_unlock(struct irq_chip_generic * gc)11967d828062SThomas Gleixner static inline void irq_gc_unlock(struct irq_chip_generic *gc)
11977d828062SThomas Gleixner {
11987d828062SThomas Gleixner raw_spin_unlock(&gc->lock);
11997d828062SThomas Gleixner }
12007d828062SThomas Gleixner #else
irq_gc_lock(struct irq_chip_generic * gc)12017d828062SThomas Gleixner static inline void irq_gc_lock(struct irq_chip_generic *gc) { }
irq_gc_unlock(struct irq_chip_generic * gc)12027d828062SThomas Gleixner static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
12037d828062SThomas Gleixner #endif
12047d828062SThomas Gleixner
1205ebf9ff75SBoris Brezillon /*
1206ebf9ff75SBoris Brezillon * The irqsave variants are for usage in non interrupt code. Do not use
1207ebf9ff75SBoris Brezillon * them in irq_chip callbacks. Use irq_gc_lock() instead.
1208ebf9ff75SBoris Brezillon */
1209ebf9ff75SBoris Brezillon #define irq_gc_lock_irqsave(gc, flags) \
1210ebf9ff75SBoris Brezillon raw_spin_lock_irqsave(&(gc)->lock, flags)
1211ebf9ff75SBoris Brezillon
1212ebf9ff75SBoris Brezillon #define irq_gc_unlock_irqrestore(gc, flags) \
1213ebf9ff75SBoris Brezillon raw_spin_unlock_irqrestore(&(gc)->lock, flags)
1214ebf9ff75SBoris Brezillon
irq_reg_writel(struct irq_chip_generic * gc,u32 val,int reg_offset)1215332fd7c4SKevin Cernekee static inline void irq_reg_writel(struct irq_chip_generic *gc,
1216332fd7c4SKevin Cernekee u32 val, int reg_offset)
1217332fd7c4SKevin Cernekee {
12182b280376SKevin Cernekee if (gc->reg_writel)
12192b280376SKevin Cernekee gc->reg_writel(val, gc->reg_base + reg_offset);
12202b280376SKevin Cernekee else
1221332fd7c4SKevin Cernekee writel(val, gc->reg_base + reg_offset);
1222332fd7c4SKevin Cernekee }
1223332fd7c4SKevin Cernekee
irq_reg_readl(struct irq_chip_generic * gc,int reg_offset)1224332fd7c4SKevin Cernekee static inline u32 irq_reg_readl(struct irq_chip_generic *gc,
1225332fd7c4SKevin Cernekee int reg_offset)
1226332fd7c4SKevin Cernekee {
12272b280376SKevin Cernekee if (gc->reg_readl)
12282b280376SKevin Cernekee return gc->reg_readl(gc->reg_base + reg_offset);
12292b280376SKevin Cernekee else
1230332fd7c4SKevin Cernekee return readl(gc->reg_base + reg_offset);
1231332fd7c4SKevin Cernekee }
1232332fd7c4SKevin Cernekee
12332f75d9e1SThomas Gleixner struct irq_matrix;
12342f75d9e1SThomas Gleixner struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits,
12352f75d9e1SThomas Gleixner unsigned int alloc_start,
12362f75d9e1SThomas Gleixner unsigned int alloc_end);
12372f75d9e1SThomas Gleixner void irq_matrix_online(struct irq_matrix *m);
12382f75d9e1SThomas Gleixner void irq_matrix_offline(struct irq_matrix *m);
12392f75d9e1SThomas Gleixner void irq_matrix_assign_system(struct irq_matrix *m, unsigned int bit, bool replace);
12402f75d9e1SThomas Gleixner int irq_matrix_reserve_managed(struct irq_matrix *m, const struct cpumask *msk);
12412f75d9e1SThomas Gleixner void irq_matrix_remove_managed(struct irq_matrix *m, const struct cpumask *msk);
124276f99ae5SDou Liyang int irq_matrix_alloc_managed(struct irq_matrix *m, const struct cpumask *msk,
124376f99ae5SDou Liyang unsigned int *mapped_cpu);
12442f75d9e1SThomas Gleixner void irq_matrix_reserve(struct irq_matrix *m);
12452f75d9e1SThomas Gleixner void irq_matrix_remove_reserved(struct irq_matrix *m);
12462f75d9e1SThomas Gleixner int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
12472f75d9e1SThomas Gleixner bool reserved, unsigned int *mapped_cpu);
12482f75d9e1SThomas Gleixner void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
12492f75d9e1SThomas Gleixner unsigned int bit, bool managed);
12502f75d9e1SThomas Gleixner void irq_matrix_assign(struct irq_matrix *m, unsigned int bit);
12512f75d9e1SThomas Gleixner unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown);
12522f75d9e1SThomas Gleixner unsigned int irq_matrix_allocated(struct irq_matrix *m);
12532f75d9e1SThomas Gleixner unsigned int irq_matrix_reserved(struct irq_matrix *m);
12542f75d9e1SThomas Gleixner void irq_matrix_debug_show(struct seq_file *sf, struct irq_matrix *m, int ind);
12552f75d9e1SThomas Gleixner
1256d17bf24eSQais Yousef /* Contrary to Linux irqs, for hardware irqs the irq number 0 is valid */
1257d17bf24eSQais Yousef #define INVALID_HWIRQ (~0UL)
1258f9bce791SQais Yousef irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu);
12593b8e29a8SQais Yousef int __ipi_send_single(struct irq_desc *desc, unsigned int cpu);
12603b8e29a8SQais Yousef int __ipi_send_mask(struct irq_desc *desc, const struct cpumask *dest);
12613b8e29a8SQais Yousef int ipi_send_single(unsigned int virq, unsigned int cpu);
12623b8e29a8SQais Yousef int ipi_send_mask(unsigned int virq, const struct cpumask *dest);
1263d17bf24eSQais Yousef
1264835a486cSAnup Patel void ipi_mux_process(void);
1265835a486cSAnup Patel int ipi_mux_create(unsigned int nr_ipi, void (*mux_send)(unsigned int cpu));
1266835a486cSAnup Patel
1267caacdbf4SPalmer Dabbelt #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
1268caacdbf4SPalmer Dabbelt /*
1269caacdbf4SPalmer Dabbelt * Registers a generic IRQ handling function as the top-level IRQ handler in
1270caacdbf4SPalmer Dabbelt * the system, which is generally the first C code called from an assembly
1271caacdbf4SPalmer Dabbelt * architecture-specific interrupt handler.
1272caacdbf4SPalmer Dabbelt *
1273caacdbf4SPalmer Dabbelt * Returns 0 on success, or -EBUSY if an IRQ handler has already been
1274caacdbf4SPalmer Dabbelt * registered.
1275caacdbf4SPalmer Dabbelt */
1276caacdbf4SPalmer Dabbelt int __init set_handle_irq(void (*handle_irq)(struct pt_regs *));
1277caacdbf4SPalmer Dabbelt
1278caacdbf4SPalmer Dabbelt /*
1279caacdbf4SPalmer Dabbelt * Allows interrupt handlers to find the irqchip that's been registered as the
1280caacdbf4SPalmer Dabbelt * top-level IRQ handler.
1281caacdbf4SPalmer Dabbelt */
1282caacdbf4SPalmer Dabbelt extern void (*handle_arch_irq)(struct pt_regs *) __ro_after_init;
1283a1b09501SMark Rutland asmlinkage void generic_handle_arch_irq(struct pt_regs *regs);
1284ea0c80d1SZhen Lei #else
1285b0b8b689SMarc Zyngier #ifndef set_handle_irq
1286ea0c80d1SZhen Lei #define set_handle_irq(handle_irq) \
1287ea0c80d1SZhen Lei do { \
1288ea0c80d1SZhen Lei (void)handle_irq; \
1289ea0c80d1SZhen Lei WARN_ON(1); \
1290ea0c80d1SZhen Lei } while (0)
1291caacdbf4SPalmer Dabbelt #endif
1292b0b8b689SMarc Zyngier #endif
1293caacdbf4SPalmer Dabbelt
129406fcb0c6SIngo Molnar #endif /* _LINUX_IRQ_H */
1295