ARM: OMAP2+: Export SoC information to userspace
authorRuslan Bilovol <ruslan.bilovol@ti.com>
Thu, 14 Feb 2013 11:55:24 +0000 (13:55 +0200)
committerGrazvydas Ignotas <notasas@gmail.com>
Mon, 14 Apr 2014 00:23:54 +0000 (03:23 +0300)
In some situations it is useful for userspace to
know some SoC-specific information. For example,
this may be used for deciding what kernel module to
use or how to better configure some settings etc.
This patch exports OMAP SoC information to userspace
using existing in Linux kernel SoC infrastructure.

This information can be read under
/sys/devices/socX directory

[notasas@gmail.com: 3.2 backport]
Signed-off-by: Ruslan Bilovol <ruslan.bilovol@ti.com>
[tony@atomide.com: updated for multiplatform changes]
Signed-off-by: Tony Lindgren <tony@atomide.com>
Conflicts:

arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/io.c

arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/id.c

index e1293aa..527c58d 100644 (file)
@@ -36,6 +36,7 @@ config ARCH_OMAP3
        select ARCH_HAS_OPP
        select PM_OPP if PM
        select ARM_CPU_SUSPEND if PM
        select ARCH_HAS_OPP
        select PM_OPP if PM
        select ARM_CPU_SUSPEND if PM
+       select SOC_BUS
 
 config ARCH_OMAP4
        bool "TI OMAP4"
 
 config ARCH_OMAP4
        bool "TI OMAP4"
index 38af794..fbede45 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_SOC_BUS
+#include <linux/sys_soc.h>
+#include <linux/err.h>
+#endif
 
 #include <asm/cputype.h>
 
 
 #include <asm/cputype.h>
 
@@ -488,3 +494,66 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
        else
                tap_prod_id = 0x0208;
 }
        else
                tap_prod_id = 0x0208;
 }
+
+#ifdef CONFIG_SOC_BUS
+
+static const char const *omap_types[] = {
+       [OMAP2_DEVICE_TYPE_TEST]        = "TST",
+       [OMAP2_DEVICE_TYPE_EMU]         = "EMU",
+       [OMAP2_DEVICE_TYPE_SEC]         = "HS",
+       [OMAP2_DEVICE_TYPE_GP]          = "GP",
+       [OMAP2_DEVICE_TYPE_BAD]         = "BAD",
+};
+
+static const char * __init omap_get_family(void)
+{
+       if (cpu_is_omap24xx())
+               return kasprintf(GFP_KERNEL, "OMAP2");
+       else if (cpu_is_omap34xx())
+               return kasprintf(GFP_KERNEL, "OMAP3");
+       else if (cpu_is_omap44xx())
+               return kasprintf(GFP_KERNEL, "OMAP4");
+       else
+               return kasprintf(GFP_KERNEL, "Unknown");
+}
+
+static ssize_t omap_get_type(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       return sprintf(buf, "%s\n", omap_types[omap_type()]);
+}
+
+static struct device_attribute omap_soc_attr =
+       __ATTR(type,  S_IRUGO, omap_get_type,  NULL);
+
+int __init omap_soc_device_init(void)
+{
+       struct device *parent;
+       struct soc_device *soc_dev;
+       struct soc_device_attribute *soc_dev_attr;
+       int ret = 0;
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return -ENOMEM;
+
+       soc_dev_attr->machine  = soc_name;
+       soc_dev_attr->family   = omap_get_family();
+       soc_dev_attr->revision = soc_rev;
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR_OR_NULL(soc_dev)) {
+               kfree(soc_dev_attr);
+               return -ENODEV;
+       }
+
+       parent = soc_device_to_device(soc_dev);
+       if (!IS_ERR_OR_NULL(parent))
+               ret = device_create_file(parent, &omap_soc_attr);
+
+       return ret;
+}
+late_initcall(omap_soc_device_init);
+
+#endif /* CONFIG_SOC_BUS */