1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#ifndef _LINUX_IRQDOMAIN_H
33#define _LINUX_IRQDOMAIN_H
34
35#include <linux/types.h>
36#include <linux/radix-tree.h>
37
38struct device_node;
39struct irq_domain;
40struct of_device_id;
41
42
43#define NUM_ISA_INTERRUPTS 16
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60struct irq_domain_ops {
61 int (*match)(struct irq_domain *d, struct device_node *node);
62 int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
63 void (*unmap)(struct irq_domain *d, unsigned int virq);
64 int (*xlate)(struct irq_domain *d, struct device_node *node,
65 const u32 *intspec, unsigned int intsize,
66 unsigned long *out_hwirq, unsigned int *out_type);
67};
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86struct irq_domain {
87 struct list_head link;
88
89
90 unsigned int revmap_type;
91 union {
92 struct {
93 unsigned int size;
94 unsigned int first_irq;
95 irq_hw_number_t first_hwirq;
96 } legacy;
97 struct {
98 unsigned int size;
99 unsigned int *revmap;
100 } linear;
101 struct {
102 unsigned int max_irq;
103 } nomap;
104 struct radix_tree_root tree;
105 } revmap_data;
106 const struct irq_domain_ops *ops;
107 void *host_data;
108 irq_hw_number_t inval_irq;
109
110
111 struct device_node *of_node;
112};
113
114#ifdef CONFIG_IRQ_DOMAIN
115struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
116 unsigned int size,
117 unsigned int first_irq,
118 const struct irq_domain_ops *ops,
119 void *host_data);
120struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
121 unsigned int size,
122 unsigned int first_irq,
123 irq_hw_number_t first_hwirq,
124 const struct irq_domain_ops *ops,
125 void *host_data);
126struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
127 unsigned int size,
128 const struct irq_domain_ops *ops,
129 void *host_data);
130struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
131 unsigned int max_irq,
132 const struct irq_domain_ops *ops,
133 void *host_data);
134struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
135 const struct irq_domain_ops *ops,
136 void *host_data);
137
138extern struct irq_domain *irq_find_host(struct device_node *node);
139extern void irq_set_default_host(struct irq_domain *host);
140
141static inline struct irq_domain *irq_domain_add_legacy_isa(
142 struct device_node *of_node,
143 const struct irq_domain_ops *ops,
144 void *host_data)
145{
146 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
147 host_data);
148}
149
150extern void irq_domain_remove(struct irq_domain *host);
151
152extern int irq_domain_associate_many(struct irq_domain *domain,
153 unsigned int irq_base,
154 irq_hw_number_t hwirq_base, int count);
155static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
156 irq_hw_number_t hwirq)
157{
158 return irq_domain_associate_many(domain, irq, hwirq, 1);
159}
160
161extern unsigned int irq_create_mapping(struct irq_domain *host,
162 irq_hw_number_t hwirq);
163extern void irq_dispose_mapping(unsigned int virq);
164extern unsigned int irq_find_mapping(struct irq_domain *host,
165 irq_hw_number_t hwirq);
166extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
167extern int irq_create_strict_mappings(struct irq_domain *domain,
168 unsigned int irq_base,
169 irq_hw_number_t hwirq_base, int count);
170
171static inline int irq_create_identity_mapping(struct irq_domain *host,
172 irq_hw_number_t hwirq)
173{
174 return irq_create_strict_mappings(host, hwirq, hwirq, 1);
175}
176
177extern unsigned int irq_linear_revmap(struct irq_domain *host,
178 irq_hw_number_t hwirq);
179
180extern const struct irq_domain_ops irq_domain_simple_ops;
181
182
183int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
184 const u32 *intspec, unsigned int intsize,
185 irq_hw_number_t *out_hwirq, unsigned int *out_type);
186int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
187 const u32 *intspec, unsigned int intsize,
188 irq_hw_number_t *out_hwirq, unsigned int *out_type);
189int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
190 const u32 *intspec, unsigned int intsize,
191 irq_hw_number_t *out_hwirq, unsigned int *out_type);
192
193#if defined(CONFIG_OF_IRQ)
194extern void irq_domain_generate_simple(const struct of_device_id *match,
195 u64 phys_base, unsigned int irq_start);
196#else
197static inline void irq_domain_generate_simple(const struct of_device_id *match,
198 u64 phys_base, unsigned int irq_start) { }
199#endif
200
201#else
202static inline void irq_dispose_mapping(unsigned int virq) { }
203#endif
204
205#endif
206