Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a659e706 authored by Murali Nalajala's avatar Murali Nalajala
Browse files

socinfo: add socinfo driver



Add socinfo driver to expose various SoC information to the clients.
This information is useful to various clients in kernel and userspace
to know about the SoC information.

Change-Id: If8b025f19a8eb5bf736d1c88c180654d724bb45f
Signed-off-by: default avatarMurali Nalajala <mnalajal@codeaurora.org>
parent 3e91323f
Loading
Loading
Loading
Loading
+742 −10
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/string.h>
#include <linux/sys_soc.h>
#include <linux/types.h>
#include <soc/qcom/socinfo.h>

/*
 * SoC version type with major number in the upper 16 bits and minor
@@ -20,8 +21,10 @@
 */
#define SOCINFO_MAJOR(ver) (((ver) >> 16) & 0xffff)
#define SOCINFO_MINOR(ver) ((ver) & 0xffff)
#define SOCINFO_VERSION(maj, min)  ((((maj) & 0xffff) << 16)|((min) & 0xffff))

#define SMEM_SOCINFO_BUILD_ID_LENGTH           32
#define SMEM_SOCINFO_CHIP_ID_LENGTH			   32

/*
 * SMEM item id, used to acquire handles to respective
@@ -29,8 +32,52 @@
 */
#define SMEM_HW_SW_BUILD_ID            137

static uint32_t socinfo_format;

enum {
	HW_PLATFORM_UNKNOWN = 0,
	HW_PLATFORM_SURF    = 1,
	HW_PLATFORM_FFA     = 2,
	HW_PLATFORM_FLUID   = 3,
	HW_PLATFORM_SVLTE_FFA	= 4,
	HW_PLATFORM_SVLTE_SURF	= 5,
	HW_PLATFORM_MTP_MDM = 7,
	HW_PLATFORM_MTP  = 8,
	HW_PLATFORM_LIQUID  = 9,
	/* Dragonboard platform id is assigned as 10 in CDT */
	HW_PLATFORM_DRAGON	= 10,
	HW_PLATFORM_QRD	= 11,
	HW_PLATFORM_HRD	= 13,
	HW_PLATFORM_DTV	= 14,
	HW_PLATFORM_RCM	= 21,
	HW_PLATFORM_STP = 23,
	HW_PLATFORM_SBC = 24,
	HW_PLATFORM_HDK = 31,
	HW_PLATFORM_INVALID
};

static const char * const hw_platform[] = {
	[HW_PLATFORM_UNKNOWN] = "Unknown",
	[HW_PLATFORM_SURF] = "Surf",
	[HW_PLATFORM_FFA] = "FFA",
	[HW_PLATFORM_FLUID] = "Fluid",
	[HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
	[HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
	[HW_PLATFORM_MTP_MDM] = "MDM_MTP_NO_DISPLAY",
	[HW_PLATFORM_MTP] = "MTP",
	[HW_PLATFORM_RCM] = "RCM",
	[HW_PLATFORM_LIQUID] = "Liquid",
	[HW_PLATFORM_DRAGON] = "Dragon",
	[HW_PLATFORM_QRD] = "QRD",
	[HW_PLATFORM_HRD] = "HRD",
	[HW_PLATFORM_DTV] = "DTV",
	[HW_PLATFORM_STP] = "STP",
	[HW_PLATFORM_SBC] = "SBC",
	[HW_PLATFORM_HDK] = "HDK",
};

/* Socinfo SMEM item structure */
struct socinfo {
static struct socinfo {
	__le32 fmt;
	__le32 id;
	__le32 ver;
@@ -65,7 +112,417 @@ struct socinfo {
	__le32 chip_family;
	__le32 raw_device_family;
	__le32 raw_device_num;
};
	/* Version 13 */
	__le32 nproduct_id;
	char chip_name[SMEM_SOCINFO_CHIP_ID_LENGTH];
	/* Version 14 */
	__le32 num_clusters;
	__le32 ncluster_array_offset;
	__le32 num_defective_parts;
	__le32 ndefective_parts_array_offset;
	/* Version 15 */
	__le32  nmodem_supported;
} *socinfo;

/* sysfs attributes */
#define ATTR_DEFINE(param)	\
	static DEVICE_ATTR(param, 0644,	\
		   msm_get_##param,	\
		   NULL)


/* Version 2 */
static uint32_t socinfo_get_raw_id(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 2) ?
			le32_to_cpu(socinfo->raw_id) : 0)
		: 0;
}

static uint32_t socinfo_get_raw_version(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 2) ?
			le32_to_cpu(socinfo->raw_ver) : 0)
		: 0;
}

