aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv/opal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powernv/opal.c')
-rw-r--r--arch/powerpc/platforms/powernv/opal.c72
1 files changed, 50 insertions, 22 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index f10b9ec8c1f5..18fd4e71c9c1 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -208,7 +208,7 @@ static int __init opal_register_exception_handlers(void)
208 * start catching/handling HMI directly in Linux. 208 * start catching/handling HMI directly in Linux.
209 */ 209 */
210 if (!opal_check_token(OPAL_HANDLE_HMI)) { 210 if (!opal_check_token(OPAL_HANDLE_HMI)) {
211 pr_info("opal: Old firmware detected, OPAL handles HMIs.\n"); 211 pr_info("Old firmware detected, OPAL handles HMIs.\n");
212 opal_register_exception_handler( 212 opal_register_exception_handler(
213 OPAL_HYPERVISOR_MAINTENANCE_HANDLER, 213 OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
214 0, glue); 214 0, glue);
@@ -667,7 +667,13 @@ static void __init opal_dump_region_init(void)
667 667
668 /* Register kernel log buffer */ 668 /* Register kernel log buffer */
669 addr = log_buf_addr_get(); 669 addr = log_buf_addr_get();
670 if (addr == NULL)
671 return;
672
670 size = log_buf_len_get(); 673 size = log_buf_len_get();
674 if (size == 0)
675 return;
676
671 rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF, 677 rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF,
672 __pa(addr), size); 678 __pa(addr), size);
673 /* Don't warn if this is just an older OPAL that doesn't 679 /* Don't warn if this is just an older OPAL that doesn't
@@ -695,15 +701,54 @@ static void opal_i2c_create_devs(void)
695 of_platform_device_create(np, NULL, NULL); 701 of_platform_device_create(np, NULL, NULL);
696} 702}
697 703
704static 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 opal_irq_count = irqs ? (irqlen / 4) : 0;
712 pr_debug("Found %d interrupts reserved for OPAL\n", opal_irq_count);
713 if (!opal_irq_count)
714 return;
715
716 /* Install interrupt handlers */
717 opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
718 for (i = 0; irqs && i < opal_irq_count; i++, irqs++) {
719 unsigned int irq, virq;
720 int rc;
721
722 /* Get hardware and virtual IRQ */
723 irq = be32_to_cpup(irqs);
724 virq = irq_create_mapping(NULL, irq);
725 if (virq == NO_IRQ) {
726 pr_warn("Failed to map irq 0x%x\n", irq);
727 continue;
728 }
729
730 /* Install interrupt handler */
731 rc = request_irq(virq, opal_interrupt, 0, "opal", NULL);
732 if (rc) {
733 irq_dispose_mapping(virq);
734 pr_warn("Error %d requesting irq %d (0x%x)\n",
735 rc, virq, irq);
736 continue;
737 }
738
739 /* Cache IRQ */
740 opal_irqs[i] = virq;
741 }
742}
743
698static int __init opal_init(void) 744static int __init opal_init(void)
699{ 745{
700 struct device_node *np, *consoles; 746 struct device_node *np, *consoles;
701 const __be32 *irqs; 747 int rc;
702 int rc, i, irqlen;
703 748
704 opal_node = of_find_node_by_path("/ibm,opal"); 749 opal_node = of_find_node_by_path("/ibm,opal");
705 if (!opal_node) { 750 if (!opal_node) {
706 pr_warn("opal: Node not found\n"); 751 pr_warn("Device node not found\n");
707 return -ENODEV; 752 return -ENODEV;
708 } 753 }
709 754
@@ -725,24 +770,7 @@ static int __init opal_init(void)
725 opal_i2c_create_devs(); 770 opal_i2c_create_devs();
726 771
727 /* Find all OPAL interrupts and request them */ 772 /* Find all OPAL interrupts and request them */
728 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); 773 opal_irq_init(opal_node);
729 pr_debug("opal: Found %d interrupts reserved for OPAL\n",
730 irqs ? (irqlen / 4) : 0);
731 opal_irq_count = irqlen / 4;
732 opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
733 for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
734 unsigned int hwirq = be32_to_cpup(irqs);
735 unsigned int irq = irq_create_mapping(NULL, hwirq);
736 if (irq == NO_IRQ) {
737 pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
738 continue;
739 }
740 rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
741 if (rc)
742 pr_warning("opal: Error %d requesting irq %d"
743 " (0x%x)\n", rc, irq, hwirq);
744 opal_irqs[i] = irq;
745 }
746 774
747 /* Create "opal" kobject under /sys/firmware */ 775 /* Create "opal" kobject under /sys/firmware */
748 rc = opal_sysfs_init(); 776 rc = opal_sysfs_init();