diff --git a/drivers/mmi_info/Android.mk b/drivers/mmi_info/Android.mk new file mode 100644 index 000000000000..d382f7197115 --- /dev/null +++ b/drivers/mmi_info/Android.mk @@ -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 diff --git a/drivers/mmi_info/Kbuild b/drivers/mmi_info/Kbuild new file mode 100644 index 000000000000..f0d26f830b91 --- /dev/null +++ b/drivers/mmi_info/Kbuild @@ -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 \ No newline at end of file diff --git a/drivers/mmi_info/Makefile b/drivers/mmi_info/Makefile new file mode 100644 index 000000000000..34b09dd815a7 --- /dev/null +++ b/drivers/mmi_info/Makefile @@ -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 \ No newline at end of file diff --git a/drivers/mmi_info/mmi_boot_info.c b/drivers/mmi_info/mmi_boot_info.c new file mode 100644 index 000000000000..fac49fd0f42e --- /dev/null +++ b/drivers/mmi_info/mmi_boot_info.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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); +} diff --git a/drivers/mmi_info/mmi_info.h b/drivers/mmi_info/mmi_info.h new file mode 100644 index 000000000000..0f3651290e85 --- /dev/null +++ b/drivers/mmi_info/mmi_info.h @@ -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 diff --git a/drivers/mmi_info/mmi_info_main.c b/drivers/mmi_info/mmi_info_main.c new file mode 100644 index 000000000000..a54e2f0f1338 --- /dev/null +++ b/drivers/mmi_info/mmi_info_main.c @@ -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 +#include +#include +#include +#include +#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"); diff --git a/drivers/mmi_info/mmi_ram_info.c b/drivers/mmi_info/mmi_ram_info.c new file mode 100644 index 000000000000..805a8eebd499 --- /dev/null +++ b/drivers/mmi_info/mmi_ram_info.c @@ -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 +#include +#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); +} diff --git a/drivers/mmi_info/mmi_soc_info.c b/drivers/mmi_info/mmi_soc_info.c new file mode 100644 index 000000000000..6e2464c3b39f --- /dev/null +++ b/drivers/mmi_info/mmi_soc_info.c @@ -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 +#include +#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); +} diff --git a/drivers/mmi_info/mmi_storage_info.c b/drivers/mmi_info/mmi_storage_info.c new file mode 100644 index 000000000000..b397fc4fd6c0 --- /dev/null +++ b/drivers/mmi_info/mmi_storage_info.c @@ -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 +#include +#include +#include +#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); +} diff --git a/drivers/mmi_info/mmi_unit_info.c b/drivers/mmi_info/mmi_unit_info.c new file mode 100644 index 000000000000..eaddc0a6f59d --- /dev/null +++ b/drivers/mmi_info/mmi_unit_info.c @@ -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 +#include +#include +#include +#include +#include +#include +#include "mmi_info.h" + +#ifndef CONFIG_ARM64 +#include +#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); +} diff --git a/include/soc/qcom/mmi_boot_info.h b/include/soc/qcom/mmi_boot_info.h new file mode 100644 index 000000000000..201f7dcbfe00 --- /dev/null +++ b/include/soc/qcom/mmi_boot_info.h @@ -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