/* Version 3 */
static uint32_t socinfo_get_platform_type(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 3) ?
			le32_to_cpu(socinfo->hw_plat) : 0)
		: 0;
}

/* Version 4 */
static uint32_t socinfo_get_platform_version(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 4) ?
			le32_to_cpu(socinfo->plat_ver) : 0)
		: 0;
}
/* Version 5 */
static uint32_t socinfo_get_accessory_chip(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 5) ?
			le32_to_cpu(socinfo->accessory_chip) : 0)
		: 0;
}

/* Version 6 */
static uint32_t socinfo_get_platform_subtype(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 6) ?
			le32_to_cpu(socinfo->hw_plat_subtype) : 0)
		: 0;
}

/* Version 7 */
static int socinfo_get_pmic_model(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 7) ?
			le32_to_cpu(socinfo->pmic_model) : 0xFFFFFFFF)
		: 0xFFFFFFFF;
}

static uint32_t socinfo_get_pmic_die_revision(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 7) ?
			le32_to_cpu(socinfo->pmic_die_rev) : 0)
		: 0;
}

/* Version 9 */
static uint32_t socinfo_get_foundry_id(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 9) ?
			le32_to_cpu(socinfo->foundry_id) : 0)
		: 0;
}

/* Version 10 */
uint32_t socinfo_get_serial_number(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 10) ?
			le32_to_cpu(socinfo->serial_num) : 0)
		: 0;
}
EXPORT_SYMBOL(socinfo_get_serial_number);

/* Version 12 */
static uint32_t socinfo_get_chip_family(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 12) ?
			le32_to_cpu(socinfo->chip_family) : 0)
		: 0;
}

static uint32_t socinfo_get_raw_device_family(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 12) ?
			le32_to_cpu(socinfo->raw_device_family) : 0)
		: 0;
}

static uint32_t socinfo_get_raw_device_number(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 12) ?
			le32_to_cpu(socinfo->raw_device_num) : 0)
		: 0;
}

/* Version 13 */
static uint32_t socinfo_get_nproduct_id(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 13) ?
			le32_to_cpu(socinfo->nproduct_id) : 0)
		: 0;
}

static char *socinfo_get_chip_name(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 13) ?
			socinfo->chip_name : "N/A")
		: "N/A";
}

/* Version 14 */
static uint32_t socinfo_get_num_clusters(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 14) ?
			le32_to_cpu(socinfo->num_clusters) : 0)
		: 0;
}

static uint32_t socinfo_get_ncluster_array_offset(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 14) ?
			le32_to_cpu(socinfo->ncluster_array_offset) : 0)
		: 0;
}

static uint32_t socinfo_get_num_defective_parts(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 14) ?
			le32_to_cpu(socinfo->num_defective_parts) : 0)
		: 0;
}

static uint32_t socinfo_get_ndefective_parts_array_offset(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 14) ?
			le32_to_cpu(socinfo->ndefective_parts_array_offset) : 0)
		: 0;
}

/* Version 15 */
static uint32_t socinfo_get_nmodem_supported(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 15) ?
			le32_to_cpu(socinfo->nmodem_supported) : 0)
		: 0;
}

/* Version 2 */
static ssize_t
msm_get_raw_id(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_raw_id());
}
ATTR_DEFINE(raw_id);

static ssize_t
msm_get_raw_ver(struct device *dev,
		     struct device_attribute *attr,
		     char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_raw_version());
}
ATTR_DEFINE(raw_ver);

/* Version 3 */
static ssize_t
msm_get_hw_plat(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	uint32_t hw_type;

	hw_type = socinfo_get_platform_type();

	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
			hw_platform[hw_type]);
}
ATTR_DEFINE(hw_plat);

/* Version 4 */
static ssize_t
msm_get_plat_ver(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_platform_version());
}
ATTR_DEFINE(plat_ver);

/* Version 5 */
static ssize_t
msm_get_accessory_chip(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_accessory_chip());
}
ATTR_DEFINE(accessory_chip);

