aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
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/powerpc
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/powerpc')
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/include/asm/ehv_pic.h2
-rw-r--r--arch/powerpc/include/asm/i8259.h2
-rw-r--r--arch/powerpc/include/asm/irq.h247
-rw-r--r--arch/powerpc/include/asm/mpic.h2
-rw-r--r--arch/powerpc/include/asm/xics.h2
-rw-r--r--arch/powerpc/kernel/irq.c617
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c12
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c15
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c16
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c12
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c14
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c15
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c15
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c29
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c16
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c16
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c14
-rw-r--r--arch/powerpc/platforms/embedded6xx/flipper-pic.c24
-rw-r--r--arch/powerpc/platforms/embedded6xx/hlwd-pic.c29
-rw-r--r--arch/powerpc/platforms/iseries/irq.c11
-rw-r--r--arch/powerpc/platforms/powermac/pic.c26
-rw-r--r--arch/powerpc/platforms/powermac/smp.c9
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c11
-rw-r--r--arch/powerpc/platforms/wsp/opb_pic.c26
-rw-r--r--arch/powerpc/sysdev/cpm1.c9
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c23
-rw-r--r--arch/powerpc/sysdev/ehv_pic.c14
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c10
-rw-r--r--arch/powerpc/sysdev/fsl_msi.h2
-rw-r--r--arch/powerpc/sysdev/i8259.c15
-rw-r--r--arch/powerpc/sysdev/ipic.c31
-rw-r--r--arch/powerpc/sysdev/ipic.h2
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c11
-rw-r--r--arch/powerpc/sysdev/mpic.c17
-rw-r--r--arch/powerpc/sysdev/mpic_msi.c2
-rw-r--r--arch/powerpc/sysdev/mv64x60_pic.c11
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c26
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.h2
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c13
-rw-r--r--arch/powerpc/sysdev/uic.c26
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c25
-rw-r--r--arch/powerpc/sysdev/xilinx_intc.c19
43 files changed, 230 insertions, 1211 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1919634a9b32..303703d716fe 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,7 @@ config PPC
135 select HAVE_GENERIC_HARDIRQS 135 select HAVE_GENERIC_HARDIRQS
136 select HAVE_SPARSE_IRQ 136 select HAVE_SPARSE_IRQ
137 select IRQ_PER_CPU 137 select IRQ_PER_CPU
138 select IRQ_DOMAIN
138 select GENERIC_IRQ_SHOW 139 select GENERIC_IRQ_SHOW
139 select GENERIC_IRQ_SHOW_LEVEL 140 select GENERIC_IRQ_SHOW_LEVEL
140 select IRQ_FORCED_THREADING 141 select IRQ_FORCED_THREADING
diff --git a/arch/powerpc/include/asm/ehv_pic.h b/arch/powerpc/include/asm/ehv_pic.h
index a9e1f4f796f6..dc7d48e3ea90 100644
--- a/arch/powerpc/include/asm/ehv_pic.h
+++ b/arch/powerpc/include/asm/ehv_pic.h
@@ -25,7 +25,7 @@
25 25
26struct ehv_pic { 26struct ehv_pic {
27 /* The remapper for this EHV_PIC */ 27 /* The remapper for this EHV_PIC */
28 struct irq_host *irqhost; 28 struct irq_domain *irqhost;
29 29
30 /* The "linux" controller struct */ 30 /* The "linux" controller struct */
31 struct irq_chip hc_irq; 31 struct irq_chip hc_irq;
diff --git a/arch/powerpc/include/asm/i8259.h b/arch/powerpc/include/asm/i8259.h
index 105ade297aad..c3fdfbd5a673 100644
--- a/arch/powerpc/include/asm/i8259.h
+++ b/arch/powerpc/include/asm/i8259.h
@@ -6,7 +6,7 @@
6 6
7extern void i8259_init(struct device_node *node, unsigned long intack_addr); 7extern void i8259_init(struct device_node *node, unsigned long intack_addr);
8extern unsigned int i8259_irq(void); 8extern unsigned int i8259_irq(void);
9extern struct irq_host *i8259_get_host(void); 9extern struct irq_domain *i8259_get_host(void);
10 10
11#endif /* __KERNEL__ */ 11#endif /* __KERNEL__ */
12#endif /* _ASM_POWERPC_I8259_H */ 12#endif /* _ASM_POWERPC_I8259_H */
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index c0e1bc319e35..fe0b09dceb7d 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -9,6 +9,7 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/irqdomain.h>
12#include <linux/threads.h> 13#include <linux/threads.h>
13#include <linux/list.h> 14#include <linux/list.h>
14#include <linux/radix-tree.h> 15#include <linux/radix-tree.h>
@@ -35,258 +36,12 @@ extern atomic_t ppc_n_lost_interrupts;
35/* Total number of virq in the platform */ 36/* Total number of virq in the platform */
36#define NR_IRQS CONFIG_NR_IRQS 37#define NR_IRQS CONFIG_NR_IRQS
37 38
38/* Number of irqs reserved for the legacy controller */
39#define NUM_ISA_INTERRUPTS 16
40
41/* Same thing, used by the generic IRQ code */ 39/* Same thing, used by the generic IRQ code */
42#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS 40#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS
43 41
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;
71
72/* Functions below are provided by the host and called whenever a new mapping
73 * is created or an old mapping is disposed. The host can then proceed to
74 * whatever internal data structures management is required. It also needs
75 * to setup the irq_desc when returning from map().
76 */
77struct irq_host_ops {
78 /* Match an interrupt controller device node to a host, returns
79 * 1 on a match
80 */
81 int (*match)(struct irq_host *h, struct device_node *node);
82
83 /* Create or update a mapping between a virtual irq number and a hw
84 * irq number. This is called only once for a given mapping.
85 */
86 int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
87
88 /* Dispose of such a mapping */
89 void (*unmap)(struct irq_host *h, unsigned int virq);
90
91 /* Translate device-tree interrupt specifier from raw format coming
92 * from the firmware to a irq_hw_number_t (interrupt line number) and
93 * type (sense) that can be passed to set_irq_type(). In the absence
94 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
95 * will return the hw number in the first cell and IRQ_TYPE_NONE for
96 * the type (which amount to keeping whatever default value the
97 * interrupt controller has for that line)
98 */
99 int (*xlate)(struct irq_host *h, struct device_node *ctrler,
100 const u32 *intspec, unsigned int intsize,
101 irq_hw_number_t *out_hwirq, unsigned int *out_type);
102};
103
104struct irq_host {
105 struct list_head link;
106
107 /* type of reverse mapping technique */
108 unsigned int revmap_type;
109#define IRQ_HOST_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
110#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */
111#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */
112#define IRQ_HOST_MAP_TREE 3 /* radix tree */
113 union {
114 struct {
115 unsigned int size;
116 unsigned int *revmap;
117 } linear;
118 struct radix_tree_root tree;
119 } revmap_data;
120 struct irq_host_ops *ops;
121 void *host_data;
122 irq_hw_number_t inval_irq;
123
124 /* Optional device node pointer */
125 struct device_node *of_node;
126};
127
128struct irq_data; 42struct irq_data;
129extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); 43extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
130extern irq_hw_number_t virq_to_hw(unsigned int virq); 44extern irq_hw_number_t virq_to_hw(unsigned int virq);
131extern bool virq_is_host(unsigned int virq, struct irq_host *host);
132
133/**
134 * irq_alloc_host - Allocate a new irq_host data structure
135 * @of_node: optional device-tree node of the interrupt controller
136 * @revmap_type: type of reverse mapping to use
137 * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
138 * @ops: map/unmap host callbacks
139 * @inval_irq: provide a hw number in that host space that is always invalid
140 *
141 * Allocates and initialize and irq_host structure. Note that in the case of
142 * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
143 * for all legacy interrupts except 0 (which is always the invalid irq for
144 * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
145 * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
146 * later during boot automatically (the reverse mapping will use the slow path
147 * until that happens).
148 */
149extern struct irq_host *irq_alloc_host(struct device_node *of_node,
150 unsigned int revmap_type,
151 unsigned int revmap_arg,
152 struct irq_host_ops *ops,
153 irq_hw_number_t inval_irq);
154
155
156/**
157 * irq_find_host - Locates a host for a given device node
158 * @node: device-tree node of the interrupt controller
159 */
160extern struct irq_host *irq_find_host(struct device_node *node);
161
162
163/**
164 * irq_set_default_host - Set a "default" host
165 * @host: default host pointer
166 *
167 * For convenience, it's possible to set a "default" host that will be used
168 * whenever NULL is passed to irq_create_mapping(). It makes life easier for
169 * platforms that want to manipulate a few hard coded interrupt numbers that
170 * aren't properly represented in the device-tree.
171 */
172extern void irq_set_default_host(struct irq_host *host);
173
174
175/**
176 * irq_set_virq_count - Set the maximum number of virt irqs
177 * @count: number of linux virtual irqs, capped with NR_IRQS
178 *
179 * This is mainly for use by platforms like iSeries who want to program
180 * the virtual irq number in the controller to avoid the reverse mapping
181 */
182extern void irq_set_virq_count(unsigned int count);
183
184
185/**
186 * irq_create_mapping - Map a hardware interrupt into linux virq space
187 * @host: host owning this hardware interrupt or NULL for default host
188 * @hwirq: hardware irq number in that host space
189 *
190 * Only one mapping per hardware interrupt is permitted. Returns a linux
191 * virq number.
192 * If the sense/trigger is to be specified, set_irq_type() should be called
193 * on the number returned from that call.
194 */
195extern unsigned int irq_create_mapping(struct irq_host *host,
196 irq_hw_number_t hwirq);
197
198
199/**
200 * irq_dispose_mapping - Unmap an interrupt
201 * @virq: linux virq number of the interrupt to unmap
202 */
203extern void irq_dispose_mapping(unsigned int virq);
204
205/**
206 * irq_find_mapping - Find a linux virq from an hw irq number.
207 * @host: host owning this hardware interrupt
208 * @hwirq: hardware irq number in that host space
209 *
210 * This is a slow path, for use by generic code. It's expected that an
211 * irq controller implementation directly calls the appropriate low level
212 * mapping function.
213 */
214extern unsigned int irq_find_mapping(struct irq_host *host,
215 irq_hw_number_t hwirq);
216
217/**
218 * irq_create_direct_mapping - Allocate a virq for direct mapping
219 * @host: host to allocate the virq for or NULL for default host
220 *
221 * This routine is used for irq controllers which can choose the hardware
222 * interrupt numbers they generate. In such a case it's simplest to use
223 * the linux virq as the hardware interrupt number.
224 */
225extern unsigned int irq_create_direct_mapping(struct irq_host *host);
226
227/**
228 * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
229 * @host: host owning this hardware interrupt
230 * @virq: linux irq number
231 * @hwirq: hardware irq number in that host space
232 *
233 * This is for use by irq controllers that use a radix tree reverse
234 * mapping for fast lookup.
235 */
236extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
237 irq_hw_number_t hwirq);
238
239/**
240 * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
241 * @host: host owning this hardware interrupt
242 * @hwirq: hardware irq number in that host space
243 *
244 * This is a fast path, for use by irq controller code that uses radix tree
245 * revmaps
246 */
247extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
248 irq_hw_number_t hwirq);
249
250/**
251 * irq_linear_revmap - Find a linux virq from a hw irq number.
252 * @host: host owning this hardware interrupt
253 * @hwirq: hardware irq number in that host space
254 *
255 * This is a fast path, for use by irq controller code that uses linear
256 * revmaps. It does fallback to the slow path if the revmap doesn't exist
257 * yet and will create the revmap entry with appropriate locking
258 */
259
260extern unsigned int irq_linear_revmap(struct irq_host *host,
261 irq_hw_number_t hwirq);
262
263
264
265/**
266 * irq_alloc_virt - Allocate virtual irq numbers
267 * @host: host owning these new virtual irqs
268 * @count: number of consecutive numbers to allocate
269 * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
270 *
271 * This is a low level function that is used internally by irq_create_mapping()
272 * and that can be used by some irq controllers implementations for things
273 * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
274 */
275extern unsigned int irq_alloc_virt(struct irq_host *host,
276 unsigned int count,
277 unsigned int hint);
278
279/**
280 * irq_free_virt - Free virtual irq numbers
281 * @virq: virtual irq number of the first interrupt to free
282 * @count: number of interrupts to free
283 *
284 * This function is the opposite of irq_alloc_virt. It will not clear reverse
285 * maps, this should be done previously by unmap'ing the interrupt. In fact,
286 * all interrupts covered by the range being freed should have been unmapped
287 * prior to calling this.
288 */
289extern void irq_free_virt(unsigned int virq, unsigned int count);
290 45
291/** 46/**
292 * irq_early_init - Init irq remapping subsystem 47 * irq_early_init - Init irq remapping subsystem
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 67b4d9837236..a5b7c56237f9 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -255,7 +255,7 @@ struct mpic
255 struct device_node *node; 255 struct device_node *node;
256 256
257 /* The remapper for this MPIC */ 257 /* The remapper for this MPIC */
258 struct irq_host *irqhost; 258 struct irq_domain *irqhost;
259 259
260 /* The "linux" controller struct */ 260 /* The "linux" controller struct */
261 struct irq_chip hc_irq; 261 struct irq_chip hc_irq;
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index c48de98ba94e..4ae9a09c3b89 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -86,7 +86,7 @@ struct ics {
86extern unsigned int xics_default_server; 86extern unsigned int xics_default_server;
87extern unsigned int xics_default_distrib_server; 87extern unsigned int xics_default_distrib_server;
88extern unsigned int xics_interrupt_server_size; 88extern unsigned int xics_interrupt_server_size;
89extern struct irq_host *xics_host; 89extern struct irq_domain *xics_host;
90 90
91struct xics_cppr { 91struct xics_cppr {
92 unsigned char stack[MAX_NUM_PRIORITIES]; 92 unsigned char stack[MAX_NUM_PRIORITIES];
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 01e2877e8e04..bdfb3eee3e6f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -490,409 +490,19 @@ void do_softirq(void)
490 local_irq_restore(flags); 490 local_irq_restore(flags);
491} 491}
492 492
493
494/*
495 * IRQ controller and virtual interrupts
496 */
497
498/* The main irq map itself is an array of NR_IRQ entries containing the
499 * associate host and irq number. An entry with a host of NULL is free.
500 * An entry can be allocated if it's free, the allocator always then sets
501 * hwirq first to the host's invalid irq number and then fills ops.
502 */
503struct irq_map_entry {
504 irq_hw_number_t hwirq;
505 struct irq_host *host;
506};
507
508static LIST_HEAD(irq_hosts);
509static DEFINE_RAW_SPINLOCK(irq_big_lock);
510static DEFINE_MUTEX(revmap_trees_mutex);
511static struct irq_map_entry irq_map[NR_IRQS];
512static unsigned int irq_virq_count = NR_IRQS;
513static struct irq_host *irq_default_host;
514
515irq_hw_number_t irqd_to_hwirq(struct irq_data *d) 493irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
516{ 494{
517 return irq_map[d->irq].hwirq; 495 return d->hwirq;
518} 496}
519EXPORT_SYMBOL_GPL(irqd_to_hwirq); 497EXPORT_SYMBOL_GPL(irqd_to_hwirq);
520 498
521irq_hw_number_t virq_to_hw(unsigned int virq) 499irq_hw_number_t virq_to_hw(unsigned int virq)
522{ 500{
523 return irq_map[virq].hwirq; 501 struct irq_data *irq_data = irq_get_irq_data(virq);
502 return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
524} 503}
525EXPORT_SYMBOL_GPL(virq_to_hw); 504EXPORT_SYMBOL_GPL(virq_to_hw);
526 505
527bool virq_is_host(unsigned int virq, struct irq_host *host)
528{
529 return irq_map[virq].host == host;
530}
531EXPORT_SYMBOL_GPL(virq_is_host);
532
533static int default_irq_host_match(struct irq_host *h, struct device_node *np)
534{
535 return h->of_node != NULL && h->of_node == np;
536}
537
538struct irq_host *irq_alloc_host(struct device_node *of_node,
539 unsigned int revmap_type,
540 unsigned int revmap_arg,
541 struct irq_host_ops *ops,
542 irq_hw_number_t inval_irq)
543{
544 struct irq_host *host;
545 unsigned int size = sizeof(struct irq_host);
546 unsigned int i;
547 unsigned int *rmap;
548 unsigned long flags;
549
550 /* Allocate structure and revmap table if using linear mapping */
551 if (revmap_type == IRQ_HOST_MAP_LINEAR)
552 size += revmap_arg * sizeof(unsigned int);
553 host = kzalloc(size, GFP_KERNEL);
554 if (host == NULL)
555 return NULL;
556
557 /* Fill structure */
558 host->revmap_type = revmap_type;
559 host->inval_irq = inval_irq;
560 host->ops = ops;
561 host->of_node = of_node_get(of_node);
562
563 if (host->ops->match == NULL)
564 host->ops->match = default_irq_host_match;
565
566 raw_spin_lock_irqsave(&irq_big_lock, flags);
567
568 /* If it's a legacy controller, check for duplicates and
569 * mark it as allocated (we use irq 0 host pointer for that
570 */
571 if (revmap_type == IRQ_HOST_MAP_LEGACY) {
572 if (irq_map[0].host != NULL) {
573 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
574 of_node_put(host->of_node);
575 kfree(host);
576 return NULL;
577 }
578 irq_map[0].host = host;
579 }
580
581 list_add(&host->link, &irq_hosts);
582 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
583
584 /* Additional setups per revmap type */
585 switch(revmap_type) {
586 case IRQ_HOST_MAP_LEGACY:
587 /* 0 is always the invalid number for legacy */
588 host->inval_irq = 0;
589 /* setup us as the host for all legacy interrupts */
590 for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
591 irq_map[i].hwirq = i;
592 smp_wmb();
593 irq_map[i].host = host;
594 smp_wmb();
595
596 /* Legacy flags are left to default at this point,
597 * one can then use irq_create_mapping() to
598 * explicitly change them
599 */
600 ops->map(host, i, i);
601
602 /* Clear norequest flags */
603 irq_clear_status_flags(i, IRQ_NOREQUEST);
604 }
605 break;
606 case IRQ_HOST_MAP_LINEAR:
607 rmap = (unsigned int *)(host + 1);
608 for (i = 0; i < revmap_arg; i++)
609 rmap[i] = NO_IRQ;
610 host->revmap_data.linear.size = revmap_arg;
611 smp_wmb();
612 host->revmap_data.linear.revmap = rmap;
613 break;
614 case IRQ_HOST_MAP_TREE:
615 INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
616 break;
617 default:
618 break;
619 }
620
621 pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
622
623 return host;
624}
625
626struct irq_host *irq_find_host(struct device_node *node)
627{
628 struct irq_host *h, *found = NULL;
629 unsigned long flags;
630
631 /* We might want to match the legacy controller last since
632 * it might potentially be set to match all interrupts in
633 * the absence of a device node. This isn't a problem so far
634 * yet though...
635 */
636 raw_spin_lock_irqsave(&irq_big_lock, flags);
637 list_for_each_entry(h, &irq_hosts, link)
638 if (h->ops->match(h, node)) {
639 found = h;
640 break;
641 }
642 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
643 return found;
644}
645EXPORT_SYMBOL_GPL(irq_find_host);
646
647void irq_set_default_host(struct irq_host *host)
648{
649 pr_debug("irq: Default host set to @0x%p\n", host);
650
651 irq_default_host = host;
652}
653
654void irq_set_virq_count(unsigned int count)
655{
656 pr_debug("irq: Trying to set virq count to %d\n", count);
657
658 BUG_ON(count < NUM_ISA_INTERRUPTS);
659 if (count < NR_IRQS)
660 irq_virq_count = count;
661}
662
663static int irq_setup_virq(struct irq_host *host, unsigned int virq,
664 irq_hw_number_t hwirq)
665{
666 int res;
667
668 res = irq_alloc_desc_at(virq, 0);
669 if (res != virq) {
670 pr_debug("irq: -> allocating desc failed\n");
671 goto error;
672 }
673
674 /* map it */
675 smp_wmb();
676 irq_map[virq].hwirq = hwirq;
677 smp_mb();
678
679 if (host->ops->map(host, virq, hwirq)) {
680 pr_debug("irq: -> mapping failed, freeing\n");
681 goto errdesc;
682 }
683
684 irq_clear_status_flags(virq, IRQ_NOREQUEST);
685
686 return 0;
687
688errdesc:
689 irq_free_descs(virq, 1);
690error:
691 irq_free_virt(virq, 1);
692 return -1;
693}
694
695unsigned int irq_create_direct_mapping(struct irq_host *host)
696{
697 unsigned int virq;
698
699 if (host == NULL)
700 host = irq_default_host;
701
702 BUG_ON(host == NULL);
703 WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
704
705 virq = irq_alloc_virt(host, 1, 0);
706 if (virq == NO_IRQ) {
707 pr_debug("irq: create_direct virq allocation failed\n");
708 return NO_IRQ;
709 }
710
711 pr_debug("irq: create_direct obtained virq %d\n", virq);
712
713 if (irq_setup_virq(host, virq, virq))
714 return NO_IRQ;
715
716 return virq;
717}
718
719unsigned int irq_create_mapping(struct irq_host *host,
720 irq_hw_number_t hwirq)
721{
722 unsigned int virq, hint;
723
724 pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
725
726 /* Look for default host if nececssary */
727 if (host == NULL)
728 host = irq_default_host;
729 if (host == NULL) {
730 printk(KERN_WARNING "irq_create_mapping called for"
731 " NULL host, hwirq=%lx\n", hwirq);
732 WARN_ON(1);
733 return NO_IRQ;
734 }
735 pr_debug("irq: -> using host @%p\n", host);
736
737 /* Check if mapping already exists */
738 virq = irq_find_mapping(host, hwirq);
739 if (virq != NO_IRQ) {
740 pr_debug("irq: -> existing mapping on virq %d\n", virq);
741 return virq;
742 }
743
744 /* Get a virtual interrupt number */
745 if (host->revmap_type == IRQ_HOST_MAP_LEGACY) {
746 /* Handle legacy */
747 virq = (unsigned int)hwirq;
748 if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
749 return NO_IRQ;
750 return virq;
751 } else {
752 /* Allocate a virtual interrupt number */
753 hint = hwirq % irq_virq_count;
754 virq = irq_alloc_virt(host, 1, hint);
755 if (virq == NO_IRQ) {
756 pr_debug("irq: -> virq allocation failed\n");
757 return NO_IRQ;
758 }
759 }
760
761 if (irq_setup_virq(host, virq, hwirq))
762 return NO_IRQ;
763
764 pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
765 hwirq, host->of_node ? host->of_node->full_name : "null", virq);
766
767 return virq;
768}
769EXPORT_SYMBOL_GPL(irq_create_mapping);
770
771unsigned int irq_create_of_mapping(struct device_node *controller,
772 const u32 *intspec, unsigned int intsize)
773{
774 struct irq_host *host;
775 irq_hw_number_t hwirq;
776 unsigned int type = IRQ_TYPE_NONE;
777 unsigned int virq;
778
779 if (controller == NULL)
780 host = irq_default_host;
781 else
782 host = irq_find_host(controller);
783 if (host == NULL) {
784 printk(KERN_WARNING "irq: no irq host found for %s !\n",
785 controller->full_name);
786 return NO_IRQ;
787 }
788
789 /* If host has no translation, then we assume interrupt line */
790 if (host->ops->xlate == NULL)
791 hwirq = intspec[0];
792 else {
793 if (host->ops->xlate(host, controller, intspec, intsize,
794 &hwirq, &type))
795 return NO_IRQ;
796 }
797
798 /* Create mapping */
799 virq = irq_create_mapping(host, hwirq);
800 if (virq == NO_IRQ)
801 return virq;
802
803 /* Set type if specified and different than the current one */
804 if (type != IRQ_TYPE_NONE &&
805 type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
806 irq_set_irq_type(virq, type);
807 return virq;
808}
809EXPORT_SYMBOL_GPL(irq_create_of_mapping);
810
811void irq_dispose_mapping(unsigned int virq)
812{
813 struct irq_host *host;
814 irq_hw_number_t hwirq;
815
816 if (virq == NO_IRQ)
817 return;
818
819 host = irq_map[virq].host;
820 if (WARN_ON(host == NULL))
821 return;
822
823 /* Never unmap legacy interrupts */
824 if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
825 return;
826
827 irq_set_status_flags(virq, IRQ_NOREQUEST);
828
829 /* remove chip and handler */
830 irq_set_chip_and_handler(virq, NULL, NULL);
831
832 /* Make sure it's completed */
833 synchronize_irq(virq);
834
835 /* Tell the PIC about it */
836 if (host->ops->unmap)
837 host->ops->unmap(host, virq);
838 smp_mb();
839
840 /* Clear reverse map */
841 hwirq = irq_map[virq].hwirq;
842 switch(host->revmap_type) {
843 case IRQ_HOST_MAP_LINEAR:
844 if (hwirq < host->revmap_data.linear.size)
845 host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
846 break;
847 case IRQ_HOST_MAP_TREE:
848 mutex_lock(&revmap_trees_mutex);
849 radix_tree_delete(&host->revmap_data.tree, hwirq);
850 mutex_unlock(&revmap_trees_mutex);
851 break;
852 }
853
854 /* Destroy map */
855 smp_mb();
856 irq_map[virq].hwirq = host->inval_irq;
857
858 irq_free_descs(virq, 1);
859 /* Free it */
860 irq_free_virt(virq, 1);
861}
862EXPORT_SYMBOL_GPL(irq_dispose_mapping);
863
864unsigned int irq_find_mapping(struct irq_host *host,
865 irq_hw_number_t hwirq)
866{
867 unsigned int i;
868 unsigned int hint = hwirq % irq_virq_count;
869
870 /* Look for default host if nececssary */
871 if (host == NULL)
872 host = irq_default_host;
873 if (host == NULL)
874 return NO_IRQ;
875
876 /* legacy -> bail early */
877 if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
878 return hwirq;
879
880 /* Slow path does a linear search of the map */
881 if (hint < NUM_ISA_INTERRUPTS)
882 hint = NUM_ISA_INTERRUPTS;
883 i = hint;
884 do {
885 if (irq_map[i].host == host &&
886 irq_map[i].hwirq == hwirq)
887 return i;
888 i++;
889 if (i >= irq_virq_count)
890 i = NUM_ISA_INTERRUPTS;
891 } while(i != hint);
892 return NO_IRQ;
893}
894EXPORT_SYMBOL_GPL(irq_find_mapping);
895
896#ifdef CONFIG_SMP 506#ifdef CONFIG_SMP
897int irq_choose_cpu(const struct cpumask *mask) 507int irq_choose_cpu(const struct cpumask *mask)
898{ 508{
@@ -929,232 +539,11 @@ int irq_choose_cpu(const struct cpumask *mask)
929} 539}
930#endif 540#endif
931 541
932unsigned int irq_radix_revmap_lookup(struct irq_host *host,
933 irq_hw_number_t hwirq)
934{
935 struct irq_map_entry *ptr;
936 unsigned int virq;
937
938 if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
939 return irq_find_mapping(host, hwirq);
940
941 /*
942 * The ptr returned references the static global irq_map.
943 * but freeing an irq can delete nodes along the path to
944 * do the lookup via call_rcu.
945 */
946 rcu_read_lock();
947 ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
948 rcu_read_unlock();
949
950 /*
951 * If found in radix tree, then fine.
952 * Else fallback to linear lookup - this should not happen in practice
953 * as it means that we failed to insert the node in the radix tree.
954 */
955 if (ptr)
956 virq = ptr - irq_map;
957 else
958 virq = irq_find_mapping(host, hwirq);
959
960 return virq;
961}
962
963void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
964 irq_hw_number_t hwirq)
965{
966 if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
967 return;
968
969 if (virq != NO_IRQ) {
970 mutex_lock(&revmap_trees_mutex);
971 radix_tree_insert(&host->revmap_data.tree, hwirq,
972 &irq_map[virq]);
973 mutex_unlock(&revmap_trees_mutex);
974 }
975}
976
977unsigned int irq_linear_revmap(struct irq_host *host,
978 irq_hw_number_t hwirq)
979{
980 unsigned int *revmap;
981
982 if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
983 return irq_find_mapping(host, hwirq);
984
985 /* Check revmap bounds */
986 if (unlikely(hwirq >= host->revmap_data.linear.size))
987 return irq_find_mapping(host, hwirq);
988
989 /* Check if revmap was allocated */
990 revmap = host->revmap_data.linear.revmap;
991 if (unlikely(revmap == NULL))
992 return irq_find_mapping(host, hwirq);
993
994 /* Fill up revmap with slow path if no mapping found */
995 if (unlikely(revmap[hwirq] == NO_IRQ))
996 revmap[hwirq] = irq_find_mapping(host, hwirq);
997
998 return revmap[hwirq];
999}
1000
1001unsigned int irq_alloc_virt(struct irq_host *host,
1002 unsigned int count,
1003 unsigned int hint)
1004{
1005 unsigned long flags;
1006 unsigned int i, j, found = NO_IRQ;
1007
1008 if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
1009 return NO_IRQ;
1010
1011 raw_spin_lock_irqsave(&irq_big_lock, flags);
1012
1013 /* Use hint for 1 interrupt if any */
1014 if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
1015 hint < irq_virq_count && irq_map[hint].host == NULL) {
1016 found = hint;
1017 goto hint_found;
1018 }
1019
1020 /* Look for count consecutive numbers in the allocatable
1021 * (non-legacy) space
1022 */
1023 for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
1024 if (irq_map[i].host != NULL)
1025 j = 0;
1026 else
1027 j++;
1028
1029 if (j == count) {
1030 found = i - count + 1;
1031 break;
1032 }
1033 }
1034 if (found == NO_IRQ) {
1035 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
1036 return NO_IRQ;
1037 }
1038 hint_found:
1039 for (i = found; i < (found + count); i++) {
1040 irq_map[i].hwirq = host->inval_irq;
1041 smp_wmb();
1042 irq_map[i].host = host;
1043 }
1044 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
1045 return found;
1046}
1047
1048void irq_free_virt(unsigned int virq, unsigned int count)
1049{
1050 unsigned long flags;
1051 unsigned int i;
1052
1053 WARN_ON (virq < NUM_ISA_INTERRUPTS);
1054 WARN_ON (count == 0 || (virq + count) > irq_virq_count);
1055
1056 if (virq < NUM_ISA_INTERRUPTS) {
1057 if (virq + count < NUM_ISA_INTERRUPTS)
1058 return;
1059 count =- NUM_ISA_INTERRUPTS - virq;
1060 virq = NUM_ISA_INTERRUPTS;
1061 }
1062
1063 if (count > irq_virq_count || virq > irq_virq_count - count) {
1064 if (virq > irq_virq_count)
1065 return;
1066 count = irq_virq_count - virq;
1067 }
1068
1069 raw_spin_lock_irqsave(&irq_big_lock, flags);
1070 for (i = virq; i < (virq + count); i++) {
1071 struct irq_host *host;
1072
1073 host = irq_map[i].host;
1074 irq_map[i].hwirq = host->inval_irq;
1075 smp_wmb();
1076 irq_map[i].host = NULL;
1077 }
1078 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
1079}
1080
1081int arch_early_irq_init(void) 542int arch_early_irq_init(void)
1082{ 543{
1083 return 0; 544 return 0;
1084} 545}
1085 546
1086#ifdef CONFIG_VIRQ_DEBUG
1087static int virq_debug_show(struct seq_file *m, void *private)
1088{
1089 unsigned long flags;
1090 struct irq_desc *desc;
1091 const char *p;
1092 static const char none[] = "none";
1093 void *data;
1094 int i;
1095
1096 seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
1097 "chip name", "chip data", "host name");
1098
1099 for (i = 1; i < nr_irqs; i++) {
1100 desc = irq_to_desc(i);
1101 if (!desc)
1102 continue;
1103
1104 raw_spin_lock_irqsave(&desc->lock, flags);
1105
1106 if (desc->action && desc->action->handler) {
1107 struct irq_chip *chip;
1108
1109 seq_printf(m, "%5d ", i);
1110 seq_printf(m, "0x%05lx ", irq_map[i].hwirq);
1111
1112 chip = irq_desc_get_chip(desc);
1113 if (chip && chip->name)
1114 p = chip->name;
1115 else
1116 p = none;
1117 seq_printf(m, "%-15s ", p);
1118
1119 data = irq_desc_get_chip_data(desc);
1120 seq_printf(m, "0x%16p ", data);
1121
1122 if (irq_map[i].host && irq_map[i].host->of_node)
1123 p = irq_map[i].host->of_node->full_name;
1124 else
1125 p = none;
1126 seq_printf(m, "%s\n", p);
1127 }
1128
1129 raw_spin_unlock_irqrestore(&desc->lock, flags);
1130 }
1131
1132 return 0;
1133}
1134
1135static int virq_debug_open(struct inode *inode, struct file *file)
1136{
1137 return single_open(file, virq_debug_show, inode->i_private);
1138}
1139
1140static const struct file_operations virq_debug_fops = {
1141 .open = virq_debug_open,
1142 .read = seq_read,
1143 .llseek = seq_lseek,
1144 .release = single_release,
1145};
1146
1147static int __init irq_debugfs_init(void)
1148{
1149 if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
1150 NULL, &virq_debug_fops) == NULL)
1151 return -ENOMEM;
1152
1153 return 0;
1154}
1155__initcall(irq_debugfs_init);
1156#endif /* CONFIG_VIRQ_DEBUG */
1157
1158#ifdef CONFIG_PPC64 547#ifdef CONFIG_PPC64
1159static int __init setup_noirqdistrib(char *str) 548static int __init setup_noirqdistrib(char *str)
1160{ 549{
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 9f09319352c0..ca3a062ed1b9 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -21,7 +21,7 @@
21#include <asm/prom.h> 21#include <asm/prom.h>
22 22
23static struct device_node *cpld_pic_node; 23static struct device_node *cpld_pic_node;
24static struct irq_host *cpld_pic_host; 24static struct irq_domain *cpld_pic_host;
25 25
26/* 26/*
27 * Bits to ignore in the misc_status register 27 * Bits to ignore in the misc_status register
@@ -123,13 +123,13 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
123} 123}
124 124
125static int 125static int
126cpld_pic_host_match(struct irq_host *h, struct device_node *node) 126cpld_pic_host_match(struct irq_domain *h, struct device_node *node)
127{ 127{
128 return cpld_pic_node == node; 128 return cpld_pic_node == node;
129} 129}
130 130
131static int 131static int
132cpld_pic_host_map(struct irq_host *h, unsigned int virq, 132cpld_pic_host_map(struct irq_domain *h, unsigned int virq,
133 irq_hw_number_t hw) 133 irq_hw_number_t hw)
134{ 134{
135 irq_set_status_flags(virq, IRQ_LEVEL); 135 irq_set_status_flags(virq, IRQ_LEVEL);
@@ -137,8 +137,7 @@ cpld_pic_host_map(struct irq_host *h, unsigned int virq,
137 return 0; 137 return 0;
138} 138}
139 139
140static struct 140static const struct irq_domain_ops cpld_pic_host_ops = {
141irq_host_ops cpld_pic_host_ops = {
142 .match = cpld_pic_host_match, 141 .match = cpld_pic_host_match,
143 .map = cpld_pic_host_map, 142 .map = cpld_pic_host_map,
144}; 143};
@@ -191,8 +190,7 @@ mpc5121_ads_cpld_pic_init(void)
191 190
192 cpld_pic_node = of_node_get(np); 191 cpld_pic_node = of_node_get(np);
193 192
194 cpld_pic_host = 193 cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL);
195 irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
196 if (!cpld_pic_host) { 194 if (!cpld_pic_host) {
197 printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n"); 195 printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
198 goto end; 196 goto end;
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 96f85e5e0cd3..17d91b7da315 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -45,7 +45,7 @@ static struct of_device_id mpc5200_gpio_ids[] __initdata = {
45struct media5200_irq { 45struct media5200_irq {
46 void __iomem *regs; 46 void __iomem *regs;
47 spinlock_t lock; 47 spinlock_t lock;
48 struct irq_host *irqhost; 48 struct irq_domain *irqhost;
49}; 49};
50struct media5200_irq media5200_irq; 50struct media5200_irq media5200_irq;
51 51
@@ -112,7 +112,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
112 raw_spin_unlock(&desc->lock); 112 raw_spin_unlock(&desc->lock);
113} 113}
114 114
115static int media5200_irq_map(struct irq_host *h, unsigned int virq, 115static int media5200_irq_map(struct irq_domain *h, unsigned int virq,
116 irq_hw_number_t hw) 116 irq_hw_number_t hw)
117{ 117{
118 pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw); 118 pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
@@ -122,7 +122,7 @@ static int media5200_irq_map(struct irq_host *h, unsigned int virq,
122 return 0; 122 return 0;
123} 123}
124 124
125static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct, 125static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct,
126 const u32 *intspec, unsigned int intsize, 126 const u32 *intspec, unsigned int intsize,
127 irq_hw_number_t *out_hwirq, 127 irq_hw_number_t *out_hwirq,
128 unsigned int *out_flags) 128 unsigned int *out_flags)
@@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
136 return 0; 136 return 0;
137} 137}
138 138
139static struct irq_host_ops media5200_irq_ops = { 139static const struct irq_domain_ops media5200_irq_ops = {
140 .map = media5200_irq_map, 140 .map = media5200_irq_map,
141 .xlate = media5200_irq_xlate, 141 .xlate = media5200_irq_xlate,
142}; 142};
@@ -173,15 +173,12 @@ static void __init media5200_init_irq(void)
173 173
174 spin_lock_init(&media5200_irq.lock); 174 spin_lock_init(&media5200_irq.lock);
175 175
176 media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR, 176 media5200_irq.irqhost = irq_domain_add_linear(fpga_np,
177 MEDIA5200_NUM_IRQS, 177 MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq);
178 &media5200_irq_ops, -1);
179 if (!media5200_irq.irqhost) 178 if (!media5200_irq.irqhost)
180 goto out; 179 goto out;
181 pr_debug("%s: allocated irqhost\n", __func__); 180 pr_debug("%s: allocated irqhost\n", __func__);
182 181
183 media5200_irq.irqhost->host_data = &media5200_irq;
184
185 irq_set_handler_data(cascade_virq, &media5200_irq); 182 irq_set_handler_data(cascade_virq, &media5200_irq);
186 irq_set_chained_handler(cascade_virq, media5200_irq_cascade); 183 irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
187 184
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index f94f06e52762..028470b95886 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL");
81 * @regs: virtual address of GPT registers 81 * @regs: virtual address of GPT registers
82 * @lock: spinlock to coordinate between different functions. 82 * @lock: spinlock to coordinate between different functions.
83 * @gc: gpio_chip instance structure; used when GPIO is enabled 83 * @gc: gpio_chip instance structure; used when GPIO is enabled
84 * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported 84 * @irqhost: Pointer to irq_domain instance; used when IRQ mode is supported
85 * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates 85 * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
86 * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates 86 * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
87 * if the timer is actively used as wdt which blocks gpt functions 87 * if the timer is actively used as wdt which blocks gpt functions
@@ -91,7 +91,7 @@ struct mpc52xx_gpt_priv {
91 struct device *dev; 91 struct device *dev;
92 struct mpc52xx_gpt __iomem *regs; 92 struct mpc52xx_gpt __iomem *regs;
93 spinlock_t lock; 93 spinlock_t lock;
94 struct irq_host *irqhost; 94 struct irq_domain *irqhost;
95 u32 ipb_freq; 95 u32 ipb_freq;
96 u8 wdt_mode; 96 u8 wdt_mode;
97 97
@@ -204,7 +204,7 @@ void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
204 } 204 }
205} 205}
206 206
207static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq, 207static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq,
208 irq_hw_number_t hw) 208 irq_hw_number_t hw)
209{ 209{
210 struct mpc52xx_gpt_priv *gpt = h->host_data; 210 struct mpc52xx_gpt_priv *gpt = h->host_data;
@@ -216,7 +216,7 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
216 return 0; 216 return 0;
217} 217}
218 218
219static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct, 219static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
220 const u32 *intspec, unsigned int intsize, 220 const u32 *intspec, unsigned int intsize,
221 irq_hw_number_t *out_hwirq, 221 irq_hw_number_t *out_hwirq,
222 unsigned int *out_flags) 222 unsigned int *out_flags)
@@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
236 return 0; 236 return 0;
237} 237}
238 238
239static struct irq_host_ops mpc52xx_gpt_irq_ops = { 239static const struct irq_domain_ops mpc52xx_gpt_irq_ops = {
240 .map = mpc52xx_gpt_irq_map, 240 .map = mpc52xx_gpt_irq_map,
241 .xlate = mpc52xx_gpt_irq_xlate, 241 .xlate = mpc52xx_gpt_irq_xlate,
242}; 242};
@@ -252,14 +252,12 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
252 if (!cascade_virq) 252 if (!cascade_virq)
253 return; 253 return;
254 254
255 gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1, 255 gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
256 &mpc52xx_gpt_irq_ops, -1);
257 if (!gpt->irqhost) { 256 if (!gpt->irqhost) {
258 dev_err(gpt->dev, "irq_alloc_host() failed\n"); 257 dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
259 return; 258 return;
260 } 259 }
261 260
262 gpt->irqhost->host_data = gpt;
263 irq_set_handler_data(cascade_virq, gpt); 261 irq_set_handler_data(cascade_virq, gpt);
264 irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); 262 irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
265 263
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 1a9a49570579..8520b58a5e9a 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -132,7 +132,7 @@ static struct of_device_id mpc52xx_sdma_ids[] __initdata = {
132 132
133static struct mpc52xx_intr __iomem *intr; 133static struct mpc52xx_intr __iomem *intr;
134static struct mpc52xx_sdma __iomem *sdma; 134static struct mpc52xx_sdma __iomem *sdma;
135static struct irq_host *mpc52xx_irqhost = NULL; 135static struct irq_domain *mpc52xx_irqhost = NULL;
136 136
137static unsigned char mpc52xx_map_senses[4] = { 137static unsigned char mpc52xx_map_senses[4] = {
138 IRQ_TYPE_LEVEL_HIGH, 138 IRQ_TYPE_LEVEL_HIGH,
@@ -301,7 +301,7 @@ static int mpc52xx_is_extirq(int l1, int l2)
301/** 301/**
302 * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property 302 * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
303 */ 303 */
304static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, 304static int mpc52xx_irqhost_xlate(struct irq_domain *h, struct device_node *ct,
305 const u32 *intspec, unsigned int intsize, 305 const u32 *intspec, unsigned int intsize,
306 irq_hw_number_t *out_hwirq, 306 irq_hw_number_t *out_hwirq,
307 unsigned int *out_flags) 307 unsigned int *out_flags)
@@ -335,7 +335,7 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
335/** 335/**
336 * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure 336 * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
337 */ 337 */
338static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, 338static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
339 irq_hw_number_t irq) 339 irq_hw_number_t irq)
340{ 340{
341 int l1irq; 341 int l1irq;
@@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
384 return 0; 384 return 0;
385} 385}
386 386
387static struct irq_host_ops mpc52xx_irqhost_ops = { 387static const struct irq_domain_ops mpc52xx_irqhost_ops = {
388 .xlate = mpc52xx_irqhost_xlate, 388 .xlate = mpc52xx_irqhost_xlate,
389 .map = mpc52xx_irqhost_map, 389 .map = mpc52xx_irqhost_map,
390}; 390};
@@ -444,9 +444,9 @@ void __init mpc52xx_init_irq(void)
444 * As last step, add an irq host to translate the real 444 * As last step, add an irq host to translate the real
445 * hw irq information provided by the ofw to linux virq 445 * hw irq information provided by the ofw to linux virq
446 */ 446 */
447 mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR, 447 mpc52xx_irqhost = irq_domain_add_linear(picnode,
448 MPC52xx_IRQ_HIGHTESTHWIRQ, 448 MPC52xx_IRQ_HIGHTESTHWIRQ,
449 &mpc52xx_irqhost_ops, -1); 449 &mpc52xx_irqhost_ops, NULL);
450 450
451 if (!mpc52xx_irqhost) 451 if (!mpc52xx_irqhost)
452 panic(__FILE__ ": Cannot allocate the IRQ host\n"); 452 panic(__FILE__ ": Cannot allocate the IRQ host\n");
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 8ccf9ed62fe2..328d221fd1c0 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -29,7 +29,7 @@ static DEFINE_RAW_SPINLOCK(pci_pic_lock);
29 29
30struct pq2ads_pci_pic { 30struct pq2ads_pci_pic {
31 struct device_node *node; 31 struct device_node *node;
32 struct irq_host *host; 32 struct irq_domain *host;
33 33
34 struct { 34 struct {
35 u32 stat; 35 u32 stat;
@@ -103,7 +103,7 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
103 } 103 }
104} 104}
105 105
106static int pci_pic_host_map(struct irq_host *h, unsigned int virq, 106static int pci_pic_host_map(struct irq_domain *h, unsigned int virq,
107 irq_hw_number_t hw) 107 irq_hw_number_t hw)
108{ 108{
109 irq_set_status_flags(virq, IRQ_LEVEL); 109 irq_set_status_flags(virq, IRQ_LEVEL);
@@ -112,14 +112,14 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
112 return 0; 112 return 0;
113} 113}
114 114
115static struct irq_host_ops pci_pic_host_ops = { 115static const struct irq_domain_ops pci_pic_host_ops = {
116 .map = pci_pic_host_map, 116 .map = pci_pic_host_map,
117}; 117};
118 118
119int __init pq2ads_pci_init_irq(void) 119int __init pq2ads_pci_init_irq(void)
120{ 120{
121 struct pq2ads_pci_pic *priv; 121 struct pq2ads_pci_pic *priv;
122 struct irq_host *host; 122 struct irq_domain *host;
123 struct device_node *np; 123 struct device_node *np;
124 int ret = -ENODEV; 124 int ret = -ENODEV;
125 int irq; 125 int irq;
@@ -156,17 +156,13 @@ int __init pq2ads_pci_init_irq(void)
156 out_be32(&priv->regs->mask, ~0); 156 out_be32(&priv->regs->mask, ~0);
157 mb(); 157 mb();
158 158
159 host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS, 159 host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv);
160 &pci_pic_host_ops, NUM_IRQS);
161 if (!host) { 160 if (!host) {
162 ret = -ENOMEM; 161 ret = -ENOMEM;
163 goto out_unmap_regs; 162 goto out_unmap_regs;
164 } 163 }
165 164
166 host->host_data = priv;
167
168 priv->host = host; 165 priv->host = host;
169 host->host_data = priv;
170 irq_set_handler_data(irq, priv); 166 irq_set_handler_data(irq, priv);
171 irq_set_chained_handler(irq, pq2ads_pci_irq_demux); 167 irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
172 168
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 12cb9bb2cc68..3bbbf7489487 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -51,7 +51,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
51static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock); 51static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
52 52
53static void __iomem *socrates_fpga_pic_iobase; 53static void __iomem *socrates_fpga_pic_iobase;
54static struct irq_host *socrates_fpga_pic_irq_host; 54static struct irq_domain *socrates_fpga_pic_irq_host;
55static unsigned int socrates_fpga_irqs[3]; 55static unsigned int socrates_fpga_irqs[3];
56 56
57static inline uint32_t socrates_fpga_pic_read(int reg) 57static inline uint32_t socrates_fpga_pic_read(int reg)
@@ -227,7 +227,7 @@ static struct irq_chip socrates_fpga_pic_chip = {
227 .irq_set_type = socrates_fpga_pic_set_type, 227 .irq_set_type = socrates_fpga_pic_set_type,
228}; 228};
229 229
230static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, 230static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq,
231 irq_hw_number_t hwirq) 231 irq_hw_number_t hwirq)
232{ 232{
233 /* All interrupts are LEVEL sensitive */ 233 /* All interrupts are LEVEL sensitive */
@@ -238,7 +238,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
238 return 0; 238 return 0;
239} 239}
240 240
241static int socrates_fpga_pic_host_xlate(struct irq_host *h, 241static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
242 struct device_node *ct, const u32 *intspec, unsigned int intsize, 242 struct device_node *ct, const u32 *intspec, unsigned int intsize,
243 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 243 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
244{ 244{
@@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_host *h,
269 return 0; 269 return 0;
270} 270}
271 271
272static struct irq_host_ops socrates_fpga_pic_host_ops = { 272static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
273 .map = socrates_fpga_pic_host_map, 273 .map = socrates_fpga_pic_host_map,
274 .xlate = socrates_fpga_pic_host_xlate, 274 .xlate = socrates_fpga_pic_host_xlate,
275}; 275};
@@ -279,10 +279,9 @@ void socrates_fpga_pic_init(struct device_node *pic)
279 unsigned long flags; 279 unsigned long flags;
280 int i; 280 int i;
281 281
282 /* Setup an irq_host structure */ 282 /* Setup an irq_domain structure */
283 socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, 283 socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
284 SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, 284 SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
285 SOCRATES_FPGA_NUM_IRQS);
286 if (socrates_fpga_pic_irq_host == NULL) { 285 if (socrates_fpga_pic_irq_host == NULL) {
287 pr_err("FPGA PIC: Unable to allocate host\n"); 286 pr_err("FPGA PIC: Unable to allocate host\n");
288 return; 287 return;
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 94594e58594c..af3fd697de82 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -50,7 +50,7 @@
50static DEFINE_RAW_SPINLOCK(gef_pic_lock); 50static DEFINE_RAW_SPINLOCK(gef_pic_lock);
51 51
52static void __iomem *gef_pic_irq_reg_base; 52static void __iomem *gef_pic_irq_reg_base;
53static struct irq_host *gef_pic_irq_host; 53static struct irq_domain *gef_pic_irq_host;
54static int gef_pic_cascade_irq; 54static int gef_pic_cascade_irq;
55 55
56/* 56/*
@@ -153,7 +153,7 @@ static struct irq_chip gef_pic_chip = {
153/* When an interrupt is being configured, this call allows some flexibilty 153/* When an interrupt is being configured, this call allows some flexibilty
154 * in deciding which irq_chip structure is used 154 * in deciding which irq_chip structure is used
155 */ 155 */
156static int gef_pic_host_map(struct irq_host *h, unsigned int virq, 156static int gef_pic_host_map(struct irq_domain *h, unsigned int virq,
157 irq_hw_number_t hwirq) 157 irq_hw_number_t hwirq)
158{ 158{
159 /* All interrupts are LEVEL sensitive */ 159 /* All interrupts are LEVEL sensitive */
@@ -163,7 +163,7 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
163 return 0; 163 return 0;
164} 164}
165 165
166static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, 166static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
167 const u32 *intspec, unsigned int intsize, 167 const u32 *intspec, unsigned int intsize,
168 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 168 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
169{ 169{
@@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
177 return 0; 177 return 0;
178} 178}
179 179
180static struct irq_host_ops gef_pic_host_ops = { 180static const struct irq_domain_ops gef_pic_host_ops = {
181 .map = gef_pic_host_map, 181 .map = gef_pic_host_map,
182 .xlate = gef_pic_host_xlate, 182 .xlate = gef_pic_host_xlate,
183}; 183};
@@ -211,10 +211,9 @@ void __init gef_pic_init(struct device_node *np)
211 return; 211 return;
212 } 212 }
213 213
214 /* Setup an irq_host structure */ 214 /* Setup an irq_domain structure */
215 gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 215 gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS,
216 GEF_PIC_NUM_IRQS, 216 &gef_pic_host_ops, NULL);
217 &gef_pic_host_ops, NO_IRQ);
218 if (gef_pic_irq_host == NULL) 217 if (gef_pic_irq_host == NULL)
219 return; 218 return;
220 219
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 40a6e34793b4..db360fc4cf0e 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -67,7 +67,7 @@
67 67
68 68
69struct axon_msic { 69struct axon_msic {
70 struct irq_host *irq_host; 70 struct irq_domain *irq_domain;
71 __le32 *fifo_virt; 71 __le32 *fifo_virt;
72 dma_addr_t fifo_phys; 72 dma_addr_t fifo_phys;
73 dcr_host_t dcr_host; 73 dcr_host_t dcr_host;
@@ -152,7 +152,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
152 152
153static struct axon_msic *find_msi_translator(struct pci_dev *dev) 153static struct axon_msic *find_msi_translator(struct pci_dev *dev)
154{ 154{
155 struct irq_host *irq_host; 155 struct irq_domain *irq_domain;
156 struct device_node *dn, *tmp; 156 struct device_node *dn, *tmp;
157 const phandle *ph; 157 const phandle *ph;
158 struct axon_msic *msic = NULL; 158 struct axon_msic *msic = NULL;
@@ -184,14 +184,14 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
184 goto out_error; 184 goto out_error;
185 } 185 }
186 186
187 irq_host = irq_find_host(dn); 187 irq_domain = irq_find_host(dn);
188 if (!irq_host) { 188 if (!irq_domain) {
189 dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n", 189 dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n",
190 dn->full_name); 190 dn->full_name);
191 goto out_error; 191 goto out_error;
192 } 192 }
193 193
194 msic = irq_host->host_data; 194 msic = irq_domain->host_data;
195 195
196out_error: 196out_error:
197 of_node_put(dn); 197 of_node_put(dn);
@@ -280,7 +280,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
280 BUILD_BUG_ON(NR_IRQS > 65536); 280 BUILD_BUG_ON(NR_IRQS > 65536);
281 281
282 list_for_each_entry(entry, &dev->msi_list, list) { 282 list_for_each_entry(entry, &dev->msi_list, list) {
283 virq = irq_create_direct_mapping(msic->irq_host); 283 virq = irq_create_direct_mapping(msic->irq_domain);
284 if (virq == NO_IRQ) { 284 if (virq == NO_IRQ) {
285 dev_warn(&dev->dev, 285 dev_warn(&dev->dev,
286 "axon_msi: virq allocation failed!\n"); 286 "axon_msi: virq allocation failed!\n");
@@ -318,7 +318,7 @@ static struct irq_chip msic_irq_chip = {
318 .name = "AXON-MSI", 318 .name = "AXON-MSI",
319}; 319};
320 320
321static int msic_host_map(struct irq_host *h, unsigned int virq, 321static int msic_host_map(struct irq_domain *h, unsigned int virq,
322 irq_hw_number_t hw) 322 irq_hw_number_t hw)
323{ 323{
324 irq_set_chip_data(virq, h->host_data); 324 irq_set_chip_data(virq, h->host_data);
@@ -327,7 +327,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
327 return 0; 327 return 0;
328} 328}
329 329
330static struct irq_host_ops msic_host_ops = { 330static const struct irq_domain_ops msic_host_ops = {
331 .map = msic_host_map, 331 .map = msic_host_map,
332}; 332};
333 333
@@ -337,7 +337,7 @@ static void axon_msi_shutdown(struct platform_device *device)
337 u32 tmp; 337 u32 tmp;
338 338
339 pr_devel("axon_msi: disabling %s\n", 339 pr_devel("axon_msi: disabling %s\n",
340 msic->irq_host->of_node->full_name); 340 msic->irq_domain->of_node->full_name);
341 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); 341 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
342 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; 342 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
343 msic_dcr_write(msic, MSIC_CTRL_REG, tmp); 343 msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
@@ -392,16 +392,13 @@ static int axon_msi_probe(struct platform_device *device)
392 } 392 }
393 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); 393 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
394 394
395 msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP, 395 msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
396 NR_IRQS, &msic_host_ops, 0); 396 if (!msic->irq_domain) {
397 if (!msic->irq_host) { 397 printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
398 printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
399 dn->full_name); 398 dn->full_name);
400 goto out_free_fifo; 399 goto out_free_fifo;
401 } 400 }
402 401
403 msic->irq_host->host_data = msic;
404
405 irq_set_handler_data(virq, msic); 402 irq_set_handler_data(virq, msic);
406 irq_set_chained_handler(virq, axon_msi_cascade); 403 irq_set_chained_handler(virq, axon_msi_cascade);
407 pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq); 404 pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 55015e1f6939..e5c3a2c6090d 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -34,7 +34,7 @@ static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
34static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64]; 34static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64];
35static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64]; 35static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64];
36 36
37static struct irq_host *beatic_host; 37static struct irq_domain *beatic_host;
38 38
39/* 39/*
40 * In this implementation, "virq" == "IRQ plug number", 40 * In this implementation, "virq" == "IRQ plug number",
@@ -122,7 +122,7 @@ static struct irq_chip beatic_pic = {
122 * 122 *
123 * Note that the number (virq) is already assigned at upper layer. 123 * Note that the number (virq) is already assigned at upper layer.
124 */ 124 */
125static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq) 125static void beatic_pic_host_unmap(struct irq_domain *h, unsigned int virq)
126{ 126{
127 beat_destruct_irq_plug(virq); 127 beat_destruct_irq_plug(virq);
128} 128}
@@ -133,7 +133,7 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
133 * 133 *
134 * Note that the number (virq) is already assigned at upper layer. 134 * Note that the number (virq) is already assigned at upper layer.
135 */ 135 */
136static int beatic_pic_host_map(struct irq_host *h, unsigned int virq, 136static int beatic_pic_host_map(struct irq_domain *h, unsigned int virq,
137 irq_hw_number_t hw) 137 irq_hw_number_t hw)
138{ 138{
139 int64_t err; 139 int64_t err;
@@ -154,7 +154,7 @@ static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
154 * Called from irq_create_of_mapping() only. 154 * Called from irq_create_of_mapping() only.
155 * Note: We have only 1 entry to translate. 155 * Note: We have only 1 entry to translate.
156 */ 156 */
157static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct, 157static int beatic_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
158 const u32 *intspec, unsigned int intsize, 158 const u32 *intspec, unsigned int intsize,
159 irq_hw_number_t *out_hwirq, 159 irq_hw_number_t *out_hwirq,
160 unsigned int *out_flags) 160 unsigned int *out_flags)
@@ -166,13 +166,13 @@ static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
166 return 0; 166 return 0;
167} 167}
168 168
169static int beatic_pic_host_match(struct irq_host *h, struct device_node *np) 169static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np)
170{ 170{
171 /* Match all */ 171 /* Match all */
172 return 1; 172 return 1;
173} 173}
174 174
175static struct irq_host_ops beatic_pic_host_ops = { 175static const struct irq_domain_ops beatic_pic_host_ops = {
176 .map = beatic_pic_host_map, 176 .map = beatic_pic_host_map,
177 .unmap = beatic_pic_host_unmap, 177 .unmap = beatic_pic_host_unmap,
178 .xlate = beatic_pic_host_xlate, 178 .xlate = beatic_pic_host_xlate,
@@ -239,9 +239,7 @@ void __init beatic_init_IRQ(void)
239 ppc_md.get_irq = beatic_get_irq; 239 ppc_md.get_irq = beatic_get_irq;
240 240
241 /* Allocate an irq host */ 241 /* Allocate an irq host */
242 beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, 242 beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
243 &beatic_pic_host_ops,
244 0);
245 BUG_ON(beatic_host == NULL); 243 BUG_ON(beatic_host == NULL);
246 irq_set_default_host(beatic_host); 244 irq_set_default_host(beatic_host);
247} 245}
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 96a433dd2d64..2d42f3bb66d6 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -56,7 +56,7 @@ struct iic {
56 56
57static DEFINE_PER_CPU(struct iic, cpu_iic); 57static DEFINE_PER_CPU(struct iic, cpu_iic);
58#define IIC_NODE_COUNT 2 58#define IIC_NODE_COUNT 2
59static struct irq_host *iic_host; 59static struct irq_domain *iic_host;
60 60
61/* Convert between "pending" bits and hw irq number */ 61/* Convert between "pending" bits and hw irq number */
62static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits) 62static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
@@ -186,7 +186,7 @@ void iic_message_pass(int cpu, int msg)
186 out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4); 186 out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
187} 187}
188 188
189struct irq_host *iic_get_irq_host(int node) 189struct irq_domain *iic_get_irq_host(int node)
190{ 190{
191 return iic_host; 191 return iic_host;
192} 192}
@@ -222,13 +222,13 @@ void iic_request_IPIs(void)
222#endif /* CONFIG_SMP */ 222#endif /* CONFIG_SMP */
223 223
224 224
225static int iic_host_match(struct irq_host *h, struct device_node *node) 225static int iic_host_match(struct irq_domain *h, struct device_node *node)
226{ 226{
227 return of_device_is_compatible(node, 227 return of_device_is_compatible(node,
228 "IBM,CBEA-Internal-Interrupt-Controller"); 228 "IBM,CBEA-Internal-Interrupt-Controller");
229} 229}
230 230
231static int iic_host_map(struct irq_host *h, unsigned int virq, 231static int iic_host_map(struct irq_domain *h, unsigned int virq,
232 irq_hw_number_t hw) 232 irq_hw_number_t hw)
233{ 233{
234 switch (hw & IIC_IRQ_TYPE_MASK) { 234 switch (hw & IIC_IRQ_TYPE_MASK) {
@@ -245,7 +245,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
245 return 0; 245 return 0;
246} 246}
247 247
248static int iic_host_xlate(struct irq_host *h, struct device_node *ct, 248static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
249 const u32 *intspec, unsigned int intsize, 249 const u32 *intspec, unsigned int intsize,
250 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 250 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
251 251
@@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
285 return 0; 285 return 0;
286} 286}
287 287
288static struct irq_host_ops iic_host_ops = { 288static const struct irq_domain_ops iic_host_ops = {
289 .match = iic_host_match, 289 .match = iic_host_match,
290 .map = iic_host_map, 290 .map = iic_host_map,
291 .xlate = iic_host_xlate, 291 .xlate = iic_host_xlate,
@@ -378,8 +378,8 @@ static int __init setup_iic(void)
378void __init iic_init_IRQ(void) 378void __init iic_init_IRQ(void)
379{ 379{
380 /* Setup an irq host data structure */ 380 /* Setup an irq host data structure */
381 iic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT, 381 iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
382 &iic_host_ops, IIC_IRQ_INVALID); 382 NULL);
383 BUG_ON(iic_host == NULL); 383 BUG_ON(iic_host == NULL);
384 irq_set_default_host(iic_host); 384 irq_set_default_host(iic_host);
385 385
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 442c28c00f88..d8b7cc8a66ca 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -62,7 +62,7 @@ enum {
62#define SPIDER_IRQ_INVALID 63 62#define SPIDER_IRQ_INVALID 63
63 63
64struct spider_pic { 64struct spider_pic {
65 struct irq_host *host; 65 struct irq_domain *host;
66 void __iomem *regs; 66 void __iomem *regs;
67 unsigned int node_id; 67 unsigned int node_id;
68}; 68};
@@ -168,7 +168,7 @@ static struct irq_chip spider_pic = {
168 .irq_set_type = spider_set_irq_type, 168 .irq_set_type = spider_set_irq_type,
169}; 169};
170 170
171static int spider_host_map(struct irq_host *h, unsigned int virq, 171static int spider_host_map(struct irq_domain *h, unsigned int virq,
172 irq_hw_number_t hw) 172 irq_hw_number_t hw)
173{ 173{
174 irq_set_chip_data(virq, h->host_data); 174 irq_set_chip_data(virq, h->host_data);
@@ -180,7 +180,7 @@ static int spider_host_map(struct irq_host *h, unsigned int virq,
180 return 0; 180 return 0;
181} 181}
182 182
183static int spider_host_xlate(struct irq_host *h, struct device_node *ct, 183static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
184 const u32 *intspec, unsigned int intsize, 184 const u32 *intspec, unsigned int intsize,
185 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 185 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
186 186
@@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
194 return 0; 194 return 0;
195} 195}
196 196
197static struct irq_host_ops spider_host_ops = { 197static const struct irq_domain_ops spider_host_ops = {
198 .map = spider_host_map, 198 .map = spider_host_map,
199 .xlate = spider_host_xlate, 199 .xlate = spider_host_xlate,
200}; 200};
@@ -299,12 +299,10 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
299 panic("spider_pic: can't map registers !"); 299 panic("spider_pic: can't map registers !");
300 300
301 /* Allocate a host */ 301 /* Allocate a host */
302 pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR, 302 pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
303 SPIDER_SRC_COUNT, &spider_host_ops, 303 &spider_host_ops, pic);
304 SPIDER_IRQ_INVALID);
305 if (pic->host == NULL) 304 if (pic->host == NULL)
306 panic("spider_pic: can't allocate irq host !"); 305 panic("spider_pic: can't allocate irq host !");
307 pic->host->host_data = pic;
308 306
309 /* Go through all sources and disable them */ 307 /* Go through all sources and disable them */
310 for (i = 0; i < SPIDER_SRC_COUNT; i++) { 308 for (i = 0; i < SPIDER_SRC_COUNT; i++) {
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index f61a2dd96b99..53d6eee01963 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -96,9 +96,9 @@ static struct irq_chip flipper_pic = {
96 * 96 *
97 */ 97 */
98 98
99static struct irq_host *flipper_irq_host; 99static struct irq_domain *flipper_irq_host;
100 100
101static int flipper_pic_map(struct irq_host *h, unsigned int virq, 101static int flipper_pic_map(struct irq_domain *h, unsigned int virq,
102 irq_hw_number_t hwirq) 102 irq_hw_number_t hwirq)
103{ 103{
104 irq_set_chip_data(virq, h->host_data); 104 irq_set_chip_data(virq, h->host_data);
@@ -107,13 +107,13 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
107 return 0; 107 return 0;
108} 108}
109 109
110static int flipper_pic_match(struct irq_host *h, struct device_node *np) 110static int flipper_pic_match(struct irq_domain *h, struct device_node *np)
111{ 111{
112 return 1; 112 return 1;
113} 113}
114 114
115 115
116static struct irq_host_ops flipper_irq_host_ops = { 116static const struct irq_domain_ops flipper_irq_domain_ops = {
117 .map = flipper_pic_map, 117 .map = flipper_pic_map,
118 .match = flipper_pic_match, 118 .match = flipper_pic_match,
119}; 119};
@@ -130,10 +130,10 @@ static void __flipper_quiesce(void __iomem *io_base)
130 out_be32(io_base + FLIPPER_ICR, 0xffffffff); 130 out_be32(io_base + FLIPPER_ICR, 0xffffffff);
131} 131}
132 132
133struct irq_host * __init flipper_pic_init(struct device_node *np) 133struct irq_domain * __init flipper_pic_init(struct device_node *np)
134{ 134{
135 struct device_node *pi; 135 struct device_node *pi;
136 struct irq_host *irq_host = NULL; 136 struct irq_domain *irq_domain = NULL;
137 struct resource res; 137 struct resource res;
138 void __iomem *io_base; 138 void __iomem *io_base;
139 int retval; 139 int retval;
@@ -159,17 +159,15 @@ struct irq_host * __init flipper_pic_init(struct device_node *np)
159 159
160 __flipper_quiesce(io_base); 160 __flipper_quiesce(io_base);
161 161
162 irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS, 162 irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS,
163 &flipper_irq_host_ops, -1); 163 &flipper_irq_domain_ops, io_base);
164 if (!irq_host) { 164 if (!irq_domain) {
165 pr_err("failed to allocate irq_host\n"); 165 pr_err("failed to allocate irq_domain\n");
166 return NULL; 166 return NULL;
167 } 167 }
168 168
169 irq_host->host_data = io_base;
170
171out: 169out:
172 return irq_host; 170 return irq_domain;
173} 171}
174 172
175unsigned int flipper_pic_get_irq(void) 173unsigned int flipper_pic_get_irq(void)
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index e4919170c6bc..3006b5117ec6 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -89,9 +89,9 @@ static struct irq_chip hlwd_pic = {
89 * 89 *
90 */ 90 */
91 91
92static struct irq_host *hlwd_irq_host; 92static struct irq_domain *hlwd_irq_host;
93 93
94static int hlwd_pic_map(struct irq_host *h, unsigned int virq, 94static int hlwd_pic_map(struct irq_domain *h, unsigned int virq,
95 irq_hw_number_t hwirq) 95 irq_hw_number_t hwirq)
96{ 96{
97 irq_set_chip_data(virq, h->host_data); 97 irq_set_chip_data(virq, h->host_data);
@@ -100,11 +100,11 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
100 return 0; 100 return 0;
101} 101}
102 102
103static struct irq_host_ops hlwd_irq_host_ops = { 103static const struct irq_domain_ops hlwd_irq_domain_ops = {
104 .map = hlwd_pic_map, 104 .map = hlwd_pic_map,
105}; 105};
106 106
107static unsigned int __hlwd_pic_get_irq(struct irq_host *h) 107static unsigned int __hlwd_pic_get_irq(struct irq_domain *h)
108{ 108{
109 void __iomem *io_base = h->host_data; 109 void __iomem *io_base = h->host_data;
110 int irq; 110 int irq;
@@ -123,14 +123,14 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
123 struct irq_desc *desc) 123 struct irq_desc *desc)
124{ 124{
125 struct irq_chip *chip = irq_desc_get_chip(desc); 125 struct irq_chip *chip = irq_desc_get_chip(desc);
126 struct irq_host *irq_host = irq_get_handler_data(cascade_virq); 126 struct irq_domain *irq_domain = irq_get_handler_data(cascade_virq);
127 unsigned int virq; 127 unsigned int virq;
128 128
129 raw_spin_lock(&desc->lock); 129 raw_spin_lock(&desc->lock);
130 chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */ 130 chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
131 raw_spin_unlock(&desc->lock); 131 raw_spin_unlock(&desc->lock);
132 132
133 virq = __hlwd_pic_get_irq(irq_host); 133 virq = __hlwd_pic_get_irq(irq_domain);
134 if (virq != NO_IRQ) 134 if (virq != NO_IRQ)
135 generic_handle_irq(virq); 135 generic_handle_irq(virq);
136 else 136 else
@@ -155,9 +155,9 @@ static void __hlwd_quiesce(void __iomem *io_base)
155 out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff); 155 out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff);
156} 156}
157 157
158struct irq_host *hlwd_pic_init(struct device_node *np) 158struct irq_domain *hlwd_pic_init(struct device_node *np)
159{ 159{
160 struct irq_host *irq_host; 160 struct irq_domain *irq_domain;
161 struct resource res; 161 struct resource res;
162 void __iomem *io_base; 162 void __iomem *io_base;
163 int retval; 163 int retval;
@@ -177,15 +177,14 @@ struct irq_host *hlwd_pic_init(struct device_node *np)
177 177
178 __hlwd_quiesce(io_base); 178 __hlwd_quiesce(io_base);
179 179
180 irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS, 180 irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS,
181 &hlwd_irq_host_ops, -1); 181 &hlwd_irq_domain_ops, io_base);
182 if (!irq_host) { 182 if (!irq_domain) {
183 pr_err("failed to allocate irq_host\n"); 183 pr_err("failed to allocate irq_domain\n");
184 return NULL; 184 return NULL;
185 } 185 }
186 irq_host->host_data = io_base;
187 186
188 return irq_host; 187 return irq_domain;
189} 188}
190 189
191unsigned int hlwd_pic_get_irq(void) 190unsigned int hlwd_pic_get_irq(void)
@@ -200,7 +199,7 @@ unsigned int hlwd_pic_get_irq(void)
200 199
201void hlwd_pic_probe(void) 200void hlwd_pic_probe(void)
202{ 201{
203 struct irq_host *host; 202 struct irq_domain *host;
204 struct device_node *np; 203 struct device_node *np;
205 const u32 *interrupts; 204 const u32 *interrupts;
206 int cascade_virq; 205 int cascade_virq;
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index b2103453eb01..05ce5164cafc 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -342,7 +342,7 @@ unsigned int iSeries_get_irq(void)
342 342
343#ifdef CONFIG_PCI 343#ifdef CONFIG_PCI
344 344
345static int iseries_irq_host_map(struct irq_host *h, unsigned int virq, 345static int iseries_irq_host_map(struct irq_domain *h, unsigned int virq,
346 irq_hw_number_t hw) 346 irq_hw_number_t hw)
347{ 347{
348 irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq); 348 irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
@@ -350,13 +350,13 @@ static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
350 return 0; 350 return 0;
351} 351}
352 352
353static int iseries_irq_host_match(struct irq_host *h, struct device_node *np) 353static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np)
354{ 354{
355 /* Match all */ 355 /* Match all */
356 return 1; 356 return 1;
357} 357}
358 358
359static struct irq_host_ops iseries_irq_host_ops = { 359static const struct irq_domain_ops iseries_irq_domain_ops = {
360 .map = iseries_irq_host_map, 360 .map = iseries_irq_host_map,
361 .match = iseries_irq_host_match, 361 .match = iseries_irq_host_match,
362}; 362};
@@ -368,7 +368,7 @@ static struct irq_host_ops iseries_irq_host_ops = {
368void __init iSeries_init_IRQ(void) 368void __init iSeries_init_IRQ(void)
369{ 369{
370 /* Register PCI event handler and open an event path */ 370 /* Register PCI event handler and open an event path */
371 struct irq_host *host; 371 struct irq_domain *host;
372 int ret; 372 int ret;
373 373
374 /* 374 /*
@@ -380,8 +380,7 @@ void __init iSeries_init_IRQ(void)
380 /* Create irq host. No need for a revmap since HV will give us 380 /* Create irq host. No need for a revmap since HV will give us
381 * back our virtual irq number 381 * back our virtual irq number
382 */ 382 */
383 host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, 383 host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL);
384 &iseries_irq_host_ops, 0);
385 BUG_ON(host == NULL); 384 BUG_ON(host == NULL);
386 irq_set_default_host(host); 385 irq_set_default_host(host);
387 386
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 7761aabfc293..92afc382a49e 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -61,7 +61,7 @@ static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
61static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; 61static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
62static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 62static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
63static int pmac_irq_cascade = -1; 63static int pmac_irq_cascade = -1;
64static struct irq_host *pmac_pic_host; 64static struct irq_domain *pmac_pic_host;
65 65
66static void __pmac_retrigger(unsigned int irq_nr) 66static void __pmac_retrigger(unsigned int irq_nr)
67{ 67{
@@ -268,13 +268,13 @@ static struct irqaction gatwick_cascade_action = {
268 .name = "cascade", 268 .name = "cascade",
269}; 269};
270 270
271static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) 271static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node)
272{ 272{
273 /* We match all, we don't always have a node anyway */ 273 /* We match all, we don't always have a node anyway */
274 return 1; 274 return 1;
275} 275}
276 276
277static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, 277static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
278 irq_hw_number_t hw) 278 irq_hw_number_t hw)
279{ 279{
280 if (hw >= max_irqs) 280 if (hw >= max_irqs)
@@ -288,21 +288,10 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
288 return 0; 288 return 0;
289} 289}
290 290
291static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct, 291static const struct irq_domain_ops pmac_pic_host_ops = {
292 const u32 *intspec, unsigned int intsize,
293 irq_hw_number_t *out_hwirq,
294 unsigned int *out_flags)
295
296{
297 *out_flags = IRQ_TYPE_NONE;
298 *out_hwirq = *intspec;
299 return 0;
300}
301
302static struct irq_host_ops pmac_pic_host_ops = {
303 .match = pmac_pic_host_match, 292 .match = pmac_pic_host_match,
304 .map = pmac_pic_host_map, 293 .map = pmac_pic_host_map,
305 .xlate = pmac_pic_host_xlate, 294 .xlate = irq_domain_xlate_onecell,
306}; 295};
307 296
308static void __init pmac_pic_probe_oldstyle(void) 297static void __init pmac_pic_probe_oldstyle(void)
@@ -352,9 +341,8 @@ static void __init pmac_pic_probe_oldstyle(void)
352 /* 341 /*
353 * Allocate an irq host 342 * Allocate an irq host
354 */ 343 */
355 pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs, 344 pmac_pic_host = irq_domain_add_linear(master, max_irqs,
356 &pmac_pic_host_ops, 345 &pmac_pic_host_ops, NULL);
357 max_irqs);
358 BUG_ON(pmac_pic_host == NULL); 346 BUG_ON(pmac_pic_host == NULL);
359 irq_set_default_host(pmac_pic_host); 347 irq_set_default_host(pmac_pic_host);
360 348
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 44d769258ebf..a81e5a88fbdf 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -125,7 +125,7 @@ static volatile u32 __iomem *psurge_start;
125static int psurge_type = PSURGE_NONE; 125static int psurge_type = PSURGE_NONE;
126 126
127/* irq for secondary cpus to report */ 127/* irq for secondary cpus to report */
128static struct irq_host *psurge_host; 128static struct irq_domain *psurge_host;
129int psurge_secondary_virq; 129int psurge_secondary_virq;
130 130
131/* 131/*
@@ -176,7 +176,7 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
176 psurge_set_ipi(cpu); 176 psurge_set_ipi(cpu);
177} 177}
178 178
179static int psurge_host_map(struct irq_host *h, unsigned int virq, 179static int psurge_host_map(struct irq_domain *h, unsigned int virq,
180 irq_hw_number_t hw) 180 irq_hw_number_t hw)
181{ 181{
182 irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq); 182 irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
@@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_host *h, unsigned int virq,
184 return 0; 184 return 0;
185} 185}
186 186
187struct irq_host_ops psurge_host_ops = { 187static const struct irq_domain_ops psurge_host_ops = {
188 .map = psurge_host_map, 188 .map = psurge_host_map,
189}; 189};
190 190
@@ -192,8 +192,7 @@ static int psurge_secondary_ipi_init(void)
192{ 192{
193 int rc = -ENOMEM; 193 int rc = -ENOMEM;
194 194
195 psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, 195 psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
196 &psurge_host_ops, 0);
197 196
198 if (psurge_host) 197 if (psurge_host)
199 psurge_secondary_virq = irq_create_direct_mapping(psurge_host); 198 psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 617efa12a3a5..2a4ff86cc21f 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -667,7 +667,7 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd,
667static void dump_bmp(struct ps3_private* pd) {}; 667static void dump_bmp(struct ps3_private* pd) {};
668#endif /* defined(DEBUG) */ 668#endif /* defined(DEBUG) */
669 669
670static int ps3_host_map(struct irq_host *h, unsigned int virq, 670static int ps3_host_map(struct irq_domain *h, unsigned int virq,
671 irq_hw_number_t hwirq) 671 irq_hw_number_t hwirq)
672{ 672{
673 DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 673 DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
@@ -678,13 +678,13 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
678 return 0; 678 return 0;
679} 679}
680 680
681static int ps3_host_match(struct irq_host *h, struct device_node *np) 681static int ps3_host_match(struct irq_domain *h, struct device_node *np)
682{ 682{
683 /* Match all */ 683 /* Match all */
684 return 1; 684 return 1;
685} 685}
686 686
687static struct irq_host_ops ps3_host_ops = { 687static const struct irq_domain_ops ps3_host_ops = {
688 .map = ps3_host_map, 688 .map = ps3_host_map,
689 .match = ps3_host_match, 689 .match = ps3_host_match,
690}; 690};
@@ -751,10 +751,9 @@ void __init ps3_init_IRQ(void)
751{ 751{
752 int result; 752 int result;
753 unsigned cpu; 753 unsigned cpu;
754 struct irq_host *host; 754 struct irq_domain *host;
755 755
756 host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops, 756 host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
757 PS3_INVALID_OUTLET);
758 irq_set_default_host(host); 757 irq_set_default_host(host);
759 irq_set_virq_count(PS3_PLUG_MAX + 1); 758 irq_set_virq_count(PS3_PLUG_MAX + 1);
760 759
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 19f353dfcd03..cb565bf93650 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -30,7 +30,7 @@
30static int opb_index = 0; 30static int opb_index = 0;
31 31
32struct opb_pic { 32struct opb_pic {
33 struct irq_host *host; 33 struct irq_domain *host;
34 void *regs; 34 void *regs;
35 int index; 35 int index;
36 spinlock_t lock; 36 spinlock_t lock;
@@ -179,7 +179,7 @@ static struct irq_chip opb_irq_chip = {
179 .irq_set_type = opb_set_irq_type 179 .irq_set_type = opb_set_irq_type
180}; 180};
181 181
182static int opb_host_map(struct irq_host *host, unsigned int virq, 182static int opb_host_map(struct irq_domain *host, unsigned int virq,
183 irq_hw_number_t hwirq) 183 irq_hw_number_t hwirq)
184{ 184{
185 struct opb_pic *opb; 185 struct opb_pic *opb;
@@ -196,20 +196,9 @@ static int opb_host_map(struct irq_host *host, unsigned int virq,
196 return 0; 196 return 0;
197} 197}
198 198
199static int opb_host_xlate(struct irq_host *host, struct device_node *dn, 199static const struct irq_domain_ops opb_host_ops = {
200 const u32 *intspec, unsigned int intsize,
201 irq_hw_number_t *out_hwirq, unsigned int *out_type)
202{
203 /* Interrupt size must == 2 */
204 BUG_ON(intsize != 2);
205 *out_hwirq = intspec[0];
206 *out_type = intspec[1];
207 return 0;
208}
209
210static struct irq_host_ops opb_host_ops = {
211 .map = opb_host_map, 200 .map = opb_host_map,
212 .xlate = opb_host_xlate, 201 .xlate = irq_domain_xlate_twocell,
213}; 202};
214 203
215irqreturn_t opb_irq_handler(int irq, void *private) 204irqreturn_t opb_irq_handler(int irq, void *private)
@@ -263,13 +252,11 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
263 goto free_opb; 252 goto free_opb;
264 } 253 }
265 254
266 /* Allocate an irq host so that Linux knows that despite only 255 /* Allocate an irq domain so that Linux knows that despite only
267 * having one interrupt to issue, we're the controller for multiple 256 * having one interrupt to issue, we're the controller for multiple
268 * hardware IRQs, so later we can lookup their virtual IRQs. */ 257 * hardware IRQs, so later we can lookup their virtual IRQs. */
269 258
270 opb->host = irq_alloc_host(dn, IRQ_HOST_MAP_LINEAR, 259 opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb);
271 OPB_NR_IRQS, &opb_host_ops, -1);
272
273 if (!opb->host) { 260 if (!opb->host) {
274 printk(KERN_ERR "opb: Failed to allocate IRQ host!\n"); 261 printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
275 goto free_regs; 262 goto free_regs;
@@ -277,7 +264,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
277 264
278 opb->index = opb_index++; 265 opb->index = opb_index++;
279 spin_lock_init(&opb->lock); 266 spin_lock_init(&opb->lock);
280 opb->host->host_data = opb;
281 267
282 /* Disable all interrupts by default */ 268 /* Disable all interrupts by default */
283 opb_out(opb, OPB_MLSASIER, 0); 269 opb_out(opb, OPB_MLSASIER, 0);
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 5d7d59a43c4c..d4fa03f2b6ac 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -54,7 +54,7 @@ cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
54immap_t __iomem *mpc8xx_immr; 54immap_t __iomem *mpc8xx_immr;
55static cpic8xx_t __iomem *cpic_reg; 55static cpic8xx_t __iomem *cpic_reg;
56 56
57static struct irq_host *cpm_pic_host; 57static struct irq_domain *cpm_pic_host;
58 58
59static void cpm_mask_irq(struct irq_data *d) 59static void cpm_mask_irq(struct irq_data *d)
60{ 60{
@@ -98,7 +98,7 @@ int cpm_get_irq(void)
98 return irq_linear_revmap(cpm_pic_host, cpm_vec); 98 return irq_linear_revmap(cpm_pic_host, cpm_vec);
99} 99}
100 100
101static int cpm_pic_host_map(struct irq_host *h, unsigned int virq, 101static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
102 irq_hw_number_t hw) 102 irq_hw_number_t hw)
103{ 103{
104 pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); 104 pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = {
123 .name = "error", 123 .name = "error",
124}; 124};
125 125
126static struct irq_host_ops cpm_pic_host_ops = { 126static const struct irq_domain_ops cpm_pic_host_ops = {
127 .map = cpm_pic_host_map, 127 .map = cpm_pic_host_map,
128}; 128};
129 129
@@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void)
164 164
165 out_be32(&cpic_reg->cpic_cimr, 0); 165 out_be32(&cpic_reg->cpic_cimr, 0);
166 166
167 cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 167 cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
168 64, &cpm_pic_host_ops, 64);
169 if (cpm_pic_host == NULL) { 168 if (cpm_pic_host == NULL) {
170 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); 169 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
171 sirq = NO_IRQ; 170 sirq = NO_IRQ;
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index bcab50e2a9eb..d3be961e2ae7 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -50,7 +50,7 @@
50 50
51static intctl_cpm2_t __iomem *cpm2_intctl; 51static intctl_cpm2_t __iomem *cpm2_intctl;
52 52
53static struct irq_host *cpm2_pic_host; 53static struct irq_domain *cpm2_pic_host;
54#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 54#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
55static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 55static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
56 56
@@ -214,7 +214,7 @@ unsigned int cpm2_get_irq(void)
214 return irq_linear_revmap(cpm2_pic_host, irq); 214 return irq_linear_revmap(cpm2_pic_host, irq);
215} 215}
216 216
217static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, 217static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq,
218 irq_hw_number_t hw) 218 irq_hw_number_t hw)
219{ 219{
220 pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); 220 pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -224,21 +224,9 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
224 return 0; 224 return 0;
225} 225}
226 226
227static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, 227static const struct irq_domain_ops cpm2_pic_host_ops = {
228 const u32 *intspec, unsigned int intsize,
229 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
230{
231 *out_hwirq = intspec[0];
232 if (intsize > 1)
233 *out_flags = intspec[1];
234 else
235 *out_flags = IRQ_TYPE_NONE;
236 return 0;
237}
238
239static struct irq_host_ops cpm2_pic_host_ops = {
240 .map = cpm2_pic_host_map, 228 .map = cpm2_pic_host_map,
241 .xlate = cpm2_pic_host_xlate, 229 .xlate = irq_domain_xlate_onetwocell,
242}; 230};
243 231
244void cpm2_pic_init(struct device_node *node) 232void cpm2_pic_init(struct device_node *node)
@@ -275,8 +263,7 @@ void cpm2_pic_init(struct device_node *node)
275 out_be32(&cpm2_intctl->ic_scprrl, 0x05309770); 263 out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
276 264
277 /* create a legacy host */ 265 /* create a legacy host */
278 cpm2_pic_host = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 266 cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL);
279 64, &cpm2_pic_host_ops, 64);
280 if (cpm2_pic_host == NULL) { 267 if (cpm2_pic_host == NULL) {
281 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); 268 printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
282 return; 269 return;
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index b6731e4a6646..6e0e1005227f 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -182,13 +182,13 @@ unsigned int ehv_pic_get_irq(void)
182 return irq_linear_revmap(global_ehv_pic->irqhost, irq); 182 return irq_linear_revmap(global_ehv_pic->irqhost, irq);
183} 183}
184 184
185static int ehv_pic_host_match(struct irq_host *h, struct device_node *node) 185static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node)
186{ 186{
187 /* Exact match, unless ehv_pic node is NULL */ 187 /* Exact match, unless ehv_pic node is NULL */
188 return h->of_node == NULL || h->of_node == node; 188 return h->of_node == NULL || h->of_node == node;
189} 189}
190 190
191static int ehv_pic_host_map(struct irq_host *h, unsigned int virq, 191static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq,
192 irq_hw_number_t hw) 192 irq_hw_number_t hw)
193{ 193{
194 struct ehv_pic *ehv_pic = h->host_data; 194 struct ehv_pic *ehv_pic = h->host_data;
@@ -217,7 +217,7 @@ static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
217 return 0; 217 return 0;
218} 218}
219 219
220static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct, 220static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
221 const u32 *intspec, unsigned int intsize, 221 const u32 *intspec, unsigned int intsize,
222 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 222 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
223 223
@@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
248 return 0; 248 return 0;
249} 249}
250 250
251static struct irq_host_ops ehv_pic_host_ops = { 251static const struct irq_domain_ops ehv_pic_host_ops = {
252 .match = ehv_pic_host_match, 252 .match = ehv_pic_host_match,
253 .map = ehv_pic_host_map, 253 .map = ehv_pic_host_map,
254 .xlate = ehv_pic_host_xlate, 254 .xlate = ehv_pic_host_xlate,
@@ -275,9 +275,8 @@ void __init ehv_pic_init(void)
275 return; 275 return;
276 } 276 }
277 277
278 ehv_pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 278 ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS,
279 NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0); 279 &ehv_pic_host_ops, ehv_pic);
280
281 if (!ehv_pic->irqhost) { 280 if (!ehv_pic->irqhost) {
282 of_node_put(np); 281 of_node_put(np);
283 kfree(ehv_pic); 282 kfree(ehv_pic);
@@ -293,7 +292,6 @@ void __init ehv_pic_init(void)
293 of_node_put(np2); 292 of_node_put(np2);
294 } 293 }
295 294
296 ehv_pic->irqhost->host_data = ehv_pic;
297 ehv_pic->hc_irq = ehv_pic_irq_chip; 295 ehv_pic->hc_irq = ehv_pic_irq_chip;
298 ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity; 296 ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
299 ehv_pic->coreint_flag = coreint_flag; 297 ehv_pic->coreint_flag = coreint_flag;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ecb5c1946d22..0c01debe963b 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -60,7 +60,7 @@ static struct irq_chip fsl_msi_chip = {
60 .name = "FSL-MSI", 60 .name = "FSL-MSI",
61}; 61};
62 62
63static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, 63static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
64 irq_hw_number_t hw) 64 irq_hw_number_t hw)
65{ 65{
66 struct fsl_msi *msi_data = h->host_data; 66 struct fsl_msi *msi_data = h->host_data;
@@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
74 return 0; 74 return 0;
75} 75}
76 76
77static struct irq_host_ops fsl_msi_host_ops = { 77static const struct irq_domain_ops fsl_msi_host_ops = {
78 .map = fsl_msi_host_map, 78 .map = fsl_msi_host_map,
79}; 79};
80 80
@@ -387,8 +387,8 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
387 } 387 }
388 platform_set_drvdata(dev, msi); 388 platform_set_drvdata(dev, msi);
389 389
390 msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, 390 msi->irqhost = irq_domain_add_linear(dev->dev.of_node,
391 NR_MSI_IRQS, &fsl_msi_host_ops, 0); 391 NR_MSI_IRQS, &fsl_msi_host_ops, msi);
392 392
393 if (msi->irqhost == NULL) { 393 if (msi->irqhost == NULL) {
394 dev_err(&dev->dev, "No memory for MSI irqhost\n"); 394 dev_err(&dev->dev, "No memory for MSI irqhost\n");
@@ -420,8 +420,6 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
420 420
421 msi->feature = features->fsl_pic_ip; 421 msi->feature = features->fsl_pic_ip;
422 422
423 msi->irqhost->host_data = msi;
424
425 /* 423 /*
426 * Remember the phandle, so that we can match with any PCI nodes 424 * Remember the phandle, so that we can match with any PCI nodes
427 * that have an "fsl,msi" property. 425 * that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index f6c646a52541..8225f8653f78 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -26,7 +26,7 @@
26#define FSL_PIC_IP_VMPIC 0x00000003 26#define FSL_PIC_IP_VMPIC 0x00000003
27 27
28struct fsl_msi { 28struct fsl_msi {
29 struct irq_host *irqhost; 29 struct irq_domain *irqhost;
30 30
31 unsigned long cascade_irq; 31 unsigned long cascade_irq;
32 32
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index d18bb27e4df9..997df6a7ab5d 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -25,7 +25,7 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
25 25
26static DEFINE_RAW_SPINLOCK(i8259_lock); 26static DEFINE_RAW_SPINLOCK(i8259_lock);
27 27
28static struct irq_host *i8259_host; 28static struct irq_domain *i8259_host;
29 29
30/* 30/*
31 * Acknowledge the IRQ using either the PCI host bridge's interrupt 31 * Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -163,12 +163,12 @@ static struct resource pic_edgectrl_iores = {
163 .flags = IORESOURCE_BUSY, 163 .flags = IORESOURCE_BUSY,
164}; 164};
165 165
166static int i8259_host_match(struct irq_host *h, struct device_node *node) 166static int i8259_host_match(struct irq_domain *h, struct device_node *node)
167{ 167{
168 return h->of_node == NULL || h->of_node == node; 168 return h->of_node == NULL || h->of_node == node;
169} 169}
170 170
171static int i8259_host_map(struct irq_host *h, unsigned int virq, 171static int i8259_host_map(struct irq_domain *h, unsigned int virq,
172 irq_hw_number_t hw) 172 irq_hw_number_t hw)
173{ 173{
174 pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw); 174 pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw);
@@ -185,7 +185,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
185 return 0; 185 return 0;
186} 186}
187 187
188static int i8259_host_xlate(struct irq_host *h, struct device_node *ct, 188static int i8259_host_xlate(struct irq_domain *h, struct device_node *ct,
189 const u32 *intspec, unsigned int intsize, 189 const u32 *intspec, unsigned int intsize,
190 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 190 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
191{ 191{
@@ -205,13 +205,13 @@ static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
205 return 0; 205 return 0;
206} 206}
207 207
208static struct irq_host_ops i8259_host_ops = { 208static struct irq_domain_ops i8259_host_ops = {
209 .match = i8259_host_match, 209 .match = i8259_host_match,
210 .map = i8259_host_map, 210 .map = i8259_host_map,
211 .xlate = i8259_host_xlate, 211 .xlate = i8259_host_xlate,
212}; 212};
213 213
214struct irq_host *i8259_get_host(void) 214struct irq_domain *i8259_get_host(void)
215{ 215{
216 return i8259_host; 216 return i8259_host;
217} 217}
@@ -263,8 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
263 raw_spin_unlock_irqrestore(&i8259_lock, flags); 263 raw_spin_unlock_irqrestore(&i8259_lock, flags);
264 264
265 /* create a legacy host */ 265 /* create a legacy host */
266 i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, 266 i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL);
267 0, &i8259_host_ops, 0);
268 if (i8259_host == NULL) { 267 if (i8259_host == NULL) {
269 printk(KERN_ERR "i8259: failed to allocate irq host !\n"); 268 printk(KERN_ERR "i8259: failed to allocate irq host !\n");
270 return; 269 return;
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 95da897f05a7..b50f97811c25 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -672,13 +672,13 @@ static struct irq_chip ipic_edge_irq_chip = {
672 .irq_set_type = ipic_set_irq_type, 672 .irq_set_type = ipic_set_irq_type,
673}; 673};
674 674
675static int ipic_host_match(struct irq_host *h, struct device_node *node) 675static int ipic_host_match(struct irq_domain *h, struct device_node *node)
676{ 676{
677 /* Exact match, unless ipic node is NULL */ 677 /* Exact match, unless ipic node is NULL */
678 return h->of_node == NULL || h->of_node == node; 678 return h->of_node == NULL || h->of_node == node;
679} 679}
680 680
681static int ipic_host_map(struct irq_host *h, unsigned int virq, 681static int ipic_host_map(struct irq_domain *h, unsigned int virq,
682 irq_hw_number_t hw) 682 irq_hw_number_t hw)
683{ 683{
684 struct ipic *ipic = h->host_data; 684 struct ipic *ipic = h->host_data;
@@ -692,26 +692,10 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
692 return 0; 692 return 0;
693} 693}
694 694
695static int ipic_host_xlate(struct irq_host *h, struct device_node *ct, 695static struct irq_domain_ops ipic_host_ops = {
696 const u32 *intspec, unsigned int intsize,
697 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
698
699{
700 /* interrupt sense values coming from the device tree equal either
701 * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
702 */
703 *out_hwirq = intspec[0];
704 if (intsize > 1)
705 *out_flags = intspec[1];
706 else
707 *out_flags = IRQ_TYPE_NONE;
708 return 0;
709}
710
711static struct irq_host_ops ipic_host_ops = {
712 .match = ipic_host_match, 696 .match = ipic_host_match,
713 .map = ipic_host_map, 697 .map = ipic_host_map,
714 .xlate = ipic_host_xlate, 698 .xlate = irq_domain_xlate_onetwocell,
715}; 699};
716 700
717struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) 701struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
@@ -728,9 +712,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
728 if (ipic == NULL) 712 if (ipic == NULL)
729 return NULL; 713 return NULL;
730 714
731 ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 715 ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
732 NR_IPIC_INTS, 716 &ipic_host_ops, ipic);
733 &ipic_host_ops, 0);
734 if (ipic->irqhost == NULL) { 717 if (ipic->irqhost == NULL) {
735 kfree(ipic); 718 kfree(ipic);
736 return NULL; 719 return NULL;
@@ -738,8 +721,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
738 721
739 ipic->regs = ioremap(res.start, resource_size(&res)); 722 ipic->regs = ioremap(res.start, resource_size(&res));
740 723
741 ipic->irqhost->host_data = ipic;
742
743 /* init hw */ 724 /* init hw */
744 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 725 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
745 726
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index 9391c57b0c51..90031d1282e1 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -43,7 +43,7 @@ struct ipic {
43 volatile u32 __iomem *regs; 43 volatile u32 __iomem *regs;
44 44
45 /* The remapper for this IPIC */ 45 /* The remapper for this IPIC */
46 struct irq_host *irqhost; 46 struct irq_domain *irqhost;
47}; 47};
48 48
49struct ipic_info { 49struct ipic_info {
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2ca0a85fcce9..d5f5416be310 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -17,7 +17,7 @@
17 17
18extern int cpm_get_irq(struct pt_regs *regs); 18extern int cpm_get_irq(struct pt_regs *regs);
19 19
20static struct irq_host *mpc8xx_pic_host; 20static struct irq_domain *mpc8xx_pic_host;
21#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 21#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
22static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 22static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
23static sysconf8xx_t __iomem *siu_reg; 23static sysconf8xx_t __iomem *siu_reg;
@@ -110,7 +110,7 @@ unsigned int mpc8xx_get_irq(void)
110 110
111} 111}
112 112
113static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq, 113static int mpc8xx_pic_host_map(struct irq_domain *h, unsigned int virq,
114 irq_hw_number_t hw) 114 irq_hw_number_t hw)
115{ 115{
116 pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw); 116 pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -121,7 +121,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
121} 121}
122 122
123 123
124static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct, 124static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
125 const u32 *intspec, unsigned int intsize, 125 const u32 *intspec, unsigned int intsize,
126 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 126 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
127{ 127{
@@ -142,7 +142,7 @@ static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
142} 142}
143 143
144 144
145static struct irq_host_ops mpc8xx_pic_host_ops = { 145static struct irq_domain_ops mpc8xx_pic_host_ops = {
146 .map = mpc8xx_pic_host_map, 146 .map = mpc8xx_pic_host_map,
147 .xlate = mpc8xx_pic_host_xlate, 147 .xlate = mpc8xx_pic_host_xlate,
148}; 148};
@@ -171,8 +171,7 @@ int mpc8xx_pic_init(void)
171 goto out; 171 goto out;
172 } 172 }
173 173
174 mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 174 mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
175 64, &mpc8xx_pic_host_ops, 64);
176 if (mpc8xx_pic_host == NULL) { 175 if (mpc8xx_pic_host == NULL) {
177 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); 176 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
178 ret = -ENOMEM; 177 ret = -ENOMEM;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e9ccb1015de..c83a512fa175 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -965,13 +965,13 @@ static struct irq_chip mpic_irq_ht_chip = {
965#endif /* CONFIG_MPIC_U3_HT_IRQS */ 965#endif /* CONFIG_MPIC_U3_HT_IRQS */
966 966
967 967
968static int mpic_host_match(struct irq_host *h, struct device_node *node) 968static int mpic_host_match(struct irq_domain *h, struct device_node *node)
969{ 969{
970 /* Exact match, unless mpic node is NULL */ 970 /* Exact match, unless mpic node is NULL */
971 return h->of_node == NULL || h->of_node == node; 971 return h->of_node == NULL || h->of_node == node;
972} 972}
973 973
974static int mpic_host_map(struct irq_host *h, unsigned int virq, 974static int mpic_host_map(struct irq_domain *h, unsigned int virq,
975 irq_hw_number_t hw) 975 irq_hw_number_t hw)
976{ 976{
977 struct mpic *mpic = h->host_data; 977 struct mpic *mpic = h->host_data;
@@ -1041,7 +1041,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
1041 return 0; 1041 return 0;
1042} 1042}
1043 1043
1044static int mpic_host_xlate(struct irq_host *h, struct device_node *ct, 1044static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
1045 const u32 *intspec, unsigned int intsize, 1045 const u32 *intspec, unsigned int intsize,
1046 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 1046 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
1047 1047
@@ -1121,13 +1121,13 @@ static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
1121 BUG_ON(!(mpic->flags & MPIC_SECONDARY)); 1121 BUG_ON(!(mpic->flags & MPIC_SECONDARY));
1122 1122
1123 virq = mpic_get_one_irq(mpic); 1123 virq = mpic_get_one_irq(mpic);
1124 if (virq != NO_IRQ) 1124 if (virq)
1125 generic_handle_irq(virq); 1125 generic_handle_irq(virq);
1126 1126
1127 chip->irq_eoi(&desc->irq_data); 1127 chip->irq_eoi(&desc->irq_data);
1128} 1128}
1129 1129
1130static struct irq_host_ops mpic_host_ops = { 1130static struct irq_domain_ops mpic_host_ops = {
1131 .match = mpic_host_match, 1131 .match = mpic_host_match,
1132 .map = mpic_host_map, 1132 .map = mpic_host_map,
1133 .xlate = mpic_host_xlate, 1133 .xlate = mpic_host_xlate,
@@ -1345,10 +1345,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1345 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); 1345 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
1346 mpic->isu_mask = (1 << mpic->isu_shift) - 1; 1346 mpic->isu_mask = (1 << mpic->isu_shift) - 1;
1347 1347
1348 mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR, 1348 mpic->irqhost = irq_domain_add_linear(mpic->node,
1349 isu_size ? isu_size : mpic->num_sources, 1349 isu_size ? isu_size : mpic->num_sources,
1350 &mpic_host_ops, 1350 &mpic_host_ops, mpic);
1351 flags & MPIC_LARGE_VECTORS ? 2048 : 256);
1352 1351
1353 /* 1352 /*
1354 * FIXME: The code leaks the MPIC object and mappings here; this 1353 * FIXME: The code leaks the MPIC object and mappings here; this
@@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1357 if (mpic->irqhost == NULL) 1356 if (mpic->irqhost == NULL)
1358 return NULL; 1357 return NULL;
1359 1358
1360 mpic->irqhost->host_data = mpic;
1361
1362 /* Display version */ 1359 /* Display version */
1363 switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) { 1360 switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
1364 case 1: 1361 case 1:
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index 0f67cd79d481..0622aa91b18a 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -32,7 +32,7 @@ void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
32static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) 32static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
33{ 33{
34 irq_hw_number_t hwirq; 34 irq_hw_number_t hwirq;
35 struct irq_host_ops *ops = mpic->irqhost->ops; 35 const struct irq_domain_ops *ops = mpic->irqhost->ops;
36 struct device_node *np; 36 struct device_node *np;
37 int flags, index, i; 37 int flags, index, i;
38 struct of_irq oirq; 38 struct of_irq oirq;
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 14d130268e7a..8848e99a83f2 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -70,7 +70,7 @@ static u32 mv64x60_cached_low_mask;
70static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS; 70static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
71static u32 mv64x60_cached_gpp_mask; 71static u32 mv64x60_cached_gpp_mask;
72 72
73static struct irq_host *mv64x60_irq_host; 73static struct irq_domain *mv64x60_irq_host;
74 74
75/* 75/*
76 * mv64x60_chip_low functions 76 * mv64x60_chip_low functions
@@ -208,7 +208,7 @@ static struct irq_chip *mv64x60_chips[] = {
208 [MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp, 208 [MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp,
209}; 209};
210 210
211static int mv64x60_host_map(struct irq_host *h, unsigned int virq, 211static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
212 irq_hw_number_t hwirq) 212 irq_hw_number_t hwirq)
213{ 213{
214 int level1; 214 int level1;
@@ -223,7 +223,7 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
223 return 0; 223 return 0;
224} 224}
225 225
226static struct irq_host_ops mv64x60_host_ops = { 226static struct irq_domain_ops mv64x60_host_ops = {
227 .map = mv64x60_host_map, 227 .map = mv64x60_host_map,
228}; 228};
229 229
@@ -250,9 +250,8 @@ void __init mv64x60_init_irq(void)
250 paddr = of_translate_address(np, reg); 250 paddr = of_translate_address(np, reg);
251 mv64x60_irq_reg_base = ioremap(paddr, reg[1]); 251 mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
252 252
253 mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 253 mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
254 MV64x60_NUM_IRQS, 254 &mv64x60_host_ops, NULL);
255 &mv64x60_host_ops, MV64x60_NUM_IRQS);
256 255
257 spin_lock_irqsave(&mv64x60_lock, flags); 256 spin_lock_irqsave(&mv64x60_lock, flags);
258 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK, 257 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 73034bd203c4..2fba6ef2f95e 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -245,13 +245,13 @@ static struct irq_chip qe_ic_irq_chip = {
245 .irq_mask_ack = qe_ic_mask_irq, 245 .irq_mask_ack = qe_ic_mask_irq,
246}; 246};
247 247
248static int qe_ic_host_match(struct irq_host *h, struct device_node *node) 248static int qe_ic_host_match(struct irq_domain *h, struct device_node *node)
249{ 249{
250 /* Exact match, unless qe_ic node is NULL */ 250 /* Exact match, unless qe_ic node is NULL */
251 return h->of_node == NULL || h->of_node == node; 251 return h->of_node == NULL || h->of_node == node;
252} 252}
253 253
254static int qe_ic_host_map(struct irq_host *h, unsigned int virq, 254static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
255 irq_hw_number_t hw) 255 irq_hw_number_t hw)
256{ 256{
257 struct qe_ic *qe_ic = h->host_data; 257 struct qe_ic *qe_ic = h->host_data;
@@ -272,23 +272,10 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
272 return 0; 272 return 0;
273} 273}
274 274
275static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct, 275static struct irq_domain_ops qe_ic_host_ops = {
276 const u32 * intspec, unsigned int intsize,
277 irq_hw_number_t * out_hwirq,
278 unsigned int *out_flags)
279{
280 *out_hwirq = intspec[0];
281 if (intsize > 1)
282 *out_flags = intspec[1];
283 else
284 *out_flags = IRQ_TYPE_NONE;
285 return 0;
286}
287
288static struct irq_host_ops qe_ic_host_ops = {
289 .match = qe_ic_host_match, 276 .match = qe_ic_host_match,
290 .map = qe_ic_host_map, 277 .map = qe_ic_host_map,
291 .xlate = qe_ic_host_xlate, 278 .xlate = irq_domain_xlate_onetwocell,
292}; 279};
293 280
294/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ 281/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
@@ -339,8 +326,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
339 if (qe_ic == NULL) 326 if (qe_ic == NULL)
340 return; 327 return;
341 328
342 qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 329 qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
343 NR_QE_IC_INTS, &qe_ic_host_ops, 0); 330 &qe_ic_host_ops, qe_ic);
344 if (qe_ic->irqhost == NULL) { 331 if (qe_ic->irqhost == NULL) {
345 kfree(qe_ic); 332 kfree(qe_ic);
346 return; 333 return;
@@ -348,7 +335,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
348 335
349 qe_ic->regs = ioremap(res.start, resource_size(&res)); 336 qe_ic->regs = ioremap(res.start, resource_size(&res));
350 337
351 qe_ic->irqhost->host_data = qe_ic;
352 qe_ic->hc_irq = qe_ic_irq_chip; 338 qe_ic->hc_irq = qe_ic_irq_chip;
353 339
354 qe_ic->virq_high = irq_of_parse_and_map(node, 0); 340 qe_ic->virq_high = irq_of_parse_and_map(node, 0);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
index c1361d005a8a..c327872ed35c 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -79,7 +79,7 @@ struct qe_ic {
79 volatile u32 __iomem *regs; 79 volatile u32 __iomem *regs;
80 80
81 /* The remapper for this QEIC */ 81 /* The remapper for this QEIC */
82 struct irq_host *irqhost; 82 struct irq_domain *irqhost;
83 83
84 /* The "linux" controller struct */ 84 /* The "linux" controller struct */
85 struct irq_chip hc_irq; 85 struct irq_chip hc_irq;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 4d18658116e5..188012c58f7f 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -51,7 +51,7 @@
51u32 tsi108_pci_cfg_base; 51u32 tsi108_pci_cfg_base;
52static u32 tsi108_pci_cfg_phys; 52static u32 tsi108_pci_cfg_phys;
53u32 tsi108_csr_vir_base; 53u32 tsi108_csr_vir_base;
54static struct irq_host *pci_irq_host; 54static struct irq_domain *pci_irq_host;
55 55
56extern u32 get_vir_csrbase(void); 56extern u32 get_vir_csrbase(void);
57extern u32 tsi108_read_reg(u32 reg_offset); 57extern u32 tsi108_read_reg(u32 reg_offset);
@@ -376,7 +376,7 @@ static struct irq_chip tsi108_pci_irq = {
376 .irq_unmask = tsi108_pci_irq_unmask, 376 .irq_unmask = tsi108_pci_irq_unmask,
377}; 377};
378 378
379static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, 379static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
380 const u32 *intspec, unsigned int intsize, 380 const u32 *intspec, unsigned int intsize,
381 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 381 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
382{ 382{
@@ -385,7 +385,7 @@ static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
385 return 0; 385 return 0;
386} 386}
387 387
388static int pci_irq_host_map(struct irq_host *h, unsigned int virq, 388static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
389 irq_hw_number_t hw) 389 irq_hw_number_t hw)
390{ unsigned int irq; 390{ unsigned int irq;
391 DBG("%s(%d, 0x%lx)\n", __func__, virq, hw); 391 DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
@@ -397,7 +397,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
397 return 0; 397 return 0;
398} 398}
399 399
400static struct irq_host_ops pci_irq_host_ops = { 400static struct irq_domain_ops pci_irq_domain_ops = {
401 .map = pci_irq_host_map, 401 .map = pci_irq_host_map,
402 .xlate = pci_irq_host_xlate, 402 .xlate = pci_irq_host_xlate,
403}; 403};
@@ -419,10 +419,9 @@ void __init tsi108_pci_int_init(struct device_node *node)
419{ 419{
420 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); 420 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
421 421
422 pci_irq_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, 422 pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL);
423 0, &pci_irq_host_ops, 0);
424 if (pci_irq_host == NULL) { 423 if (pci_irq_host == NULL) {
425 printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n"); 424 printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
426 return; 425 return;
427 } 426 }
428 427
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 063c901b1265..92033936a8f7 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -49,7 +49,7 @@ struct uic {
49 raw_spinlock_t lock; 49 raw_spinlock_t lock;
50 50
51 /* The remapper for this UIC */ 51 /* The remapper for this UIC */
52 struct irq_host *irqhost; 52 struct irq_domain *irqhost;
53}; 53};
54 54
55static void uic_unmask_irq(struct irq_data *d) 55static void uic_unmask_irq(struct irq_data *d)
@@ -174,7 +174,7 @@ static struct irq_chip uic_irq_chip = {
174 .irq_set_type = uic_set_irq_type, 174 .irq_set_type = uic_set_irq_type,
175}; 175};
176 176
177static int uic_host_map(struct irq_host *h, unsigned int virq, 177static int uic_host_map(struct irq_domain *h, unsigned int virq,
178 irq_hw_number_t hw) 178 irq_hw_number_t hw)
179{ 179{
180 struct uic *uic = h->host_data; 180 struct uic *uic = h->host_data;
@@ -190,21 +190,9 @@ static int uic_host_map(struct irq_host *h, unsigned int virq,
190 return 0; 190 return 0;
191} 191}
192 192
193static int uic_host_xlate(struct irq_host *h, struct device_node *ct, 193static struct irq_domain_ops uic_host_ops = {
194 const u32 *intspec, unsigned int intsize,
195 irq_hw_number_t *out_hwirq, unsigned int *out_type)
196
197{
198 /* UIC intspecs must have 2 cells */
199 BUG_ON(intsize != 2);
200 *out_hwirq = intspec[0];
201 *out_type = intspec[1];
202 return 0;
203}
204
205static struct irq_host_ops uic_host_ops = {
206 .map = uic_host_map, 194 .map = uic_host_map,
207 .xlate = uic_host_xlate, 195 .xlate = irq_domain_xlate_twocell,
208}; 196};
209 197
210void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) 198void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
@@ -270,13 +258,11 @@ static struct uic * __init uic_init_one(struct device_node *node)
270 } 258 }
271 uic->dcrbase = *dcrreg; 259 uic->dcrbase = *dcrreg;
272 260
273 uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 261 uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops,
274 NR_UIC_INTS, &uic_host_ops, -1); 262 uic);
275 if (! uic->irqhost) 263 if (! uic->irqhost)
276 return NULL; /* FIXME: panic? */ 264 return NULL; /* FIXME: panic? */
277 265
278 uic->irqhost->host_data = uic;
279
280 /* Start with all interrupts disabled, level and non-critical */ 266 /* Start with all interrupts disabled, level and non-critical */
281 mtdcr(uic->dcrbase + UIC_ER, 0); 267 mtdcr(uic->dcrbase + UIC_ER, 0);
282 mtdcr(uic->dcrbase + UIC_CR, 0); 268 mtdcr(uic->dcrbase + UIC_CR, 0);
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index d72eda6a4c05..ea5e204e3450 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -40,7 +40,7 @@ unsigned int xics_interrupt_server_size = 8;
40 40
41DEFINE_PER_CPU(struct xics_cppr, xics_cppr); 41DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
42 42
43struct irq_host *xics_host; 43struct irq_domain *xics_host;
44 44
45static LIST_HEAD(ics_list); 45static LIST_HEAD(ics_list);
46 46
@@ -212,16 +212,16 @@ void xics_migrate_irqs_away(void)
212 /* We can't set affinity on ISA interrupts */ 212 /* We can't set affinity on ISA interrupts */
213 if (virq < NUM_ISA_INTERRUPTS) 213 if (virq < NUM_ISA_INTERRUPTS)
214 continue; 214 continue;
215 if (!virq_is_host(virq, xics_host))
216 continue;
217 irq = (unsigned int)virq_to_hw(virq);
218 /* We need to get IPIs still. */
219 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
220 continue;
221 desc = irq_to_desc(virq); 215 desc = irq_to_desc(virq);
222 /* We only need to migrate enabled IRQS */ 216 /* We only need to migrate enabled IRQS */
223 if (!desc || !desc->action) 217 if (!desc || !desc->action)
224 continue; 218 continue;
219 if (desc->irq_data.domain != xics_host)
220 continue;
221 irq = desc->irq_data.hwirq;
222 /* We need to get IPIs still. */
223 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
224 continue;
225 chip = irq_desc_get_chip(desc); 225 chip = irq_desc_get_chip(desc);
226 if (!chip || !chip->irq_set_affinity) 226 if (!chip || !chip->irq_set_affinity)
227 continue; 227 continue;
@@ -301,7 +301,7 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
301} 301}
302#endif /* CONFIG_SMP */ 302#endif /* CONFIG_SMP */
303 303
304static int xics_host_match(struct irq_host *h, struct device_node *node) 304static int xics_host_match(struct irq_domain *h, struct device_node *node)
305{ 305{
306 struct ics *ics; 306 struct ics *ics;
307 307
@@ -323,7 +323,7 @@ static struct irq_chip xics_ipi_chip = {
323 .irq_unmask = xics_ipi_unmask, 323 .irq_unmask = xics_ipi_unmask,
324}; 324};
325 325
326static int xics_host_map(struct irq_host *h, unsigned int virq, 326static int xics_host_map(struct irq_domain *h, unsigned int virq,
327 irq_hw_number_t hw) 327 irq_hw_number_t hw)
328{ 328{
329 struct ics *ics; 329 struct ics *ics;
@@ -351,7 +351,7 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
351 return -EINVAL; 351 return -EINVAL;
352} 352}
353 353
354static int xics_host_xlate(struct irq_host *h, struct device_node *ct, 354static int xics_host_xlate(struct irq_domain *h, struct device_node *ct,
355 const u32 *intspec, unsigned int intsize, 355 const u32 *intspec, unsigned int intsize,
356 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 356 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
357 357
@@ -366,7 +366,7 @@ static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
366 return 0; 366 return 0;
367} 367}
368 368
369static struct irq_host_ops xics_host_ops = { 369static struct irq_domain_ops xics_host_ops = {
370 .match = xics_host_match, 370 .match = xics_host_match,
371 .map = xics_host_map, 371 .map = xics_host_map,
372 .xlate = xics_host_xlate, 372 .xlate = xics_host_xlate,
@@ -374,8 +374,7 @@ static struct irq_host_ops xics_host_ops = {
374 374
375static void __init xics_init_host(void) 375static void __init xics_init_host(void)
376{ 376{
377 xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops, 377 xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL);
378 XICS_IRQ_SPURIOUS);
379 BUG_ON(xics_host == NULL); 378 BUG_ON(xics_host == NULL);
380 irq_set_default_host(xics_host); 379 irq_set_default_host(xics_host);
381} 380}
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 6183799754af..8d73c3c0bee6 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -40,7 +40,7 @@
40#define XINTC_IVR 24 /* Interrupt Vector */ 40#define XINTC_IVR 24 /* Interrupt Vector */
41#define XINTC_MER 28 /* Master Enable */ 41#define XINTC_MER 28 /* Master Enable */
42 42
43static struct irq_host *master_irqhost; 43static struct irq_domain *master_irqhost;
44 44
45#define XILINX_INTC_MAXIRQS (32) 45#define XILINX_INTC_MAXIRQS (32)
46 46
@@ -141,7 +141,7 @@ static struct irq_chip xilinx_intc_edge_irqchip = {
141/** 141/**
142 * xilinx_intc_xlate - translate virq# from device tree interrupts property 142 * xilinx_intc_xlate - translate virq# from device tree interrupts property
143 */ 143 */
144static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct, 144static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct,
145 const u32 *intspec, unsigned int intsize, 145 const u32 *intspec, unsigned int intsize,
146 irq_hw_number_t *out_hwirq, 146 irq_hw_number_t *out_hwirq,
147 unsigned int *out_flags) 147 unsigned int *out_flags)
@@ -161,7 +161,7 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
161 161
162 return 0; 162 return 0;
163} 163}
164static int xilinx_intc_map(struct irq_host *h, unsigned int virq, 164static int xilinx_intc_map(struct irq_domain *h, unsigned int virq,
165 irq_hw_number_t irq) 165 irq_hw_number_t irq)
166{ 166{
167 irq_set_chip_data(virq, h->host_data); 167 irq_set_chip_data(virq, h->host_data);
@@ -177,15 +177,15 @@ static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
177 return 0; 177 return 0;
178} 178}
179 179
180static struct irq_host_ops xilinx_intc_ops = { 180static struct irq_domain_ops xilinx_intc_ops = {
181 .map = xilinx_intc_map, 181 .map = xilinx_intc_map,
182 .xlate = xilinx_intc_xlate, 182 .xlate = xilinx_intc_xlate,
183}; 183};
184 184
185struct irq_host * __init 185struct irq_domain * __init
186xilinx_intc_init(struct device_node *np) 186xilinx_intc_init(struct device_node *np)
187{ 187{
188 struct irq_host * irq; 188 struct irq_domain * irq;
189 void * regs; 189 void * regs;
190 190
191 /* Find and map the intc registers */ 191 /* Find and map the intc registers */
@@ -200,12 +200,11 @@ xilinx_intc_init(struct device_node *np)
200 out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */ 200 out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */
201 out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */ 201 out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
202 202
203 /* Allocate and initialize an irq_host structure. */ 203 /* Allocate and initialize an irq_domain structure. */
204 irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS, 204 irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
205 &xilinx_intc_ops, -1); 205 regs);
206 if (!irq) 206 if (!irq)
207 panic(__FILE__ ": Cannot allocate IRQ host\n"); 207 panic(__FILE__ ": Cannot allocate IRQ host\n");
208 irq->host_data = regs;
209 208
210 return irq; 209 return irq;
211} 210}