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)
6792068d17SMika Westerberg * IRQ_NESTED_THREAD - Interrupt nests into another thread
6831d9d9b6SMarc Zyngier * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
69b39898cdSThomas Gleixner * IRQ_IS_POLLED - Always polled by another interrupt. Exclude
70b39898cdSThomas Gleixner * it from the spurious interrupt detection
71b39898cdSThomas Gleixner * mechanism and from core side polling.
72e9849777SThomas Gleixner * IRQ_DISABLE_UNLAZY - Disable lazy irq disable
7383cfac95SMarc Zyngier * IRQ_HIDDEN - Don't show up in /proc/interrupts
74c2b1063eSThomas Gleixner * IRQ_NO_DEBUG - Exclude from note_interrupt() debugging
751da177e4SLinus Torvalds */
765d4d8fc9SThomas Gleixner enum {
775d4d8fc9SThomas Gleixner IRQ_TYPE_NONE = 0x00000000,
785d4d8fc9SThomas Gleixner IRQ_TYPE_EDGE_RISING = 0x00000001,
795d4d8fc9SThomas Gleixner IRQ_TYPE_EDGE_FALLING = 0x00000002,
805d4d8fc9SThomas Gleixner IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
815d4d8fc9SThomas Gleixner IRQ_TYPE_LEVEL_HIGH = 0x00000004,
825d4d8fc9SThomas Gleixner IRQ_TYPE_LEVEL_LOW = 0x00000008,
835d4d8fc9SThomas Gleixner IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),
845d4d8fc9SThomas Gleixner IRQ_TYPE_SENSE_MASK = 0x0000000f,
853fca40c7SBenjamin Herrenschmidt IRQ_TYPE_DEFAULT = IRQ_TYPE_SENSE_MASK,
86876dbd4cSThomas Gleixner
875d4d8fc9SThomas Gleixner IRQ_TYPE_PROBE = 0x00000010,
886e213616SThomas Gleixner
895d4d8fc9SThomas Gleixner IRQ_LEVEL = (1 << 8),
905d4d8fc9SThomas Gleixner IRQ_PER_CPU = (1 << 9),
915d4d8fc9SThomas Gleixner IRQ_NOPROBE = (1 << 10),
925d4d8fc9SThomas Gleixner IRQ_NOREQUEST = (1 << 11),
935d4d8fc9SThomas Gleixner IRQ_NOAUTOEN = (1 << 12),
945d4d8fc9SThomas Gleixner IRQ_NO_BALANCING = (1 << 13),
955d4d8fc9SThomas Gleixner IRQ_NESTED_THREAD = (1 << 15),
967f1b1244SPaul Mundt IRQ_NOTHREAD = (1 << 16),
9731d9d9b6SMarc Zyngier IRQ_PER_CPU_DEVID = (1 << 17),
98b39898cdSThomas Gleixner IRQ_IS_POLLED = (1 << 18),
99e9849777SThomas Gleixner IRQ_DISABLE_UNLAZY = (1 << 19),
10083cfac95SMarc Zyngier IRQ_HIDDEN = (1 << 20),
101c2b1063eSThomas Gleixner IRQ_NO_DEBUG = (1 << 21),
1025d4d8fc9SThomas Gleixner };
103950f4427SThomas Gleixner
10444247184SThomas Gleixner #define IRQF_MODIFY_MASK \
10544247184SThomas Gleixner (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
106f94a1824SThomas Gleixner IRQ_NOAUTOEN | IRQ_LEVEL | IRQ_NO_BALANCING | \
107b39898cdSThomas Gleixner IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \
10883cfac95SMarc Zyngier IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_HIDDEN)
10944247184SThomas Gleixner
110950f4427SThomas Gleixner #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
1111da177e4SLinus Torvalds
1123b8249e7SThomas Gleixner /*
1133b8249e7SThomas Gleixner * Return value for chip->irq_set_affinity()
1143b8249e7SThomas Gleixner *
1159df872faSJiang Liu * IRQ_SET_MASK_OK - OK, core updates irq_common_data.affinity
11663752ad1SAndy Shevchenko * IRQ_SET_MASK_NOCOPY - OK, chip did update irq_common_data.affinity
1172cb62547SJiang Liu * IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to
1182cb62547SJiang Liu * support stacked irqchips, which indicates skipping
119a359f757SIngo Molnar * all descendant irqchips.
1203b8249e7SThomas Gleixner */
1213b8249e7SThomas Gleixner enum {
1223b8249e7SThomas Gleixner IRQ_SET_MASK_OK = 0,
1233b8249e7SThomas Gleixner IRQ_SET_MASK_OK_NOCOPY,
1242cb62547SJiang Liu IRQ_SET_MASK_OK_DONE,
1253b8249e7SThomas Gleixner };
1263b8249e7SThomas Gleixner
1275b912c10SEric W. Biederman struct msi_desc;
12808a543adSGrant Likely struct irq_domain;
1296a6de9efSThomas Gleixner
1308fee5c36SIngo Molnar /**
1310d0b4c86SJiang Liu * struct irq_common_data - per irq data shared by all irqchips
1320d0b4c86SJiang Liu * @state_use_accessors: status information for irq chip functions.
1330d0b4c86SJiang Liu * Use accessor functions to deal with it
134449e9caeSJiang Liu * @node: node index useful for balancing
135af7080e0SJiang Liu * @handler_data: per-IRQ data for the irq_chip methods
136955bfe59SQais Yousef * @affinity: IRQ affinity on SMP. If this is an IPI
137955bfe59SQais Yousef * related irq, then this is the mask of the
138955bfe59SQais Yousef * CPUs to which an IPI can be sent.
1390d3f5425SThomas Gleixner * @effective_affinity: The effective IRQ affinity on SMP as some irq
1400d3f5425SThomas Gleixner * chips do not allow multi CPU destinations.
1410d3f5425SThomas Gleixner * A subset of @affinity.
142b237721cSJiang Liu * @msi_desc: MSI descriptor
143f256c9a0SQais Yousef * @ipi_offset: Offset of first IPI target cpu in @affinity. Optional.
1440d0b4c86SJiang Liu */
1450d0b4c86SJiang Liu struct irq_common_data {
146b354286eSBoqun Feng unsigned int __private state_use_accessors;
147449e9caeSJiang Liu #ifdef CONFIG_NUMA
148449e9caeSJiang Liu unsigned int node;
149449e9caeSJiang Liu #endif
150af7080e0SJiang Liu void *handler_data;
151b237721cSJiang Liu struct msi_desc *msi_desc;
152aa081358SSamuel Holland #ifdef CONFIG_SMP
1539df872faSJiang Liu cpumask_var_t affinity;
154aa081358SSamuel Holland #endif
1550d3f5425SThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
1560d3f5425SThomas Gleixner cpumask_var_t effective_affinity;
1570d3f5425SThomas Gleixner #endif
158f256c9a0SQais Yousef #ifdef CONFIG_GENERIC_IRQ_IPI
159f256c9a0SQais Yousef unsigned int ipi_offset;
160f256c9a0SQais Yousef #endif
1610d0b4c86SJiang Liu };
1620d0b4c86SJiang Liu
1630d0b4c86SJiang Liu /**
1640d0b4c86SJiang Liu * struct irq_data - per irq chip data passed down to chip functions
165966dc736SThomas Gleixner * @mask: precomputed bitmask for accessing the chip registers
166ff7dcd44SThomas Gleixner * @irq: interrupt number
16708a543adSGrant Likely * @hwirq: hardware interrupt number, local to the interrupt domain
1680d0b4c86SJiang Liu * @common: point to data shared by all irqchips
169ff7dcd44SThomas Gleixner * @chip: low level interrupt hardware access
17008a543adSGrant Likely * @domain: Interrupt translation domain; responsible for mapping
17108a543adSGrant Likely * between hwirq number and linux irq number.
172f8264e34SJiang Liu * @parent_data: pointer to parent struct irq_data to support hierarchy
173f8264e34SJiang Liu * irq_domain
174ff7dcd44SThomas Gleixner * @chip_data: platform-specific per-chip private data for the chip
175ff7dcd44SThomas Gleixner * methods, to allow shared chip implementations
176ff7dcd44SThomas Gleixner */
177ff7dcd44SThomas Gleixner struct irq_data {
178966dc736SThomas Gleixner u32 mask;
179ff7dcd44SThomas Gleixner unsigned int irq;
180d22083a5SDawei Li irq_hw_number_t hwirq;
1810d0b4c86SJiang Liu struct irq_common_data *common;
182ff7dcd44SThomas Gleixner struct irq_chip *chip;
18308a543adSGrant Likely struct irq_domain *domain;
184f8264e34SJiang Liu #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
185f8264e34SJiang Liu struct irq_data *parent_data;
186f8264e34SJiang Liu #endif
187ff7dcd44SThomas Gleixner void *chip_data;
188ff7dcd44SThomas Gleixner };
189ff7dcd44SThomas Gleixner
190f230b6d5SThomas Gleixner /*
1910d0b4c86SJiang Liu * Bit masks for irq_common_data.state_use_accessors
192f230b6d5SThomas Gleixner *
193876dbd4cSThomas Gleixner * IRQD_TRIGGER_MASK - Mask for the trigger type bits
194f230b6d5SThomas Gleixner * IRQD_SETAFFINITY_PENDING - Affinity setting is pending
19508d85f3eSMarc Zyngier * IRQD_ACTIVATED - Interrupt has already been activated
196a005677bSThomas Gleixner * IRQD_NO_BALANCING - Balancing disabled for this IRQ
197a005677bSThomas Gleixner * IRQD_PER_CPU - Interrupt is per cpu
1982bdd1055SThomas Gleixner * IRQD_AFFINITY_SET - Interrupt affinity was set
199876dbd4cSThomas Gleixner * IRQD_LEVEL - Interrupt is level triggered
2007f94226fSThomas Gleixner * IRQD_WAKEUP_STATE - Interrupt is configured for wakeup
2017f94226fSThomas Gleixner * from suspend
20232f4125eSThomas Gleixner * IRQD_IRQ_DISABLED - Disabled state of the interrupt
20332f4125eSThomas Gleixner * IRQD_IRQ_MASKED - Masked state of the interrupt
20432f4125eSThomas Gleixner * IRQD_IRQ_INPROGRESS - In progress state of the interrupt
205b76f1674SThomas Gleixner * IRQD_WAKEUP_ARMED - Wakeup mode armed
206fc569712SThomas Gleixner * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU
2079c255583SThomas Gleixner * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel
2081bb04016SThomas Gleixner * IRQD_IRQ_STARTED - Startup state of the interrupt
20954fdf6a0SThomas Gleixner * IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity
21054fdf6a0SThomas Gleixner * mask. Applies only to affinity managed irqs.
211d52dd441SThomas Gleixner * IRQD_SINGLE_TARGET - IRQ allows only a single affinity target
2124f8413a3SMarc Zyngier * IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set
21369790ba9SThomas Gleixner * IRQD_CAN_RESERVE - Can use reservation mode
214c16816acSThomas Gleixner * IRQD_HANDLE_ENFORCE_IRQCTX - Enforce that handle_irq_*() is only invoked
215c16816acSThomas Gleixner * from actual interrupt context.
216f0c7bacaSThomas Gleixner * IRQD_AFFINITY_ON_ACTIVATE - Affinity is set on activation. Don't call
217f0c7bacaSThomas Gleixner * irq_chip::irq_set_affinity() when deactivated.
21890428a8eSMaulik Shah * IRQD_IRQ_ENABLED_ON_SUSPEND - Interrupt is enabled on suspend by irq pm if
21990428a8eSMaulik Shah * irqchip have flag IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND set.
2209c15eeb5SJames Gowans * IRQD_RESEND_WHEN_IN_PROGRESS - Interrupt may fire when already in progress in which
2219c15eeb5SJames Gowans * case it must be resent at the next available opportunity.
222f230b6d5SThomas Gleixner */
223f230b6d5SThomas Gleixner enum {
224876dbd4cSThomas Gleixner IRQD_TRIGGER_MASK = 0xf,
2250cfb4a1aSMarc Zyngier IRQD_SETAFFINITY_PENDING = BIT(8),
2260cfb4a1aSMarc Zyngier IRQD_ACTIVATED = BIT(9),
2270cfb4a1aSMarc Zyngier IRQD_NO_BALANCING = BIT(10),
2280cfb4a1aSMarc Zyngier IRQD_PER_CPU = BIT(11),
2290cfb4a1aSMarc Zyngier IRQD_AFFINITY_SET = BIT(12),
2300cfb4a1aSMarc Zyngier IRQD_LEVEL = BIT(13),
2310cfb4a1aSMarc Zyngier IRQD_WAKEUP_STATE = BIT(14),
2320cfb4a1aSMarc Zyngier IRQD_IRQ_DISABLED = BIT(16),
2330cfb4a1aSMarc Zyngier IRQD_IRQ_MASKED = BIT(17),
2340cfb4a1aSMarc Zyngier IRQD_IRQ_INPROGRESS = BIT(18),
2350cfb4a1aSMarc Zyngier IRQD_WAKEUP_ARMED = BIT(19),
2360cfb4a1aSMarc Zyngier IRQD_FORWARDED_TO_VCPU = BIT(20),
2370cfb4a1aSMarc Zyngier IRQD_AFFINITY_MANAGED = BIT(21),
2380cfb4a1aSMarc Zyngier IRQD_IRQ_STARTED = BIT(22),
2390cfb4a1aSMarc Zyngier IRQD_MANAGED_SHUTDOWN = BIT(23),
2400cfb4a1aSMarc Zyngier IRQD_SINGLE_TARGET = BIT(24),
2410cfb4a1aSMarc Zyngier IRQD_DEFAULT_TRIGGER_SET = BIT(25),
2420cfb4a1aSMarc Zyngier IRQD_CAN_RESERVE = BIT(26),
243b56ebe7cSKoichiro Den IRQD_HANDLE_ENFORCE_IRQCTX = BIT(27),
244b56ebe7cSKoichiro Den IRQD_AFFINITY_ON_ACTIVATE = BIT(28),
245b56ebe7cSKoichiro Den IRQD_IRQ_ENABLED_ON_SUSPEND = BIT(29),
246b56ebe7cSKoichiro Den IRQD_RESEND_WHEN_IN_PROGRESS = BIT(30),
247f230b6d5SThomas Gleixner };
248f230b6d5SThomas Gleixner
249b354286eSBoqun Feng #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
2500d0b4c86SJiang Liu
irqd_is_setaffinity_pending(struct irq_data * d)251f230b6d5SThomas Gleixner static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
252f230b6d5SThomas Gleixner {
2530d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
254f230b6d5SThomas Gleixner }
255f230b6d5SThomas Gleixner
irqd_is_per_cpu(struct irq_data * d)256a005677bSThomas Gleixner static inline bool irqd_is_per_cpu(struct irq_data *d)
257a005677bSThomas Gleixner {
2580d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_PER_CPU;
259a005677bSThomas Gleixner }
260a005677bSThomas Gleixner
irqd_can_balance(struct irq_data * d)261a005677bSThomas Gleixner static inline bool irqd_can_balance(struct irq_data *d)
262a005677bSThomas Gleixner {
2630d0b4c86SJiang Liu return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
264a005677bSThomas Gleixner }
265a005677bSThomas Gleixner
irqd_affinity_was_set(struct irq_data * d)2662bdd1055SThomas Gleixner static inline bool irqd_affinity_was_set(struct irq_data *d)
2672bdd1055SThomas Gleixner {
2680d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_AFFINITY_SET;
2692bdd1055SThomas Gleixner }
2702bdd1055SThomas Gleixner
irqd_mark_affinity_was_set(struct irq_data * d)271ee38c04bSThomas Gleixner static inline void irqd_mark_affinity_was_set(struct irq_data *d)
272ee38c04bSThomas Gleixner {
2730d0b4c86SJiang Liu __irqd_to_state(d) |= IRQD_AFFINITY_SET;
274ee38c04bSThomas Gleixner }
275ee38c04bSThomas Gleixner
irqd_trigger_type_was_set(struct irq_data * d)2764f8413a3SMarc Zyngier static inline bool irqd_trigger_type_was_set(struct irq_data *d)
2774f8413a3SMarc Zyngier {
2784f8413a3SMarc Zyngier return __irqd_to_state(d) & IRQD_DEFAULT_TRIGGER_SET;
2794f8413a3SMarc Zyngier }
2804f8413a3SMarc Zyngier
irqd_get_trigger_type(struct irq_data * d)281876dbd4cSThomas Gleixner static inline u32 irqd_get_trigger_type(struct irq_data *d)
282876dbd4cSThomas Gleixner {
2830d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
284876dbd4cSThomas Gleixner }
285876dbd4cSThomas Gleixner
286876dbd4cSThomas Gleixner /*
2874f8413a3SMarc Zyngier * Must only be called inside irq_chip.irq_set_type() functions or
2884f8413a3SMarc Zyngier * from the DT/ACPI setup code.
289876dbd4cSThomas Gleixner */
irqd_set_trigger_type(struct irq_data * d,u32 type)290876dbd4cSThomas Gleixner static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
291876dbd4cSThomas Gleixner {
2920d0b4c86SJiang Liu __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
2930d0b4c86SJiang Liu __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
2944f8413a3SMarc Zyngier __irqd_to_state(d) |= IRQD_DEFAULT_TRIGGER_SET;
295876dbd4cSThomas Gleixner }
296876dbd4cSThomas Gleixner
irqd_is_level_type(struct irq_data * d)297876dbd4cSThomas Gleixner static inline bool irqd_is_level_type(struct irq_data *d)
298876dbd4cSThomas Gleixner {
2990d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_LEVEL;
300876dbd4cSThomas Gleixner }
301876dbd4cSThomas Gleixner
302d52dd441SThomas Gleixner /*
303d52dd441SThomas Gleixner * Must only be called of irqchip.irq_set_affinity() or low level
304a359f757SIngo Molnar * hierarchy domain allocation functions.
305d52dd441SThomas Gleixner */
irqd_set_single_target(struct irq_data * d)306d52dd441SThomas Gleixner static inline void irqd_set_single_target(struct irq_data *d)
307d52dd441SThomas Gleixner {
308d52dd441SThomas Gleixner __irqd_to_state(d) |= IRQD_SINGLE_TARGET;
309d52dd441SThomas Gleixner }
310d52dd441SThomas Gleixner
irqd_is_single_target(struct irq_data * d)311d52dd441SThomas Gleixner static inline bool irqd_is_single_target(struct irq_data *d)
312d52dd441SThomas Gleixner {
313d52dd441SThomas Gleixner return __irqd_to_state(d) & IRQD_SINGLE_TARGET;
314d52dd441SThomas Gleixner }
315d52dd441SThomas Gleixner
irqd_set_handle_enforce_irqctx(struct irq_data * d)316c16816acSThomas Gleixner static inline void irqd_set_handle_enforce_irqctx(struct irq_data *d)
317c16816acSThomas Gleixner {
318c16816acSThomas Gleixner __irqd_to_state(d) |= IRQD_HANDLE_ENFORCE_IRQCTX;
319c16816acSThomas Gleixner }
320c16816acSThomas Gleixner
irqd_is_handle_enforce_irqctx(struct irq_data * d)321c16816acSThomas Gleixner static inline bool irqd_is_handle_enforce_irqctx(struct irq_data *d)
322c16816acSThomas Gleixner {
323c16816acSThomas Gleixner return __irqd_to_state(d) & IRQD_HANDLE_ENFORCE_IRQCTX;
324c16816acSThomas Gleixner }
325c16816acSThomas Gleixner
irqd_is_enabled_on_suspend(struct irq_data * d)32690428a8eSMaulik Shah static inline bool irqd_is_enabled_on_suspend(struct irq_data *d)
32790428a8eSMaulik Shah {
32890428a8eSMaulik Shah return __irqd_to_state(d) & IRQD_IRQ_ENABLED_ON_SUSPEND;
32990428a8eSMaulik Shah }
33090428a8eSMaulik Shah
irqd_is_wakeup_set(struct irq_data * d)3317f94226fSThomas Gleixner static inline bool irqd_is_wakeup_set(struct irq_data *d)
3327f94226fSThomas Gleixner {
3330d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
3347f94226fSThomas Gleixner }
3357f94226fSThomas Gleixner
irqd_irq_disabled(struct irq_data * d)336801a0e9aSThomas Gleixner static inline bool irqd_irq_disabled(struct irq_data *d)
337801a0e9aSThomas Gleixner {
3380d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
339801a0e9aSThomas Gleixner }
340801a0e9aSThomas Gleixner
irqd_irq_masked(struct irq_data * d)34132f4125eSThomas Gleixner static inline bool irqd_irq_masked(struct irq_data *d)
34232f4125eSThomas Gleixner {
3430d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_IRQ_MASKED;
34432f4125eSThomas Gleixner }
34532f4125eSThomas Gleixner
irqd_irq_inprogress(struct irq_data * d)34632f4125eSThomas Gleixner static inline bool irqd_irq_inprogress(struct irq_data *d)
34732f4125eSThomas Gleixner {
3480d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
34932f4125eSThomas Gleixner }
35032f4125eSThomas Gleixner
irqd_is_wakeup_armed(struct irq_data * d)351b76f1674SThomas Gleixner static inline bool irqd_is_wakeup_armed(struct irq_data *d)
352b76f1674SThomas Gleixner {
3530d0b4c86SJiang Liu return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
354b76f1674SThomas Gleixner }
355b76f1674SThomas Gleixner
irqd_is_forwarded_to_vcpu(struct irq_data * d)356fc569712SThomas Gleixner static inline bool irqd_is_forwarded_to_vcpu(struct irq_data *d)
357fc569712SThomas Gleixner {
358fc569712SThomas Gleixner return __irqd_to_state(d) & IRQD_FORWARDED_TO_VCPU;
359fc569712SThomas Gleixner }
360fc569712SThomas Gleixner
irqd_set_forwarded_to_vcpu(struct irq_data * d)361fc569712SThomas Gleixner static inline void irqd_set_forwarded_to_vcpu(struct irq_data *d)
362fc569712SThomas Gleixner {
363fc569712SThomas Gleixner __irqd_to_state(d) |= IRQD_FORWARDED_TO_VCPU;
364fc569712SThomas Gleixner }
365fc569712SThomas Gleixner
irqd_clr_forwarded_to_vcpu(struct irq_data * d)366fc569712SThomas Gleixner static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d)
367fc569712SThomas Gleixner {
368fc569712SThomas Gleixner __irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU;
369fc569712SThomas Gleixner }
370b76f1674SThomas Gleixner
irqd_affinity_is_managed(struct irq_data * d)3719c255583SThomas Gleixner static inline bool irqd_affinity_is_managed(struct irq_data *d)
3729c255583SThomas Gleixner {
3739c255583SThomas Gleixner return __irqd_to_state(d) & IRQD_AFFINITY_MANAGED;
3749c255583SThomas Gleixner }
3759c255583SThomas Gleixner
irqd_is_activated(struct irq_data * d)37608d85f3eSMarc Zyngier static inline bool irqd_is_activated(struct irq_data *d)
37708d85f3eSMarc Zyngier {
37808d85f3eSMarc Zyngier return __irqd_to_state(d) & IRQD_ACTIVATED;
37908d85f3eSMarc Zyngier }
38008d85f3eSMarc Zyngier
irqd_set_activated(struct irq_data * d)38108d85f3eSMarc Zyngier static inline void irqd_set_activated(struct irq_data *d)
38208d85f3eSMarc Zyngier {
38308d85f3eSMarc Zyngier __irqd_to_state(d) |= IRQD_ACTIVATED;
38408d85f3eSMarc Zyngier }
38508d85f3eSMarc Zyngier
irqd_clr_activated(struct irq_data * d)38608d85f3eSMarc Zyngier static inline void irqd_clr_activated(struct irq_data *d)
38708d85f3eSMarc Zyngier {
38808d85f3eSMarc Zyngier __irqd_to_state(d) &= ~IRQD_ACTIVATED;
38908d85f3eSMarc Zyngier }
39008d85f3eSMarc Zyngier
irqd_is_started(struct irq_data * d)391201d7f47SThomas Gleixner static inline bool irqd_is_started(struct irq_data *d)
392201d7f47SThomas Gleixner {
393201d7f47SThomas Gleixner return __irqd_to_state(d) & IRQD_IRQ_STARTED;
394201d7f47SThomas Gleixner }
395201d7f47SThomas Gleixner
irqd_is_managed_and_shutdown(struct irq_data * d)396761ea388SThomas Gleixner static inline bool irqd_is_managed_and_shutdown(struct irq_data *d)
39754fdf6a0SThomas Gleixner {
39854fdf6a0SThomas Gleixner return __irqd_to_state(d) & IRQD_MANAGED_SHUTDOWN;
39954fdf6a0SThomas Gleixner }
40054fdf6a0SThomas Gleixner
irqd_set_can_reserve(struct irq_data * d)40169790ba9SThomas Gleixner static inline void irqd_set_can_reserve(struct irq_data *d)
40269790ba9SThomas Gleixner {
40369790ba9SThomas Gleixner __irqd_to_state(d) |= IRQD_CAN_RESERVE;
40469790ba9SThomas Gleixner }
40569790ba9SThomas Gleixner
irqd_clr_can_reserve(struct irq_data * d)40669790ba9SThomas Gleixner static inline void irqd_clr_can_reserve(struct irq_data *d)
40769790ba9SThomas Gleixner {
40869790ba9SThomas Gleixner __irqd_to_state(d) &= ~IRQD_CAN_RESERVE;
40969790ba9SThomas Gleixner }
41069790ba9SThomas Gleixner
irqd_can_reserve(struct irq_data * d)41169790ba9SThomas Gleixner static inline bool irqd_can_reserve(struct irq_data *d)
41269790ba9SThomas Gleixner {
41369790ba9SThomas Gleixner return __irqd_to_state(d) & IRQD_CAN_RESERVE;
41469790ba9SThomas Gleixner }
41569790ba9SThomas Gleixner
irqd_set_affinity_on_activate(struct irq_data * d)416f0c7bacaSThomas Gleixner static inline void irqd_set_affinity_on_activate(struct irq_data *d)
417f0c7bacaSThomas Gleixner {
418f0c7bacaSThomas Gleixner __irqd_to_state(d) |= IRQD_AFFINITY_ON_ACTIVATE;
419f0c7bacaSThomas Gleixner }
420f0c7bacaSThomas Gleixner
irqd_affinity_on_activate(struct irq_data * d)421f0c7bacaSThomas Gleixner static inline bool irqd_affinity_on_activate(struct irq_data *d)
422f0c7bacaSThomas Gleixner {
423f0c7bacaSThomas Gleixner return __irqd_to_state(d) & IRQD_AFFINITY_ON_ACTIVATE;
424f0c7bacaSThomas Gleixner }
425f0c7bacaSThomas Gleixner
irqd_set_resend_when_in_progress(struct irq_data * d)4269c15eeb5SJames Gowans static inline void irqd_set_resend_when_in_progress(struct irq_data *d)
4279c15eeb5SJames Gowans {
4289c15eeb5SJames Gowans __irqd_to_state(d) |= IRQD_RESEND_WHEN_IN_PROGRESS;
4299c15eeb5SJames Gowans }
4309c15eeb5SJames Gowans
irqd_needs_resend_when_in_progress(struct irq_data * d)4319c15eeb5SJames Gowans static inline bool irqd_needs_resend_when_in_progress(struct irq_data *d)
4329c15eeb5SJames Gowans {
4339c15eeb5SJames Gowans return __irqd_to_state(d) & IRQD_RESEND_WHEN_IN_PROGRESS;
4349c15eeb5SJames Gowans }
4359c15eeb5SJames Gowans
436b354286eSBoqun Feng #undef __irqd_to_state
437b354286eSBoqun Feng
irqd_to_hwirq(struct irq_data * d)438a699e4e4SGrant Likely static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
439a699e4e4SGrant Likely {
440a699e4e4SGrant Likely return d->hwirq;
441a699e4e4SGrant Likely }
442a699e4e4SGrant Likely
443ff7dcd44SThomas Gleixner /**
4446a6de9efSThomas Gleixner * struct irq_chip - hardware interrupt chip descriptor
4458fee5c36SIngo Molnar *
4468fee5c36SIngo Molnar * @name: name for /proc/interrupts
447f8822657SThomas Gleixner * @irq_startup: start up the interrupt (defaults to ->enable if NULL)
448f8822657SThomas Gleixner * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL)
449f8822657SThomas Gleixner * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL)
450f8822657SThomas Gleixner * @irq_disable: disable the interrupt
451f8822657SThomas Gleixner * @irq_ack: start of a new interrupt
452f8822657SThomas Gleixner * @irq_mask: mask an interrupt source
453f8822657SThomas Gleixner * @irq_mask_ack: ack and mask an interrupt source
454f8822657SThomas Gleixner * @irq_unmask: unmask an interrupt source
455f8822657SThomas Gleixner * @irq_eoi: end of interrupt
45683979133SThomas Gleixner * @irq_set_affinity: Set the CPU affinity on SMP machines. If the force
45783979133SThomas Gleixner * argument is true, it tells the driver to
45883979133SThomas Gleixner * unconditionally apply the affinity setting. Sanity
45983979133SThomas Gleixner * checks against the supplied affinity mask are not
46083979133SThomas Gleixner * required. This is used for CPU hotplug where the
46183979133SThomas Gleixner * target CPU is not yet set in the cpu_online_mask.
462f8822657SThomas Gleixner * @irq_retrigger: resend an IRQ to the CPU
463f8822657SThomas Gleixner * @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
464f8822657SThomas Gleixner * @irq_set_wake: enable/disable power-management wake-on of an IRQ
465f8822657SThomas Gleixner * @irq_bus_lock: function to lock access to slow bus (i2c) chips
466f8822657SThomas Gleixner * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
4670fdb4b25SDavid Daney * @irq_cpu_online: configure an interrupt source for a secondary CPU
4680fdb4b25SDavid Daney * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU
469be9b22b6SBrian Norris * @irq_suspend: function called from core code on suspend once per
470be9b22b6SBrian Norris * chip, when one or more interrupts are installed
471be9b22b6SBrian Norris * @irq_resume: function called from core code on resume once per chip,
472be9b22b6SBrian Norris * when one ore more interrupts are installed
473cfefd21eSThomas Gleixner * @irq_pm_shutdown: function called from core code on shutdown once per chip
474d0051816SThomas Gleixner * @irq_calc_mask: Optional function to set irq_data.mask for special cases
475ab7798ffSThomas Gleixner * @irq_print_chip: optional to print special chip info in show_interrupts
476c1bacbaeSThomas Gleixner * @irq_request_resources: optional to request resources before calling
477c1bacbaeSThomas Gleixner * any other callback related to this irq
478c1bacbaeSThomas Gleixner * @irq_release_resources: optional to release resources acquired with
479c1bacbaeSThomas Gleixner * irq_request_resources
480515085efSJiang Liu * @irq_compose_msi_msg: optional to compose message content for MSI
4819dde55b7SJiang Liu * @irq_write_msi_msg: optional to write message content for MSI
4821b7047edSMarc Zyngier * @irq_get_irqchip_state: return the internal state of an interrupt
4831b7047edSMarc Zyngier * @irq_set_irqchip_state: set the internal state of a interrupt
4840a4377deSJiang Liu * @irq_set_vcpu_affinity: optional to target a vCPU in a virtual machine
48534dc1ae1SQais Yousef * @ipi_send_single: send a single IPI to destination cpus
48634dc1ae1SQais Yousef * @ipi_send_mask: send an IPI to destination cpus in cpumask
487b525903cSJulien Thierry * @irq_nmi_setup: function called from core code before enabling an NMI
488b525903cSJulien Thierry * @irq_nmi_teardown: function called from core code after disabling an NMI
489751dc837SThomas Gleixner * @irq_force_complete_move: optional function to force complete pending irq move
4902bff17adSThomas Gleixner * @flags: chip specific flags
4911da177e4SLinus Torvalds */
4926a6de9efSThomas Gleixner struct irq_chip {
4936a6de9efSThomas Gleixner const char *name;
494f8822657SThomas Gleixner unsigned int (*irq_startup)(struct irq_data *data);
495f8822657SThomas Gleixner void (*irq_shutdown)(struct irq_data *data);
496f8822657SThomas Gleixner void (*irq_enable)(struct irq_data *data);
497f8822657SThomas Gleixner void (*irq_disable)(struct irq_data *data);
498f8822657SThomas Gleixner
499f8822657SThomas Gleixner void (*irq_ack)(struct irq_data *data);
500f8822657SThomas Gleixner void (*irq_mask)(struct irq_data *data);
501f8822657SThomas Gleixner void (*irq_mask_ack)(struct irq_data *data);
502f8822657SThomas Gleixner void (*irq_unmask)(struct irq_data *data);
503f8822657SThomas Gleixner void (*irq_eoi)(struct irq_data *data);
504f8822657SThomas Gleixner
505f8822657SThomas Gleixner int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force);
506f8822657SThomas Gleixner int (*irq_retrigger)(struct irq_data *data);
507f8822657SThomas Gleixner int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);
508f8822657SThomas Gleixner int (*irq_set_wake)(struct irq_data *data, unsigned int on);
509f8822657SThomas Gleixner
510f8822657SThomas Gleixner void (*irq_bus_lock)(struct irq_data *data);
511f8822657SThomas Gleixner void (*irq_bus_sync_unlock)(struct irq_data *data);
512f8822657SThomas Gleixner
5138d15a729SMarc Zyngier #ifdef CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE
5140fdb4b25SDavid Daney void (*irq_cpu_online)(struct irq_data *data);
5150fdb4b25SDavid Daney void (*irq_cpu_offline)(struct irq_data *data);
5168d15a729SMarc Zyngier #endif
517cfefd21eSThomas Gleixner void (*irq_suspend)(struct irq_data *data);
518cfefd21eSThomas Gleixner void (*irq_resume)(struct irq_data *data);
519cfefd21eSThomas Gleixner void (*irq_pm_shutdown)(struct irq_data *data);
520cfefd21eSThomas Gleixner
521d0051816SThomas Gleixner void (*irq_calc_mask)(struct irq_data *data);
522d0051816SThomas Gleixner
523ab7798ffSThomas Gleixner void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
524c1bacbaeSThomas Gleixner int (*irq_request_resources)(struct irq_data *data);
525c1bacbaeSThomas Gleixner void (*irq_release_resources)(struct irq_data *data);
526ab7798ffSThomas Gleixner
527515085efSJiang Liu void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg);
5289dde55b7SJiang Liu void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg);
529515085efSJiang Liu
5301b7047edSMarc Zyngier int (*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state);
5311b7047edSMarc Zyngier int (*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state);
5321b7047edSMarc Zyngier
5330a4377deSJiang Liu int (*irq_set_vcpu_affinity)(struct irq_data *data, void *vcpu_info);
5340a4377deSJiang Liu
53534dc1ae1SQais Yousef void (*ipi_send_single)(struct irq_data *data, unsigned int cpu);
53634dc1ae1SQais Yousef void (*ipi_send_mask)(struct irq_data *data, const struct cpumask *dest);
53734dc1ae1SQais Yousef
538b525903cSJulien Thierry int (*irq_nmi_setup)(struct irq_data *data);
539b525903cSJulien Thierry void (*irq_nmi_teardown)(struct irq_data *data);
540b525903cSJulien Thierry
541751dc837SThomas Gleixner void (*irq_force_complete_move)(struct irq_data *data);
542751dc837SThomas Gleixner
5432bff17adSThomas Gleixner unsigned long flags;
5441da177e4SLinus Torvalds };
5451da177e4SLinus Torvalds
546d4d5e089SThomas Gleixner /*
547d4d5e089SThomas Gleixner * irq_chip specific flags
548d4d5e089SThomas Gleixner *
549d4d5e089SThomas Gleixner * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type()
55077694b40SThomas Gleixner * IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled
551d209a699SThomas Gleixner * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path
552b3d42232SThomas Gleixner * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks
553b3d42232SThomas Gleixner * when irq enabled
55460f96b41SSantosh Shilimkar * IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
5554f6e4f71SThomas Gleixner * IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask
556328a4978SThomas Gleixner * IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode
55790428a8eSMaulik Shah * IRQCHIP_SUPPORTS_LEVEL_MSI: Chip can provide two doorbells for Level MSIs
558b525903cSJulien Thierry * IRQCHIP_SUPPORTS_NMI: Chip can deliver NMIs, only for root irqchips
55990428a8eSMaulik Shah * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs
56090428a8eSMaulik Shah * in the suspend path if they are in disabled state
561826da771SThomas Gleixner * IRQCHIP_AFFINITY_PRE_STARTUP: Default affinity update before startup
5626c846d02SMarc Zyngier * IRQCHIP_IMMUTABLE: Don't ever change anything in this chip
563a648eb3aSThomas Gleixner * IRQCHIP_MOVE_DEFERRED: Move the interrupt in actual interrupt context
564d4d5e089SThomas Gleixner */
565d4d5e089SThomas Gleixner enum {
566d4d5e089SThomas Gleixner IRQCHIP_SET_TYPE_MASKED = (1 << 0),
56777694b40SThomas Gleixner IRQCHIP_EOI_IF_HANDLED = (1 << 1),
568d209a699SThomas Gleixner IRQCHIP_MASK_ON_SUSPEND = (1 << 2),
569b3d42232SThomas Gleixner IRQCHIP_ONOFFLINE_ENABLED = (1 << 3),
57060f96b41SSantosh Shilimkar IRQCHIP_SKIP_SET_WAKE = (1 << 4),
571dc9b229aSThomas Gleixner IRQCHIP_ONESHOT_SAFE = (1 << 5),
572328a4978SThomas Gleixner IRQCHIP_EOI_THREADED = (1 << 6),
5736988e0e0SMarc Zyngier IRQCHIP_SUPPORTS_LEVEL_MSI = (1 << 7),
574b525903cSJulien Thierry IRQCHIP_SUPPORTS_NMI = (1 << 8),
57590428a8eSMaulik Shah IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = (1 << 9),
576826da771SThomas Gleixner IRQCHIP_AFFINITY_PRE_STARTUP = (1 << 10),
5776c846d02SMarc Zyngier IRQCHIP_IMMUTABLE = (1 << 11),
578a648eb3aSThomas Gleixner IRQCHIP_MOVE_DEFERRED = (1 << 12),
579d4d5e089SThomas Gleixner };
580d4d5e089SThomas Gleixner
581e144710bSThomas Gleixner #include <linux/irqdesc.h>
582c6b7674fSThomas Gleixner
58334ffdb72SIngo Molnar /*
58434ffdb72SIngo Molnar * Pick up the arch-dependent methods:
58534ffdb72SIngo Molnar */
58634ffdb72SIngo Molnar #include <asm/hw_irq.h>
5871da177e4SLinus Torvalds
588b683de2bSThomas Gleixner #ifndef NR_IRQS_LEGACY
589b683de2bSThomas Gleixner # define NR_IRQS_LEGACY 0
590b683de2bSThomas Gleixner #endif
591b683de2bSThomas Gleixner
5921318a481SThomas Gleixner #ifndef ARCH_IRQ_INIT_FLAGS
5931318a481SThomas Gleixner # define ARCH_IRQ_INIT_FLAGS 0
5941318a481SThomas Gleixner #endif
5951318a481SThomas Gleixner
596c1594b77SThomas Gleixner #define IRQ_DEFAULT_INIT_FLAGS ARCH_IRQ_INIT_FLAGS
5971318a481SThomas Gleixner
598e144710bSThomas Gleixner struct irqaction;
59931d9d9b6SMarc Zyngier extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
60031d9d9b6SMarc Zyngier extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
6011da177e4SLinus Torvalds
6028d15a729SMarc Zyngier #ifdef CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE
6030fdb4b25SDavid Daney extern void irq_cpu_online(void);
6040fdb4b25SDavid Daney extern void irq_cpu_offline(void);
6058d15a729SMarc Zyngier #endif
60601f8fa4fSThomas Gleixner extern int irq_set_affinity_locked(struct irq_data *data,
60701f8fa4fSThomas Gleixner const struct cpumask *cpumask, bool force);
6080a4377deSJiang Liu extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
6090fdb4b25SDavid Daney
610c5cb83bbSThomas Gleixner #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_IRQ_MIGRATION)
611f1e0bb0aSYang Yingliang extern void irq_migrate_all_off_this_cpu(void);
612c5cb83bbSThomas Gleixner extern int irq_affinity_online_cpu(unsigned int cpu);
613c5cb83bbSThomas Gleixner #else
614c5cb83bbSThomas Gleixner # define irq_affinity_online_cpu NULL
615c5cb83bbSThomas Gleixner #endif
616f1e0bb0aSYang Yingliang
6173a3856d0SThomas Gleixner #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
618*e54b1b5eSAnup Patel bool irq_can_move_in_process_context(struct irq_data *data);
619d340ebd6SThomas Gleixner void __irq_move_irq(struct irq_data *data);
irq_move_irq(struct irq_data * data)620d340ebd6SThomas Gleixner static inline void irq_move_irq(struct irq_data *data)
621d340ebd6SThomas Gleixner {
622d340ebd6SThomas Gleixner if (unlikely(irqd_is_setaffinity_pending(data)))
623d340ebd6SThomas Gleixner __irq_move_irq(data);
624d340ebd6SThomas Gleixner }
625a439520fSThomas Gleixner void irq_move_masked_irq(struct irq_data *data);
626e144710bSThomas Gleixner #else
irq_can_move_in_process_context(struct irq_data * data)627*e54b1b5eSAnup Patel static inline bool irq_can_move_in_process_context(struct irq_data *data) { return true; }
irq_move_irq(struct irq_data * data)628a439520fSThomas Gleixner static inline void irq_move_irq(struct irq_data *data) { }
irq_move_masked_irq(struct irq_data * data)629a439520fSThomas Gleixner static inline void irq_move_masked_irq(struct irq_data *data) { }
630e144710bSThomas Gleixner #endif
63154d5d424SAshok Raj
6321da177e4SLinus Torvalds extern int no_irq_affinity;
6331da177e4SLinus Torvalds
634293a7a0aSThomas Gleixner #ifdef CONFIG_HARDIRQS_SW_RESEND
635293a7a0aSThomas Gleixner int irq_set_parent(int irq, int parent_irq);
636293a7a0aSThomas Gleixner #else
irq_set_parent(int irq,int parent_irq)637293a7a0aSThomas Gleixner static inline int irq_set_parent(int irq, int parent_irq)
638293a7a0aSThomas Gleixner {
639293a7a0aSThomas Gleixner return 0;
640293a7a0aSThomas Gleixner }
641293a7a0aSThomas Gleixner #endif
642293a7a0aSThomas Gleixner
6432e60bbb6SIngo Molnar /*
6446a6de9efSThomas Gleixner * Built-in IRQ handlers for various IRQ types,
645bebd04ccSKrzysztof Halasa * callable via desc->handle_irq()
6466a6de9efSThomas Gleixner */
647bd0b9ac4SThomas Gleixner extern void handle_level_irq(struct irq_desc *desc);
648bd0b9ac4SThomas Gleixner extern void handle_fasteoi_irq(struct irq_desc *desc);
649bd0b9ac4SThomas Gleixner extern void handle_edge_irq(struct irq_desc *desc);
650bd0b9ac4SThomas Gleixner extern void handle_edge_eoi_irq(struct irq_desc *desc);
651bd0b9ac4SThomas Gleixner extern void handle_simple_irq(struct irq_desc *desc);
652edd14cfeSKeith Busch extern void handle_untracked_irq(struct irq_desc *desc);
653bd0b9ac4SThomas Gleixner extern void handle_percpu_irq(struct irq_desc *desc);
654bd0b9ac4SThomas Gleixner extern void handle_percpu_devid_irq(struct irq_desc *desc);
655bd0b9ac4SThomas Gleixner extern void handle_bad_irq(struct irq_desc *desc);
65631b47cf7SMark Brown extern void handle_nested_irq(unsigned int irq);
6576a6de9efSThomas Gleixner
6582dcf1fbcSJulien Thierry extern void handle_fasteoi_nmi(struct irq_desc *desc);
6592dcf1fbcSJulien Thierry extern void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc);
6602dcf1fbcSJulien Thierry
661515085efSJiang Liu extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
662be45beb2SJon Hunter extern int irq_chip_pm_get(struct irq_data *data);
663be45beb2SJon Hunter extern int irq_chip_pm_put(struct irq_data *data);
66485f08c17SJiang Liu #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
6657703b08cSDavid Daney extern void handle_fasteoi_ack_irq(struct irq_desc *desc);
6667703b08cSDavid Daney extern void handle_fasteoi_mask_irq(struct irq_desc *desc);
6674a169a95SMaulik Shah extern int irq_chip_set_parent_state(struct irq_data *data,
6684a169a95SMaulik Shah enum irqchip_irq_state which,
6694a169a95SMaulik Shah bool val);
6704a169a95SMaulik Shah extern int irq_chip_get_parent_state(struct irq_data *data,
6714a169a95SMaulik Shah enum irqchip_irq_state which,
6724a169a95SMaulik Shah bool *state);
6733cfeffc2SStefan Agner extern void irq_chip_enable_parent(struct irq_data *data);
6743cfeffc2SStefan Agner extern void irq_chip_disable_parent(struct irq_data *data);
67585f08c17SJiang Liu extern void irq_chip_ack_parent(struct irq_data *data);
67685f08c17SJiang Liu extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
67756e8ababSYingjoe Chen extern void irq_chip_mask_parent(struct irq_data *data);
6785aa5bd56SLinus Walleij extern void irq_chip_mask_ack_parent(struct irq_data *data);
67956e8ababSYingjoe Chen extern void irq_chip_unmask_parent(struct irq_data *data);
68056e8ababSYingjoe Chen extern void irq_chip_eoi_parent(struct irq_data *data);
68156e8ababSYingjoe Chen extern int irq_chip_set_affinity_parent(struct irq_data *data,
68256e8ababSYingjoe Chen const struct cpumask *dest,
68356e8ababSYingjoe Chen bool force);
68408b55e2aSMarc Zyngier extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
6850a4377deSJiang Liu extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
6860a4377deSJiang Liu void *vcpu_info);
687b7560de1SGrygorii Strashko extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
6882bd1298aSLokesh Vutla extern int irq_chip_request_resources_parent(struct irq_data *data);
6892bd1298aSLokesh Vutla extern void irq_chip_release_resources_parent(struct irq_data *data);
69085f08c17SJiang Liu #endif
69185f08c17SJiang Liu
692bad6722eSEliav Farber /* Disable or mask interrupts during a kernel kexec */
693bad6722eSEliav Farber extern void machine_kexec_mask_interrupts(void);
694bad6722eSEliav Farber
6956a6de9efSThomas Gleixner /* Handling of unhandled and spurious interrupts: */
6960dcdbc97SJiang Liu extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
6971da177e4SLinus Torvalds
698a4633adcSThomas Gleixner
6996a6de9efSThomas Gleixner /* Enable/disable irq debugging output: */
7006a6de9efSThomas Gleixner extern int noirqdebug_setup(char *str);
7011da177e4SLinus Torvalds
7026a6de9efSThomas Gleixner /* Checks whether the interrupt can be requested by request_irq(): */
7036a6de9efSThomas Gleixner extern int can_request_irq(unsigned int irq, unsigned long irqflags);
7046a6de9efSThomas Gleixner
705f8b5473fSThomas Gleixner /* Dummy irq-chip implementations: */
7066a6de9efSThomas Gleixner extern struct irq_chip no_irq_chip;
707f8b5473fSThomas Gleixner extern struct irq_chip dummy_irq_chip;
7086a6de9efSThomas Gleixner
7096a6de9efSThomas Gleixner extern void
710393e1280SMarc Zyngier irq_set_chip_and_handler_name(unsigned int irq, const struct irq_chip *chip,
711a460e745SIngo Molnar irq_flow_handler_t handle, const char *name);
712a460e745SIngo Molnar
irq_set_chip_and_handler(unsigned int irq,const struct irq_chip * chip,irq_flow_handler_t handle)713393e1280SMarc Zyngier static inline void irq_set_chip_and_handler(unsigned int irq,
714393e1280SMarc Zyngier const struct irq_chip *chip,
7153836ca08SThomas Gleixner irq_flow_handler_t handle)
7163836ca08SThomas Gleixner {
7173836ca08SThomas Gleixner irq_set_chip_and_handler_name(irq, chip, handle, NULL);
7183836ca08SThomas Gleixner }
7193836ca08SThomas Gleixner
72031d9d9b6SMarc Zyngier extern int irq_set_percpu_devid(unsigned int irq);
721222df54fSMarc Zyngier extern int irq_set_percpu_devid_partition(unsigned int irq,
722222df54fSMarc Zyngier const struct cpumask *affinity);
723222df54fSMarc Zyngier extern int irq_get_percpu_devid_partition(unsigned int irq,
724222df54fSMarc Zyngier struct cpumask *affinity);
72531d9d9b6SMarc Zyngier
7266a6de9efSThomas Gleixner extern void
7273836ca08SThomas Gleixner __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
728a460e745SIngo Molnar const char *name);
7296a6de9efSThomas Gleixner
7306a6de9efSThomas Gleixner static inline void
irq_set_handler(unsigned int irq,irq_flow_handler_t handle)7313836ca08SThomas Gleixner irq_set_handler(unsigned int irq, irq_flow_handler_t handle)
7326a6de9efSThomas Gleixner {
7333836ca08SThomas Gleixner __irq_set_handler(irq, handle, 0, NULL);
7346a6de9efSThomas Gleixner }
7356a6de9efSThomas Gleixner
7366a6de9efSThomas Gleixner /*
7376a6de9efSThomas Gleixner * Set a highlevel chained flow handler for a given IRQ.
7386a6de9efSThomas Gleixner * (a chained handler is automatically enabled and set to
7397f1b1244SPaul Mundt * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
7406a6de9efSThomas Gleixner */
7416a6de9efSThomas Gleixner static inline void
irq_set_chained_handler(unsigned int irq,irq_flow_handler_t handle)7423836ca08SThomas Gleixner irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle)
7436a6de9efSThomas Gleixner {
7443836ca08SThomas Gleixner __irq_set_handler(irq, handle, 1, NULL);
7456a6de9efSThomas Gleixner }
7466a6de9efSThomas Gleixner
7473b0f95beSRussell King /*
7483b0f95beSRussell King * Set a highlevel chained flow handler and its data for a given IRQ.
7493b0f95beSRussell King * (a chained handler is automatically enabled and set to
7503b0f95beSRussell King * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
7513b0f95beSRussell King */
7523b0f95beSRussell King void
7533b0f95beSRussell King irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
7543b0f95beSRussell King void *data);
7553b0f95beSRussell King
75644247184SThomas Gleixner void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
75744247184SThomas Gleixner
irq_set_status_flags(unsigned int irq,unsigned long set)75844247184SThomas Gleixner static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
75944247184SThomas Gleixner {
76044247184SThomas Gleixner irq_modify_status(irq, 0, set);
76144247184SThomas Gleixner }
76244247184SThomas Gleixner
irq_clear_status_flags(unsigned int irq,unsigned long clr)76344247184SThomas Gleixner static inline void irq_clear_status_flags(unsigned int irq, unsigned long clr)
76444247184SThomas Gleixner {
76544247184SThomas Gleixner irq_modify_status(irq, clr, 0);
76644247184SThomas Gleixner }
76744247184SThomas Gleixner
irq_set_noprobe(unsigned int irq)768a0cd9ca2SThomas Gleixner static inline void irq_set_noprobe(unsigned int irq)
76944247184SThomas Gleixner {
77044247184SThomas Gleixner irq_modify_status(irq, 0, IRQ_NOPROBE);
77144247184SThomas Gleixner }
77244247184SThomas Gleixner
irq_set_probe(unsigned int irq)773a0cd9ca2SThomas Gleixner static inline void irq_set_probe(unsigned int irq)
77444247184SThomas Gleixner {
77544247184SThomas Gleixner irq_modify_status(irq, IRQ_NOPROBE, 0);
77644247184SThomas Gleixner }
77746f4f8f6SRalf Baechle
irq_set_nothread(unsigned int irq)7787f1b1244SPaul Mundt static inline void irq_set_nothread(unsigned int irq)
7797f1b1244SPaul Mundt {
7807f1b1244SPaul Mundt irq_modify_status(irq, 0, IRQ_NOTHREAD);
7817f1b1244SPaul Mundt }
7827f1b1244SPaul Mundt
irq_set_thread(unsigned int irq)7837f1b1244SPaul Mundt static inline void irq_set_thread(unsigned int irq)
7847f1b1244SPaul Mundt {
7857f1b1244SPaul Mundt irq_modify_status(irq, IRQ_NOTHREAD, 0);
7867f1b1244SPaul Mundt }
7877f1b1244SPaul Mundt
irq_set_nested_thread(unsigned int irq,bool nest)7886f91a52dSThomas Gleixner static inline void irq_set_nested_thread(unsigned int irq, bool nest)
7896f91a52dSThomas Gleixner {
7906f91a52dSThomas Gleixner if (nest)
7916f91a52dSThomas Gleixner irq_set_status_flags(irq, IRQ_NESTED_THREAD);
7926f91a52dSThomas Gleixner else
7936f91a52dSThomas Gleixner irq_clear_status_flags(irq, IRQ_NESTED_THREAD);
7946f91a52dSThomas Gleixner }
7956f91a52dSThomas Gleixner
irq_set_percpu_devid_flags(unsigned int irq)79631d9d9b6SMarc Zyngier static inline void irq_set_percpu_devid_flags(unsigned int irq)
79731d9d9b6SMarc Zyngier {
79831d9d9b6SMarc Zyngier irq_set_status_flags(irq,
79931d9d9b6SMarc Zyngier IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD |
80031d9d9b6SMarc Zyngier IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
80131d9d9b6SMarc Zyngier }
80231d9d9b6SMarc Zyngier
8033a16d713SEric W. Biederman /* Set/get chip/data for an IRQ: */
804393e1280SMarc Zyngier extern int irq_set_chip(unsigned int irq, const struct irq_chip *chip);
805a0cd9ca2SThomas Gleixner extern int irq_set_handler_data(unsigned int irq, void *data);
806a0cd9ca2SThomas Gleixner extern int irq_set_chip_data(unsigned int irq, void *data);
807a0cd9ca2SThomas Gleixner extern int irq_set_irq_type(unsigned int irq, unsigned int type);
808a0cd9ca2SThomas Gleixner extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry);
80951906e77SAlexander Gordeev extern int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset,
81051906e77SAlexander Gordeev struct msi_desc *entry);
811f303a6ddSThomas Gleixner extern struct irq_data *irq_get_irq_data(unsigned int irq);
812dd87eb3aSThomas Gleixner
irq_get_chip(unsigned int irq)813a0cd9ca2SThomas Gleixner static inline struct irq_chip *irq_get_chip(unsigned int irq)
814f303a6ddSThomas Gleixner {
815f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
816f303a6ddSThomas Gleixner return d ? d->chip : NULL;
817f303a6ddSThomas Gleixner }
818f303a6ddSThomas Gleixner
irq_data_get_irq_chip(struct irq_data * d)819f303a6ddSThomas Gleixner static inline struct irq_chip *irq_data_get_irq_chip(struct irq_data *d)
820f303a6ddSThomas Gleixner {
821f303a6ddSThomas Gleixner return d->chip;
822f303a6ddSThomas Gleixner }
823f303a6ddSThomas Gleixner
irq_get_chip_data(unsigned int irq)824a0cd9ca2SThomas Gleixner static inline void *irq_get_chip_data(unsigned int irq)
825f303a6ddSThomas Gleixner {
826f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
827f303a6ddSThomas Gleixner return d ? d->chip_data : NULL;
828f303a6ddSThomas Gleixner }
829f303a6ddSThomas Gleixner
irq_data_get_irq_chip_data(struct irq_data * d)830f303a6ddSThomas Gleixner static inline void *irq_data_get_irq_chip_data(struct irq_data *d)
831f303a6ddSThomas Gleixner {
832f303a6ddSThomas Gleixner return d->chip_data;
833f303a6ddSThomas Gleixner }
834f303a6ddSThomas Gleixner
irq_get_handler_data(unsigned int irq)835a0cd9ca2SThomas Gleixner static inline void *irq_get_handler_data(unsigned int irq)
836f303a6ddSThomas Gleixner {
837f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
838af7080e0SJiang Liu return d ? d->common->handler_data : NULL;
839f303a6ddSThomas Gleixner }
840f303a6ddSThomas Gleixner
irq_data_get_irq_handler_data(struct irq_data * d)841a0cd9ca2SThomas Gleixner static inline void *irq_data_get_irq_handler_data(struct irq_data *d)
842f303a6ddSThomas Gleixner {
843af7080e0SJiang Liu return d->common->handler_data;
844f303a6ddSThomas Gleixner }
845f303a6ddSThomas Gleixner
irq_get_msi_desc(unsigned int irq)846a0cd9ca2SThomas Gleixner static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
847f303a6ddSThomas Gleixner {
848f303a6ddSThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
849b237721cSJiang Liu return d ? d->common->msi_desc : NULL;
850f303a6ddSThomas Gleixner }
851f303a6ddSThomas Gleixner
irq_data_get_msi_desc(struct irq_data * d)852c391f262SJiang Liu static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d)
853f303a6ddSThomas Gleixner {
854b237721cSJiang Liu return d->common->msi_desc;
855f303a6ddSThomas Gleixner }
856f303a6ddSThomas Gleixner
irq_get_trigger_type(unsigned int irq)8571f6236bfSJavier Martinez Canillas static inline u32 irq_get_trigger_type(unsigned int irq)
8581f6236bfSJavier Martinez Canillas {
8591f6236bfSJavier Martinez Canillas struct irq_data *d = irq_get_irq_data(irq);
8601f6236bfSJavier Martinez Canillas return d ? irqd_get_trigger_type(d) : 0;
8611f6236bfSJavier Martinez Canillas }
8621f6236bfSJavier Martinez Canillas
irq_common_data_get_node(struct irq_common_data * d)863449e9caeSJiang Liu static inline int irq_common_data_get_node(struct irq_common_data *d)
864449e9caeSJiang Liu {
865449e9caeSJiang Liu #ifdef CONFIG_NUMA
866449e9caeSJiang Liu return d->node;
867449e9caeSJiang Liu #else
868449e9caeSJiang Liu return 0;
869449e9caeSJiang Liu #endif
870449e9caeSJiang Liu }
871449e9caeSJiang Liu
irq_data_get_node(struct irq_data * d)8726783011bSJiang Liu static inline int irq_data_get_node(struct irq_data *d)
8736783011bSJiang Liu {
874449e9caeSJiang Liu return irq_common_data_get_node(d->common);
8756783011bSJiang Liu }
8766783011bSJiang Liu
8774d0b8298SSamuel Holland static inline
irq_data_get_affinity_mask(struct irq_data * d)8784d0b8298SSamuel Holland const struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
879961343d7SSamuel Holland {
880aa081358SSamuel Holland #ifdef CONFIG_SMP
881961343d7SSamuel Holland return d->common->affinity;
882aa081358SSamuel Holland #else
883aa081358SSamuel Holland return cpumask_of(0);
884aa081358SSamuel Holland #endif
885961343d7SSamuel Holland }
886961343d7SSamuel Holland
irq_data_update_affinity(struct irq_data * d,const struct cpumask * m)887073352e9SSamuel Holland static inline void irq_data_update_affinity(struct irq_data *d,
888073352e9SSamuel Holland const struct cpumask *m)
889073352e9SSamuel Holland {
890aa081358SSamuel Holland #ifdef CONFIG_SMP
891073352e9SSamuel Holland cpumask_copy(d->common->affinity, m);
892aa081358SSamuel Holland #endif
893073352e9SSamuel Holland }
894073352e9SSamuel Holland
irq_get_affinity_mask(int irq)8954d0b8298SSamuel Holland static inline const struct cpumask *irq_get_affinity_mask(int irq)
896c64301a2SJiang Liu {
897c64301a2SJiang Liu struct irq_data *d = irq_get_irq_data(irq);
898c64301a2SJiang Liu
899961343d7SSamuel Holland return d ? irq_data_get_affinity_mask(d) : NULL;
900c64301a2SJiang Liu }
901c64301a2SJiang Liu
9020d3f5425SThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
9030d3f5425SThomas Gleixner static inline
irq_data_get_effective_affinity_mask(struct irq_data * d)9044d0b8298SSamuel Holland const struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d)
9050d3f5425SThomas Gleixner {
9060d3f5425SThomas Gleixner return d->common->effective_affinity;
9070d3f5425SThomas Gleixner }
irq_data_update_effective_affinity(struct irq_data * d,const struct cpumask * m)9080d3f5425SThomas Gleixner static inline void irq_data_update_effective_affinity(struct irq_data *d,
9090d3f5425SThomas Gleixner const struct cpumask *m)
9100d3f5425SThomas Gleixner {
9110d3f5425SThomas Gleixner cpumask_copy(d->common->effective_affinity, m);
9120d3f5425SThomas Gleixner }
9130d3f5425SThomas Gleixner #else
irq_data_update_effective_affinity(struct irq_data * d,const struct cpumask * m)9140d3f5425SThomas Gleixner static inline void irq_data_update_effective_affinity(struct irq_data *d,
9150d3f5425SThomas Gleixner const struct cpumask *m)
9160d3f5425SThomas Gleixner {
9170d3f5425SThomas Gleixner }
9180d3f5425SThomas Gleixner static inline
irq_data_get_effective_affinity_mask(struct irq_data * d)9194d0b8298SSamuel Holland const struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d)
9200d3f5425SThomas Gleixner {
921961343d7SSamuel Holland return irq_data_get_affinity_mask(d);
9220d3f5425SThomas Gleixner }
9230d3f5425SThomas Gleixner #endif
9240d3f5425SThomas Gleixner
9254d0b8298SSamuel Holland static inline
irq_get_effective_affinity_mask(unsigned int irq)9264d0b8298SSamuel Holland const struct cpumask *irq_get_effective_affinity_mask(unsigned int irq)
9273e238012SThomas Gleixner {
9283e238012SThomas Gleixner struct irq_data *d = irq_get_irq_data(irq);
9293e238012SThomas Gleixner
9303e238012SThomas Gleixner return d ? irq_data_get_effective_affinity_mask(d) : NULL;
9313e238012SThomas Gleixner }
9323e238012SThomas Gleixner
93362a08ae2SThomas Gleixner unsigned int arch_dynirq_lower_bound(unsigned int from);
93462a08ae2SThomas Gleixner
935b6873807SSebastian Andrzej Siewior int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
936bec04037SDou Liyang struct module *owner,
937bec04037SDou Liyang const struct irq_affinity_desc *affinity);
938b6873807SSebastian Andrzej Siewior
9392b5e7730SBartosz Golaszewski int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
9402b5e7730SBartosz Golaszewski unsigned int cnt, int node, struct module *owner,
941bec04037SDou Liyang const struct irq_affinity_desc *affinity);
9422b5e7730SBartosz Golaszewski
943ec53cf23SPaul Gortmaker /* use macros to avoid needing export.h for THIS_MODULE */
944ec53cf23SPaul Gortmaker #define irq_alloc_descs(irq, from, cnt, node) \
94506ee6d57SThomas Gleixner __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL)
946ec53cf23SPaul Gortmaker
947ec53cf23SPaul Gortmaker #define irq_alloc_desc(node) \
9484c7bcb51SHans de Goede irq_alloc_descs(-1, 1, 1, node)
949ec53cf23SPaul Gortmaker
950ec53cf23SPaul Gortmaker #define irq_alloc_desc_at(at, node) \
951ec53cf23SPaul Gortmaker irq_alloc_descs(at, at, 1, node)
952ec53cf23SPaul Gortmaker
953ec53cf23SPaul Gortmaker #define irq_alloc_desc_from(from, node) \
954ec53cf23SPaul Gortmaker irq_alloc_descs(-1, from, 1, node)
955b6873807SSebastian Andrzej Siewior
95651906e77SAlexander Gordeev #define irq_alloc_descs_from(from, cnt, node) \
95751906e77SAlexander Gordeev irq_alloc_descs(-1, from, cnt, node)
95851906e77SAlexander Gordeev
9592b5e7730SBartosz Golaszewski #define devm_irq_alloc_descs(dev, irq, from, cnt, node) \
9602b5e7730SBartosz Golaszewski __devm_irq_alloc_descs(dev, irq, from, cnt, node, THIS_MODULE, NULL)
9612b5e7730SBartosz Golaszewski
9622b5e7730SBartosz Golaszewski #define devm_irq_alloc_desc(dev, node) \
9634c7bcb51SHans de Goede devm_irq_alloc_descs(dev, -1, 1, 1, node)
9642b5e7730SBartosz Golaszewski
9652b5e7730SBartosz Golaszewski #define devm_irq_alloc_desc_at(dev, at, node) \
9662b5e7730SBartosz Golaszewski devm_irq_alloc_descs(dev, at, at, 1, node)
9672b5e7730SBartosz Golaszewski
9682b5e7730SBartosz Golaszewski #define devm_irq_alloc_desc_from(dev, from, node) \
9692b5e7730SBartosz Golaszewski devm_irq_alloc_descs(dev, -1, from, 1, node)
9702b5e7730SBartosz Golaszewski
9712b5e7730SBartosz Golaszewski #define devm_irq_alloc_descs_from(dev, from, cnt, node) \
9722b5e7730SBartosz Golaszewski devm_irq_alloc_descs(dev, -1, from, cnt, node)
9732b5e7730SBartosz Golaszewski
9741f5a5b87SThomas Gleixner void irq_free_descs(unsigned int irq, unsigned int cnt);
irq_free_desc(unsigned int irq)9751f5a5b87SThomas Gleixner static inline void irq_free_desc(unsigned int irq)
9761f5a5b87SThomas Gleixner {
9771f5a5b87SThomas Gleixner irq_free_descs(irq, 1);
9781f5a5b87SThomas Gleixner }
9791f5a5b87SThomas Gleixner
980c940e01cSThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_LEGACY
981c940e01cSThomas Gleixner void irq_init_desc(unsigned int irq);
982c940e01cSThomas Gleixner #endif
983c940e01cSThomas Gleixner
9847d828062SThomas Gleixner /**
9857d828062SThomas Gleixner * struct irq_chip_regs - register offsets for struct irq_gci
9867d828062SThomas Gleixner * @enable: Enable register offset to reg_base
9877d828062SThomas Gleixner * @disable: Disable register offset to reg_base
9887d828062SThomas Gleixner * @mask: Mask register offset to reg_base
9897d828062SThomas Gleixner * @ack: Ack register offset to reg_base
9907d828062SThomas Gleixner * @eoi: Eoi register offset to reg_base
9917d828062SThomas Gleixner * @type: Type configuration register offset to reg_base
9927d828062SThomas Gleixner */
9937d828062SThomas Gleixner struct irq_chip_regs {
9947d828062SThomas Gleixner unsigned long enable;
9957d828062SThomas Gleixner unsigned long disable;
9967d828062SThomas Gleixner unsigned long mask;
9977d828062SThomas Gleixner unsigned long ack;
9987d828062SThomas Gleixner unsigned long eoi;
9997d828062SThomas Gleixner unsigned long type;
10007d828062SThomas Gleixner };
10017d828062SThomas Gleixner
10027d828062SThomas Gleixner /**
10037d828062SThomas Gleixner * struct irq_chip_type - Generic interrupt chip instance for a flow type
10047d828062SThomas Gleixner * @chip: The real interrupt chip which provides the callbacks
10057d828062SThomas Gleixner * @regs: Register offsets for this chip
10067d828062SThomas Gleixner * @handler: Flow handler associated with this chip
10077d828062SThomas Gleixner * @type: Chip can handle these flow types
1008899f0e66SGerlando Falauto * @mask_cache_priv: Cached mask register private to the chip type
1009899f0e66SGerlando Falauto * @mask_cache: Pointer to cached mask register
10107d828062SThomas Gleixner *
10117d828062SThomas Gleixner * A irq_generic_chip can have several instances of irq_chip_type when
10127d828062SThomas Gleixner * it requires different functions and register offsets for different
10137d828062SThomas Gleixner * flow types.
10147d828062SThomas Gleixner */
10157d828062SThomas Gleixner struct irq_chip_type {
10167d828062SThomas Gleixner struct irq_chip chip;
10177d828062SThomas Gleixner struct irq_chip_regs regs;
10187d828062SThomas Gleixner irq_flow_handler_t handler;
10197d828062SThomas Gleixner u32 type;
1020899f0e66SGerlando Falauto u32 mask_cache_priv;
1021899f0e66SGerlando Falauto u32 *mask_cache;
10227d828062SThomas Gleixner };
10237d828062SThomas Gleixner
10247d828062SThomas Gleixner /**
10257d828062SThomas Gleixner * struct irq_chip_generic - Generic irq chip data structure
10267d828062SThomas Gleixner * @lock: Lock to protect register and cache data access
10277d828062SThomas Gleixner * @reg_base: Register base address (virtual)
10282b280376SKevin Cernekee * @reg_readl: Alternate I/O accessor (defaults to readl if NULL)
10292b280376SKevin Cernekee * @reg_writel: Alternate I/O accessor (defaults to writel if NULL)
1030be9b22b6SBrian Norris * @suspend: Function called from core code on suspend once per
1031be9b22b6SBrian Norris * chip; can be useful instead of irq_chip::suspend to
1032be9b22b6SBrian Norris * handle chip details even when no interrupts are in use
1033be9b22b6SBrian Norris * @resume: Function called from core code on resume once per chip;
1034be9b22b6SBrian Norris * can be useful instead of irq_chip::suspend to handle
1035be9b22b6SBrian Norris * chip details even when no interrupts are in use
10367d828062SThomas Gleixner * @irq_base: Interrupt base nr for this chip
10377d828062SThomas Gleixner * @irq_cnt: Number of interrupts handled by this chip
1038899f0e66SGerlando Falauto * @mask_cache: Cached mask register shared between all chip types
10397d828062SThomas Gleixner * @wake_enabled: Interrupt can wakeup from suspend
10407d828062SThomas Gleixner * @wake_active: Interrupt is marked as an wakeup from suspend source
10417d828062SThomas Gleixner * @num_ct: Number of available irq_chip_type instances (usually 1)
10427d828062SThomas Gleixner * @private: Private data for non generic chip callbacks
1043088f40b7SThomas Gleixner * @installed: bitfield to denote installed interrupts
1044e8bd834fSGrant Likely * @unused: bitfield to denote unused interrupts
1045088f40b7SThomas Gleixner * @domain: irq domain pointer
1046cfefd21eSThomas Gleixner * @list: List head for keeping track of instances
10477d828062SThomas Gleixner * @chip_types: Array of interrupt irq_chip_types
10487d828062SThomas Gleixner *
10497d828062SThomas Gleixner * Note, that irq_chip_generic can have multiple irq_chip_type
10507d828062SThomas Gleixner * implementations which can be associated to a particular irq line of
10517d828062SThomas Gleixner * an irq_chip_generic instance. That allows to share and protect
10527d828062SThomas Gleixner * state in an irq_chip_generic instance when we need to implement
10537d828062SThomas Gleixner * different flow mechanisms (level/edge) for it.
10547d828062SThomas Gleixner */
10557d828062SThomas Gleixner struct irq_chip_generic {
10567d828062SThomas Gleixner raw_spinlock_t lock;
10577d828062SThomas Gleixner void __iomem *reg_base;
10582b280376SKevin Cernekee u32 (*reg_readl)(void __iomem *addr);
10592b280376SKevin Cernekee void (*reg_writel)(u32 val, void __iomem *addr);
1060be9b22b6SBrian Norris void (*suspend)(struct irq_chip_generic *gc);
1061be9b22b6SBrian Norris void (*resume)(struct irq_chip_generic *gc);
10627d828062SThomas Gleixner unsigned int irq_base;
10637d828062SThomas Gleixner unsigned int irq_cnt;
10647d828062SThomas Gleixner u32 mask_cache;
10657d828062SThomas Gleixner u32 wake_enabled;
10667d828062SThomas Gleixner u32 wake_active;
10677d828062SThomas Gleixner unsigned int num_ct;
10687d828062SThomas Gleixner void *private;
1069088f40b7SThomas Gleixner unsigned long installed;
1070e8bd834fSGrant Likely unsigned long unused;
1071088f40b7SThomas Gleixner struct irq_domain *domain;
1072cfefd21eSThomas Gleixner struct list_head list;
10737856e9f1SGustavo A. R. Silva struct irq_chip_type chip_types[];
10747d828062SThomas Gleixner };
10757d828062SThomas Gleixner
10767d828062SThomas Gleixner /**
10777d828062SThomas Gleixner * enum irq_gc_flags - Initialization flags for generic irq chips
10787d828062SThomas Gleixner * @IRQ_GC_INIT_MASK_CACHE: Initialize the mask_cache by reading mask reg
10797d828062SThomas Gleixner * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for
10807d828062SThomas Gleixner * irq chips which need to call irq_set_wake() on
10817d828062SThomas Gleixner * the parent irq. Usually GPIO implementations
1082af80b0feSGerlando Falauto * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private
1083966dc736SThomas Gleixner * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask
1084b7905595SKevin Cernekee * @IRQ_GC_BE_IO: Use big-endian register accesses (default: LE)
10857d828062SThomas Gleixner */
10867d828062SThomas Gleixner enum irq_gc_flags {
10877d828062SThomas Gleixner IRQ_GC_INIT_MASK_CACHE = 1 << 0,
10887d828062SThomas Gleixner IRQ_GC_INIT_NESTED_LOCK = 1 << 1,
1089af80b0feSGerlando Falauto IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2,
1090966dc736SThomas Gleixner IRQ_GC_NO_MASK = 1 << 3,
1091b7905595SKevin Cernekee IRQ_GC_BE_IO = 1 << 4,
10927d828062SThomas Gleixner };
10937d828062SThomas Gleixner
1094088f40b7SThomas Gleixner /*
1095088f40b7SThomas Gleixner * struct irq_domain_chip_generic - Generic irq chip data structure for irq domains
1096088f40b7SThomas Gleixner * @irqs_per_chip: Number of interrupts per chip
1097088f40b7SThomas Gleixner * @num_chips: Number of chips
1098088f40b7SThomas Gleixner * @irq_flags_to_set: IRQ* flags to set on irq setup
1099088f40b7SThomas Gleixner * @irq_flags_to_clear: IRQ* flags to clear on irq setup
1100088f40b7SThomas Gleixner * @gc_flags: Generic chip specific setup flags
1101fea922eeSHerve Codina * @exit: Function called on each chip when they are destroyed.
1102088f40b7SThomas Gleixner * @gc: Array of pointers to generic interrupt chips
1103088f40b7SThomas Gleixner */
1104088f40b7SThomas Gleixner struct irq_domain_chip_generic {
1105088f40b7SThomas Gleixner unsigned int irqs_per_chip;
1106088f40b7SThomas Gleixner unsigned int num_chips;
1107088f40b7SThomas Gleixner unsigned int irq_flags_to_clear;
1108088f40b7SThomas Gleixner unsigned int irq_flags_to_set;
1109088f40b7SThomas Gleixner enum irq_gc_flags gc_flags;
1110fea922eeSHerve Codina void (*exit)(struct irq_chip_generic *gc);
11117856e9f1SGustavo A. R. Silva struct irq_chip_generic *gc[];
1112088f40b7SThomas Gleixner };
1113088f40b7SThomas Gleixner
1114e25f553aSHerve Codina /**
1115e25f553aSHerve Codina * struct irq_domain_chip_generic_info - Generic chip information structure
1116e25f553aSHerve Codina * @name: Name of the generic interrupt chip
1117e25f553aSHerve Codina * @handler: Interrupt handler used by the generic interrupt chip
1118e25f553aSHerve Codina * @irqs_per_chip: Number of interrupts each chip handles (max 32)
1119e25f553aSHerve Codina * @num_ct: Number of irq_chip_type instances associated with each
1120e25f553aSHerve Codina * chip
1121e25f553aSHerve Codina * @irq_flags_to_clear: IRQ_* bits to clear in the mapping function
1122e25f553aSHerve Codina * @irq_flags_to_set: IRQ_* bits to set in the mapping function
1123e25f553aSHerve Codina * @gc_flags: Generic chip specific setup flags
1124fea922eeSHerve Codina * @init: Function called on each chip when they are created.
1125fea922eeSHerve Codina * Allow to do some additional chip initialisation.
1126fea922eeSHerve Codina * @exit: Function called on each chip when they are destroyed.
1127fea922eeSHerve Codina * Allow to do some chip cleanup operation.
1128e25f553aSHerve Codina */
1129e25f553aSHerve Codina struct irq_domain_chip_generic_info {
1130e25f553aSHerve Codina const char *name;
1131e25f553aSHerve Codina irq_flow_handler_t handler;
1132e25f553aSHerve Codina unsigned int irqs_per_chip;
1133e25f553aSHerve Codina unsigned int num_ct;
1134e25f553aSHerve Codina unsigned int irq_flags_to_clear;
1135e25f553aSHerve Codina unsigned int irq_flags_to_set;
1136e25f553aSHerve Codina enum irq_gc_flags gc_flags;
1137fea922eeSHerve Codina int (*init)(struct irq_chip_generic *gc);
1138fea922eeSHerve Codina void (*exit)(struct irq_chip_generic *gc);
1139e25f553aSHerve Codina };
1140e25f553aSHerve Codina
11417d828062SThomas Gleixner /* Generic chip callback functions */
11427d828062SThomas Gleixner void irq_gc_noop(struct irq_data *d);
11437d828062SThomas Gleixner void irq_gc_mask_disable_reg(struct irq_data *d);
11447d828062SThomas Gleixner void irq_gc_mask_set_bit(struct irq_data *d);
11457d828062SThomas Gleixner void irq_gc_mask_clr_bit(struct irq_data *d);
11467d828062SThomas Gleixner void irq_gc_unmask_enable_reg(struct irq_data *d);
1147659fb32dSSimon Guinot void irq_gc_ack_set_bit(struct irq_data *d);
1148659fb32dSSimon Guinot void irq_gc_ack_clr_bit(struct irq_data *d);
114920608924SDoug Berger void irq_gc_mask_disable_and_ack_set(struct irq_data *d);
11507d828062SThomas Gleixner void irq_gc_eoi(struct irq_data *d);
11517d828062SThomas Gleixner int irq_gc_set_wake(struct irq_data *d, unsigned int on);
11527d828062SThomas Gleixner
11537d828062SThomas Gleixner /* Setup functions for irq_chip_generic */
1154a5152c8aSBoris BREZILLON int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
1155a5152c8aSBoris BREZILLON irq_hw_number_t hw_irq);
1156d319a299SJianmin Lv void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq);
11577d828062SThomas Gleixner struct irq_chip_generic *
11587d828062SThomas Gleixner irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base,
11597d828062SThomas Gleixner void __iomem *reg_base, irq_flow_handler_t handler);
11607d828062SThomas Gleixner void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
11617d828062SThomas Gleixner enum irq_gc_flags flags, unsigned int clr,
11627d828062SThomas Gleixner unsigned int set);
11637d828062SThomas Gleixner int irq_setup_alt_chip(struct irq_data *d, unsigned int type);
1164cfefd21eSThomas Gleixner void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
1165cfefd21eSThomas Gleixner unsigned int clr, unsigned int set);
11667d828062SThomas Gleixner
11671c3e3630SBartosz Golaszewski struct irq_chip_generic *
11681c3e3630SBartosz Golaszewski devm_irq_alloc_generic_chip(struct device *dev, const char *name, int num_ct,
11691c3e3630SBartosz Golaszewski unsigned int irq_base, void __iomem *reg_base,
11701c3e3630SBartosz Golaszewski irq_flow_handler_t handler);
117130fd8fc5SBartosz Golaszewski int devm_irq_setup_generic_chip(struct device *dev, struct irq_chip_generic *gc,
117230fd8fc5SBartosz Golaszewski u32 msk, enum irq_gc_flags flags,
117330fd8fc5SBartosz Golaszewski unsigned int clr, unsigned int set);
11741c3e3630SBartosz Golaszewski
1175088f40b7SThomas Gleixner struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
1176f88eecfeSSebastian Frias
11778cb2dbf9SThomas Gleixner #ifdef CONFIG_GENERIC_IRQ_CHIP
1178e25f553aSHerve Codina int irq_domain_alloc_generic_chips(struct irq_domain *d,
1179e25f553aSHerve Codina const struct irq_domain_chip_generic_info *info);
1180e25f553aSHerve Codina void irq_domain_remove_generic_chips(struct irq_domain *d);
11818cb2dbf9SThomas Gleixner #else
11828cb2dbf9SThomas Gleixner static inline int
irq_domain_alloc_generic_chips(struct irq_domain * d,const struct irq_domain_chip_generic_info * info)11838cb2dbf9SThomas Gleixner irq_domain_alloc_generic_chips(struct irq_domain *d,
11848cb2dbf9SThomas Gleixner const struct irq_domain_chip_generic_info *info)
11858cb2dbf9SThomas Gleixner {
11868cb2dbf9SThomas Gleixner return -EINVAL;
11878cb2dbf9SThomas Gleixner }
irq_domain_remove_generic_chips(struct irq_domain * d)11888cb2dbf9SThomas Gleixner static inline void irq_domain_remove_generic_chips(struct irq_domain *d) { }
11898cb2dbf9SThomas Gleixner #endif /* CONFIG_GENERIC_IRQ_CHIP */
1190e25f553aSHerve Codina
1191f88eecfeSSebastian Frias int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
1192088f40b7SThomas Gleixner int num_ct, const char *name,
1193088f40b7SThomas Gleixner irq_flow_handler_t handler,
1194088f40b7SThomas Gleixner unsigned int clr, unsigned int set,
1195088f40b7SThomas Gleixner enum irq_gc_flags flags);
1196088f40b7SThomas Gleixner
1197f88eecfeSSebastian Frias #define irq_alloc_domain_generic_chips(d, irqs_per_chip, num_ct, name, \
1198f88eecfeSSebastian Frias handler, clr, set, flags) \
1199f88eecfeSSebastian Frias ({ \
1200f88eecfeSSebastian Frias MAYBE_BUILD_BUG_ON(irqs_per_chip > 32); \
1201f88eecfeSSebastian Frias __irq_alloc_domain_generic_chips(d, irqs_per_chip, num_ct, name,\
1202f88eecfeSSebastian Frias handler, clr, set, flags); \
1203f88eecfeSSebastian Frias })
1204088f40b7SThomas Gleixner
irq_free_generic_chip(struct irq_chip_generic * gc)1205707188f5SBartosz Golaszewski static inline void irq_free_generic_chip(struct irq_chip_generic *gc)
1206707188f5SBartosz Golaszewski {
1207707188f5SBartosz Golaszewski kfree(gc);
1208707188f5SBartosz Golaszewski }
1209707188f5SBartosz Golaszewski
irq_destroy_generic_chip(struct irq_chip_generic * gc,u32 msk,unsigned int clr,unsigned int set)121032bb6cbbSBartosz Golaszewski static inline void irq_destroy_generic_chip(struct irq_chip_generic *gc,
121132bb6cbbSBartosz Golaszewski u32 msk, unsigned int clr,
121232bb6cbbSBartosz Golaszewski unsigned int set)
121332bb6cbbSBartosz Golaszewski {
121432bb6cbbSBartosz Golaszewski irq_remove_generic_chip(gc, msk, clr, set);
121532bb6cbbSBartosz Golaszewski irq_free_generic_chip(gc);
121632bb6cbbSBartosz Golaszewski }
121732bb6cbbSBartosz Golaszewski
irq_data_get_chip_type(struct irq_data * d)12187d828062SThomas Gleixner static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d)
12197d828062SThomas Gleixner {
12207d828062SThomas Gleixner return container_of(d->chip, struct irq_chip_type, chip);
12217d828062SThomas Gleixner }
12227d828062SThomas Gleixner
12237d828062SThomas Gleixner #define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX)
12247d828062SThomas Gleixner
12257d828062SThomas Gleixner #ifdef CONFIG_SMP
irq_gc_lock(struct irq_chip_generic * gc)12267d828062SThomas Gleixner static inline void irq_gc_lock(struct irq_chip_generic *gc)
12277d828062SThomas Gleixner {
12287d828062SThomas Gleixner raw_spin_lock(&gc->lock);
12297d828062SThomas Gleixner }
12307d828062SThomas Gleixner
irq_gc_unlock(struct irq_chip_generic * gc)12317d828062SThomas Gleixner static inline void irq_gc_unlock(struct irq_chip_generic *gc)
12327d828062SThomas Gleixner {
12337d828062SThomas Gleixner raw_spin_unlock(&gc->lock);
12347d828062SThomas Gleixner }
12357d828062SThomas Gleixner #else
irq_gc_lock(struct irq_chip_generic * gc)12367d828062SThomas Gleixner static inline void irq_gc_lock(struct irq_chip_generic *gc) { }
irq_gc_unlock(struct irq_chip_generic * gc)12377d828062SThomas Gleixner static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
12387d828062SThomas Gleixner #endif
12397d828062SThomas Gleixner
1240ebf9ff75SBoris Brezillon /*
1241ebf9ff75SBoris Brezillon * The irqsave variants are for usage in non interrupt code. Do not use
1242ebf9ff75SBoris Brezillon * them in irq_chip callbacks. Use irq_gc_lock() instead.
1243ebf9ff75SBoris Brezillon */
1244ebf9ff75SBoris Brezillon #define irq_gc_lock_irqsave(gc, flags) \
1245ebf9ff75SBoris Brezillon raw_spin_lock_irqsave(&(gc)->lock, flags)
1246ebf9ff75SBoris Brezillon
1247ebf9ff75SBoris Brezillon #define irq_gc_unlock_irqrestore(gc, flags) \
1248ebf9ff75SBoris Brezillon raw_spin_unlock_irqrestore(&(gc)->lock, flags)
1249ebf9ff75SBoris Brezillon
irq_reg_writel(struct irq_chip_generic * gc,u32 val,int reg_offset)1250332fd7c4SKevin Cernekee static inline void irq_reg_writel(struct irq_chip_generic *gc,
1251332fd7c4SKevin Cernekee u32 val, int reg_offset)
1252332fd7c4SKevin Cernekee {
12532b280376SKevin Cernekee if (gc->reg_writel)
12542b280376SKevin Cernekee gc->reg_writel(val, gc->reg_base + reg_offset);
12552b280376SKevin Cernekee else
1256332fd7c4SKevin Cernekee writel(val, gc->reg_base + reg_offset);
1257332fd7c4SKevin Cernekee }
1258332fd7c4SKevin Cernekee
irq_reg_readl(struct irq_chip_generic * gc,int reg_offset)1259332fd7c4SKevin Cernekee static inline u32 irq_reg_readl(struct irq_chip_generic *gc,
1260332fd7c4SKevin Cernekee int reg_offset)
1261332fd7c4SKevin Cernekee {
12622b280376SKevin Cernekee if (gc->reg_readl)
12632b280376SKevin Cernekee return gc->reg_readl(gc->reg_base + reg_offset);
12642b280376SKevin Cernekee else
1265332fd7c4SKevin Cernekee return readl(gc->reg_base + reg_offset);
1266332fd7c4SKevin Cernekee }
1267332fd7c4SKevin Cernekee
12682f75d9e1SThomas Gleixner struct irq_matrix;
12692f75d9e1SThomas Gleixner struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits,
12702f75d9e1SThomas Gleixner unsigned int alloc_start,
12712f75d9e1SThomas Gleixner unsigned int alloc_end);
12722f75d9e1SThomas Gleixner void irq_matrix_online(struct irq_matrix *m);
12732f75d9e1SThomas Gleixner void irq_matrix_offline(struct irq_matrix *m);
12742f75d9e1SThomas Gleixner void irq_matrix_assign_system(struct irq_matrix *m, unsigned int bit, bool replace);
12752f75d9e1SThomas Gleixner int irq_matrix_reserve_managed(struct irq_matrix *m, const struct cpumask *msk);
12762f75d9e1SThomas Gleixner void irq_matrix_remove_managed(struct irq_matrix *m, const struct cpumask *msk);
127776f99ae5SDou Liyang int irq_matrix_alloc_managed(struct irq_matrix *m, const struct cpumask *msk,
127876f99ae5SDou Liyang unsigned int *mapped_cpu);
12792f75d9e1SThomas Gleixner void irq_matrix_reserve(struct irq_matrix *m);
12802f75d9e1SThomas Gleixner void irq_matrix_remove_reserved(struct irq_matrix *m);
12812f75d9e1SThomas Gleixner int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
12822f75d9e1SThomas Gleixner bool reserved, unsigned int *mapped_cpu);
12832f75d9e1SThomas Gleixner void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
12842f75d9e1SThomas Gleixner unsigned int bit, bool managed);
12852f75d9e1SThomas Gleixner void irq_matrix_assign(struct irq_matrix *m, unsigned int bit);
12862f75d9e1SThomas Gleixner unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown);
12872f75d9e1SThomas Gleixner unsigned int irq_matrix_allocated(struct irq_matrix *m);
12882f75d9e1SThomas Gleixner unsigned int irq_matrix_reserved(struct irq_matrix *m);
12892f75d9e1SThomas Gleixner void irq_matrix_debug_show(struct seq_file *sf, struct irq_matrix *m, int ind);
12902f75d9e1SThomas Gleixner
1291d17bf24eSQais Yousef /* Contrary to Linux irqs, for hardware irqs the irq number 0 is valid */
1292d17bf24eSQais Yousef #define INVALID_HWIRQ (~0UL)
1293f9bce791SQais Yousef irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu);
12943b8e29a8SQais Yousef int __ipi_send_single(struct irq_desc *desc, unsigned int cpu);
12953b8e29a8SQais Yousef int __ipi_send_mask(struct irq_desc *desc, const struct cpumask *dest);
12963b8e29a8SQais Yousef int ipi_send_single(unsigned int virq, unsigned int cpu);
12973b8e29a8SQais Yousef int ipi_send_mask(unsigned int virq, const struct cpumask *dest);
1298d17bf24eSQais Yousef
1299835a486cSAnup Patel void ipi_mux_process(void);
1300835a486cSAnup Patel int ipi_mux_create(unsigned int nr_ipi, void (*mux_send)(unsigned int cpu));
1301835a486cSAnup Patel
1302caacdbf4SPalmer Dabbelt #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
1303caacdbf4SPalmer Dabbelt /*
1304caacdbf4SPalmer Dabbelt * Registers a generic IRQ handling function as the top-level IRQ handler in
1305caacdbf4SPalmer Dabbelt * the system, which is generally the first C code called from an assembly
1306caacdbf4SPalmer Dabbelt * architecture-specific interrupt handler.
1307caacdbf4SPalmer Dabbelt *
1308caacdbf4SPalmer Dabbelt * Returns 0 on success, or -EBUSY if an IRQ handler has already been
1309caacdbf4SPalmer Dabbelt * registered.
1310caacdbf4SPalmer Dabbelt */
1311caacdbf4SPalmer Dabbelt int __init set_handle_irq(void (*handle_irq)(struct pt_regs *));
1312caacdbf4SPalmer Dabbelt
1313caacdbf4SPalmer Dabbelt /*
1314caacdbf4SPalmer Dabbelt * Allows interrupt handlers to find the irqchip that's been registered as the
1315caacdbf4SPalmer Dabbelt * top-level IRQ handler.
1316caacdbf4SPalmer Dabbelt */
1317caacdbf4SPalmer Dabbelt extern void (*handle_arch_irq)(struct pt_regs *) __ro_after_init;
1318a1b09501SMark Rutland asmlinkage void generic_handle_arch_irq(struct pt_regs *regs);
1319ea0c80d1SZhen Lei #else
1320b0b8b689SMarc Zyngier #ifndef set_handle_irq
1321ea0c80d1SZhen Lei #define set_handle_irq(handle_irq) \
1322ea0c80d1SZhen Lei do { \
1323ea0c80d1SZhen Lei (void)handle_irq; \
1324ea0c80d1SZhen Lei WARN_ON(1); \
1325ea0c80d1SZhen Lei } while (0)
1326caacdbf4SPalmer Dabbelt #endif
1327b0b8b689SMarc Zyngier #endif
1328caacdbf4SPalmer Dabbelt
132906fcb0c6SIngo Molnar #endif /* _LINUX_IRQ_H */
1330