/* Version 6 */
static ssize_t
msm_get_hw_plat_subtype(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	uint32_t hw_subtype;

	hw_subtype = socinfo_get_platform_subtype();
	return snprintf(buf, PAGE_SIZE, "%u\n",
		hw_subtype);
}
ATTR_DEFINE(hw_plat_subtype);

/* Version 7 */
static ssize_t
msm_get_pmic_model(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_pmic_model());
}
ATTR_DEFINE(pmic_model);

static ssize_t
msm_get_pmic_die_rev(struct device *dev,
			       struct device_attribute *attr,
			       char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
			 socinfo_get_pmic_die_revision());
}
ATTR_DEFINE(pmic_die_rev);

/* Version 8 (skip) */
/* Version 9 */
static ssize_t
msm_get_foundry_id(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_foundry_id());
}
ATTR_DEFINE(foundry_id);

/* Version 10 */
static ssize_t
msm_get_serial_num(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u\n",
		socinfo_get_serial_number());
}
ATTR_DEFINE(serial_num);

/* Version 11 (skip) */
/* Version 12 */
static ssize_t
msm_get_chip_family(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_chip_family());
}
ATTR_DEFINE(chip_family);

static ssize_t
msm_get_raw_device_family(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_raw_device_family());
}
ATTR_DEFINE(raw_device_family);

static ssize_t
msm_get_raw_device_num(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_raw_device_number());
}
ATTR_DEFINE(raw_device_num);

/* Version 13 */
static ssize_t
msm_get_nproduct_id(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_nproduct_id());
}
ATTR_DEFINE(nproduct_id);

static ssize_t
msm_get_chip_name(struct device *dev,
		   struct device_attribute *attr,
		   char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
			socinfo_get_chip_name());
}
ATTR_DEFINE(chip_name);

/* Version 14 */
static ssize_t
msm_get_num_clusters(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_num_clusters());
}
ATTR_DEFINE(num_clusters);

static ssize_t
msm_get_ncluster_array_offset(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_ncluster_array_offset());
}
ATTR_DEFINE(ncluster_array_offset);

static ssize_t
msm_get_num_defective_parts(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_num_defective_parts());
}
ATTR_DEFINE(num_defective_parts);

static ssize_t
msm_get_ndefective_parts_array_offset(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_ndefective_parts_array_offset());
}
ATTR_DEFINE(ndefective_parts_array_offset);

/* Version 15 */
static ssize_t
msm_get_nmodem_supported(struct device *dev,
			struct device_attribute *attr,
			char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%x\n",
		socinfo_get_nmodem_supported());
}
ATTR_DEFINE(nmodem_supported);

