aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/irqdomain.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/irqdomain.h')
-rw-r--r--include/linux/irqdomain.h142
1 files changed, 75 insertions, 67 deletions
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index ba2c708adcff..c983ed18c332 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,57 +73,48 @@ struct irq_domain_chip_generic;
73/** 73/**
74 * struct irq_domain - Hardware interrupt number translation object 74 * struct irq_domain - Hardware interrupt number translation object
75 * @link: Element in global irq_domain list. 75 * @link: Element in global irq_domain list.
76 * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This 76 * @name: Name of interrupt domain
77 * will be one of the IRQ_DOMAIN_MAP_* values.
78 * @revmap_data: Revmap method specific data.
79 * @ops: pointer to irq_domain methods 77 * @ops: pointer to irq_domain methods
80 * @host_data: private data pointer for use by owner. Not touched by irq_domain 78 * @host_data: private data pointer for use by owner. Not touched by irq_domain
81 * core code. 79 * core code.
82 * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator 80 *
83 * of the irq_domain is responsible for allocating the array of 81 * Optional elements
84 * irq_desc structures. 82 * @of_node: Pointer to device tree nodes associated with the irq_domain. Used
85 * @nr_irq: Number of irqs managed by the irq domain 83 * when decoding device tree interrupt specifiers.
86 * @hwirq_base: Starting number for hwirqs managed by the irq domain 84 * @gc: Pointer to a list of generic chips. There is a helper function for
87 * @of_node: (optional) Pointer to device tree nodes associated with the 85 * setting up one or more generic chips for interrupt controllers
88 * irq_domain. Used when decoding device tree interrupt specifiers. 86 * drivers using the generic chip library which uses this pointer.
87 *
88 * Revmap data, used internally by irq_domain
89 * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
90 * support direct mapping
91 * @revmap_size: Size of the linear map table @linear_revmap[]
92 * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
93 * @linear_revmap: Linear table of hwirq->virq reverse mappings
89 */ 94 */
90struct irq_domain { 95struct irq_domain {
91 struct list_head link; 96 struct list_head link;
92 97 const char *name;
93 /* type of reverse mapping_technique */
94 unsigned int revmap_type;
95 union {
96 struct {
97 unsigned int size;
98 unsigned int first_irq;
99 irq_hw_number_t first_hwirq;
100 } legacy;
101 struct {
102 unsigned int size;
103 unsigned int *revmap;
104 } linear;
105 struct {
106 unsigned int max_irq;
107 } nomap;
108 struct radix_tree_root tree;
109 } revmap_data;
110 const struct irq_domain_ops *ops; 98 const struct irq_domain_ops *ops;
111 void *host_data; 99 void *host_data;
112 irq_hw_number_t inval_irq;
113 100
114 /* Optional device node pointer */ 101 /* Optional data */
115 struct device_node *of_node; 102 struct device_node *of_node;
116 /* Optional pointer to generic interrupt chips */
117 struct irq_domain_chip_generic *gc; 103 struct irq_domain_chip_generic *gc;
118};
119 104
120#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs. 105 /* reverse map data. The linear map gets appended to the irq_domain */
121 * ie. legacy 8259, gets irqs 1..15 */ 106 irq_hw_number_t hwirq_max;
122#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */ 107 unsigned int revmap_direct_max_irq;
123#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */ 108 unsigned int revmap_size;
124#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */ 109 struct radix_tree_root revmap_tree;
110 unsigned int linear_revmap[];
111};
125 112
126#ifdef CONFIG_IRQ_DOMAIN 113#ifdef CONFIG_IRQ_DOMAIN
114struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
115 irq_hw_number_t hwirq_max, int direct_max,
116 const struct irq_domain_ops *ops,
117 void *host_data);
127struct irq_domain *irq_domain_add_simple(struct device_node *of_node, 118struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
128 unsigned int size, 119 unsigned int size,
129 unsigned int first_irq, 120 unsigned int first_irq,
@@ -135,21 +126,30 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
135 irq_hw_number_t first_hwirq, 126 irq_hw_number_t first_hwirq,
136 const struct irq_domain_ops *ops, 127 const struct irq_domain_ops *ops,
137 void *host_data); 128 void *host_data);
138struct irq_domain *irq_domain_add_linear(struct device_node *of_node, 129extern struct irq_domain *irq_find_host(struct device_node *node);
130extern void irq_set_default_host(struct irq_domain *host);
131
132/**
133 * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
134 * @of_node: pointer to interrupt controller's device tree node.
135 * @size: Number of interrupts in the domain.
136 * @ops: map/unmap domain callbacks
137 * @host_data: Controller private data pointer
138 */
139static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
139 unsigned int size, 140 unsigned int size,
140 const struct irq_domain_ops *ops, 141 const struct irq_domain_ops *ops,
141 void *host_data); 142 void *host_data)
142struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 143{
144 return __irq_domain_add(of_node, size, size, 0, ops, host_data);
145}
146static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
143 unsigned int max_irq, 147 unsigned int max_irq,
144 const struct irq_domain_ops *ops, 148 const struct irq_domain_ops *ops,
145 void *host_data); 149 void *host_data)
146struct irq_domain *irq_domain_add_tree(struct device_node *of_node, 150{
147 const struct irq_domain_ops *ops, 151 return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data);
148 void *host_data); 152}
149
150extern struct irq_domain *irq_find_host(struct device_node *node);
151extern void irq_set_default_host(struct irq_domain *host);
152
153static inline struct irq_domain *irq_domain_add_legacy_isa( 153static inline struct irq_domain *irq_domain_add_legacy_isa(
154 struct device_node *of_node, 154 struct device_node *of_node,
155 const struct irq_domain_ops *ops, 155 const struct irq_domain_ops *ops,
@@ -158,21 +158,40 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
158 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, 158 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
159 host_data); 159 host_data);
160} 160}
161static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
162 const struct irq_domain_ops *ops,
163 void *host_data)
164{
165 return __irq_domain_add(of_node, 0, ~0, 0, ops, host_data);
166}
161 167
162extern void irq_domain_remove(struct irq_domain *host); 168extern void irq_domain_remove(struct irq_domain *host);
163 169
164extern int irq_domain_associate_many(struct irq_domain *domain, 170extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
165 unsigned int irq_base, 171 irq_hw_number_t hwirq);
166 irq_hw_number_t hwirq_base, int count); 172extern void irq_domain_associate_many(struct irq_domain *domain,
167static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq, 173 unsigned int irq_base,
168 irq_hw_number_t hwirq) 174 irq_hw_number_t hwirq_base, int count);
169{
170 return irq_domain_associate_many(domain, irq, hwirq, 1);
171}
172 175
173extern unsigned int irq_create_mapping(struct irq_domain *host, 176extern unsigned int irq_create_mapping(struct irq_domain *host,
174 irq_hw_number_t hwirq); 177 irq_hw_number_t hwirq);
175extern void irq_dispose_mapping(unsigned int virq); 178extern void irq_dispose_mapping(unsigned int virq);
179
180/**
181 * irq_linear_revmap() - Find a linux irq from a hw irq number.
182 * @domain: domain owning this hardware interrupt
183 * @hwirq: hardware irq number in that domain space
184 *
185 * This is a fast path alternative to irq_find_mapping() that can be
186 * called directly by irq controller code to save a handful of
187 * instructions. It is always safe to call, but won't find irqs mapped
188 * using the radix tree.
189 */
190static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
191 irq_hw_number_t hwirq)
192{
193 return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0;
194}
176extern unsigned int irq_find_mapping(struct irq_domain *host, 195extern unsigned int irq_find_mapping(struct irq_domain *host,
177 irq_hw_number_t hwirq); 196 irq_hw_number_t hwirq);
178extern unsigned int irq_create_direct_mapping(struct irq_domain *host); 197extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
@@ -186,9 +205,6 @@ static inline int irq_create_identity_mapping(struct irq_domain *host,
186 return irq_create_strict_mappings(host, hwirq, hwirq, 1); 205 return irq_create_strict_mappings(host, hwirq, hwirq, 1);
187} 206}
188 207
189extern unsigned int irq_linear_revmap(struct irq_domain *host,
190 irq_hw_number_t hwirq);
191
192extern const struct irq_domain_ops irq_domain_simple_ops; 208extern const struct irq_domain_ops irq_domain_simple_ops;
193 209
194/* stock xlate functions */ 210/* stock xlate functions */
@@ -202,14 +218,6 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
202 const u32 *intspec, unsigned int intsize, 218 const u32 *intspec, unsigned int intsize,
203 irq_hw_number_t *out_hwirq, unsigned int *out_type); 219 irq_hw_number_t *out_hwirq, unsigned int *out_type);
204 220
205#if defined(CONFIG_OF_IRQ)
206extern void irq_domain_generate_simple(const struct of_device_id *match,
207 u64 phys_base, unsigned int irq_start);
208#else /* CONFIG_OF_IRQ */
209static inline void irq_domain_generate_simple(const struct of_device_id *match,
210 u64 phys_base, unsigned int irq_start) { }
211#endif /* !CONFIG_OF_IRQ */
212
213#else /* CONFIG_IRQ_DOMAIN */ 221#else /* CONFIG_IRQ_DOMAIN */
214static inline void irq_dispose_mapping(unsigned int virq) { } 222static inline void irq_dispose_mapping(unsigned int virq) { }
215#endif /* !CONFIG_IRQ_DOMAIN */ 223#endif /* !CONFIG_IRQ_DOMAIN */