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.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index cb0b6de79cd4..f10b9ec8c1f5 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -9,8 +9,9 @@
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#undef DEBUG 12#define pr_fmt(fmt) "opal: " fmt
13 13
14#include <linux/printk.h>
14#include <linux/types.h> 15#include <linux/types.h>
15#include <linux/of.h> 16#include <linux/of.h>
16#include <linux/of_fdt.h> 17#include <linux/of_fdt.h>
@@ -625,6 +626,39 @@ static int opal_sysfs_init(void)
625 return 0; 626 return 0;
626} 627}
627 628
629static ssize_t symbol_map_read(struct file *fp, struct kobject *kobj,
630 struct bin_attribute *bin_attr,
631 char *buf, loff_t off, size_t count)
632{
633 return memory_read_from_buffer(buf, count, &off, bin_attr->private,
634 bin_attr->size);
635}
636
637static BIN_ATTR_RO(symbol_map, 0);
638
639static void opal_export_symmap(void)
640{
641 const __be64 *syms;
642 unsigned int size;
643 struct device_node *fw;
644 int rc;
645
646 fw = of_find_node_by_path("/ibm,opal/firmware");
647 if (!fw)
648 return;
649 syms = of_get_property(fw, "symbol-map", &size);
650 if (!syms || size != 2 * sizeof(__be64))
651 return;
652
653 /* Setup attributes */
654 bin_attr_symbol_map.private = __va(be64_to_cpu(syms[0]));
655 bin_attr_symbol_map.size = be64_to_cpu(syms[1]);
656
657 rc = sysfs_create_bin_file(opal_kobj, &bin_attr_symbol_map);
658 if (rc)
659 pr_warn("Error %d creating OPAL symbols file\n", rc);
660}
661
628static void __init opal_dump_region_init(void) 662static void __init opal_dump_region_init(void)
629{ 663{
630 void *addr; 664 void *addr;
@@ -653,6 +687,14 @@ static void opal_ipmi_init(struct device_node *opal_node)
653 of_platform_device_create(np, NULL, NULL); 687 of_platform_device_create(np, NULL, NULL);
654} 688}
655 689
690static void opal_i2c_create_devs(void)
691{
692 struct device_node *np;
693
694 for_each_compatible_node(np, NULL, "ibm,opal-i2c")
695 of_platform_device_create(np, NULL, NULL);
696}
697
656static int __init opal_init(void) 698static int __init opal_init(void)
657{ 699{
658 struct device_node *np, *consoles; 700 struct device_node *np, *consoles;
@@ -679,6 +721,9 @@ static int __init opal_init(void)
679 of_node_put(consoles); 721 of_node_put(consoles);
680 } 722 }
681 723
724 /* Create i2c platform devices */
725 opal_i2c_create_devs();
726
682 /* Find all OPAL interrupts and request them */ 727 /* Find all OPAL interrupts and request them */
683 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); 728 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
684 pr_debug("opal: Found %d interrupts reserved for OPAL\n", 729 pr_debug("opal: Found %d interrupts reserved for OPAL\n",
@@ -702,6 +747,8 @@ static int __init opal_init(void)
702 /* Create "opal" kobject under /sys/firmware */ 747 /* Create "opal" kobject under /sys/firmware */
703 rc = opal_sysfs_init(); 748 rc = opal_sysfs_init();
704 if (rc == 0) { 749 if (rc == 0) {
750 /* Export symbol map to userspace */
751 opal_export_symmap();
705 /* Setup dump region interface */ 752 /* Setup dump region interface */
706 opal_dump_region_init(); 753 opal_dump_region_init();
707 /* Setup error log interface */ 754 /* Setup error log interface */
@@ -824,3 +871,4 @@ EXPORT_SYMBOL_GPL(opal_rtc_read);
824EXPORT_SYMBOL_GPL(opal_rtc_write); 871EXPORT_SYMBOL_GPL(opal_rtc_write);
825EXPORT_SYMBOL_GPL(opal_tpo_read); 872EXPORT_SYMBOL_GPL(opal_tpo_read);
826EXPORT_SYMBOL_GPL(opal_tpo_write); 873EXPORT_SYMBOL_GPL(opal_tpo_write);
874EXPORT_SYMBOL_GPL(opal_i2c_request);