struct qcom_socinfo {
	struct soc_device *soc_dev;
@@ -116,9 +573,282 @@ static const struct soc_id soc_id[] = {
	{ 310, "MSM8996AU" },
	{ 311, "APQ8096AU" },
	{ 312, "APQ8096SG" },
	{ 356, "KONA" },
	{ 415, "LAHAINA" },
};

static const char *socinfo_machine(struct device *dev, unsigned int id)
static struct attribute *msm_custom_socinfo_attrs[35];

static umode_t soc_info_attribute(struct kobject *kobj,
						   struct attribute *attr,
						   int index)
{
	return attr->mode;
}

static const struct attribute_group custom_soc_attr_group = {
	.attrs = msm_custom_socinfo_attrs,
	.is_visible = soc_info_attribute,
};

static void socinfo_populate_sysfs(struct qcom_socinfo *qcom_socinfo)
{
	int i = 0;

	switch (socinfo_format) {
	case SOCINFO_VERSION(0, 15):
		msm_custom_socinfo_attrs[i++] = &dev_attr_nmodem_supported.attr;
	case SOCINFO_VERSION(0, 14):
		msm_custom_socinfo_attrs[i++] = &dev_attr_num_clusters.attr;
		msm_custom_socinfo_attrs[i++] =
		&dev_attr_ncluster_array_offset.attr;
		msm_custom_socinfo_attrs[i++] =
		&dev_attr_num_defective_parts.attr;
		msm_custom_socinfo_attrs[i++] =
		&dev_attr_ndefective_parts_array_offset.attr;
	case SOCINFO_VERSION(0, 13):
		msm_custom_socinfo_attrs[i++] = &dev_attr_nproduct_id.attr;
		msm_custom_socinfo_attrs[i++] = &dev_attr_chip_name.attr;
	case SOCINFO_VERSION(0, 12):
		msm_custom_socinfo_attrs[i++] = &dev_attr_chip_family.attr;
		msm_custom_socinfo_attrs[i++] =
		&dev_attr_raw_device_family.attr;
		msm_custom_socinfo_attrs[i++] = &dev_attr_raw_device_num.attr;
	case SOCINFO_VERSION(0, 11):
	case SOCINFO_VERSION(0, 10):
		msm_custom_socinfo_attrs[i++] = &dev_attr_serial_num.attr;
	case SOCINFO_VERSION(0, 9):
		msm_custom_socinfo_attrs[i++] = &dev_attr_foundry_id.attr;
	case SOCINFO_VERSION(0, 8):
	case SOCINFO_VERSION(0, 7):
		msm_custom_socinfo_attrs[i++] = &dev_attr_pmic_model.attr;
		msm_custom_socinfo_attrs[i++] = &dev_attr_pmic_die_rev.attr;
	case SOCINFO_VERSION(0, 6):
		msm_custom_socinfo_attrs[i++] = &dev_attr_hw_plat_subtype.attr;
	case SOCINFO_VERSION(0, 5):
		msm_custom_socinfo_attrs[i++] = &dev_attr_accessory_chip.attr;
	case SOCINFO_VERSION(0, 4):
		msm_custom_socinfo_attrs[i++] = &dev_attr_plat_ver.attr;
	case SOCINFO_VERSION(0, 3):
		msm_custom_socinfo_attrs[i++] = &dev_attr_hw_plat.attr;
	case SOCINFO_VERSION(0, 2):
		msm_custom_socinfo_attrs[i++] = &dev_attr_raw_id.attr;
		msm_custom_socinfo_attrs[i++] = &dev_attr_raw_ver.attr;
	case SOCINFO_VERSION(0, 1):
		break;
	default:
		pr_err("Unknown socinfo format: v%u.%u\n",
				SOCINFO_MAJOR(socinfo_format),
				SOCINFO_MINOR(socinfo_format));
		break;
	}

	msm_custom_socinfo_attrs[i++] = NULL;
	qcom_socinfo->attr.custom_attr_group = &custom_soc_attr_group;
}

static void socinfo_print(void)
{
	uint32_t f_maj = SOCINFO_MAJOR(socinfo_format);
	uint32_t f_min = SOCINFO_MINOR(socinfo_format);
	uint32_t v_maj = SOCINFO_MAJOR(le32_to_cpu(socinfo->ver));
	uint32_t v_min = SOCINFO_MINOR(le32_to_cpu(socinfo->ver));

	switch (socinfo_format) {
	case SOCINFO_VERSION(0, 1):
		pr_info("v%u.%u, id=%u, ver=%u.%u\n",
				f_maj, f_min, socinfo->id, v_maj, v_min);
		break;
	case SOCINFO_VERSION(0, 2):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u\n",
				f_maj, f_min, socinfo->id, v_maj, v_min,
				socinfo->raw_id, socinfo->raw_ver);
		break;
	case SOCINFO_VERSION(0, 3):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u\n",
				f_maj, f_min, socinfo->id, v_maj, v_min,
				socinfo->raw_id, socinfo->raw_ver,
				socinfo->hw_plat);
		break;
	case SOCINFO_VERSION(0, 4):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver);
		break;
	case SOCINFO_VERSION(0, 5):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip);
		break;
	case SOCINFO_VERSION(0, 6):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u hw_plat_subtype=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype);
		break;
	case SOCINFO_VERSION(0, 7):
	case SOCINFO_VERSION(0, 8):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev);
		break;
	case SOCINFO_VERSION(0, 9):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id);
		break;
	case SOCINFO_VERSION(0, 10):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id,
			socinfo->serial_num);
		break;
	case SOCINFO_VERSION(0, 11):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id,
			socinfo->serial_num,
			socinfo->num_pmics);
		break;
	case SOCINFO_VERSION(0, 12):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id,
			socinfo->serial_num,
			socinfo->num_pmics,
			socinfo->chip_family,
			socinfo->raw_device_family,
			socinfo->raw_device_num);
		break;
	case SOCINFO_VERSION(0, 13):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id,
			socinfo->serial_num,
			socinfo->num_pmics,
			socinfo->chip_family,
			socinfo->raw_device_family,
			socinfo->raw_device_num,
			socinfo->nproduct_id);
		break;

	case SOCINFO_VERSION(0, 14):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_defective_parts=0x%x ndefective_parts_array_offset=0x%x\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id,
			socinfo->serial_num,
			socinfo->num_pmics,
			socinfo->chip_family,
			socinfo->raw_device_family,
			socinfo->raw_device_num,
			socinfo->nproduct_id,
			socinfo->num_clusters,
			socinfo->ncluster_array_offset,
			socinfo->num_defective_parts,
			socinfo->ndefective_parts_array_offset);
		break;

	case SOCINFO_VERSION(0, 15):
		pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_defective_parts=0x%x ndefective_parts_array_offset=0x%x nmodem_supported=0x%x\n",
			f_maj, f_min, socinfo->id, v_maj, v_min,
			socinfo->raw_id, socinfo->raw_ver,
			socinfo->hw_plat,
			socinfo->plat_ver,
			socinfo->accessory_chip,
			socinfo->hw_plat_subtype,
			socinfo->pmic_model,
			socinfo->pmic_die_rev,
			socinfo->foundry_id,
			socinfo->serial_num,
			socinfo->num_pmics,
			socinfo->chip_family,
			socinfo->raw_device_family,
			socinfo->raw_device_num,
			socinfo->nproduct_id,
			socinfo->num_clusters,
			socinfo->ncluster_array_offset,
			socinfo->num_defective_parts,
			socinfo->ndefective_parts_array_offset,
			socinfo->nmodem_supported);
		break;

	default:
		pr_err("Unknown format found: v%u.%u\n", f_maj, f_min);
		break;
	}
}

