ARM: OMAP2+: Export SoC information to userspace
[pandora-kernel.git] / arch / arm / mach-omap2 / id.c
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 */