aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/kvm/arm_vgic.h4
-rw-r--r--include/linux/acpi.h3
-rw-r--r--include/linux/fwnode.h1
-rw-r--r--include/linux/interrupt.h2
-rw-r--r--include/linux/irq.h23
-rw-r--r--include/linux/irqchip/arm-gic-v3.h105
-rw-r--r--include/linux/irqchip/arm-gic.h9
-rw-r--r--include/linux/irqdomain.h106
-rw-r--r--include/linux/irqreturn.h2
-rw-r--r--include/linux/msi.h16
-rw-r--r--include/linux/of_irq.h23
11 files changed, 161 insertions, 133 deletions
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 4e14dac282bb..6a3538ef7275 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -282,7 +282,7 @@ struct vgic_v2_cpu_if {
282}; 282};
283 283
284struct vgic_v3_cpu_if { 284struct vgic_v3_cpu_if {
285#ifdef CONFIG_ARM_GIC_V3 285#ifdef CONFIG_KVM_ARM_VGIC_V3
286 u32 vgic_hcr; 286 u32 vgic_hcr;
287 u32 vgic_vmcr; 287 u32 vgic_vmcr;
288 u32 vgic_sre; /* Restored only, change ignored */ 288 u32 vgic_sre; /* Restored only, change ignored */
@@ -364,7 +364,7 @@ void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
364int vgic_v2_probe(struct device_node *vgic_node, 364int vgic_v2_probe(struct device_node *vgic_node,
365 const struct vgic_ops **ops, 365 const struct vgic_ops **ops,
366 const struct vgic_params **params); 366 const struct vgic_params **params);
367#ifdef CONFIG_ARM_GIC_V3 367#ifdef CONFIG_KVM_ARM_VGIC_V3
368int vgic_v3_probe(struct device_node *vgic_node, 368int vgic_v3_probe(struct device_node *vgic_node,
369 const struct vgic_ops **ops, 369 const struct vgic_ops **ops,
370 const struct vgic_params **params); 370 const struct vgic_params **params);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 43856d19cf4d..d863e12bbead 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -201,6 +201,9 @@ int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity
201int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); 201int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
202int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); 202int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
203 203
204void acpi_set_irq_model(enum acpi_irq_model_id model,
205 struct fwnode_handle *fwnode);
206
204#ifdef CONFIG_X86_IO_APIC 207#ifdef CONFIG_X86_IO_APIC
205extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); 208extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
206#else 209#else
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 0408545bce42..37ec668546ab 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -17,6 +17,7 @@ enum fwnode_type {
17 FWNODE_OF, 17 FWNODE_OF,
18 FWNODE_ACPI, 18 FWNODE_ACPI,
19 FWNODE_PDATA, 19 FWNODE_PDATA,
20 FWNODE_IRQCHIP,
20}; 21};
21 22
22struct fwnode_handle { 23struct fwnode_handle {
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index be7e75c945e9..ad16809c8596 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -102,6 +102,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
102 * @flags: flags (see IRQF_* above) 102 * @flags: flags (see IRQF_* above)
103 * @thread_fn: interrupt handler function for threaded interrupts 103 * @thread_fn: interrupt handler function for threaded interrupts
104 * @thread: thread pointer for threaded interrupts 104 * @thread: thread pointer for threaded interrupts
105 * @secondary: pointer to secondary irqaction (force threading)
105 * @thread_flags: flags related to @thread 106 * @thread_flags: flags related to @thread
106 * @thread_mask: bitmask for keeping track of @thread activity 107 * @thread_mask: bitmask for keeping track of @thread activity
107 * @dir: pointer to the proc/irq/NN/name entry 108 * @dir: pointer to the proc/irq/NN/name entry
@@ -113,6 +114,7 @@ struct irqaction {
113 struct irqaction *next; 114 struct irqaction *next;
114 irq_handler_t thread_fn; 115 irq_handler_t thread_fn;
115 struct task_struct *thread; 116 struct task_struct *thread;
117 struct irqaction *secondary;
116 unsigned int irq; 118 unsigned int irq;
117 unsigned int flags; 119 unsigned int flags;
118 unsigned long thread_flags; 120 unsigned long thread_flags;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 11bf09288ddb..3c1c96786248 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -67,11 +67,12 @@ enum irqchip_irq_state;
67 * request/setup_irq() 67 * request/setup_irq()
68 * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) 68 * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
69 * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context 69 * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
70 * IRQ_NESTED_TRHEAD - Interrupt nests into another thread 70 * IRQ_NESTED_THREAD - Interrupt nests into another thread
71 * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable 71 * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
72 * IRQ_IS_POLLED - Always polled by another interrupt. Exclude 72 * IRQ_IS_POLLED - Always polled by another interrupt. Exclude
73 * it from the spurious interrupt detection 73 * it from the spurious interrupt detection
74 * mechanism and from core side polling. 74 * mechanism and from core side polling.
75 * IRQ_DISABLE_UNLAZY - Disable lazy irq disable
75 */ 76 */
76enum { 77enum {
77 IRQ_TYPE_NONE = 0x00000000, 78 IRQ_TYPE_NONE = 0x00000000,
@@ -97,13 +98,14 @@ enum {
97 IRQ_NOTHREAD = (1 << 16), 98 IRQ_NOTHREAD = (1 << 16),
98 IRQ_PER_CPU_DEVID = (1 << 17), 99 IRQ_PER_CPU_DEVID = (1 << 17),
99 IRQ_IS_POLLED = (1 << 18), 100 IRQ_IS_POLLED = (1 << 18),
101 IRQ_DISABLE_UNLAZY = (1 << 19),
100}; 102};
101 103
102#define IRQF_MODIFY_MASK \ 104#define IRQF_MODIFY_MASK \
103 (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ 105 (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
104 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ 106 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
105 IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \ 107 IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \
106 IRQ_IS_POLLED) 108 IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY)
107 109
108#define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) 110#define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
109 111
@@ -297,21 +299,6 @@ static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d)
297 __irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU; 299 __irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU;
298} 300}
299 301
300/*
301 * Functions for chained handlers which can be enabled/disabled by the
302 * standard disable_irq/enable_irq calls. Must be called with
303 * irq_desc->lock held.
304 */
305static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
306{
307 __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
308}
309
310static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
311{
312 __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
313}
314
315static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) 302static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
316{ 303{
317 return d->hwirq; 304 return d->hwirq;
@@ -452,6 +439,8 @@ extern int irq_set_affinity_locked(struct irq_data *data,
452 const struct cpumask *cpumask, bool force); 439 const struct cpumask *cpumask, bool force);
453extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info); 440extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
454 441
442extern void irq_migrate_all_off_this_cpu(void);
443
455#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) 444#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
456void irq_move_irq(struct irq_data *data); 445void irq_move_irq(struct irq_data *data);
457void irq_move_masked_irq(struct irq_data *data); 446void irq_move_masked_irq(struct irq_data *data);
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 9eeeb9589acf..c9ae0c6ec050 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -18,8 +18,6 @@
18#ifndef __LINUX_IRQCHIP_ARM_GIC_V3_H 18#ifndef __LINUX_IRQCHIP_ARM_GIC_V3_H
19#define __LINUX_IRQCHIP_ARM_GIC_V3_H 19#define __LINUX_IRQCHIP_ARM_GIC_V3_H
20 20
21#include <asm/sysreg.h>
22
23/* 21/*
24 * Distributor registers. We assume we're running non-secure, with ARE 22 * Distributor registers. We assume we're running non-secure, with ARE
25 * being set. Secure-only and non-ARE registers are not described. 23 * being set. Secure-only and non-ARE registers are not described.
@@ -231,6 +229,7 @@
231#define GITS_BASER_PAGE_SIZE_16K (1UL << GITS_BASER_PAGE_SIZE_SHIFT) 229#define GITS_BASER_PAGE_SIZE_16K (1UL << GITS_BASER_PAGE_SIZE_SHIFT)
232#define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT) 230#define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT)
233#define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT) 231#define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT)
232#define GITS_BASER_PAGES_MAX 256
234 233
235#define GITS_BASER_TYPE_NONE 0 234#define GITS_BASER_TYPE_NONE 0
236#define GITS_BASER_TYPE_DEVICE 1 235#define GITS_BASER_TYPE_DEVICE 1
@@ -266,16 +265,16 @@
266/* 265/*
267 * Hypervisor interface registers (SRE only) 266 * Hypervisor interface registers (SRE only)
268 */ 267 */
269#define ICH_LR_VIRTUAL_ID_MASK ((1UL << 32) - 1) 268#define ICH_LR_VIRTUAL_ID_MASK ((1ULL << 32) - 1)
270 269
271#define ICH_LR_EOI (1UL << 41) 270#define ICH_LR_EOI (1ULL << 41)
272#define ICH_LR_GROUP (1UL << 60) 271#define ICH_LR_GROUP (1ULL << 60)
273#define ICH_LR_HW (1UL << 61) 272#define ICH_LR_HW (1ULL << 61)
274#define ICH_LR_STATE (3UL << 62) 273#define ICH_LR_STATE (3ULL << 62)
275#define ICH_LR_PENDING_BIT (1UL << 62) 274#define ICH_LR_PENDING_BIT (1ULL << 62)
276#define ICH_LR_ACTIVE_BIT (1UL << 63) 275#define ICH_LR_ACTIVE_BIT (1ULL << 63)
277#define ICH_LR_PHYS_ID_SHIFT 32 276#define ICH_LR_PHYS_ID_SHIFT 32
278#define ICH_LR_PHYS_ID_MASK (0x3ffUL << ICH_LR_PHYS_ID_SHIFT) 277#define ICH_LR_PHYS_ID_MASK (0x3ffULL << ICH_LR_PHYS_ID_SHIFT)
279 278
280#define ICH_MISR_EOI (1 << 0) 279#define ICH_MISR_EOI (1 << 0)
281#define ICH_MISR_U (1 << 1) 280#define ICH_MISR_U (1 << 1)
@@ -292,19 +291,8 @@
292#define ICH_VMCR_PMR_SHIFT 24 291#define ICH_VMCR_PMR_SHIFT 24
293#define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT) 292#define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT)
294 293
295#define ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1)
296#define ICC_DIR_EL1 sys_reg(3, 0, 12, 11, 1)
297#define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
298#define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
299#define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
300#define ICC_CTLR_EL1 sys_reg(3, 0, 12, 12, 4)
301#define ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5)
302#define ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7)
303
304#define ICC_IAR1_EL1_SPURIOUS 0x3ff 294#define ICC_IAR1_EL1_SPURIOUS 0x3ff
305 295
306#define ICC_SRE_EL2 sys_reg(3, 4, 12, 9, 5)
307
308#define ICC_SRE_EL2_SRE (1 << 0) 296#define ICC_SRE_EL2_SRE (1 << 0)
309#define ICC_SRE_EL2_ENABLE (1 << 3) 297#define ICC_SRE_EL2_ENABLE (1 << 3)
310 298
@@ -320,54 +308,10 @@
320#define ICC_SGI1R_AFFINITY_3_SHIFT 48 308#define ICC_SGI1R_AFFINITY_3_SHIFT 48
321#define ICC_SGI1R_AFFINITY_3_MASK (0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT) 309#define ICC_SGI1R_AFFINITY_3_MASK (0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT)
322 310
323/* 311#include <asm/arch_gicv3.h>
324 * System register definitions
325 */
326#define ICH_VSEIR_EL2 sys_reg(3, 4, 12, 9, 4)
327#define ICH_HCR_EL2 sys_reg(3, 4, 12, 11, 0)
328#define ICH_VTR_EL2 sys_reg(3, 4, 12, 11, 1)
329#define ICH_MISR_EL2 sys_reg(3, 4, 12, 11, 2)
330#define ICH_EISR_EL2 sys_reg(3, 4, 12, 11, 3)
331#define ICH_ELSR_EL2 sys_reg(3, 4, 12, 11, 5)
332#define ICH_VMCR_EL2 sys_reg(3, 4, 12, 11, 7)
333
334#define __LR0_EL2(x) sys_reg(3, 4, 12, 12, x)
335#define __LR8_EL2(x) sys_reg(3, 4, 12, 13, x)
336
337#define ICH_LR0_EL2 __LR0_EL2(0)
338#define ICH_LR1_EL2 __LR0_EL2(1)
339#define ICH_LR2_EL2 __LR0_EL2(2)
340#define ICH_LR3_EL2 __LR0_EL2(3)
341#define ICH_LR4_EL2 __LR0_EL2(4)
342#define ICH_LR5_EL2 __LR0_EL2(5)
343#define ICH_LR6_EL2 __LR0_EL2(6)
344#define ICH_LR7_EL2 __LR0_EL2(7)
345#define ICH_LR8_EL2 __LR8_EL2(0)
346#define ICH_LR9_EL2 __LR8_EL2(1)
347#define ICH_LR10_EL2 __LR8_EL2(2)
348#define ICH_LR11_EL2 __LR8_EL2(3)
349#define ICH_LR12_EL2 __LR8_EL2(4)
350#define ICH_LR13_EL2 __LR8_EL2(5)
351#define ICH_LR14_EL2 __LR8_EL2(6)
352#define ICH_LR15_EL2 __LR8_EL2(7)
353
354#define __AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x)
355#define ICH_AP0R0_EL2 __AP0Rx_EL2(0)
356#define ICH_AP0R1_EL2 __AP0Rx_EL2(1)
357#define ICH_AP0R2_EL2 __AP0Rx_EL2(2)
358#define ICH_AP0R3_EL2 __AP0Rx_EL2(3)
359
360#define __AP1Rx_EL2(x) sys_reg(3, 4, 12, 9, x)
361#define ICH_AP1R0_EL2 __AP1Rx_EL2(0)
362#define ICH_AP1R1_EL2 __AP1Rx_EL2(1)
363#define ICH_AP1R2_EL2 __AP1Rx_EL2(2)
364#define ICH_AP1R3_EL2 __AP1Rx_EL2(3)
365 312
366#ifndef __ASSEMBLY__ 313#ifndef __ASSEMBLY__
367 314
368#include <linux/stringify.h>
369#include <asm/msi.h>
370
371/* 315/*
372 * We need a value to serve as a irq-type for LPIs. Choose one that will 316 * We need a value to serve as a irq-type for LPIs. Choose one that will
373 * hopefully pique the interest of the reviewer. 317 * hopefully pique the interest of the reviewer.
@@ -385,23 +329,26 @@ struct rdists {
385 u64 flags; 329 u64 flags;
386}; 330};
387 331
388static inline void gic_write_eoir(u64 irq)
389{
390 asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq));
391 isb();
392}
393
394static inline void gic_write_dir(u64 irq)
395{
396 asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
397 isb();
398}
399
400struct irq_domain; 332struct irq_domain;
401int its_cpu_init(void); 333int its_cpu_init(void);
402int its_init(struct device_node *node, struct rdists *rdists, 334int its_init(struct device_node *node, struct rdists *rdists,
403 struct irq_domain *domain); 335 struct irq_domain *domain);
404 336
337static inline bool gic_enable_sre(void)
338{
339 u32 val;
340
341 val = gic_read_sre();
342 if (val & ICC_SRE_EL1_SRE)
343 return true;
344
345 val |= ICC_SRE_EL1_SRE;
346 gic_write_sre(val);
347 val = gic_read_sre();
348
349 return !!(val & ICC_SRE_EL1_SRE);
350}
351
405#endif 352#endif
406 353
407#endif 354#endif
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index b8901dfd9e95..bae69e5d693c 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -100,16 +100,11 @@
100 100
101struct device_node; 101struct device_node;
102 102
103void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
104 u32 offset, struct device_node *);
105void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); 103void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
106int gic_cpu_if_down(unsigned int gic_nr); 104int gic_cpu_if_down(unsigned int gic_nr);
107 105
108static inline void gic_init(unsigned int nr, int start, 106void gic_init(unsigned int nr, int start,
109 void __iomem *dist , void __iomem *cpu) 107 void __iomem *dist , void __iomem *cpu);
110{
111 gic_init_bases(nr, start, dist, cpu, 0, NULL);
112}
113 108
114int gicv2m_of_init(struct device_node *node, struct irq_domain *parent); 109int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
115 110
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index f644fdb06dd6..d5e5c5bef28c 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -5,9 +5,10 @@
5 * helpful for interrupt controllers to implement mapping between hardware 5 * helpful for interrupt controllers to implement mapping between hardware
6 * irq numbers and the Linux irq number space. 6 * irq numbers and the Linux irq number space.
7 * 7 *
8 * irq_domains also have a hook for translating device tree interrupt 8 * irq_domains also have hooks for translating device tree or other
9 * representation into a hardware irq number that can be mapped back to a 9 * firmware interrupt representations into a hardware irq number that
10 * Linux irq number without any extra platform support code. 10 * can be mapped back to a Linux irq number without any extra platform
11 * support code.
11 * 12 *
12 * Interrupt controller "domain" data structure. This could be defined as a 13 * Interrupt controller "domain" data structure. This could be defined as a
13 * irq domain controller. That is, it handles the mapping between hardware 14 * irq domain controller. That is, it handles the mapping between hardware
@@ -17,16 +18,12 @@
17 * model). It's the domain callbacks that are responsible for setting the 18 * model). It's the domain callbacks that are responsible for setting the
18 * irq_chip on a given irq_desc after it's been mapped. 19 * irq_chip on a given irq_desc after it's been mapped.
19 * 20 *
20 * The host code and data structures are agnostic to whether or not 21 * The host code and data structures use a fwnode_handle pointer to
21 * we use an open firmware device-tree. We do have references to struct 22 * identify the domain. In some cases, and in order to preserve source
22 * device_node in two places: in irq_find_host() to find the host matching 23 * code compatibility, this fwnode pointer is "upgraded" to a DT
23 * a given interrupt controller node, and of course as an argument to its 24 * device_node. For those firmware infrastructures that do not provide
24 * counterpart domain->ops->match() callback. However, those are treated as 25 * a unique identifier for an interrupt controller, the irq_domain
25 * generic pointers by the core and the fact that it's actually a device-node 26 * code offers a fwnode allocator.
26 * pointer is purely a convention between callers and implementation. This
27 * code could thus be used on other architectures by replacing those two
28 * by some sort of arch-specific void * "token" used to identify interrupt
29 * controllers.
30 */ 27 */
31 28
32#ifndef _LINUX_IRQDOMAIN_H 29#ifndef _LINUX_IRQDOMAIN_H
@@ -34,6 +31,7 @@
34 31
35#include <linux/types.h> 32#include <linux/types.h>
36#include <linux/irqhandler.h> 33#include <linux/irqhandler.h>
34#include <linux/of.h>
37#include <linux/radix-tree.h> 35#include <linux/radix-tree.h>
38 36
39struct device_node; 37struct device_node;
@@ -45,6 +43,24 @@ struct irq_data;
45/* Number of irqs reserved for a legacy isa controller */ 43/* Number of irqs reserved for a legacy isa controller */
46#define NUM_ISA_INTERRUPTS 16 44#define NUM_ISA_INTERRUPTS 16
47 45
46#define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
47
48/**
49 * struct irq_fwspec - generic IRQ specifier structure
50 *
51 * @fwnode: Pointer to a firmware-specific descriptor
52 * @param_count: Number of device-specific parameters
53 * @param: Device-specific parameters
54 *
55 * This structure, directly modeled after of_phandle_args, is used to
56 * pass a device-specific description of an interrupt.
57 */
58struct irq_fwspec {
59 struct fwnode_handle *fwnode;
60 int param_count;
61 u32 param[IRQ_DOMAIN_IRQ_SPEC_PARAMS];
62};
63
48/* 64/*
49 * Should several domains have the same device node, but serve 65 * Should several domains have the same device node, but serve
50 * different purposes (for example one domain is for PCI/MSI, and the 66 * different purposes (for example one domain is for PCI/MSI, and the
@@ -91,6 +107,8 @@ struct irq_domain_ops {
91 unsigned int nr_irqs); 107 unsigned int nr_irqs);
92 void (*activate)(struct irq_domain *d, struct irq_data *irq_data); 108 void (*activate)(struct irq_domain *d, struct irq_data *irq_data);
93 void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data); 109 void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data);
110 int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec,
111 unsigned long *out_hwirq, unsigned int *out_type);
94#endif 112#endif
95}; 113};
96 114
@@ -130,7 +148,7 @@ struct irq_domain {
130 unsigned int flags; 148 unsigned int flags;
131 149
132 /* Optional data */ 150 /* Optional data */
133 struct device_node *of_node; 151 struct fwnode_handle *fwnode;
134 enum irq_domain_bus_token bus_token; 152 enum irq_domain_bus_token bus_token;
135 struct irq_domain_chip_generic *gc; 153 struct irq_domain_chip_generic *gc;
136#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 154#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -163,11 +181,13 @@ enum {
163 181
164static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d) 182static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
165{ 183{
166 return d->of_node; 184 return to_of_node(d->fwnode);
167} 185}
168 186
169#ifdef CONFIG_IRQ_DOMAIN 187#ifdef CONFIG_IRQ_DOMAIN
170struct irq_domain *__irq_domain_add(struct device_node *of_node, int size, 188struct fwnode_handle *irq_domain_alloc_fwnode(void *data);
189void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
190struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
171 irq_hw_number_t hwirq_max, int direct_max, 191 irq_hw_number_t hwirq_max, int direct_max,
172 const struct irq_domain_ops *ops, 192 const struct irq_domain_ops *ops,
173 void *host_data); 193 void *host_data);
@@ -182,10 +202,21 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
182 irq_hw_number_t first_hwirq, 202 irq_hw_number_t first_hwirq,
183 const struct irq_domain_ops *ops, 203 const struct irq_domain_ops *ops,
184 void *host_data); 204 void *host_data);
185extern struct irq_domain *irq_find_matching_host(struct device_node *node, 205extern struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
186 enum irq_domain_bus_token bus_token); 206 enum irq_domain_bus_token bus_token);
187extern void irq_set_default_host(struct irq_domain *host); 207extern void irq_set_default_host(struct irq_domain *host);
188 208
209static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
210{
211 return node ? &node->fwnode : NULL;
212}
213
214static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
215 enum irq_domain_bus_token bus_token)
216{
217 return irq_find_matching_fwnode(of_node_to_fwnode(node), bus_token);
218}
219
189static inline struct irq_domain *irq_find_host(struct device_node *node) 220static inline struct irq_domain *irq_find_host(struct device_node *node)
190{ 221{
191 return irq_find_matching_host(node, DOMAIN_BUS_ANY); 222 return irq_find_matching_host(node, DOMAIN_BUS_ANY);
@@ -203,14 +234,14 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
203 const struct irq_domain_ops *ops, 234 const struct irq_domain_ops *ops,
204 void *host_data) 235 void *host_data)
205{ 236{
206 return __irq_domain_add(of_node, size, size, 0, ops, host_data); 237 return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
207} 238}
208static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 239static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
209 unsigned int max_irq, 240 unsigned int max_irq,
210 const struct irq_domain_ops *ops, 241 const struct irq_domain_ops *ops,
211 void *host_data) 242 void *host_data)
212{ 243{
213 return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data); 244 return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
214} 245}
215static inline struct irq_domain *irq_domain_add_legacy_isa( 246static inline struct irq_domain *irq_domain_add_legacy_isa(
216 struct device_node *of_node, 247 struct device_node *of_node,
@@ -224,7 +255,22 @@ static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node
224 const struct irq_domain_ops *ops, 255 const struct irq_domain_ops *ops,
225 void *host_data) 256 void *host_data)
226{ 257{
227 return __irq_domain_add(of_node, 0, ~0, 0, ops, host_data); 258 return __irq_domain_add(of_node_to_fwnode(of_node), 0, ~0, 0, ops, host_data);
259}
260
261static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
262 unsigned int size,
263 const struct irq_domain_ops *ops,
264 void *host_data)
265{
266 return __irq_domain_add(fwnode, size, size, 0, ops, host_data);
267}
268
269static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
270 const struct irq_domain_ops *ops,
271 void *host_data)
272{
273 return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
228} 274}
229 275
230extern void irq_domain_remove(struct irq_domain *host); 276extern void irq_domain_remove(struct irq_domain *host);
@@ -239,6 +285,7 @@ extern void irq_domain_disassociate(struct irq_domain *domain,
239 285
240extern unsigned int irq_create_mapping(struct irq_domain *host, 286extern unsigned int irq_create_mapping(struct irq_domain *host,
241 irq_hw_number_t hwirq); 287 irq_hw_number_t hwirq);
288extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
242extern void irq_dispose_mapping(unsigned int virq); 289extern void irq_dispose_mapping(unsigned int virq);
243 290
244/** 291/**
@@ -290,10 +337,23 @@ extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
290 void *chip_data, irq_flow_handler_t handler, 337 void *chip_data, irq_flow_handler_t handler,
291 void *handler_data, const char *handler_name); 338 void *handler_data, const char *handler_name);
292#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 339#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
293extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent, 340extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
294 unsigned int flags, unsigned int size, 341 unsigned int flags, unsigned int size,
295 struct device_node *node, 342 struct fwnode_handle *fwnode,
296 const struct irq_domain_ops *ops, void *host_data); 343 const struct irq_domain_ops *ops, void *host_data);
344
345static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
346 unsigned int flags,
347 unsigned int size,
348 struct device_node *node,
349 const struct irq_domain_ops *ops,
350 void *host_data)
351{
352 return irq_domain_create_hierarchy(parent, flags, size,
353 of_node_to_fwnode(node),
354 ops, host_data);
355}
356
297extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, 357extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
298 unsigned int nr_irqs, int node, void *arg, 358 unsigned int nr_irqs, int node, void *arg,
299 bool realloc); 359 bool realloc);
diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h
index e374e369fb2f..eb1bdcf95f2e 100644
--- a/include/linux/irqreturn.h
+++ b/include/linux/irqreturn.h
@@ -3,7 +3,7 @@
3 3
4/** 4/**
5 * enum irqreturn 5 * enum irqreturn
6 * @IRQ_NONE interrupt was not from this device 6 * @IRQ_NONE interrupt was not from this device or was not handled
7 * @IRQ_HANDLED interrupt was handled by this device 7 * @IRQ_HANDLED interrupt was handled by this device
8 * @IRQ_WAKE_THREAD handler requests to wake the handler thread 8 * @IRQ_WAKE_THREAD handler requests to wake the handler thread
9 */ 9 */
diff --git a/include/linux/msi.h b/include/linux/msi.h
index ad939d0ba816..0b4460374020 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -174,6 +174,7 @@ struct msi_controller {
174struct irq_domain; 174struct irq_domain;
175struct irq_chip; 175struct irq_chip;
176struct device_node; 176struct device_node;
177struct fwnode_handle;
177struct msi_domain_info; 178struct msi_domain_info;
178 179
179/** 180/**
@@ -262,7 +263,7 @@ enum {
262int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask, 263int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
263 bool force); 264 bool force);
264 265
265struct irq_domain *msi_create_irq_domain(struct device_node *of_node, 266struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
266 struct msi_domain_info *info, 267 struct msi_domain_info *info,
267 struct irq_domain *parent); 268 struct irq_domain *parent);
268int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, 269int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
@@ -270,7 +271,7 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
270void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev); 271void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev);
271struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain); 272struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);
272 273
273struct irq_domain *platform_msi_create_irq_domain(struct device_node *np, 274struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
274 struct msi_domain_info *info, 275 struct msi_domain_info *info,
275 struct irq_domain *parent); 276 struct irq_domain *parent);
276int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, 277int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
@@ -280,19 +281,26 @@ void platform_msi_domain_free_irqs(struct device *dev);
280 281
281#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN 282#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
282void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg); 283void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg);
283struct irq_domain *pci_msi_create_irq_domain(struct device_node *node, 284struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
284 struct msi_domain_info *info, 285 struct msi_domain_info *info,
285 struct irq_domain *parent); 286 struct irq_domain *parent);
286int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev, 287int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev,
287 int nvec, int type); 288 int nvec, int type);
288void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev); 289void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev);
289struct irq_domain *pci_msi_create_default_irq_domain(struct device_node *node, 290struct irq_domain *pci_msi_create_default_irq_domain(struct fwnode_handle *fwnode,
290 struct msi_domain_info *info, struct irq_domain *parent); 291 struct msi_domain_info *info, struct irq_domain *parent);
291 292
292irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev, 293irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
293 struct msi_desc *desc); 294 struct msi_desc *desc);
294int pci_msi_domain_check_cap(struct irq_domain *domain, 295int pci_msi_domain_check_cap(struct irq_domain *domain,
295 struct msi_domain_info *info, struct device *dev); 296 struct msi_domain_info *info, struct device *dev);
297u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev);
298struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);
299#else
300static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
301{
302 return NULL;
303}
296#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */ 304#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
297 305
298#endif /* LINUX_MSI_H */ 306#endif /* LINUX_MSI_H */
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 4bcbd586a672..65d969246a4d 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -46,6 +46,11 @@ extern int of_irq_get(struct device_node *dev, int index);
46extern int of_irq_get_byname(struct device_node *dev, const char *name); 46extern int of_irq_get_byname(struct device_node *dev, const char *name);
47extern int of_irq_to_resource_table(struct device_node *dev, 47extern int of_irq_to_resource_table(struct device_node *dev,
48 struct resource *res, int nr_irqs); 48 struct resource *res, int nr_irqs);
49extern struct irq_domain *of_msi_get_domain(struct device *dev,
50 struct device_node *np,
51 enum irq_domain_bus_token token);
52extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
53 u32 rid);
49#else 54#else
50static inline int of_irq_count(struct device_node *dev) 55static inline int of_irq_count(struct device_node *dev)
51{ 56{
@@ -64,6 +69,17 @@ static inline int of_irq_to_resource_table(struct device_node *dev,
64{ 69{
65 return 0; 70 return 0;
66} 71}
72static inline struct irq_domain *of_msi_get_domain(struct device *dev,
73 struct device_node *np,
74 enum irq_domain_bus_token token)
75{
76 return NULL;
77}
78static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
79 u32 rid)
80{
81 return NULL;
82}
67#endif 83#endif
68 84
69#if defined(CONFIG_OF) 85#if defined(CONFIG_OF)
@@ -75,6 +91,7 @@ static inline int of_irq_to_resource_table(struct device_node *dev,
75extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); 91extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
76extern struct device_node *of_irq_find_parent(struct device_node *child); 92extern struct device_node *of_irq_find_parent(struct device_node *child);
77extern void of_msi_configure(struct device *dev, struct device_node *np); 93extern void of_msi_configure(struct device *dev, struct device_node *np);
94u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
78 95
79#else /* !CONFIG_OF */ 96#else /* !CONFIG_OF */
80static inline unsigned int irq_of_parse_and_map(struct device_node *dev, 97static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
@@ -87,6 +104,12 @@ static inline void *of_irq_find_parent(struct device_node *child)
87{ 104{
88 return NULL; 105 return NULL;
89} 106}
107
108static inline u32 of_msi_map_rid(struct device *dev,
109 struct device_node *msi_np, u32 rid_in)
110{
111 return rid_in;
112}
90#endif /* !CONFIG_OF */ 113#endif /* !CONFIG_OF */
91 114
92#endif /* __OF_IRQ_H */ 115#endif /* __OF_IRQ_H */