aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-06-04 01:04:35 -0400
committerGrant Likely <grant.likely@secretlab.ca>2012-07-11 11:15:34 -0400
commit913af2070731bfc1bd39bb35c5cd2fd66f5eff12 (patch)
tree26e177b59bdc23aa5d0ef75a51cc76abdfd1281e
parent80c1834fc86c2bbacb54a8fc3c04a8b0066b0996 (diff)
irqdomain: Split disassociating code into separate function
This patch moves the irq disassociation code out into a separate function in preparation to extend irq_setup_virq to handle multiple irqs and rename it for use by interrupt controller drivers. The new function will be used by irq_setup_virq() in its error path. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mundt <lethal@linux-sh.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Rob Herring <rob.herring@calxeda.com>
-rw-r--r--kernel/irq/irqdomain.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 622fdf4b82b6..17634f2c9f6c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -364,6 +364,52 @@ void irq_set_default_host(struct irq_domain *domain)
364} 364}
365EXPORT_SYMBOL_GPL(irq_set_default_host); 365EXPORT_SYMBOL_GPL(irq_set_default_host);
366 366
367static void irq_domain_disassociate_many(struct irq_domain *domain,
368 unsigned int irq_base, int count)
369{
370 /*
371 * disassociate in reverse order;
372 * not strictly necessary, but nice for unwinding
373 */
374 while (count--) {
375 int irq = irq_base + count;
376 struct irq_data *irq_data = irq_get_irq_data(irq);
377 irq_hw_number_t hwirq = irq_data->hwirq;
378
379 if (WARN_ON(!irq_data || irq_data->domain != domain))
380 continue;
381
382 irq_set_status_flags(irq, IRQ_NOREQUEST);
383
384 /* remove chip and handler */
385 irq_set_chip_and_handler(irq, NULL, NULL);
386
387 /* Make sure it's completed */
388 synchronize_irq(irq);
389
390 /* Tell the PIC about it */
391 if (domain->ops->unmap)
392 domain->ops->unmap(domain, irq);
393 smp_mb();
394
395 irq_data->domain = NULL;
396 irq_data->hwirq = 0;
397
398 /* Clear reverse map */
399 switch(domain->revmap_type) {
400 case IRQ_DOMAIN_MAP_LINEAR:
401 if (hwirq < domain->revmap_data.linear.size)
402 domain->revmap_data.linear.revmap[hwirq] = 0;
403 break;
404 case IRQ_DOMAIN_MAP_TREE:
405 mutex_lock(&revmap_trees_mutex);
406 radix_tree_delete(&domain->revmap_data.tree, hwirq);
407 mutex_unlock(&revmap_trees_mutex);
408 break;
409 }
410 }
411}
412
367static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, 413static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
368 irq_hw_number_t hwirq) 414 irq_hw_number_t hwirq)
369{ 415{
@@ -544,7 +590,6 @@ void irq_dispose_mapping(unsigned int virq)
544{ 590{
545 struct irq_data *irq_data = irq_get_irq_data(virq); 591 struct irq_data *irq_data = irq_get_irq_data(virq);
546 struct irq_domain *domain; 592 struct irq_domain *domain;
547 irq_hw_number_t hwirq;
548 593
549 if (!virq || !irq_data) 594 if (!virq || !irq_data)
550 return; 595 return;
@@ -557,33 +602,7 @@ void irq_dispose_mapping(unsigned int virq)
557 if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) 602 if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
558 return; 603 return;
559 604
560 irq_set_status_flags(virq, IRQ_NOREQUEST); 605 irq_domain_disassociate_many(domain, virq, 1);
561
562 /* remove chip and handler */
563 irq_set_chip_and_handler(virq, NULL, NULL);
564
565 /* Make sure it's completed */
566 synchronize_irq(virq);
567
568 /* Tell the PIC about it */
569 if (domain->ops->unmap)
570 domain->ops->unmap(domain, virq);
571 smp_mb();
572
573 /* Clear reverse map */
574 hwirq = irq_data->hwirq;
575 switch(domain->revmap_type) {
576 case IRQ_DOMAIN_MAP_LINEAR:
577 if (hwirq < domain->revmap_data.linear.size)
578 domain->revmap_data.linear.revmap[hwirq] = 0;
579 break;
580 case IRQ_DOMAIN_MAP_TREE:
581 mutex_lock(&revmap_trees_mutex);
582 radix_tree_delete(&domain->revmap_data.tree, hwirq);
583 mutex_unlock(&revmap_trees_mutex);
584 break;
585 }
586
587 irq_free_desc(virq); 606 irq_free_desc(virq);
588} 607}
589EXPORT_SYMBOL_GPL(irq_dispose_mapping); 608EXPORT_SYMBOL_GPL(irq_dispose_mapping);