create mmi_info module

Convert mmi_ram_info mmi_soc_info mmi_storage_info
and bootinfo into a single loadable module.

Change-Id: I8de7933904f66573b0d5c70c8a7dd154911f354e
Signed-off-by: Ryan Lattrel <ryanl@motorola.com>
Reviewed-on: https://gerrit.mot.com/1114526
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Shi-Yong Li <a22381@motorola.com>
Reviewed-by: Kenneth Kessler <kennykessler@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Ryan Lattrel 2018-01-08 17:22:36 -06:00
commit a1d4d757ef
11 changed files with 1184 additions and 0 deletions

View file

@ -0,0 +1,8 @@
DLKM_DIR := motorola/kernel/modules
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mmi_info.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk

11
drivers/mmi_info/Kbuild Normal file
View file

@ -0,0 +1,11 @@
# add -Wall to try to catch everything we can.
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include
mmi_info-objs += mmi_soc_info.o
mmi_info-objs += mmi_storage_info.o
mmi_info-objs += mmi_ram_info.o
mmi_info-objs += mmi_unit_info.o
mmi_info-objs += mmi_boot_info.o
mmi_info-objs += mmi_info_main.o
obj-m += mmi_info.o

10
drivers/mmi_info/Makefile Normal file
View file

@ -0,0 +1,10 @@
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
modules_install:
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean

View file

