mmi:export device info
authorzhaoxp3 <zhaoxp3@motorola.com>
Wed, 15 Aug 2018 05:33:32 +0000 (13:33 +0800)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:49 +0000 (20:23 +0300)
export unit info, ram info

Change-Id: Ibe514dd54e6832b6f591c968f2ae1f97f3799d4c
Signed-off-by: zhaoxp3 <zhaoxp3@motorola.com>
Reviewed-on: https://gerrit.mot.com/1227145
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Submit-Approved: Jira Key

arch/arm64/kernel/cpuinfo.c
drivers/soc/samsung/Kconfig
drivers/soc/samsung/Makefile
drivers/soc/samsung/mmi-ram-info.c [new file with mode: 0644]
drivers/soc/samsung/mmi-unit-info.c [new file with mode: 0644]
drivers/soc/samsung/mmi-unit-info.h [new file with mode: 0644]
drivers/soc/samsung/mmi_soc_info.c [new file with mode: 0644]
drivers/soc/samsung/mmi_storage_info.c [new file with mode: 0644]
drivers/soc/samsung/mmi_storage_info.h [new file with mode: 0644]
drivers/soc/samsung/socinfo.h [new file with mode: 0644]

index 8a12ebe621279a5b1d32193a964aa7376187a07e..2a693425bae1e875281a02ea4eb5eee87a1f4216 100644 (file)
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/delay.h>
+#include <linux/of_fdt.h>
+#if defined(CONFIG_BOOTINFO)
+#include <soc/samsung/bootinfo.h>
+#endif
+
+
+void __attribute__((weak)) mach_cpuinfo_show(struct seq_file *m, void *v);
 
 /*
  * In case the boot CPU is hotpluggable, we record its initial state and
@@ -176,6 +183,14 @@ static int c_show(struct seq_file *m, void *v)
                seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
        }
 
+#if defined(CONFIG_BOOTINFO)
+       seq_printf(m, "Revision\t: %04x\n", system_rev);
+       seq_printf(m, "Serial\t\t: %08x%08x\n",
+                system_serial_high, system_serial_low);
+
+       if (mach_cpuinfo_show)
+               mach_cpuinfo_show(m, v);
+#endif
        return 0;
 }
 
index 56c8a9047206589eb45c81cc2907d351570a6d28..636eeda6dd0ec11cdf14956b35e17b3af71f1df0 100644 (file)
@@ -194,6 +194,30 @@ config DEBUG_SNAPSHOT_LOGGING_SMC
        depends on DEBUG_SNAPSHOT
        default y
 
+config MMI_SOC_INFO
+    default n
+    bool "Motorola Mobility SOC Info"
+    help
+      Provide mechanism to export SOC info.
+
+config MMI_RAM_INFO
+    default n
+    bool "Motorola Mobility RAM Info"
+    help
+    Provide mechanism to access RAM size and MR registers values via sysfs.
+
+config MMI_STORAGE_INFO
+    default n
+    bool "Motorola Mobility STORAGE Info"
+    help
+    Provide mechanism to export EMMC/UFS type, size and vendor info.
+
+config MMI_UNIT_INFO
+    default n
+    bool "Motorola Mobility Unit Info"
+    help
+    Provide mechanism to expose unit information to other cpu via smem.
+
 config BOOTINFO
     bool "Boot Information Feature"
     default n
index 7a7644e388aac89af41c36c2d7e5834f2ff56780..b523187b1239266efe619c9b0dd7d93d44ec978f 100644 (file)
@@ -75,3 +75,8 @@ obj-$(CONFIG_EXYNOS_PSTATE_HAFM_TB)   += exynos-hafm-tb.o
 
 # bootinfo
 obj-$(CONFIG_BOOTINFO) += bootinfo.o
+
+obj-$(CONFIG_MMI_SOC_INFO) += mmi_soc_info.o
+obj-$(CONFIG_MMI_RAM_INFO) += mmi-ram-info.o
+obj-$(CONFIG_MMI_STORAGE_INFO) += mmi_storage_info.o
+obj-$(CONFIG_MMI_UNIT_INFO) += mmi-unit-info.o
diff --git a/drivers/soc/samsung/mmi-ram-info.c b/drivers/soc/samsung/mmi-ram-info.c
new file mode 100644 (file)
index 0000000..bb37e70
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2012 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/pstore.h>
+#include <linux/of.h>
+
+static struct mmi_ddr_info {
+       unsigned mr5;
+       unsigned mr6;
+       unsigned mr7;
+       unsigned mr8;
+       unsigned ramsize;
+} *smem_ddr_info;
+
+static char sysfsram_type_name[20] = "unknown";
+static char sysfsram_vendor_name[20] = "unknown";
+static uint32_t sysfsram_ramsize;
+static struct mmi_ddr_info ddr_info;
+
+static ssize_t sysfsram_mr_register_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       uint32_t val = 0;
+       const char *name = attr->attr.name;
+
+       if (smem_ddr_info != NULL &&
+               strnlen(name, 4) == 3 && name[0] == 'm' && name[1] == 'r')
+       {
+               switch (name[2]) {
+               case '5': val = smem_ddr_info->mr5; break;
+               case '6': val = smem_ddr_info->mr6; break;
+               case '7': val = smem_ddr_info->mr7; break;
+               case '8': val = smem_ddr_info->mr8; break;
+               }
+       }
+
+       return snprintf(buf, 6, "0x%02x\n", val);
+}
+
+static ssize_t sysfsram_size_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 12, "%u\n", sysfsram_ramsize);
+}
+
+static ssize_t sysfsram_info_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 60, "%s:%s:%uMB\n",
+                       sysfsram_vendor_name,
+                       sysfsram_type_name,
+                       sysfsram_ramsize);
+}
+
+static ssize_t sysfsram_type_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 20, "%s\n", sysfsram_type_name);
+}
+
+static struct kobj_attribute ddr_mr5_register_attr =
+       __ATTR(mr5, 0444, sysfsram_mr_register_show, NULL);
+
+static struct kobj_attribute ddr_mr6_register_attr =
+       __ATTR(mr6, 0444, sysfsram_mr_register_show, NULL);
+
+static struct kobj_attribute ddr_mr7_register_attr =
+       __ATTR(mr7, 0444, sysfsram_mr_register_show, NULL);
+
+static struct kobj_attribute ddr_mr8_register_attr =
+       __ATTR(mr8, 0444, sysfsram_mr_register_show, NULL);
+
+static struct kobj_attribute ddr_size_attr =
+       __ATTR(size, 0444, sysfsram_size_show, NULL);
+
+static struct kobj_attribute ddr_type_attr =
+       __ATTR(type, 0444, sysfsram_type_show, NULL);
+
+static struct kobj_attribute ddr_info_attr =
+       __ATTR(info, 0444, sysfsram_info_show, NULL);
+
+static struct attribute *ram_info_properties_attrs[] = {
+       &ddr_mr5_register_attr.attr,
+       &ddr_mr6_register_attr.attr,
+       &ddr_mr7_register_attr.attr,
+       &ddr_mr8_register_attr.attr,
+       &ddr_size_attr.attr,
+       &ddr_type_attr.attr,
+       &ddr_info_attr.attr,
+       NULL
+};
+
+static struct attribute_group ram_info_properties_attr_group = {
+       .attrs = ram_info_properties_attrs,
+};
+
+static int __init init_mmi_ram_info(void)
+{
+       int status = 0;
+       int rc;
+       struct device_node *n;
+
+       static struct kobject *ram_info_properties_kobj;
+       uint32_t vid, tid;
+       const char *tname = "unknown";
+       const char *vname = "unknown";
+       static const char *vendors[] = {
+               "unknown",
+               "Samsung",
+               "Qimonda",
+               "Elpida",
+               "Etron",
+               "Nanya",
+               "Hynix",
+               "Mosel",
+               "Winbond",
+               "ESMT",
+               "unknown",
+               "Spansion",
+               "SST",
+               "ZMOS",
+               "Intel"
+       };
+       static const char *types[] = {
+               "S4 SDRAM",
+               "S2 SDRAM",
+               "N NVM",
+               "Reserved"
+       };
+
+       smem_ddr_info =  NULL;
+       n = of_find_node_by_path("/chosen/mmi,ram");
+       if (n != NULL) {
+               rc = of_property_read_u32(n,"ramsize", &ddr_info.ramsize);
+               if (rc == 0 )
+                       rc = of_property_read_u32(n,"mr5", &ddr_info.mr5);
+               if (rc == 0 )
+                       rc = of_property_read_u32(n,"mr6", &ddr_info.mr6);
+               if (rc == 0 )
+                       rc = of_property_read_u32(n,"mr7", &ddr_info.mr7);
+               if (rc == 0 )
+                       rc = of_property_read_u32(n,"mr8", &ddr_info.mr8);
+               of_node_put(n);
+               if (rc == 0 )
+                       smem_ddr_info = &ddr_info;
+       }
+
+       if (smem_ddr_info != NULL) {
+               char apanic_annotation[128];
+
+               /* identify vendor */
+               vid = smem_ddr_info->mr5 & 0xFF;
+               if (vid < (sizeof(vendors)/sizeof(vendors[0])))
+                       vname = vendors[vid];
+               else if (vid == 0xFE)
+                       vname = "Numonyx";
+               else if (vid == 0xFF)
+                       vname = "Micron";
+
+               snprintf(sysfsram_vendor_name, sizeof(sysfsram_vendor_name),
+                       "%s", vname);
+
+               /* identify type */
+               tid = smem_ddr_info->mr8 & 0x03;
+               if (tid < (sizeof(types)/sizeof(types[0])))
+                       tname = types[tid];
+
+               snprintf(sysfsram_type_name, sizeof(sysfsram_type_name),
+                       "%s", tname);
+
+               /* extract size */
+               sysfsram_ramsize = smem_ddr_info->ramsize;
+
+               snprintf(apanic_annotation, sizeof(apanic_annotation),
+                       "RAM: %s, %s, %u MB, MR5:0x%02X, MR6:0x%02X, "
+                       "MR7:0x%02X, MR8:0x%02X\n",
+                       vname, tname, smem_ddr_info->ramsize,
+                       smem_ddr_info->mr5, smem_ddr_info->mr6,
+                       smem_ddr_info->mr7, smem_ddr_info->mr8);
+               pstore_annotate(apanic_annotation);
+       }
+       else {
+               /* complain, but do not fail if SMEM was not allocated */
+               /* defaults will be reported */
+               pr_err("%s: failed to access RAM info in SMEM\n", __func__);
+       }
+
+       /* create sysfs object */
+       ram_info_properties_kobj = kobject_create_and_add("ram", NULL);
+
+       if (ram_info_properties_kobj)
+               status = sysfs_create_group(ram_info_properties_kobj,
+                       &ram_info_properties_attr_group);
+
+       if (!ram_info_properties_kobj || status) {
+               pr_err("%s: failed to create /sys/ram\n", __func__);
+               return 1;
+       }
+       else
+               return 0;
+}
+
+module_init(init_mmi_ram_info);
+MODULE_DESCRIPTION("Motorola Mobility Inc. RAM Info");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/samsung/mmi-unit-info.c b/drivers/soc/samsung/mmi-unit-info.c
new file mode 100644 (file)
index 0000000..9a171d1
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2013 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <asm/setup.h>
+#include <soc/samsung/bootinfo.h>
+
+#include "mmi-unit-info.h"
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+
+static u32 prod_id;
+
+#define SERIALNO_MAX_LEN 64
+static char serialno[SERIALNO_MAX_LEN];
+int __init board_serialno_init(char *s)
+{
+       strlcpy(serialno, s, SERIALNO_MAX_LEN);
+       return 1;
+}
+__setup("androidboot.serialno=", board_serialno_init);
+
+static char carrier[CARRIER_MAX_LEN];
+int __init board_carrier_init(char *s)
+{
+       strlcpy(carrier, s, SERIALNO_MAX_LEN);
+       return 1;
+}
+__setup("androidboot.carrier=", board_carrier_init);
+
+static char baseband[BASEBAND_MAX_LEN];
+int __init board_baseband_init(char *s)
+{
+       strlcpy(baseband, s, SERIALNO_MAX_LEN);
+       return 1;
+}
+__setup("androidboot.baseband=", board_baseband_init);
+
+#define ANDROIDBOOT_DEVICE_MAX_LEN 32
+static char androidboot_device[ANDROIDBOOT_DEVICE_MAX_LEN];
+int __init setup_androidboot_device_init(char *s)
+{
+       strlcpy(androidboot_device, s, ANDROIDBOOT_DEVICE_MAX_LEN);
+       return 1;
+}
+__setup("androidboot.device=", setup_androidboot_device_init);
+
+static unsigned int androidboot_radio;
+static char androidboot_radio_str[RADIO_MAX_LEN];
+int __init setup_androidboot_radio_init(char *s)
+{
+       int retval = kstrtouint(s, 16, &androidboot_radio);
+
+       if (retval < 0) {
+               androidboot_radio = 0;
+       }
+
+       strlcpy(androidboot_radio_str, s, RADIO_MAX_LEN);
+
+       return 1;
+}
+__setup("androidboot.radio=", setup_androidboot_radio_init);
+
+static struct mmi_unit_info *mui;
+void mmi_set_pureason(uint32_t val)
+{
+       if (mui) {
+               mui->powerup_reason = val;
+               pr_debug("%s: Set modem PU reason value in SMEM to %d\n",
+                               __func__, mui->powerup_reason);
+       }
+}
+
+static char soc_hw[SOCHW_MAX_LEN+1];
+
+void mach_cpuinfo_show(struct seq_file *m, void *v)
+{
+       seq_printf(m, "Device\t\t: %s\n", androidboot_device);
+       /* Zero is not a valid "Radio" value.      */
+       /* Lack of "Radio" entry in cpuinfo means: */
+       /*      look for radio in "Revision"       */
+       if (strnlen(androidboot_radio_str, RADIO_MAX_LEN))
+               seq_printf(m, "Radio\t\t: %s\n", androidboot_radio_str);
+
+       seq_printf(m, "SOC Hardware\t: %s\n", soc_hw);
+}
+
+static char extended_baseband[BASEBAND_MAX_LEN+1] = "\0";
+
+struct mmi_of_lookup {
+       const char *compatible;
+       unsigned int *data;
+};
+
+static struct mmi_of_lookup mmi_of_setup[] __initdata = {
+       { .compatible = "linux,seriallow", .data = &system_serial_low },
+       { .compatible = "linux,serialhigh", .data = &system_serial_high },
+       { .compatible = "linux,hwrev", .data = &system_rev },
+       { .compatible = "mmi,prod_id", .data = &prod_id },
+       { }
+};
+
+static void __init mmi_of_populate_setup(void)
+{
+       struct device_node *n = of_find_node_by_path("/chosen");
+       struct mmi_of_lookup *tbl = mmi_of_setup;
+       const char *baseband;
+       const char *temp;
+
+       while (tbl->data) {
+               of_property_read_u32(n, tbl->compatible, tbl->data);
+               tbl++;
+       }
+
+       if (0 == of_property_read_string(n, "mmi,baseband", &baseband))
+               strlcpy(extended_baseband, baseband, sizeof(extended_baseband));
+
+       if (0 == of_property_read_string(n, "mmi,soc_hw", &temp))
+               strlcpy(soc_hw, temp, sizeof(soc_hw));
+
+       of_node_put(n);
+}
+
+static int __init mmi_unit_info_init(void)
+{
+       int ret = 0;
+       struct mmi_unit_info *mui_copy;
+
+       mmi_of_populate_setup();
+
+       #define SMEM_KERNEL_RESERVE_SIZE 1024
+       mui_copy = kzalloc(SMEM_KERNEL_RESERVE_SIZE, GFP_KERNEL);
+       if (!mui_copy) {
+               pr_err("%s: failed to allocate space for mmi_unit_info\n",
+                       __func__);
+               ret = 1;
+               goto err;
+       }
+
+       mui_copy->version = MMI_UNIT_INFO_VER;
+       mui_copy->system_rev = system_rev;
+       mui_copy->system_serial_low = system_serial_low;
+       mui_copy->system_serial_high = system_serial_high;
+#ifndef CONFIG_ARM64
+       strlcpy(mui_copy->machine, machine_desc->name, MACHINE_MAX_LEN);
+#else
+       strlcpy(mui_copy->machine, "", MACHINE_MAX_LEN);
+#endif
+       strlcpy(mui_copy->barcode, serialno, BARCODE_MAX_LEN);
+       strlcpy(mui_copy->baseband, extended_baseband, BASEBAND_MAX_LEN);
+       strlcpy(mui_copy->carrier, carrier, CARRIER_MAX_LEN);
+       strlcpy(mui_copy->device, androidboot_device, DEVICE_MAX_LEN);
+       mui_copy->radio = androidboot_radio;
+       strlcpy(mui_copy->radio_str, androidboot_radio_str, RADIO_MAX_LEN);
+       mui_copy->powerup_reason = bi_powerup_reason();
+
+       pr_info("mmi_unit_info (SMEM) for modem: version = 0x%02x,"
+               " device = '%s', radio = 0x%x, radio_str = '%s',"
+               " system_rev = 0x%04x, system_serial = 0x%08x%08x,"
+               " machine = '%s', barcode = '%s', baseband = '%s',"
+               " carrier = '%s', pu_reason = 0x%08x\n",
+               mui_copy->version,
+               mui_copy->device,
+               mui_copy->radio,
+               mui_copy->radio_str,
+               mui_copy->system_rev,
+               mui_copy->system_serial_high, mui_copy->system_serial_low,
+               mui_copy->machine, mui_copy->barcode,
+               mui_copy->baseband, mui_copy->carrier,
+               mui_copy->powerup_reason);
+
+       mui = NULL;
+
+       if (!mui) {
+               pr_err("%s: failed to allocate mmi_unit_info in SMEM\n",
+                       __func__);
+               ret = 1;
+               goto err_free;
+       } else if (PTR_ERR(mui_copy) == -EPROBE_DEFER) {
+               pr_err("%s: SMEM not yet initialized\n", __func__);
+               ret = 1;
+               goto err_free;
+       }
+
+       memcpy(mui, mui_copy, SMEM_KERNEL_RESERVE_SIZE);
+
+err_free:
+       kfree(mui_copy);
+err:
+       return ret;
+}
+
+module_init(mmi_unit_info_init);
+MODULE_DESCRIPTION("Motorola Mobility LLC. Unit Info");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/samsung/mmi-unit-info.h b/drivers/soc/samsung/mmi-unit-info.h
new file mode 100644 (file)
index 0000000..8439a2f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ARCH_ARM_MACH_SOC_MMI_UNIT_INFO_H
+#define __ARCH_ARM_MACH_SOC_MMI_UNIT_INFO_H
+
+/* set of data provided to the modem over SMEM */
+#define MMI_UNIT_INFO_VER 3
+#define BARCODE_MAX_LEN 65
+#define MACHINE_MAX_LEN 33
+#define CARRIER_MAX_LEN 65
+#define BASEBAND_MAX_LEN 97
+#define SOCHW_MAX_LEN 32
+#define DEVICE_MAX_LEN 33
+#define RADIO_MAX_LEN 33
+struct mmi_unit_info {
+       uint32_t version;
+       uint32_t system_rev;
+       uint32_t system_serial_low;
+       uint32_t system_serial_high;
+       char machine[MACHINE_MAX_LEN];
+       char barcode[BARCODE_MAX_LEN];
+       char carrier[CARRIER_MAX_LEN];
+       char baseband[BASEBAND_MAX_LEN];
+       char device[DEVICE_MAX_LEN];
+       uint32_t radio;
+       uint32_t powerup_reason;
+       char radio_str[RADIO_MAX_LEN];
+};
+
+/* Function that sets the modem reset value in the SMEM location
+ * where mmi_unit_info is stored.
+ */
+void mmi_set_pureason(uint32_t val);
+
+#endif
diff --git a/drivers/soc/samsung/mmi_soc_info.c b/drivers/soc/samsung/mmi_soc_info.c
new file mode 100644 (file)
index 0000000..8d2fa77
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013 - 2015 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/pstore.h>
+
+#include "socinfo.h"
+
+struct mmi_soc_bin {
+       int     set;
+       int     speed;
+       int     pvs;
+       int     ver;
+};
+
+#define MMI_SOC_BIN_INVAL      INT_MAX
+#define ACPU_BIN_SET           BIT(0)
+
+static struct mmi_soc_bin mmi_soc_bin_info;
+static DEFINE_SPINLOCK(mmi_soc_bin_lock);
+
+static inline void mmi_panic_annotate(const char *str)
+{
+       pstore_annotate(str);
+}
+
+static void __init mmi_soc_annotate_socinfo(void)
+{
+       char socinfo[32];
+
+       snprintf(socinfo, sizeof(socinfo), "socinfo: id=%u, ",
+                       socinfo_get_id());
+       mmi_panic_annotate(socinfo);
+
+       snprintf(socinfo, sizeof(socinfo), "ver=%u.%u, ",
+                       SOCINFO_VERSION_MAJOR(socinfo_get_version()),
+                       SOCINFO_VERSION_MINOR(socinfo_get_version()));
+       mmi_panic_annotate(socinfo);
+
+       snprintf(socinfo, sizeof(socinfo), "raw_id=%u, ",
+                       socinfo_get_raw_id());
+       mmi_panic_annotate(socinfo);
+
+       snprintf(socinfo, sizeof(socinfo), "raw_ver=%u, ",
+                       socinfo_get_raw_version());
+       mmi_panic_annotate(socinfo);
+
+       snprintf(socinfo, sizeof(socinfo), "hw_plat=%u, ",
+                       socinfo_get_platform_type());
+       mmi_panic_annotate(socinfo);
+
+       snprintf(socinfo, sizeof(socinfo), "hw_plat_ver=%u, ",
+                       socinfo_get_platform_version());
+       mmi_panic_annotate(socinfo);
+
+       snprintf(socinfo, sizeof(socinfo), "hw_plat_subtype=%u\n",
+                       socinfo_get_platform_subtype());
+       mmi_panic_annotate(socinfo);
+}
+
+static ssize_t mmi_acpu_proc_read(struct file *file, char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       void *data = PDE_DATA(file_inode(file));
+       char local_buf[8];
+       int len = snprintf(local_buf, 2, "%1p", data);
+
+       return simple_read_from_buffer(buf, count, ppos, local_buf, len);
+}
+
+static const struct file_operations mmi_acpu_proc_fops = {
+       .read = mmi_acpu_proc_read,
+       .llseek = default_llseek,
+};
+
+void mmi_acpu_bin_set(int *speed, int *pvs, int *ver)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&mmi_soc_bin_lock, flags);
+       if (mmi_soc_bin_info.set & ACPU_BIN_SET) {
+               spin_unlock_irqrestore(&mmi_soc_bin_lock, flags);
+               return;
+       }
+       mmi_soc_bin_info.speed = speed ? *speed : MMI_SOC_BIN_INVAL;
+       mmi_soc_bin_info.pvs = pvs ? *pvs : MMI_SOC_BIN_INVAL;
+       mmi_soc_bin_info.ver = ver ? *ver : MMI_SOC_BIN_INVAL;
+       mmi_soc_bin_info.set |= ACPU_BIN_SET;
+       spin_unlock_irqrestore(&mmi_soc_bin_lock, flags);
+}
+
+static void __init mmi_soc_acpu_bin_export(void)
+{
+       struct proc_dir_entry *proc;
+       unsigned long flags;
+       char acpu[64];
+
+       spin_lock_irqsave(&mmi_soc_bin_lock, flags);
+       if (!(mmi_soc_bin_info.set & ACPU_BIN_SET)) {
+               spin_unlock_irqrestore(&mmi_soc_bin_lock, flags);
+               pr_err("ACPU Bin is not available.\n");
+               return;
+       }
+       spin_unlock_irqrestore(&mmi_soc_bin_lock, flags);
+
+       mmi_panic_annotate("ACPU: ");
+       if (mmi_soc_bin_info.speed != MMI_SOC_BIN_INVAL) {
+               snprintf(acpu, sizeof(acpu), "Speed bin %d ",
+                               mmi_soc_bin_info.speed);
+               mmi_panic_annotate(acpu);
+       }
+       if (mmi_soc_bin_info.pvs != MMI_SOC_BIN_INVAL) {
+               proc = proc_create_data("cpu/soc_acpu_pvs",
+                       (S_IFREG | S_IRUGO), NULL,
+                       &mmi_acpu_proc_fops, (void *)(uintptr_t)mmi_soc_bin_info.pvs);
+               if (!proc)
+                       pr_err("Failed to create /proc/cpu/soc_acpu_pvs.\n");
+               else
+                       proc_set_size(proc, 1);
+               snprintf(acpu, sizeof(acpu), "PVS bin %d ",
+                               mmi_soc_bin_info.pvs);
+               mmi_panic_annotate(acpu);
+       }
+       if (mmi_soc_bin_info.ver != MMI_SOC_BIN_INVAL) {
+               snprintf(acpu, sizeof(acpu), "PVS version %d ",
+                               mmi_soc_bin_info.ver);
+               mmi_panic_annotate(acpu);
+       }
+       mmi_panic_annotate("\n");
+}
+
+static int __init init_mmi_soc_info(void)
+{
+       mmi_soc_annotate_socinfo();
+       mmi_soc_acpu_bin_export();
+       return 0;
+}
+module_init(init_mmi_soc_info);
+MODULE_DESCRIPTION("Motorola Mobility LLC. SOC Info");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/samsung/mmi_storage_info.c b/drivers/soc/samsung/mmi_storage_info.c
new file mode 100644 (file)
index 0000000..3bd8242
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2016 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/pstore.h>
+#include "mmi_storage_info.h"
+
+struct mmi_storage_info *info;
+
+static ssize_t sysfsst_fw_show(struct kobject *kobj,
+               struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 32, "%s\n", info->firmware_version);
+}
+
+static ssize_t sysfsst_model_show(struct kobject *kobj,
+               struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 32, "%s\n", info->product_name);
+}
+
+static ssize_t sysfsst_vendor_show(struct kobject *kobj,
+               struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 32, "%s\n", info->card_manufacturer);
+}
+
+static ssize_t sysfsst_size_show(struct kobject *kobj,
+               struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 16, "%s\n", info->size);
+}
+
+static ssize_t sysfsst_type_show(struct kobject *kobj,
+               struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, 16, "%s\n", info->type);
+}
+
+static struct kobj_attribute st_fw_attr =
+       __ATTR(fw, 0444, sysfsst_fw_show, NULL);
+
+static struct kobj_attribute st_model_attr =
+       __ATTR(model, 0444, sysfsst_model_show, NULL);
+
+static struct kobj_attribute st_vendor_attr =
+       __ATTR(vendor, 0444, sysfsst_vendor_show, NULL);
+
+static struct kobj_attribute st_size_attr =
+       __ATTR(size, 0444, sysfsst_size_show, NULL);
+
+static struct kobj_attribute st_type_attr =
+       __ATTR(type, 0444, sysfsst_type_show, NULL);
+
+static struct attribute *st_info_properties_attrs[] = {
+       &st_fw_attr.attr,
+       &st_model_attr.attr,
+       &st_vendor_attr.attr,
+       &st_size_attr.attr,
+       &st_type_attr.attr,
+       NULL
+};
+
+static struct attribute_group st_info_properties_attr_group = {
+       .attrs = st_info_properties_attrs,
+};
+
+static int __init mmi_storage_info_init(void)
+{
+       int ret = 0;
+       int status = 0;
+       struct property *p;
+       struct device_node *n;
+       char apanic_annotation[128];
+       static struct kobject *st_info_properties_kobj;
+
+       n = of_find_node_by_path("/chosen/mmi,storage");
+       if (n == NULL) {
+               ret = 1;
+               goto err;
+       }
+
+       info = kzalloc(sizeof(struct mmi_storage_info), GFP_KERNEL);
+       if (!info) {
+               pr_err("%s: failed to allocate space for mmi_storage_info\n",
+                       __func__);
+               ret = 1;
+               goto err;
+       }
+
+       for_each_property_of_node(n, p) {
+               if (!strcmp(p->name, "type") && p->value)
+                       strlcpy(info->type, (char *)p->value,
+                               sizeof(info->type));
+               if (!strcmp(p->name, "size") && p->value)
+                       strlcpy(info->size, (char *)p->value,
+                               sizeof(info->size));
+               if (!strcmp(p->name, "manufacturer") && p->value)
+                       strlcpy(info->card_manufacturer, (char *)p->value,
+                               sizeof(info->card_manufacturer));
+               if (!strcmp(p->name, "product") && p->value)
+                       strlcpy(info->product_name, (char *)p->value,
+                               sizeof(info->product_name));
+               if (!strcmp(p->name, "firmware") && p->value)
+                       strlcpy(info->firmware_version, (char *)p->value,
+                               sizeof(info->firmware_version));
+       }
+
+       of_node_put(n);
+
+       pr_info("mmi_storage_info :%s: %s %s %s FV=%s\n",
+               info->type,
+               info->size,
+               info->card_manufacturer,
+               info->product_name,
+               info->firmware_version);
+
+       /* Append the storage info to apanic annotation */
+       snprintf(apanic_annotation, sizeof(apanic_annotation),
+               "%s: %s %s %s FV=%s\n",
+               info->type,
+               info->size,
+               info->card_manufacturer,
+               info->product_name,
+               info->firmware_version);
+       pstore_annotate(apanic_annotation);
+
+       /* Export to sysfs*/
+       st_info_properties_kobj = kobject_create_and_add("storage", NULL);
+       if (st_info_properties_kobj)
+               status = sysfs_create_group(st_info_properties_kobj,
+                               &st_info_properties_attr_group);
+
+       if (!st_info_properties_kobj || status) {
+               pr_err("%s: failed to create /sys/storage\n", __func__);
+               ret = 1;
+               goto err;
+       }
+
+err:
+       return ret;
+}
+
+void __exit mmi_storage_info_exit(void)
+{
+       if (info) {
+               kfree(info);
+               info = NULL;
+       }
+}
+
+module_init(mmi_storage_info_init);
+module_exit(mmi_storage_info_exit);
+MODULE_DESCRIPTION("Motorola Mobility LLC. Storage Info");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/samsung/mmi_storage_info.h b/drivers/soc/samsung/mmi_storage_info.h
new file mode 100644 (file)
index 0000000..70dd4eb
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ARCH_ARM_MACH_SOC_MMI_EMMC_INFO_H
+#define __ARCH_ARM_MACH_SOC_MMI_EMMC_INFO_H
+
+struct mmi_storage_info {
+       char type[16];  /* UFS or eMMC */
+       char size[16];  /* size in GB */
+       char card_manufacturer[32];
+       char product_name[32];  /* model ID */
+       char firmware_version[32];
+};
+
+#endif
diff --git a/drivers/soc/samsung/socinfo.h b/drivers/soc/samsung/socinfo.h
new file mode 100644 (file)
index 0000000..93f81d5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SOCINFO_H_
+#define _SOCINFO_H_
+
+#define SOCINFO_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16)
+#define SOCINFO_VERSION_MINOR(ver) ((ver) & 0x0000ffff)
+#define SOCINFO_VERSION(maj, min)  ((((maj) & 0xffff) << 16)|((min) & 0xffff))
+
+
+uint32_t socinfo_get_id(void)
+{
+       return 0;
+}
+uint32_t socinfo_get_version(void)
+{
+       return 0;
+}
+uint32_t socinfo_get_raw_id(void)
+{
+       return 0;
+}
+uint32_t socinfo_get_raw_version(void)
+{
+       return 0;
+}
+uint32_t socinfo_get_platform_type(void)
+{
+       return 0;
+}
+uint32_t socinfo_get_platform_subtype(void)
+{
+       return 0;
+}
+uint32_t socinfo_get_platform_version(void)
+{
+       return 0;
+}
+
+#endif