irq_domain: Replace irq_alloc_host() with revmap-specific initializers
[linux-2.6-block.git] / kernel / irq / irqdomain.c
1 #include <linux/debugfs.h>
2 #include <linux/hardirq.h>
3 #include <linux/interrupt.h>
4 #include <linux/irq.h>
5 #include <linux/irqdesc.h>
6 #include <linux/irqdomain.h>
7 #include <linux/module.h>
8 #include <linux/mutex.h>
9 #include <linux/of.h>
10 #include <linux/of_address.h>
11 #include <linux/seq_file.h>
12 #include <linux/slab.h>
13 #include <linux/smp.h>
14 #include <linux/fs.h>
15
16 #define IRQ_DOMAIN_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
17 #define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
18 #define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
19 #define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
20
21 static LIST_HEAD(irq_domain_list);
22 static DEFINE_MUTEX(irq_domain_mutex);
23
24 #ifdef CONFIG_PPC
25 static DEFINE_MUTEX(revmap_trees_mutex);
26 static unsigned int irq_virq_count = NR_IRQS;
27 static struct irq_domain *irq_default_domain;
28
29 static int default_irq_domain_match(struct irq_domain *d, struct device_node *np)
30 {
31         return d->of_node != NULL && d->of_node == np;
32 }
33
34 /**
35  * irq_domain_alloc() - Allocate a new irq_domain data structure
36  * @of_node: optional device-tree node of the interrupt controller
37  * @revmap_type: type of reverse mapping to use
38  * @ops: map/unmap domain callbacks
39  * @host_data: Controller private data pointer
40  *
41  * Allocates and initialize and irq_domain structure.  Caller is expected to
42  * register allocated irq_domain with irq_domain_register().  Returns pointer
43  * to IRQ domain, or NULL on failure.
44  */
45 static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
46                                            unsigned int revmap_type,
47                                            struct irq_domain_ops *ops,
48                                            void *host_data)
49 {
50         struct irq_domain *domain;
51
52         domain = kzalloc(sizeof(*domain), GFP_KERNEL);
53         if (WARN_ON(!domain))
54                 return NULL;
55
56         /* Fill structure */
57         domain->revmap_type = revmap_type;
58         domain->ops = ops;
59         domain->host_data = host_data;
60         domain->of_node = of_node_get(of_node);
61
62         if (domain->ops->match == NULL)
63                 domain->ops->match = default_irq_domain_match;
64
65         return domain;
66 }
67
68 static void irq_domain_add(struct irq_domain *domain)
69 {
70         mutex_lock(&irq_domain_mutex);
71         list_add(&domain->link, &irq_domain_list);
72         mutex_unlock(&irq_domain_mutex);
73         pr_debug("irq: Allocated domain of type %d @0x%p\n",
74                  domain->revmap_type, domain);
75 }
76
77 /**
78  * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
79  * @of_node: pointer to interrupt controller's device tree node.
80  * @ops: map/unmap domain callbacks
81  * @host_data: Controller private data pointer
82  *
83  * Note: the map() callback will be called before this function returns
84  * for all legacy interrupts except 0 (which is always the invalid irq for
85  * a legacy controller).
86  */
87 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
88                                          struct irq_domain_ops *ops,
89                                          void *host_data)
90 {
91         struct irq_domain *domain, *h;
92         unsigned int i;
93
94         domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
95         if (!domain)
96                 return NULL;
97
98         mutex_lock(&irq_domain_mutex);
99         /* Make sure only one legacy controller can be created */
100         list_for_each_entry(h, &irq_domain_list, link) {
101                 if (WARN_ON(h->revmap_type == IRQ_DOMAIN_MAP_LEGACY)) {
102                         mutex_unlock(&irq_domain_mutex);
103                         of_node_put(domain->of_node);
104                         kfree(domain);
105                         return NULL;
106                 }
107         }
108         list_add(&domain->link, &irq_domain_list);
109         mutex_unlock(&irq_domain_mutex);
110
111         /* setup us as the domain for all legacy interrupts */
112         for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
113                 struct irq_data *irq_data = irq_get_irq_data(i);
114                 irq_data->hwirq = i;
115                 irq_data->domain = domain;
116
117                 /* Legacy flags are left to default at this point,
118                  * one can then use irq_create_mapping() to
119                  * explicitly change them
120                  */
121                 ops->map(domain, i, i);
122
123                 /* Clear norequest flags */
124                 irq_clear_status_flags(i, IRQ_NOREQUEST);
125         }
126         return domain;
127 }
128
129 /**
130  * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
131  * @of_node: pointer to interrupt controller's device tree node.
132  * @ops: map/unmap domain callbacks
133  * @host_data: Controller private data pointer
134  */
135 struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
136                                          unsigned int size,
137                                          struct irq_domain_ops *ops,
138                                          void *host_data)
139 {
140         struct irq_domain *domain;
141         unsigned int *revmap;
142
143         revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
144         if (WARN_ON(!revmap))
145                 return NULL;
146
147         domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data);
148         if (!domain) {
149                 kfree(revmap);
150                 return NULL;
151         }
152         domain->revmap_data.linear.size = size;
153         domain->revmap_data.linear.revmap = revmap;
154         irq_domain_add(domain);
155         return domain;
156 }
157
158 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
159                                          struct irq_domain_ops *ops,
160                                          void *host_data)
161 {
162         struct irq_domain *domain = irq_domain_alloc(of_node,
163                                         IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
164         if (domain)
165                 irq_domain_add(domain);
166         return domain;
167 }
168
169 /**
170  * irq_domain_add_tree()
171  * @of_node: pointer to interrupt controller's device tree node.
172  * @ops: map/unmap domain callbacks
173  *
174  * Note: The radix tree will be allocated later during boot automatically
175  * (the reverse mapping will use the slow path until that happens).
176  */
177 struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
178                                          struct irq_domain_ops *ops,
179                                          void *host_data)
180 {
181         struct irq_domain *domain = irq_domain_alloc(of_node,
182                                         IRQ_DOMAIN_MAP_TREE, ops, host_data);
183         if (domain) {
184                 INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
185                 irq_domain_add(domain);
186         }
187         return domain;
188 }
189
190 /**
191  * irq_find_host() - Locates a domain for a given device node
192  * @node: device-tree node of the interrupt controller
193  */
194 struct irq_domain *irq_find_host(struct device_node *node)
195 {
196         struct irq_domain *h, *found = NULL;
197
198         /* We might want to match the legacy controller last since
199          * it might potentially be set to match all interrupts in
200          * the absence of a device node. This isn't a problem so far
201          * yet though...
202          */
203         mutex_lock(&irq_domain_mutex);
204         list_for_each_entry(h, &irq_domain_list, link)
205                 if (h->ops->match(h, node)) {
206                         found = h;
207                         break;
208                 }
209         mutex_unlock(&irq_domain_mutex);
210         return found;
211 }
212 EXPORT_SYMBOL_GPL(irq_find_host);
213
214 /**
215  * irq_set_default_host() - Set a "default" irq domain
216  * @domain: default domain pointer
217  *
218  * For convenience, it's possible to set a "default" domain that will be used
219  * whenever NULL is passed to irq_create_mapping(). It makes life easier for
220  * platforms that want to manipulate a few hard coded interrupt numbers that
221  * aren't properly represented in the device-tree.
222  */
223 void irq_set_default_host(struct irq_domain *domain)
224 {
225         pr_debug("irq: Default domain set to @0x%p\n", domain);
226
227         irq_default_domain = domain;
228 }
229
230 /**
231  * irq_set_virq_count() - Set the maximum number of linux irqs
232  * @count: number of linux irqs, capped with NR_IRQS
233  *
234  * This is mainly for use by platforms like iSeries who want to program
235  * the virtual irq number in the controller to avoid the reverse mapping
236  */
237 void irq_set_virq_count(unsigned int count)
238 {
239         pr_debug("irq: Trying to set virq count to %d\n", count);
240
241         BUG_ON(count < NUM_ISA_INTERRUPTS);
242         if (count < NR_IRQS)
243                 irq_virq_count = count;
244 }
245
246 static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
247                             irq_hw_number_t hwirq)
248 {
249         struct irq_data *irq_data = irq_get_irq_data(virq);
250
251         irq_data->hwirq = hwirq;
252         irq_data->domain = domain;
253         if (domain->ops->map(domain, virq, hwirq)) {
254                 pr_debug("irq: -> mapping failed, freeing\n");
255                 irq_data->domain = NULL;
256                 irq_data->hwirq = 0;
257                 return -1;
258         }
259
260         irq_clear_status_flags(virq, IRQ_NOREQUEST);
261
262         return 0;
263 }
264
265 /**
266  * irq_create_direct_mapping() - Allocate an irq for direct mapping
267  * @domain: domain to allocate the irq for or NULL for default domain
268  *
269  * This routine is used for irq controllers which can choose the hardware
270  * interrupt numbers they generate. In such a case it's simplest to use
271  * the linux irq as the hardware interrupt number.
272  */
273 unsigned int irq_create_direct_mapping(struct irq_domain *domain)
274 {
275         unsigned int virq;
276
277         if (domain == NULL)
278                 domain = irq_default_domain;
279
280         BUG_ON(domain == NULL);
281         WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
282
283         virq = irq_alloc_desc_from(1, 0);
284         if (!virq) {
285                 pr_debug("irq: create_direct virq allocation failed\n");
286                 return 0;
287         }
288         if (virq >= irq_virq_count) {
289                 pr_err("ERROR: no free irqs available below %i maximum\n",
290                         irq_virq_count);
291                 irq_free_desc(virq);
292                 return 0;
293         }
294
295         pr_debug("irq: create_direct obtained virq %d\n", virq);
296
297         if (irq_setup_virq(domain, virq, virq)) {
298                 irq_free_desc(virq);
299                 return 0;
300         }
301
302         return virq;
303 }
304
305 /**
306  * irq_create_mapping() - Map a hardware interrupt into linux irq space
307  * @domain: domain owning this hardware interrupt or NULL for default domain
308  * @hwirq: hardware irq number in that domain space
309  *
310  * Only one mapping per hardware interrupt is permitted. Returns a linux
311  * irq number.
312  * If the sense/trigger is to be specified, set_irq_type() should be called
313  * on the number returned from that call.
314  */
315 unsigned int irq_create_mapping(struct irq_domain *domain,
316                                 irq_hw_number_t hwirq)
317 {
318         unsigned int virq, hint;
319
320         pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
321
322         /* Look for default domain if nececssary */
323         if (domain == NULL)
324                 domain = irq_default_domain;
325         if (domain == NULL) {
326                 printk(KERN_WARNING "irq_create_mapping called for"
327                        " NULL domain, hwirq=%lx\n", hwirq);
328                 WARN_ON(1);
329                 return 0;
330         }
331         pr_debug("irq: -> using domain @%p\n", domain);
332
333         /* Check if mapping already exists */
334         virq = irq_find_mapping(domain, hwirq);
335         if (virq) {
336                 pr_debug("irq: -> existing mapping on virq %d\n", virq);
337                 return virq;
338         }
339
340         /* Get a virtual interrupt number */
341         if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) {
342                 /* Handle legacy */
343                 virq = (unsigned int)hwirq;
344                 if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
345                         return 0;
346                 return virq;
347         } else {
348                 /* Allocate a virtual interrupt number */
349                 hint = hwirq % irq_virq_count;
350                 if (hint == 0)
351                         hint++;
352                 virq = irq_alloc_desc_from(hint, 0);
353                 if (!virq)
354                         virq = irq_alloc_desc_from(1, 0);
355                 if (!virq) {
356                         pr_debug("irq: -> virq allocation failed\n");
357                         return 0;
358                 }
359         }
360
361         if (irq_setup_virq(domain, virq, hwirq)) {
362                 if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
363                         irq_free_desc(virq);
364                 return 0;
365         }
366
367         pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
368                 hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
369
370         return virq;
371 }
372 EXPORT_SYMBOL_GPL(irq_create_mapping);
373
374 unsigned int irq_create_of_mapping(struct device_node *controller,
375                                    const u32 *intspec, unsigned int intsize)
376 {
377         struct irq_domain *domain;
378         irq_hw_number_t hwirq;
379         unsigned int type = IRQ_TYPE_NONE;
380         unsigned int virq;
381
382         domain = controller ? irq_find_host(controller) : irq_default_domain;
383         if (!domain) {
384                 printk(KERN_WARNING "irq: no irq domain found for %s !\n",
385                        controller->full_name);
386                 return 0;
387         }
388
389         /* If domain has no translation, then we assume interrupt line */
390         if (domain->ops->xlate == NULL)
391                 hwirq = intspec[0];
392         else {
393                 if (domain->ops->xlate(domain, controller, intspec, intsize,
394                                      &hwirq, &type))
395                         return 0;
396         }
397
398         /* Create mapping */
399         virq = irq_create_mapping(domain, hwirq);
400         if (!virq)
401                 return virq;
402
403         /* Set type if specified and different than the current one */
404         if (type != IRQ_TYPE_NONE &&
405             type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
406                 irq_set_irq_type(virq, type);
407         return virq;
408 }
409 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
410
411 /**
412  * irq_dispose_mapping() - Unmap an interrupt
413  * @virq: linux irq number of the interrupt to unmap
414  */
415 void irq_dispose_mapping(unsigned int virq)
416 {
417         struct irq_data *irq_data = irq_get_irq_data(virq);
418         struct irq_domain *domain;
419         irq_hw_number_t hwirq;
420
421         if (!virq || !irq_data)
422                 return;
423
424         domain = irq_data->domain;
425         if (WARN_ON(domain == NULL))
426                 return;
427
428         /* Never unmap legacy interrupts */
429         if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
430                 return;
431
432         irq_set_status_flags(virq, IRQ_NOREQUEST);
433
434         /* remove chip and handler */
435         irq_set_chip_and_handler(virq, NULL, NULL);
436
437         /* Make sure it's completed */
438         synchronize_irq(virq);
439
440         /* Tell the PIC about it */
441         if (domain->ops->unmap)
442                 domain->ops->unmap(domain, virq);
443         smp_mb();
444
445         /* Clear reverse map */
446         hwirq = irq_data->hwirq;
447         switch(domain->revmap_type) {
448         case IRQ_DOMAIN_MAP_LINEAR:
449                 if (hwirq < domain->revmap_data.linear.size)
450                         domain->revmap_data.linear.revmap[hwirq] = 0;
451                 break;
452         case IRQ_DOMAIN_MAP_TREE:
453                 mutex_lock(&revmap_trees_mutex);
454                 radix_tree_delete(&domain->revmap_data.tree, hwirq);
455                 mutex_unlock(&revmap_trees_mutex);
456                 break;
457         }
458
459         irq_free_desc(virq);
460 }
461 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
462
463 /**
464  * irq_find_mapping() - Find a linux irq from an hw irq number.
465  * @domain: domain owning this hardware interrupt
466  * @hwirq: hardware irq number in that domain space
467  *
468  * This is a slow path, for use by generic code. It's expected that an
469  * irq controller implementation directly calls the appropriate low level
470  * mapping function.
471  */
472 unsigned int irq_find_mapping(struct irq_domain *domain,
473                               irq_hw_number_t hwirq)
474 {
475         unsigned int i;
476         unsigned int hint = hwirq % irq_virq_count;
477
478         /* Look for default domain if nececssary */
479         if (domain == NULL)
480                 domain = irq_default_domain;
481         if (domain == NULL)
482                 return 0;
483
484         /* legacy -> bail early */
485         if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
486                 return hwirq;
487
488         /* Slow path does a linear search of the map */
489         if (hint == 0)
490                 hint = 1;
491         i = hint;
492         do {
493                 struct irq_data *data = irq_get_irq_data(i);
494                 if (data && (data->domain == domain) && (data->hwirq == hwirq))
495                         return i;
496                 i++;
497                 if (i >= irq_virq_count)
498                         i = 1;
499         } while(i != hint);
500         return 0;
501 }
502 EXPORT_SYMBOL_GPL(irq_find_mapping);
503
504 /**
505  * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
506  * @domain: domain owning this hardware interrupt
507  * @hwirq: hardware irq number in that domain space
508  *
509  * This is a fast path, for use by irq controller code that uses radix tree
510  * revmaps
511  */
512 unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
513                                      irq_hw_number_t hwirq)
514 {
515         struct irq_data *irq_data;
516
517         if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
518                 return irq_find_mapping(domain, hwirq);
519
520         /*
521          * Freeing an irq can delete nodes along the path to
522          * do the lookup via call_rcu.
523          */
524         rcu_read_lock();
525         irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq);
526         rcu_read_unlock();
527
528         /*
529          * If found in radix tree, then fine.
530          * Else fallback to linear lookup - this should not happen in practice
531          * as it means that we failed to insert the node in the radix tree.
532          */
533         return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
534 }
535
536 /**
537  * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
538  * @domain: domain owning this hardware interrupt
539  * @virq: linux irq number
540  * @hwirq: hardware irq number in that domain space
541  *
542  * This is for use by irq controllers that use a radix tree reverse
543  * mapping for fast lookup.
544  */
545 void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
546                              irq_hw_number_t hwirq)
547 {
548         struct irq_data *irq_data = irq_get_irq_data(virq);
549
550         if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
551                 return;
552
553         if (virq) {
554                 mutex_lock(&revmap_trees_mutex);
555                 radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
556                 mutex_unlock(&revmap_trees_mutex);
557         }
558 }
559
560 /**
561  * irq_linear_revmap() - Find a linux irq from a hw irq number.
562  * @domain: domain owning this hardware interrupt
563  * @hwirq: hardware irq number in that domain space
564  *
565  * This is a fast path, for use by irq controller code that uses linear
566  * revmaps. It does fallback to the slow path if the revmap doesn't exist
567  * yet and will create the revmap entry with appropriate locking
568  */
569 unsigned int irq_linear_revmap(struct irq_domain *domain,
570                                irq_hw_number_t hwirq)
571 {
572         unsigned int *revmap;
573
574         if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
575                 return irq_find_mapping(domain, hwirq);
576
577         /* Check revmap bounds */
578         if (unlikely(hwirq >= domain->revmap_data.linear.size))
579                 return irq_find_mapping(domain, hwirq);
580
581         /* Check if revmap was allocated */
582         revmap = domain->revmap_data.linear.revmap;
583         if (unlikely(revmap == NULL))
584                 return irq_find_mapping(domain, hwirq);
585
586         /* Fill up revmap with slow path if no mapping found */
587         if (unlikely(!revmap[hwirq]))
588                 revmap[hwirq] = irq_find_mapping(domain, hwirq);
589
590         return revmap[hwirq];
591 }
592
593 #ifdef CONFIG_VIRQ_DEBUG
594 static int virq_debug_show(struct seq_file *m, void *private)
595 {
596         unsigned long flags;
597         struct irq_desc *desc;
598         const char *p;
599         static const char none[] = "none";
600         void *data;
601         int i;
602
603         seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
604                       "chip name", "chip data", "domain name");
605
606         for (i = 1; i < nr_irqs; i++) {
607                 desc = irq_to_desc(i);
608                 if (!desc)
609                         continue;
610
611                 raw_spin_lock_irqsave(&desc->lock, flags);
612
613                 if (desc->action && desc->action->handler) {
614                         struct irq_chip *chip;
615
616                         seq_printf(m, "%5d  ", i);
617                         seq_printf(m, "0x%05lx  ", desc->irq_data.hwirq);
618
619                         chip = irq_desc_get_chip(desc);
620                         if (chip && chip->name)
621                                 p = chip->name;
622                         else
623                                 p = none;
624                         seq_printf(m, "%-15s  ", p);
625
626                         data = irq_desc_get_chip_data(desc);
627                         seq_printf(m, "0x%16p  ", data);
628
629                         if (desc->irq_data.domain->of_node)
630                                 p = desc->irq_data.domain->of_node->full_name;
631                         else
632                                 p = none;
633                         seq_printf(m, "%s\n", p);
634                 }
635
636                 raw_spin_unlock_irqrestore(&desc->lock, flags);
637         }
638
639         return 0;
640 }
641
642 static int virq_debug_open(struct inode *inode, struct file *file)
643 {
644         return single_open(file, virq_debug_show, inode->i_private);
645 }
646
647 static const struct file_operations virq_debug_fops = {
648         .open = virq_debug_open,
649         .read = seq_read,
650         .llseek = seq_lseek,
651         .release = single_release,
652 };
653
654 static int __init irq_debugfs_init(void)
655 {
656         if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
657                                  NULL, &virq_debug_fops) == NULL)
658                 return -ENOMEM;
659
660         return 0;
661 }
662 __initcall(irq_debugfs_init);
663 #endif /* CONFIG_VIRQ_DEBUG */
664
665 #else /* CONFIG_PPC */
666
667 /**
668  * irq_domain_add() - Register an irq_domain
669  * @domain: ptr to initialized irq_domain structure
670  *
671  * Registers an irq_domain structure.  The irq_domain must at a minimum be
672  * initialized with an ops structure pointer, and either a ->to_irq hook or
673  * a valid irq_base value.  Everything else is optional.
674  */
675 void irq_domain_add(struct irq_domain *domain)
676 {
677         struct irq_data *d;
678         int hwirq, irq;
679
680         /*
681          * This assumes that the irq_domain owner has already allocated
682          * the irq_descs.  This block will be removed when support for dynamic
683          * allocation of irq_descs is added to irq_domain.
684          */
685         irq_domain_for_each_irq(domain, hwirq, irq) {
686                 d = irq_get_irq_data(irq);
687                 if (!d) {
688                         WARN(1, "error: assigning domain to non existant irq_desc");
689                         return;
690                 }
691                 if (d->domain) {
692                         /* things are broken; just report, don't clean up */
693                         WARN(1, "error: irq_desc already assigned to a domain");
694                         return;
695                 }
696                 d->domain = domain;
697                 d->hwirq = hwirq;
698         }
699
700         mutex_lock(&irq_domain_mutex);
701         list_add(&domain->link, &irq_domain_list);
702         mutex_unlock(&irq_domain_mutex);
703 }
704
705 /**
706  * irq_domain_del() - Unregister an irq_domain
707  * @domain: ptr to registered irq_domain.
708  */
709 void irq_domain_del(struct irq_domain *domain)
710 {
711         struct irq_data *d;
712         int hwirq, irq;
713
714         mutex_lock(&irq_domain_mutex);
715         list_del(&domain->link);
716         mutex_unlock(&irq_domain_mutex);
717
718         /* Clear the irq_domain assignments */
719         irq_domain_for_each_irq(domain, hwirq, irq) {
720                 d = irq_get_irq_data(irq);
721                 d->domain = NULL;
722         }
723 }
724
725 #if defined(CONFIG_OF_IRQ)
726 /**
727  * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
728  *
729  * Used by the device tree interrupt mapping code to translate a device tree
730  * interrupt specifier to a valid linux irq number.  Returns either a valid
731  * linux IRQ number or 0.
732  *
733  * When the caller no longer need the irq number returned by this function it
734  * should arrange to call irq_dispose_mapping().
735  */
736 unsigned int irq_create_of_mapping(struct device_node *controller,
737                                    const u32 *intspec, unsigned int intsize)
738 {
739         struct irq_domain *domain;
740         unsigned long hwirq;
741         unsigned int irq, type;
742         int rc = -EINVAL;
743
744         /* Find a domain which can translate the irq spec */
745         mutex_lock(&irq_domain_mutex);
746         list_for_each_entry(domain, &irq_domain_list, link) {
747                 if (!domain->ops->xlate)
748                         continue;
749                 rc = domain->ops->xlate(domain, controller,
750                                         intspec, intsize, &hwirq, &type);
751                 if (rc == 0)
752                         break;
753         }
754         mutex_unlock(&irq_domain_mutex);
755
756         if (rc != 0)
757                 return 0;
758
759         irq = irq_domain_to_irq(domain, hwirq);
760         if (type != IRQ_TYPE_NONE)
761                 irq_set_irq_type(irq, type);
762         pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
763                  controller->full_name, (int)hwirq, irq, type);
764         return irq;
765 }
766 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
767
768 /**
769  * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
770  * @irq: linux irq number to be discarded
771  *
772  * Calling this function indicates the caller no longer needs a reference to
773  * the linux irq number returned by a prior call to irq_create_of_mapping().
774  */
775 void irq_dispose_mapping(unsigned int irq)
776 {
777         /*
778          * nothing yet; will be filled when support for dynamic allocation of
779          * irq_descs is added to irq_domain
780          */
781 }
782 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
783
784 int irq_domain_simple_xlate(struct irq_domain *d,
785                             struct device_node *controller,
786                             const u32 *intspec, unsigned int intsize,
787                             unsigned long *out_hwirq, unsigned int *out_type)
788 {
789         if (d->of_node != controller)
790                 return -EINVAL;
791         if (intsize < 1)
792                 return -EINVAL;
793         if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
794             (intspec[0] >= d->hwirq_base + d->nr_irq)))
795                 return -EINVAL;
796
797         *out_hwirq = intspec[0];
798         *out_type = IRQ_TYPE_NONE;
799         if (intsize > 1)
800                 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
801         return 0;
802 }
803
804 /**
805  * irq_domain_create_simple() - Set up a 'simple' translation range
806  */
807 void irq_domain_add_simple(struct device_node *controller, int irq_base)
808 {
809         struct irq_domain *domain;
810
811         domain = kzalloc(sizeof(*domain), GFP_KERNEL);
812         if (!domain) {
813                 WARN_ON(1);
814                 return;
815         }
816
817         domain->irq_base = irq_base;
818         domain->of_node = of_node_get(controller);
819         domain->ops = &irq_domain_simple_ops;
820         irq_domain_add(domain);
821 }
822 EXPORT_SYMBOL_GPL(irq_domain_add_simple);
823
824 void irq_domain_generate_simple(const struct of_device_id *match,
825                                 u64 phys_base, unsigned int irq_start)
826 {
827         struct device_node *node;
828         pr_debug("looking for phys_base=%llx, irq_start=%i\n",
829                 (unsigned long long) phys_base, (int) irq_start);
830         node = of_find_matching_node_by_address(NULL, match, phys_base);
831         if (node)
832                 irq_domain_add_simple(node, irq_start);
833 }
834 EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
835 #endif /* CONFIG_OF_IRQ */
836
837 struct irq_domain_ops irq_domain_simple_ops = {
838 #ifdef CONFIG_OF_IRQ
839         .xlate = irq_domain_simple_xlate,
840 #endif /* CONFIG_OF_IRQ */
841 };
842 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
843
844 #endif /* !CONFIG_PPC */