@ -0,0 +1,300 @@
/*
* Copyright (C) 2009 Motorola, Inc.
* Copyright (C) 2012 Motorola Mobility. All rights reserved.
* Copyright (C) 2018 Motorola Mobility LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/of.h>
#include <asm/setup.h>
#include <linux/seq_file.h>
#include <soc/qcom/mmi_boot_info.h>
#include "mmi_info.h"
/*
* EMIT_BOOTINFO and EMIT_BOOTINFO_STR are used to emit the bootinfo
* information for data provided via DEVICE TREE.
*
* The format for all bootinfo lines is "name : val" and these macros
* enforce that format.
*
* strname is the name printed in the name/val pair.
* name is the name of the function to call
*
* EMIT_BOOTINFO and EMIT_BOOTINFO_STR depend on buf and len to already
* be defined.
*/
#define EMIT_BOOTINFO(strname, fmt, name) \
do { \
seq_printf(m, strname ": " fmt "\n", \
bi_##name()); \
} while (0)
#define EMIT_BOOTINFO_STR(strname, strval) \
do { \
if (strlen(strval) == 0) { \
seq_printf(m, "%s: UNKNOWN\n", \
strname); \
} else { \
seq_printf(m, "%s: %s\n", \
strname, strval); \
} \
} while (0)
/*-------------------------------------------------------------------------*/
#define BOOTREASON_MAX_LEN 64
#define BOOTMODE_MAX_LEN 64
static char bootreason[BOOTREASON_MAX_LEN];
static char bootmode[BOOTMODE_MAX_LEN];
static void mmi_bootarg_setup(void)
{
char *s;
if (mmi_get_bootarg("androidboot.bootreason=", &s) == 0)
strlcpy(bootreason, s, BOOTREASON_MAX_LEN);
if (mmi_get_bootarg("androidboot.mode=", &s) == 0)
strlcpy(bootmode, s, BOOTMODE_MAX_LEN);
}
/*
* powerup_reason contains the powerup reason provided by the ATAGs when
* the machine boots.
*
* Exported symbols:
* bi_powerup_reason() -- returns the powerup reason
*/
u32 bi_powerup_reason(void)
{
return mmi_chosen_data.powerup_reason;
}
EXPORT_SYMBOL(bi_powerup_reason);
#define EMIT_POWERUPREASON() \
EMIT_BOOTINFO("POWERUPREASON", "0x%08x", powerup_reason)
/*
* mbm_version contains the MBM version.
* mbm_loader_version contains the MBM loader version.
* mbm_version and mbm_loader_version default to 0 if they are
* not set.
*
* Exported symbols:
* bi_mbm_version() -- returns the MBM version
*/
u32 bi_mbm_version(void)
{
return mmi_chosen_data.mbmversion;
}
EXPORT_SYMBOL(bi_mbm_version);
#define EMIT_MBM_VERSION() \
EMIT_BOOTINFO("MBM_VERSION", "0x%08x", mbm_version)
/*
* boot_seq contains the boot sequence number.
* boot_seq default to 0 if it is not set.
*
* Exported symbols:
* bi_boot_seq() -- returns the boot seq
*/
u32 bi_boot_seq(void)
{
return mmi_chosen_data.boot_seq;
}
EXPORT_SYMBOL(bi_boot_seq);
#define EMIT_BOOT_SEQ() \
EMIT_BOOTINFO("BOOT_SEQ", "0x%08x", boot_seq)
/*
* BL build signature a succession of lines of text each denoting
* build/versioning information for each bootloader component,
* as passed along from bootloader via ATAG_BL_BUILD_SIG(s)
*/
#define MAX_BL_BUILD_SIG 16
#define MAX_BLD_SIG_ITEM 20
#define MAX_BLD_SIG_VALUE 80
struct bl_build_sig {
char item[MAX_BLD_SIG_ITEM];
char value[MAX_BLD_SIG_VALUE];
};
static unsigned int bl_build_sig_count;
static struct bl_build_sig bl_build_sigs[MAX_BL_BUILD_SIG];
static void convert_to_upper(char *str)
{
while (*str) {
*str = toupper(*str);
str++;
}
}
void bi_add_bl_build_sig(char *bld_sig)
{
int pos;
char *value;
char *ptr;
if (!bld_sig || (bl_build_sig_count >= MAX_BL_BUILD_SIG))
return;
value = (char *)memchr((void *)bld_sig, '=', MAX_BLD_SIG_ITEM);
if (!value)
return;
pos = value - bld_sig;
ptr = bl_build_sigs[bl_build_sig_count].item;
strlcpy(ptr, bld_sig, pos+1);
convert_to_upper(ptr);
ptr = bl_build_sigs[bl_build_sig_count].value;
strlcpy(ptr, value+1, MAX_BLD_SIG_VALUE);
bl_build_sig_count++;
}
static void of_blsig(void)
{
struct property *p;
struct device_node *n;
/* Only do this one time once we find the sigs */
if (bl_build_sig_count)
return;
n = of_find_node_by_path("/chosen/mmi,bl_sigs");
if (n == NULL)
return;
for_each_property_of_node(n, p)
if (strcmp(p->name, "name"))
bi_add_bl_build_sig(p->value);
of_node_put(n);
}
#define EMIT_BL_BUILD_SIG() \
do { \
int i; \
for (i = 0; i < bl_build_sig_count; i++) { \
EMIT_BOOTINFO_STR(bl_build_sigs[i].item, \
bl_build_sigs[i].value); \
} \
} while (0)
/* System revision s global symbol exported by setup.c
* use wrapper to maintain coherent format with the other
* boot info elements
*/
static u32 bi_hwrev(void)
{
return mmi_chosen_data.system_rev;
}
#define EMIT_HWREV() \
EMIT_BOOTINFO("HW_REV", "0x%04x", hwrev)
/* Serial high and low are symbols exported by setup.c
* use wrapper to maintain coherent format with the other
* boot info elements
*/
static u64 bi_serial(void)
{
return ((u64)mmi_chosen_data.system_serial_high << 32)
| (u64)mmi_chosen_data.system_serial_low;
}
#define EMIT_SERIAL() \
EMIT_BOOTINFO("SERIAL", "0x%llx", serial)
const char *bi_bootreason(void)
{
return bootreason;
}
EXPORT_SYMBOL(bi_bootreason);
const char *bi_bootmode(void)
{
return bootmode;
}
EXPORT_SYMBOL(bi_bootmode);
/* get_bootinfo fills in the /proc/bootinfo information.
* We currently only have the powerup reason, mbm_version, serial
* and hwrevision.
*/
static int get_bootinfo(struct seq_file *m, void *v)
{
EMIT_SERIAL();
EMIT_HWREV();
EMIT_POWERUPREASON();
EMIT_MBM_VERSION();
EMIT_BL_BUILD_SIG();
EMIT_BOOT_SEQ();
EMIT_BOOTINFO("Last boot reason", "%s", bootreason);
return 0;
}
static struct proc_dir_entry *proc_bootinfo;
static int bootinfo_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, get_bootinfo, PDE_DATA(inode));
}
static const struct file_operations bootinfo_proc_fops = {
.open = bootinfo_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
int mmi_boot_info_init(void)
{
of_blsig();
mmi_bootarg_setup();
/* /proc/bootinfo */
proc_bootinfo = proc_create("bootinfo",
0444, NULL, &bootinfo_proc_fops);
return 0;
}
void mmi_boot_info_exit(void)
{
if (proc_bootinfo)
remove_proc_entry("bootinfo", NULL);
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (C) 2013 Motorola Mobility LLC
* Copyright (C) 2018 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_MSM_MMI_HW_INFO_H
#define __ARCH_ARM_MACH_MSM_MMI_HW_INFO_H
int mmi_storage_info_init(void);
void mmi_storage_info_exit(void);
int mmi_soc_info_init(void);
void mmi_soc_info_exit(void);
int mmi_ram_info_init(void);
void mmi_ram_info_exit(void);
int mmi_unit_info_init(void);
void mmi_unit_info_exit(void);
int mmi_boot_info_init(void);
void mmi_boot_info_exit(void);
int mmi_get_bootarg(char *key, char **value);
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];
};
/* set of data provided to the modem over SMEM */
#define SERIALNO_MAX_LEN 64
#define ANDROIDBOOT_DEVICE_MAX_LEN 32
#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 MSMHW_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];
};
/* select properties from /chosen node in of */
struct mmi_chosen_info {
unsigned int system_rev;
unsigned int system_serial_low;
unsigned int system_serial_high;
unsigned int powerup_reason;
unsigned int product_id;
unsigned int mbmversion;
unsigned int boot_seq;
char baseband[BASEBAND_MAX_LEN];
char msm_hw[MSMHW_MAX_LEN];
};
extern struct mmi_chosen_info mmi_chosen_data;
#define SYSFS_ATTRIBUTE(_name, _mode) \
static struct kobj_attribute _name##_attr = \
__ATTR(_name, _mode, _name##_show, NULL); \
#define SYSFS_SIMPLE_SHOW(_name, _param, _type, _size) \
static ssize_t _name##_show(struct kobject *kobj, \
struct kobj_attribute *attr, char *buf) \
{ \
return snprintf(buf, _size, _type"\n", _param); \
} \
#endif

