aboutsummaryrefslogtreecommitdiffstats
path: root/arch/c6x/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 13:27:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 13:27:19 -0400
commitc207f3a43194e108dda43dc9a1ce507335cff6b9 (patch)
tree55880f8301e8546b1908f69947d0d41aaa044814 /arch/c6x/include
parentc7c66c0cb0c77b1a8edf09bca57d922312d58030 (diff)
parente7cc3aca0f6a36b018934264ee20bee45dc13e29 (diff)
Merge tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull irq_domain support for all architectures from Grant Likely: "Generialize powerpc's irq_host as irq_domain This branch takes the PowerPC irq_host infrastructure (reverse mapping from Linux IRQ numbers to hardware irq numbering), generalizes it, renames it to irq_domain, and makes it available to all architectures. Originally the plan has been to create an all-new irq_domain implementation which addresses some of the powerpc shortcomings such as not handling 1:1 mappings well, but doing that proved to be far more difficult and invasive than generalizing the working code and refactoring it in-place. So, this branch rips out the 'new' irq_domain and replaces it with the modified powerpc version (in a fully bisectable way of course). It converts all users over to the new API and makes irq_domain selectable on any architecture. No architecture is forced to enable irq_domain, but the infrastructure is required for doing OpenFirmware style irq translations. It will even work on SPARC even though SPARC has it's own mechanism for translating irqs at boot time. MIPS, microblaze, embedded x86 and c6x are converted too. The resulting irq_domain code is probably still too verbose and can be optimized more, but that can be done incrementally and is a task for follow-on patches." * tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6: (31 commits) dt: fix twl4030 for non-dt compile on x86 mfd: twl-core: Add IRQ_DOMAIN dependency devicetree: Add empty of_platform_populate() for !CONFIG_OF_ADDRESS (sparc) irq_domain: Centralize definition of irq_dispose_mapping() irq_domain/mips: Allow irq_domain on MIPS irq_domain/x86: Convert x86 (embedded) to use common irq_domain ppc-6xx: fix build failure in flipper-pic.c and hlwd-pic.c irq_domain/microblaze: Convert microblaze to use irq_domains irq_domain/powerpc: Replace custom xlate functions with library functions irq_domain/powerpc: constify irq_domain_ops irq_domain/c6x: Use library of xlate functions irq_domain/c6x: constify irq_domain structures irq_domain/c6x: Convert c6x to use generic irq_domain support. irq_domain: constify irq_domain_ops irq_domain: Create common xlate functions that device drivers can use irq_domain: Remove irq_domain_add_simple() irq_domain: Remove 'new' irq_domain in favour of the ppc one mfd: twl-core.c: Fix the number of interrupts managed by twl4030 of/address: add empty static inlines for !CONFIG_OF irq_domain: Add support for base irq and hwirq in legacy mappings ...
Diffstat (limited to 'arch/c6x/include')
-rw-r--r--arch/c6x/include/asm/irq.h245
1 files changed, 1 insertions, 244 deletions
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
index a6ae3c9d9c40..f13b78d5e1ca 100644
--- a/arch/c6x/include/asm/irq.h
+++ b/arch/c6x/include/asm/irq.h
@@ -13,6 +13,7 @@
13#ifndef _ASM_C6X_IRQ_H 13#ifndef _ASM_C6X_IRQ_H
14#define _ASM_C6X_IRQ_H 14#define _ASM_C6X_IRQ_H
15 15
16#include <linux/irqdomain.h>
16#include <linux/threads.h> 17#include <linux/threads.h>
17#include <linux/list.h> 18#include <linux/list.h>
18#include <linux/radix-tree.h> 19#include <linux/radix-tree.h>
@@ -41,253 +42,9 @@
41/* This number is used when no interrupt has been assigned */ 42/* This number is used when no interrupt has been assigned */
42#define NO_IRQ 0 43#define NO_IRQ 0
43 44
44/* This type is the placeholder for a hardware interrupt number. It has to
45 * be big enough to enclose whatever representation is used by a given
46 * platform.
47 */
48typedef unsigned long irq_hw_number_t;
49
50/* Interrupt controller "host" data structure. This could be defined as a
51 * irq domain controller. That is, it handles the mapping between hardware
52 * and virtual interrupt numbers for a given interrupt domain. The host
53 * structure is generally created by the PIC code for a given PIC instance
54 * (though a host can cover more than one PIC if they have a flat number
55 * model). It's the host callbacks that are responsible for setting the
56 * irq_chip on a given irq_desc after it's been mapped.
57 *
58 * The host code and data structures are fairly agnostic to the fact that
59 * we use an open firmware device-tree. We do have references to struct
60 * device_node in two places: in irq_find_host() to find the host matching
61 * a given interrupt controller node, and of course as an argument to its
62 * counterpart host->ops->match() callback. However, those are treated as
63 * generic pointers by the core and the fact that it's actually a device-node
64 * pointer is purely a convention between callers and implementation. This
65 * code could thus be used on other architectures by replacing those two
66 * by some sort of arch-specific void * "token" used to identify interrupt
67 * controllers.
68 */
69struct irq_host;
70struct radix_tree_root;
71struct device_node;
72
73/* Functions below are provided by the host and called whenever a new mapping
74 * is created or an old mapping is disposed. The host can then proceed to
75 * whatever internal data structures management is required. It also needs
76 * to setup the irq_desc when returning from map().
77 */
78struct irq_host_ops {
79 /* Match an interrupt controller device node to a host, returns
80 * 1 on a match
81 */
82 int (*match)(struct irq_host *h, struct device_node *node);
83
84 /* Create or update a mapping between a virtual irq number and a hw
85 * irq number. This is called only once for a given mapping.
86 */
87 int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
88
89 /* Dispose of such a mapping */
90 void (*unmap)(struct irq_host *h, unsigned int virq);
91
92 /* Translate device-tree interrupt specifier from raw format coming
93 * from the firmware to a irq_hw_number_t (interrupt line number) and
94 * type (sense) that can be passed to set_irq_type(). In the absence
95 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
96 * will return the hw number in the first cell and IRQ_TYPE_NONE for
97 * the type (which amount to keeping whatever default value the
98 * interrupt controller has for that line)
99 */
100 int (*xlate)(struct irq_host *h, struct device_node *ctrler,
101 const u32 *intspec, unsigned int intsize,
102 irq_hw_number_t *out_hwirq, unsigned int *out_type);
103};
104
105struct irq_host {
106 struct list_head link;
107
108 /* type of reverse mapping technique */
109 unsigned int revmap_type;
110#define IRQ_HOST_MAP_PRIORITY 0 /* core priority irqs, get irqs 1..15 */
111#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */
112#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */
113#define IRQ_HOST_MAP_TREE 3 /* radix tree */
114 union {
115 struct {
116 unsigned int size;
117 unsigned int *revmap;
118 } linear;
119 struct radix_tree_root tree;
120 } revmap_data;
121 struct irq_host_ops *ops;
122 void *host_data;
123 irq_hw_number_t inval_irq;
124
125 /* Optional device node pointer */
126 struct device_node *of_node;
127};
128
129struct irq_data; 45struct irq_data;
130extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); 46extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
131extern irq_hw_number_t virq_to_hw(unsigned int virq); 47extern irq_hw_number_t virq_to_hw(unsigned int virq);
132extern bool virq_is_host(unsigned int virq, struct irq_host *host);
133
134/**
135 * irq_alloc_host - Allocate a new irq_host data structure
136 * @of_node: optional device-tree node of the interrupt controller
137 * @revmap_type: type of reverse mapping to use
138 * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
139 * @ops: map/unmap host callbacks
140 * @inval_irq: provide a hw number in that host space that is always invalid
141 *
142 * Allocates and initialize and irq_host structure. Note that in the case of
143 * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
144 * for all legacy interrupts except 0 (which is always the invalid irq for
145 * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
146 * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
147 * later during boot automatically (the reverse mapping will use the slow path
148 * until that happens).
149 */
150extern struct irq_host *irq_alloc_host(struct device_node *of_node,
151 unsigned int revmap_type,
152 unsigned int revmap_arg,
153 struct irq_host_ops *ops,
154 irq_hw_number_t inval_irq);
155
156
157/**
158 * irq_find_host - Locates a host for a given device node
159 * @node: device-tree node of the interrupt controller
160 */
161extern struct irq_host *irq_find_host(struct device_node *node);
162
163
164/**
165 * irq_set_default_host - Set a "default" host
166 * @host: default host pointer
167 *
168 * For convenience, it's possible to set a "default" host that will be used
169 * whenever NULL is passed to irq_create_mapping(). It makes life easier for
170 * platforms that want to manipulate a few hard coded interrupt numbers that
171 * aren't properly represented in the device-tree.
172 */
173extern void irq_set_default_host(struct irq_host *host);
174
175
176/**
177 * irq_set_virq_count - Set the maximum number of virt irqs
178 * @count: number of linux virtual irqs, capped with NR_IRQS
179 *
180 * This is mainly for use by platforms like iSeries who want to program
181 * the virtual irq number in the controller to avoid the reverse mapping
182 */
183extern void irq_set_virq_count(unsigned int count);
184
185
186/**
187 * irq_create_mapping - Map a hardware interrupt into linux virq space
188 * @host: host owning this hardware interrupt or NULL for default host
189 * @hwirq: hardware irq number in that host space
190 *
191 * Only one mapping per hardware interrupt is permitted. Returns a linux
192 * virq number.
193 * If the sense/trigger is to be specified, set_irq_type() should be called
194 * on the number returned from that call.
195 */
196extern unsigned int irq_create_mapping(struct irq_host *host,
197 irq_hw_number_t hwirq);
198
199
200/**
201 * irq_dispose_mapping - Unmap an interrupt
202 * @virq: linux virq number of the interrupt to unmap
203 */
204extern void irq_dispose_mapping(unsigned int virq);
205
206/**
207 * irq_find_mapping - Find a linux virq from an hw irq number.
208 * @host: host owning this hardware interrupt
209 * @hwirq: hardware irq number in that host space
210 *
211 * This is a slow path, for use by generic code. It's expected that an
212 * irq controller implementation directly calls the appropriate low level
213 * mapping function.
214 */
215extern unsigned int irq_find_mapping(struct irq_host *host,
216 irq_hw_number_t hwirq);
217
218/**
219 * irq_create_direct_mapping - Allocate a virq for direct mapping
220 * @host: host to allocate the virq for or NULL for default host
221 *
222 * This routine is used for irq controllers which can choose the hardware
223 * interrupt numbers they generate. In such a case it's simplest to use
224 * the linux virq as the hardware interrupt number.
225 */
226extern unsigned int irq_create_direct_mapping(struct irq_host *host);
227
228/**
229 * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
230 * @host: host owning this hardware interrupt
231 * @virq: linux irq number
232 * @hwirq: hardware irq number in that host space
233 *
234 * This is for use by irq controllers that use a radix tree reverse
235 * mapping for fast lookup.
236 */
237extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
238 irq_hw_number_t hwirq);
239
240/**
241 * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
242 * @host: host owning this hardware interrupt
243 * @hwirq: hardware irq number in that host space
244 *
245 * This is a fast path, for use by irq controller code that uses radix tree
246 * revmaps
247 */
248extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
249 irq_hw_number_t hwirq);
250
251/**
252 * irq_linear_revmap - Find a linux virq from a hw irq number.
253 * @host: host owning this hardware interrupt
254 * @hwirq: hardware irq number in that host space
255 *
256 * This is a fast path, for use by irq controller code that uses linear
257 * revmaps. It does fallback to the slow path if the revmap doesn't exist
258 * yet and will create the revmap entry with appropriate locking
259 */
260
261extern unsigned int irq_linear_revmap(struct irq_host *host,
262 irq_hw_number_t hwirq);
263
264
265
266/**
267 * irq_alloc_virt - Allocate virtual irq numbers
268 * @host: host owning these new virtual irqs
269 * @count: number of consecutive numbers to allocate
270 * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
271 *
272 * This is a low level function that is used internally by irq_create_mapping()
273 * and that can be used by some irq controllers implementations for things
274 * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
275 */
276extern unsigned int irq_alloc_virt(struct irq_host *host,
277 unsigned int count,
278 unsigned int hint);
279
280/**
281 * irq_free_virt - Free virtual irq numbers
282 * @virq: virtual irq number of the first interrupt to free
283 * @count: number of interrupts to free
284 *
285 * This function is the opposite of irq_alloc_virt. It will not clear reverse
286 * maps, this should be done previously by unmap'ing the interrupt. In fact,
287 * all interrupts covered by the range being freed should have been unmapped
288 * prior to calling this.
289 */
290extern void irq_free_virt(unsigned int virq, unsigned int count);
291 48
292extern void __init init_pic_c64xplus(void); 49extern void __init init_pic_c64xplus(void);
293 50