uint32_t socinfo_get_id(void)
{
	return (socinfo) ? le32_to_cpu(socinfo->id) : 0;
}
EXPORT_SYMBOL(socinfo_get_id);

const char *socinfo_get_id_string(void)
{
	uint32_t id = socinfo_get_id();

	return (socinfo) ? soc_id[id].name : NULL;
}
EXPORT_SYMBOL(socinfo_get_id_string);

static const char *socinfo_machine(unsigned int id)
{
	int idx;

@@ -143,20 +873,22 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
		return PTR_ERR(info);
	}

	socinfo_format = le32_to_cpu(info->fmt);
	socinfo = info;

	qs = devm_kzalloc(&pdev->dev, sizeof(*qs), GFP_KERNEL);
	if (!qs)
		return -ENOMEM;

	qs->attr.machine = socinfo_machine(le32_to_cpu(info->id));
	qs->attr.family = "Snapdragon";
	qs->attr.machine = socinfo_machine(&pdev->dev,
					   le32_to_cpu(info->id));
	qs->attr.revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u.%u",
					   SOCINFO_MAJOR(le32_to_cpu(info->ver)),
					   SOCINFO_MINOR(le32_to_cpu(info->ver)));
	if (offsetof(struct socinfo, serial_num) <= item_size)
		qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL,
							"%u",
							le32_to_cpu(info->serial_num));
	qs->attr.soc_id = kasprintf(GFP_KERNEL, "%d", socinfo_get_id());

	socinfo_populate_sysfs(qs);
	socinfo_print();

	qs->soc_dev = soc_device_register(&qs->attr);
	if (IS_ERR(qs->soc_dev))
@@ -165,7 +897,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
	/* Feed the soc specific unique data into entropy pool */
	add_device_randomness(info, item_size);

	platform_set_drvdata(pdev, qs->soc_dev);
	platform_set_drvdata(pdev, qs);

	return 0;
}
+30 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 */

#ifndef __SOC_QCOM_SOCINFO_H__
#define __SOC_QCOM_SOCINFO_H__

#if IS_ENABLED(CONFIG_QCOM_SOCINFO)
uint32_t socinfo_get_id(void);
uint32_t socinfo_get_serial_number(void);
const char *socinfo_get_id_string(void);
#else
static inline uint32_t socinfo_get_id(void)
{
	return 0;
}

static inline uint32_t socinfo_get_serial_number(void)
{
	return 0;
}

static inline const char *socinfo_get_id_string(void)
{
	return "N/A";
}
#endif /* CONFIG_QCOM_SOCINFO */

#endif /* __SOC_QCOM_SOCINFO_H__ */