View file

@ -0,0 +1,115 @@
/*
* Copyright (C) 2018 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/ctype.h>
#include <linux/slab.h>
#include "mmi_info.h"
struct mmi_chosen_info mmi_chosen_data;
static char *bootargs_str;
int mmi_get_bootarg(char *key, char **value)
{
const char *bootargs_tmp = NULL;
char *idx = NULL;
char *kvpair = NULL;
int err = 1;
struct device_node *n = of_find_node_by_path("/chosen");
if (n == NULL)
goto err;
if (of_property_read_string(n, "bootargs", &bootargs_tmp) != 0)
goto putnode;
if (!bootargs_str)
/* The following operations need a non-const
* version of bootargs
*/
bootargs_str = kzalloc(strlen(bootargs_tmp) + 1, GFP_KERNEL);
if (!bootargs_str)
goto putnode;
strlcpy(bootargs_str, bootargs_tmp, strlen(bootargs_tmp) + 1);
idx = strnstr(bootargs_str, key, strlen(bootargs_str));
if (idx) {
kvpair = strsep(&idx, " ");
if (kvpair)
if (strsep(&kvpair, "=")) {
*value = strsep(&kvpair, " ");
if (*value)
err = 0;
}
}
putnode:
of_node_put(n);
err:
return err;
}
static void mmi_of_populate_setup(void)
{
const char *temp;
struct device_node *n = of_find_node_by_path("/chosen");
if (n == NULL)
return;
of_property_read_u32(n, "mmi,powerup_reason",
&mmi_chosen_data.powerup_reason);
of_property_read_u32(n, "mmi,mbmversion", &mmi_chosen_data.mbmversion);
of_property_read_u32(n, "mmi,boot_seq", &mmi_chosen_data.boot_seq);
of_property_read_u32(n, "mmi,prod_id", &mmi_chosen_data.product_id);
of_property_read_u32(n, "linux,hwrev", &mmi_chosen_data.system_rev);
of_property_read_u32(n, "linux,seriallow",
&mmi_chosen_data.system_serial_low);
of_property_read_u32(n, "linux,serialhigh",
&mmi_chosen_data.system_serial_high);
if (of_property_read_string(n, "mmi,baseband", &temp) == 0)
strlcpy(mmi_chosen_data.baseband, temp, BASEBAND_MAX_LEN);
if (of_property_read_string(n, "mmi,msm_hw", &temp) == 0)
strlcpy(mmi_chosen_data.msm_hw, temp, MSMHW_MAX_LEN);
of_node_put(n);
}
static int __init mmi_hw_info_init(void)
{
mmi_of_populate_setup();
mmi_storage_info_init();
mmi_soc_info_init();
mmi_ram_info_init();
mmi_unit_info_init();
mmi_boot_info_init();
return 0;
}
static void mmi_hw_info_exit(void)
{
mmi_storage_info_exit();
mmi_soc_info_exit();
mmi_ram_info_exit();
mmi_unit_info_exit();
mmi_boot_info_exit();
kfree(bootargs_str);
}
module_init(mmi_hw_info_init);
module_exit(mmi_hw_info_exit);
MODULE_DESCRIPTION("Motorola Mobility LLC. HW Info");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,186 @@
/*
* Copyright (C) 2012 Motorola Mobility LLC
* Copyright (C) 2018 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 <soc/qcom/smsm.h>
#include "mmi_info.h"
#define SMEM_SDRAM_INFO SMEM_ID_VENDOR1
static struct {
unsigned int mr5;
unsigned int mr6;
unsigned int mr7;
unsigned int mr8;
unsigned int ramsize;
} *smem_ddr_info;
static char sysfsram_type_name[20] = "unknown";
static char sysfsram_vendor_name[20] = "unknown";
static uint32_t sysfsram_ramsize;
static ssize_t 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, 8, "0x%02x\n", val);
}
static ssize_t 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);
}
SYSFS_SIMPLE_SHOW(size, sysfsram_ramsize, "%u", 12)
SYSFS_SIMPLE_SHOW(type, sysfsram_type_name, "%s", 20)
SYSFS_ATTRIBUTE(size, 0444)
SYSFS_ATTRIBUTE(type, 0444)
SYSFS_ATTRIBUTE(info, 0444)
static struct kobj_attribute mr5_register_attr =
__ATTR(mr5, 0444, mr_register_show, NULL);
static struct kobj_attribute mr6_register_attr =
__ATTR(mr6, 0444, mr_register_show, NULL);
static struct kobj_attribute mr7_register_attr =
__ATTR(mr7, 0444, mr_register_show, NULL);
static struct kobj_attribute mr8_register_attr =
__ATTR(mr8, 0444, mr_register_show, NULL);
static struct attribute *ram_info_properties_attrs[] = {
&mr5_register_attr.attr,
&mr6_register_attr.attr,
&mr7_register_attr.attr,
&mr8_register_attr.attr,
&size_attr.attr,
&type_attr.attr,
&info_attr.attr,
NULL
};
static struct attribute_group ram_info_properties_attr_group = {
.attrs = ram_info_properties_attrs,
};
static struct kobject *ram_info_properties_kobj;
int mmi_ram_info_init(void)
{
int status = 0;
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 = smem_alloc(SMEM_SDRAM_INFO, sizeof(*smem_ddr_info), 0,
SMEM_ANY_HOST_FLAG);
if (smem_ddr_info != NULL) {
/* identify vendor */
vid = smem_ddr_info->mr5 & 0xFF;
if (vid < ARRAY_SIZE(vendors))
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 < ARRAY_SIZE(types))
tname = types[tid];
snprintf(sysfsram_type_name, sizeof(sysfsram_type_name),
"%s", tname);
/* extract size */
sysfsram_ramsize = smem_ddr_info->ramsize;
} 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;
}
void mmi_ram_info_exit(void)
{
sysfs_remove_group(ram_info_properties_kobj,
&ram_info_properties_attr_group);
kobject_del(ram_info_properties_kobj);
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (C) 2013 - 2015 Motorola Mobility LLC
* Copyright (C) 2018 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 <soc/qcom/socinfo.h>
#include "mmi_info.h"
static ssize_t version_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return snprintf(buf, 32, "%u.%u\n",
SOCINFO_VERSION_MAJOR(socinfo_get_version()),
SOCINFO_VERSION_MINOR(socinfo_get_version()));
}
SYSFS_SIMPLE_SHOW(id, socinfo_get_id(), "%u", 32)
SYSFS_SIMPLE_SHOW(raw_id, socinfo_get_raw_id(), "%u", 32)
SYSFS_SIMPLE_SHOW(raw_version, socinfo_get_raw_version(), "%u", 32)
SYSFS_SIMPLE_SHOW(platform_type, socinfo_get_platform_type(), "%u", 32)
SYSFS_SIMPLE_SHOW(platform_version, socinfo_get_platform_version(), "%u", 32)
SYSFS_SIMPLE_SHOW(platform_subtype, socinfo_get_platform_subtype(), "%u", 32)
SYSFS_ATTRIBUTE(version, 0444)
SYSFS_ATTRIBUTE(id, 0444)
SYSFS_ATTRIBUTE(raw_id, 0444)
SYSFS_ATTRIBUTE(raw_version, 0444)
SYSFS_ATTRIBUTE(platform_type, 0444)
SYSFS_ATTRIBUTE(platform_version, 0444)
SYSFS_ATTRIBUTE(platform_subtype, 0444)
static struct attribute *soc_info_properties_attrs[] = {
&id_attr.attr,
&version_attr.attr,
&raw_id_attr.attr,
&raw_version_attr.attr,
&platform_type_attr.attr,
&platform_version_attr.attr,
&platform_subtype_attr.attr,
NULL
};
static struct attribute_group soc_info_properties_attr_group = {
.attrs = soc_info_properties_attrs,
};
static struct kobject *soc_info_properties_kobj;
int mmi_soc_info_init(void)
{
int ret = 0;
int status = 0;
soc_info_properties_kobj = kobject_create_and_add("soc", NULL);
if (soc_info_properties_kobj)
status = sysfs_create_group(soc_info_properties_kobj,
&soc_info_properties_attr_group);
if (!soc_info_properties_kobj || status) {
pr_err("%s: failed to create /sys/soc\n", __func__);
ret = 1;
goto err;
}
err:
return ret;
}
void mmi_soc_info_exit(void)
{
sysfs_remove_group(soc_info_properties_kobj,
&soc_info_properties_attr_group);
kobject_del(soc_info_properties_kobj);
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2016 Motorola Mobility LLC
* Copyright (C) 2018 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 "mmi_info.h"
struct mmi_storage_info *info;
SYSFS_SIMPLE_SHOW(fw, info->firmware_version, "%s", 32)
SYSFS_SIMPLE_SHOW(model, info->product_name, "%s", 32)
SYSFS_SIMPLE_SHOW(vendor, info->card_manufacturer, "%s", 32)
SYSFS_SIMPLE_SHOW(size, info->size, "%s", 16)
SYSFS_SIMPLE_SHOW(type, info->type, "%s", 16)
SYSFS_ATTRIBUTE(fw, 0444)
SYSFS_ATTRIBUTE(model, 0444)
SYSFS_ATTRIBUTE(vendor, 0444)
SYSFS_ATTRIBUTE(size, 0444)
SYSFS_ATTRIBUTE(type, 0444)
static struct attribute *st_info_properties_attrs[] = {
&fw_attr.attr,
&model_attr.attr,
&vendor_attr.attr,
&size_attr.attr,
&type_attr.attr,
NULL
};
static struct attribute_group st_info_properties_attr_group = {
.attrs = st_info_properties_attrs,
};
static struct kobject *st_info_properties_kobj;
int mmi_storage_info_init(void)
{
int ret = 0;
int status = 0;
struct property *p;
struct device_node *n;
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);
/* 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 mmi_storage_info_exit(void)
{
kfree(info);
info = NULL;
sysfs_remove_group(st_info_properties_kobj,
&st_info_properties_attr_group);
kobject_del(st_info_properties_kobj);
}

View file

@ -0,0 +1,178 @@
/*
* Copyright (C) 2013 Motorola Mobility LLC
* Copyright (C) 2018 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/qcom/smem.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <asm/system_misc.h>
#include "mmi_info.h"
#ifndef CONFIG_ARM64
#include <asm/mach/arch.h>
#endif
#define SMEM_KERNEL_RESERVE SMEM_ID_VENDOR0
static struct proc_dir_entry *unitinfo_procfs_file;
static struct mmi_unit_info *mui;
static char serialno[SERIALNO_MAX_LEN];
static char carrier[CARRIER_MAX_LEN];
static char baseband[BASEBAND_MAX_LEN];
static char androidboot_device[ANDROIDBOOT_DEVICE_MAX_LEN];
static unsigned int androidboot_radio;
static char androidboot_radio_str[RADIO_MAX_LEN];
static void mmi_bootarg_setup(void)
{
char *s;
if (mmi_get_bootarg("androidboot.radio=", &s) == 0) {
if (kstrtouint(s, 16, &androidboot_radio) < 0)
androidboot_radio = 0;
strlcpy(androidboot_radio_str, s, RADIO_MAX_LEN);
}
if (mmi_get_bootarg("androidboot.device=", &s) == 0)
strlcpy(androidboot_device, s, ANDROIDBOOT_DEVICE_MAX_LEN);
if (mmi_get_bootarg("androidboot.baseband=", &s) == 0)
strlcpy(baseband, s, BASEBAND_MAX_LEN);
if (mmi_get_bootarg("androidboot.carrier=", &s) == 0)
strlcpy(carrier, s, CARRIER_MAX_LEN);
if (mmi_get_bootarg("androidboot.serialno=", &s) == 0)
strlcpy(serialno, s, SERIALNO_MAX_LEN);
}
static int unitinfo_seq_show(struct seq_file *f, void *ptr)
{
seq_printf(f, "Hardware\t: %s\n", arch_read_hardware_id());
seq_printf(f, "Revision\t: %04x\n", mmi_chosen_data.system_rev);
seq_printf(f, "Serial\t\t: %08x%08x\n",
mmi_chosen_data.system_serial_high,
mmi_chosen_data.system_serial_low);
seq_printf(f, "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(f, "Radio\t\t: %s\n", androidboot_radio_str);
seq_printf(f, "MSM Hardware\t: %s\n", mmi_chosen_data.msm_hw);
return 0;
}
static int mmi_unit_smem_setup(void)
{
int ret = 0;
struct mmi_unit_info *mui_copy;
#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 = mmi_chosen_data.system_rev;
mui_copy->system_serial_low = mmi_chosen_data.system_serial_low;
mui_copy->system_serial_high = mmi_chosen_data.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, mmi_chosen_data.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 = mmi_chosen_data.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 = (struct mmi_unit_info *) smem_alloc(SMEM_KERNEL_RESERVE,
SMEM_KERNEL_RESERVE_SIZE, 0, SMEM_ANY_HOST_FLAG);
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;
}
static int unitinfo_open(struct inode *inode, struct file *file)
{
return single_open(file, unitinfo_seq_show, inode->i_private);
}
static const struct file_operations unitinfo_operations = {
.open = unitinfo_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
int mmi_unit_info_init(void)
{
mmi_bootarg_setup();
mmi_unit_smem_setup();
/* /proc/unitinfo */
unitinfo_procfs_file = proc_create("unitinfo",
0444, NULL, &unitinfo_operations);
return 0;
}
void mmi_unit_info_exit(void)
{
if (unitinfo_procfs_file)
remove_proc_entry("unitinfo", NULL);
}

