diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2015-01-22 22:25:05 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-01-27 23:28:04 -0500 |
commit | c1c3a526bb4ddbec7639a9fb3b84fede25b201d9 (patch) | |
tree | 2fa22209519544f4733852fd24b4d0696c82c96f /arch/powerpc/platforms/powernv | |
parent | 08135139430fabdeaa990da8a9e0d436aad0672b (diff) |
powerpc/powernv: Separate function for OPAL IRQ setup
The patch put the OPAL interrupt setup logic in opal_init() into
seperate function opal_irq_init() for easier code maintaining. The
patch doesn't introduce logic changes except:
* Rename variable names.
* Release virtual IRQ upon error from request_irq().
* Don't cache the virtual IRQ to opal_irqs[] upon error from
request_irq().
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv')
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 8f5bbfae9c32..933c7fbd6b54 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -701,11 +701,49 @@ static void opal_i2c_create_devs(void) | |||
701 | of_platform_device_create(np, NULL, NULL); | 701 | of_platform_device_create(np, NULL, NULL); |
702 | } | 702 | } |
703 | 703 | ||
704 | static void __init opal_irq_init(struct device_node *dn) | ||
705 | { | ||
706 | const __be32 *irqs; | ||
707 | int i, irqlen; | ||
708 | |||
709 | /* Get interrupt property */ | ||
710 | irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); | ||
711 | pr_debug("Found %d interrupts reserved for OPAL\n", | ||
712 | irqs ? (irqlen / 4) : 0); | ||
713 | |||
714 | /* Install interrupt handlers */ | ||
715 | opal_irq_count = irqlen / 4; | ||
716 | opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL); | ||
717 | for (i = 0; irqs && i < opal_irq_count; i++, irqs++) { | ||
718 | unsigned int irq, virq; | ||
719 | int rc; | ||
720 | |||
721 | /* Get hardware and virtual IRQ */ | ||
722 | irq = be32_to_cpup(irqs); | ||
723 | virq = irq_create_mapping(NULL, irq); | ||
724 | if (virq == NO_IRQ) { | ||
725 | pr_warn("Failed to map irq 0x%x\n", irq); | ||
726 | continue; | ||
727 | } | ||
728 | |||
729 | /* Install interrupt handler */ | ||
730 | rc = request_irq(virq, opal_interrupt, 0, "opal", NULL); | ||
731 | if (rc) { | ||
732 | irq_dispose_mapping(virq); | ||
733 | pr_warn("Error %d requesting irq %d (0x%x)\n", | ||
734 | rc, virq, irq); | ||
735 | continue; | ||
736 | } | ||
737 | |||
738 | /* Cache IRQ */ | ||
739 | opal_irqs[i] = virq; | ||
740 | } | ||
741 | } | ||
742 | |||
704 | static int __init opal_init(void) | 743 | static int __init opal_init(void) |
705 | { | 744 | { |
706 | struct device_node *np, *consoles; | 745 | struct device_node *np, *consoles; |
707 | const __be32 *irqs; | 746 | int rc; |
708 | int rc, i, irqlen; | ||
709 | 747 | ||
710 | opal_node = of_find_node_by_path("/ibm,opal"); | 748 | opal_node = of_find_node_by_path("/ibm,opal"); |
711 | if (!opal_node) { | 749 | if (!opal_node) { |
@@ -731,24 +769,7 @@ static int __init opal_init(void) | |||
731 | opal_i2c_create_devs(); | 769 | opal_i2c_create_devs(); |
732 | 770 | ||
733 | /* Find all OPAL interrupts and request them */ | 771 | /* Find all OPAL interrupts and request them */ |
734 | irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); | 772 | opal_irq_init(opal_node); |
735 | pr_debug("Found %d interrupts reserved for OPAL\n", | ||
736 | irqs ? (irqlen / 4) : 0); | ||
737 | opal_irq_count = irqlen / 4; | ||
738 | opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL); | ||
739 | for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) { | ||
740 | unsigned int hwirq = be32_to_cpup(irqs); | ||
741 | unsigned int irq = irq_create_mapping(NULL, hwirq); | ||
742 | if (irq == NO_IRQ) { | ||
743 | pr_warning("Failed to map irq 0x%x\n", hwirq); | ||
744 | continue; | ||
745 | } | ||
746 | rc = request_irq(irq, opal_interrupt, 0, "opal", NULL); | ||
747 | if (rc) | ||
748 | pr_warning("Error %d requesting irq %d (0x%x)\n", | ||
749 | rc, irq, hwirq); | ||
750 | opal_irqs[i] = irq; | ||
751 | } | ||
752 | 773 | ||
753 | /* Create "opal" kobject under /sys/firmware */ | 774 | /* Create "opal" kobject under /sys/firmware */ |
754 | rc = opal_sysfs_init(); | 775 | rc = opal_sysfs_init(); |