.. | .. |
---|
16 | 16 | #include <linux/irqhandler.h> |
---|
17 | 17 | #include <linux/irqreturn.h> |
---|
18 | 18 | #include <linux/irqnr.h> |
---|
| 19 | +#include <linux/irq_work.h> |
---|
19 | 20 | #include <linux/topology.h> |
---|
20 | 21 | #include <linux/io.h> |
---|
21 | 22 | #include <linux/slab.h> |
---|
.. | .. |
---|
73 | 74 | * IRQ_DISABLE_UNLAZY - Disable lazy irq disable |
---|
74 | 75 | * IRQ_HIDDEN - Don't show up in /proc/interrupts |
---|
75 | 76 | * IRQ_RAW - Skip tick management and irqtime accounting |
---|
| 77 | + * IRQ_OOB - Interrupt can be delivered to the out-of-band handler |
---|
| 78 | + * when pipelining is enabled (CONFIG_IRQ_PIPELINE), |
---|
| 79 | + * regardless of the (virtualized) interrupt state |
---|
| 80 | + * maintained by local_irq_save/disable(). |
---|
| 81 | + * IRQ_CHAINED - Interrupt is chained. |
---|
76 | 82 | */ |
---|
77 | 83 | enum { |
---|
78 | 84 | IRQ_TYPE_NONE = 0x00000000, |
---|
.. | .. |
---|
101 | 107 | IRQ_DISABLE_UNLAZY = (1 << 19), |
---|
102 | 108 | IRQ_HIDDEN = (1 << 20), |
---|
103 | 109 | IRQ_RAW = (1 << 21), |
---|
| 110 | + IRQ_OOB = (1 << 22), |
---|
| 111 | + IRQ_CHAINED = (1 << 23), |
---|
104 | 112 | }; |
---|
105 | 113 | |
---|
106 | 114 | #define IRQF_MODIFY_MASK \ |
---|
107 | 115 | (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ |
---|
108 | 116 | IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ |
---|
109 | 117 | IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \ |
---|
110 | | - IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_HIDDEN) |
---|
| 118 | + IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_HIDDEN | IRQ_OOB) |
---|
111 | 119 | |
---|
112 | 120 | #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) |
---|
113 | 121 | |
---|
.. | .. |
---|
173 | 181 | * irq_domain |
---|
174 | 182 | * @chip_data: platform-specific per-chip private data for the chip |
---|
175 | 183 | * methods, to allow shared chip implementations |
---|
| 184 | + * @move_work: irq_work for setaffinity deferral when pipelining irqs |
---|
176 | 185 | */ |
---|
177 | 186 | struct irq_data { |
---|
178 | 187 | u32 mask; |
---|
.. | .. |
---|
183 | 192 | struct irq_domain *domain; |
---|
184 | 193 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY |
---|
185 | 194 | struct irq_data *parent_data; |
---|
| 195 | +#endif |
---|
| 196 | +#if defined(CONFIG_IRQ_PIPELINE) && defined(CONFIG_GENERIC_PENDING_IRQ) |
---|
| 197 | + struct irq_work move_work; |
---|
186 | 198 | #endif |
---|
187 | 199 | void *chip_data; |
---|
188 | 200 | }; |
---|
.. | .. |
---|
221 | 233 | * irq_chip::irq_set_affinity() when deactivated. |
---|
222 | 234 | * IRQD_IRQ_ENABLED_ON_SUSPEND - Interrupt is enabled on suspend by irq pm if |
---|
223 | 235 | * irqchip have flag IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND set. |
---|
| 236 | + * IRQD_SETAFFINITY_BLOCKED - Pending affinity setting on hold (IRQ_PIPELINE) |
---|
224 | 237 | */ |
---|
225 | 238 | enum { |
---|
226 | 239 | IRQD_TRIGGER_MASK = 0xf, |
---|
.. | .. |
---|
247 | 260 | IRQD_HANDLE_ENFORCE_IRQCTX = (1 << 28), |
---|
248 | 261 | IRQD_AFFINITY_ON_ACTIVATE = (1 << 29), |
---|
249 | 262 | IRQD_IRQ_ENABLED_ON_SUSPEND = (1 << 30), |
---|
| 263 | + IRQD_SETAFFINITY_BLOCKED = (1 << 31), |
---|
250 | 264 | }; |
---|
251 | 265 | |
---|
252 | 266 | #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) |
---|
.. | .. |
---|
254 | 268 | static inline bool irqd_is_setaffinity_pending(struct irq_data *d) |
---|
255 | 269 | { |
---|
256 | 270 | return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING; |
---|
| 271 | +} |
---|
| 272 | + |
---|
| 273 | +static inline void irqd_set_move_blocked(struct irq_data *d) |
---|
| 274 | +{ |
---|
| 275 | + __irqd_to_state(d) |= IRQD_SETAFFINITY_BLOCKED; |
---|
| 276 | +} |
---|
| 277 | + |
---|
| 278 | +static inline void irqd_clr_move_blocked(struct irq_data *d) |
---|
| 279 | +{ |
---|
| 280 | + __irqd_to_state(d) &= ~IRQD_SETAFFINITY_BLOCKED; |
---|
| 281 | +} |
---|
| 282 | + |
---|
| 283 | +static inline bool irqd_is_setaffinity_blocked(struct irq_data *d) |
---|
| 284 | +{ |
---|
| 285 | + return irqs_pipelined() && __irqd_to_state(d) & IRQD_SETAFFINITY_BLOCKED; |
---|
257 | 286 | } |
---|
258 | 287 | |
---|
259 | 288 | static inline bool irqd_is_per_cpu(struct irq_data *d) |
---|
.. | .. |
---|
570 | 599 | * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND: Invokes __enable_irq()/__disable_irq() for wake irqs |
---|
571 | 600 | * in the suspend path if they are in disabled state |
---|
572 | 601 | * IRQCHIP_AFFINITY_PRE_STARTUP: Default affinity update before startup |
---|
| 602 | + * IRQCHIP_PIPELINE_SAFE: Chip can work in pipelined mode |
---|
573 | 603 | */ |
---|
574 | 604 | enum { |
---|
575 | 605 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), |
---|
.. | .. |
---|
583 | 613 | IRQCHIP_SUPPORTS_NMI = (1 << 8), |
---|
584 | 614 | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = (1 << 9), |
---|
585 | 615 | IRQCHIP_AFFINITY_PRE_STARTUP = (1 << 10), |
---|
| 616 | + IRQCHIP_PIPELINE_SAFE = (1 << 11), |
---|
586 | 617 | }; |
---|
587 | 618 | |
---|
588 | 619 | #include <linux/irqdesc.h> |
---|
.. | .. |
---|
660 | 691 | extern void handle_percpu_devid_irq(struct irq_desc *desc); |
---|
661 | 692 | extern void handle_bad_irq(struct irq_desc *desc); |
---|
662 | 693 | extern void handle_nested_irq(unsigned int irq); |
---|
| 694 | +extern void handle_synthetic_irq(struct irq_desc *desc); |
---|
663 | 695 | |
---|
664 | 696 | extern void handle_fasteoi_nmi(struct irq_desc *desc); |
---|
665 | 697 | extern void handle_percpu_devid_fasteoi_nmi(struct irq_desc *desc); |
---|
.. | .. |
---|
813 | 845 | extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry); |
---|
814 | 846 | extern int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset, |
---|
815 | 847 | struct msi_desc *entry); |
---|
816 | | -extern struct irq_data *irq_get_irq_data(unsigned int irq); |
---|
| 848 | + |
---|
| 849 | +static inline struct irq_data *irq_get_irq_data(unsigned int irq) |
---|
| 850 | +{ |
---|
| 851 | + struct irq_desc *desc = irq_to_desc(irq); |
---|
| 852 | + |
---|
| 853 | + return desc ? &desc->irq_data : NULL; |
---|
| 854 | +} |
---|
817 | 855 | |
---|
818 | 856 | static inline struct irq_chip *irq_get_chip(unsigned int irq) |
---|
819 | 857 | { |
---|
.. | .. |
---|
1056 | 1094 | * different flow mechanisms (level/edge) for it. |
---|
1057 | 1095 | */ |
---|
1058 | 1096 | struct irq_chip_generic { |
---|
1059 | | - raw_spinlock_t lock; |
---|
| 1097 | + hard_spinlock_t lock; |
---|
1060 | 1098 | void __iomem *reg_base; |
---|
1061 | 1099 | u32 (*reg_readl)(void __iomem *addr); |
---|
1062 | 1100 | void (*reg_writel)(u32 val, void __iomem *addr); |
---|
.. | .. |
---|
1183 | 1221 | |
---|
1184 | 1222 | #define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX) |
---|
1185 | 1223 | |
---|
| 1224 | +#ifdef CONFIG_IRQ_PIPELINE |
---|
| 1225 | + |
---|
| 1226 | +int irq_switch_oob(unsigned int irq, bool on); |
---|
| 1227 | + |
---|
| 1228 | +#endif /* !CONFIG_IRQ_PIPELINE */ |
---|
| 1229 | + |
---|
1186 | 1230 | #ifdef CONFIG_SMP |
---|
1187 | 1231 | static inline void irq_gc_lock(struct irq_chip_generic *gc) |
---|
1188 | 1232 | { |
---|