View file

@ -0,0 +1,81 @@
/*
* include/soc/qcom/mmi_boot_info.h: Include file for boot information
* provided on Motorola phones
*
* Copyright (C) 2009 Motorola, Inc.
* Copyright (C) 2018 Motorola, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Date Author Comment
* 01/07/2009 Motorola Initial version
*/
#ifndef __ASMARM_BOOTINFO_H
#define __ASMARM_BOOTINFO_H
/*
* These #defines are used for the bits in powerup_reason.
*/
#define PU_REASON_USB_CABLE 0x00000010 /* Bit 4 */
#define PU_REASON_FACTORY_CABLE 0x00000020 /* Bit 5 */
#define PU_REASON_PWR_KEY_PRESS 0x00000080 /* Bit 7 */
#define PU_REASON_CHARGER 0x00000100 /* Bit 8 */
#define PU_REASON_POWER_CUT 0x00000200 /* bit 9 */
#define PU_REASON_SW_AP_RESET 0x00004000 /* Bit 14 */
#define PU_REASON_WDOG_AP_RESET 0x00008000 /* Bit 15 */
#define PU_REASON_AP_KERNEL_PANIC 0x00020000 /* Bit 17 */
#define PU_REASON_MODEM_RESET 0x80000000 /* Bit 31 */
#define PU_REASON_INVALID 0xFFFFFFFF
/*
* These #defines are used for the battery status at boot.
* When no battery is present, the status is BATTERY_LO_VOLTAGE.
*/
#define BATTERY_GOOD_VOLTAGE 1
#define BATTERY_LO_VOLTAGE 2
#define BATTERY_UNKNOWN (-1)
/*
* /proc/bootinfo has a strict format. Each line contains a name/value
* pair which are separated with a colon and a single space on both
* sides of the colon. The following defines help you size the
* buffers used to read the data from /proc/bootinfo.
*
* BOOTINFO_MAX_NAME_LEN: maximum size in bytes of a name in the
* bootinfo line. Don't forget to add space
* for the NUL if you need it.
* BOOTINFO_MAX_VAL_LEN: maximum size in bytes of a value in the
* bootinfo line. Don't forget to add space
* for the NUL if you need it.
* BOOTINFO_BUF_SIZE: size in bytes of buffer that is large enough
* to read a /proc/bootinfo line. The extra
* 3 is for the " : ". Don't forget to add
* space for the NUL and newline if you
* need them.
*/
#define BOOTINFO_MAX_NAME_LEN 32
#define BOOTINFO_MAX_VAL_LEN 128
#define BOOTINFO_BUF_SIZE (BOOTINFO_MAX_NAME_LEN + \
3 + BOOTINFO_MAX_VAL_LEN)
u32 bi_powerup_reason(void);
const char *bi_bootreason(void);
u32 bi_mbm_version(void);
const char *bi_bootmode(void);
u32 bi_boot_seq(void);
#endif