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

Commit bd75e2d4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: socinfo: handle 'too new' format versions gracefully"

parents b33e43a5 cc208a0f
Loading
Loading
Loading
Loading
+235 −237
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
 *
 */

#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/export.h>
#include <linux/module.h>
#include <linux/err.h>
@@ -121,59 +123,59 @@ const char *hw_platform_subtype[] = {
};

/* Used to parse shared memory.  Must match the modem. */
struct socinfo_v1 {
struct socinfo_v0_1 {
	uint32_t format;
	uint32_t id;
	uint32_t version;
	char build_id[BUILD_ID_LENGTH];
};

struct socinfo_v2 {
	struct socinfo_v1 v1;
struct socinfo_v0_2 {
	struct socinfo_v0_1 v0_1;

	/* only valid when format==2 */
	uint32_t raw_id;
	uint32_t raw_version;
};

struct socinfo_v3 {
	struct socinfo_v2 v2;
struct socinfo_v0_3 {
	struct socinfo_v0_2 v0_2;

	/* only valid when format==3 */
	uint32_t hw_platform;
};

struct socinfo_v4 {
	struct socinfo_v3 v3;
struct socinfo_v0_4 {
	struct socinfo_v0_3 v0_3;

	/* only valid when format==4 */
	uint32_t platform_version;
};

struct socinfo_v5 {
	struct socinfo_v4 v4;
struct socinfo_v0_5 {
	struct socinfo_v0_4 v0_4;

	/* only valid when format==5 */
	uint32_t accessory_chip;
};

struct socinfo_v6 {
	struct socinfo_v5 v5;
struct socinfo_v0_6 {
	struct socinfo_v0_5 v0_5;

	/* only valid when format==6 */
	uint32_t hw_platform_subtype;
};

struct socinfo_v7 {
	struct socinfo_v6 v6;
struct socinfo_v0_7 {
	struct socinfo_v0_6 v0_6;

	/* only valid when format==7 */
	uint32_t pmic_model;
	uint32_t pmic_die_revision;
};

struct socinfo_v8 {
	struct socinfo_v7 v7;
struct socinfo_v0_8 {
	struct socinfo_v0_7 v0_7;

	/* only valid when format==8*/
	uint32_t pmic_model_1;
@@ -182,33 +184,45 @@ struct socinfo_v8 {
	uint32_t pmic_die_revision_2;
};

struct socinfo_v9 {
	struct socinfo_v8 v8;
struct socinfo_v0_9 {
	struct socinfo_v0_8 v0_8;

	/* only valid when format==9*/
	uint32_t foundry_id;
};

struct socinfo_v10 {
	struct socinfo_v9 v9;
struct socinfo_v0_10 {
	struct socinfo_v0_9 v0_9;

	/* only valid when format==10*/
	uint32_t serial_number;
};

struct socinfo_v0_11 {
	struct socinfo_v0_10 v0_10;

	/* only valid when format==11*/
	uint32_t num_pmics;
	uint32_t pmic_array_offset;
};

static union {
	struct socinfo_v1 v1;
	struct socinfo_v2 v2;
	struct socinfo_v3 v3;
	struct socinfo_v4 v4;
	struct socinfo_v5 v5;
	struct socinfo_v6 v6;
	struct socinfo_v7 v7;
	struct socinfo_v8 v8;
	struct socinfo_v9 v9;
	struct socinfo_v10 v10;
	struct socinfo_v0_1 v0_1;
	struct socinfo_v0_2 v0_2;
	struct socinfo_v0_3 v0_3;
	struct socinfo_v0_4 v0_4;
	struct socinfo_v0_5 v0_5;
	struct socinfo_v0_6 v0_6;
	struct socinfo_v0_7 v0_7;
	struct socinfo_v0_8 v0_8;
	struct socinfo_v0_9 v0_9;
	struct socinfo_v0_10 v0_10;
	struct socinfo_v0_11 v0_11;
} *socinfo;

/* max socinfo format version supported */
#define MAX_SOCINFO_FORMAT SOCINFO_VERSION(0, 11)

static struct msm_soc_info cpu_of_id[] = {

	/* 7x01 IDs */
@@ -523,31 +537,32 @@ static struct msm_soc_info cpu_of_id[] = {

static enum msm_cpu cur_cpu;
static int current_image;
static uint32_t socinfo_format;

static struct socinfo_v1 dummy_socinfo = {
	.format = 1,
static struct socinfo_v0_1 dummy_socinfo = {
	.format = SOCINFO_VERSION(0, 1),
	.version = 1,
};

uint32_t socinfo_get_id(void)
{
	return (socinfo) ? socinfo->v1.id : 0;
	return (socinfo) ? socinfo->v0_1.id : 0;
}
EXPORT_SYMBOL_GPL(socinfo_get_id);

static char *socinfo_get_id_string(void)
{
	return (socinfo) ? cpu_of_id[socinfo->v1.id].soc_id_string : NULL;
	return (socinfo) ? cpu_of_id[socinfo->v0_1.id].soc_id_string : NULL;
}

uint32_t socinfo_get_version(void)
{
	return (socinfo) ? socinfo->v1.version : 0;
	return (socinfo) ? socinfo->v0_1.version : 0;
}

char *socinfo_get_build_id(void)
{
	return (socinfo) ? socinfo->v1.build_id : NULL;
	return (socinfo) ? socinfo->v0_1.build_id : NULL;
}

static char *msm_read_hardware_id(void)
@@ -560,10 +575,10 @@ static char *msm_read_hardware_id(void)
		return msm_soc_str;
	if (!socinfo)
		goto err_path;
	if (!cpu_of_id[socinfo->v1.id].soc_id_string)
	if (!cpu_of_id[socinfo->v0_1.id].soc_id_string)
		goto err_path;

	ret = strlcat(msm_soc_str, cpu_of_id[socinfo->v1.id].soc_id_string,
	ret = strlcat(msm_soc_str, cpu_of_id[socinfo->v0_1.id].soc_id_string,
			sizeof(msm_soc_str));
	if (ret > sizeof(msm_soc_str))
		goto err_path;
@@ -577,21 +592,24 @@ err_path:
uint32_t socinfo_get_raw_id(void)
{
	return socinfo ?
		(socinfo->v1.format >= 2 ? socinfo->v2.raw_id : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 2) ?
			socinfo->v0_2.raw_id : 0)
		: 0;
}

uint32_t socinfo_get_raw_version(void)
{
	return socinfo ?
		(socinfo->v1.format >= 2 ? socinfo->v2.raw_version : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 2) ?
			socinfo->v0_2.raw_version : 0)
		: 0;
}

uint32_t socinfo_get_platform_type(void)
{
	return socinfo ?
		(socinfo->v1.format >= 3 ? socinfo->v3.hw_platform : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 3) ?
			socinfo->v0_3.hw_platform : 0)
		: 0;
}

@@ -599,7 +617,8 @@ uint32_t socinfo_get_platform_type(void)
uint32_t socinfo_get_platform_version(void)
{
	return socinfo ?
		(socinfo->v1.format >= 4 ? socinfo->v4.platform_version : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 4) ?
			socinfo->v0_4.platform_version : 0)
		: 0;
}

@@ -608,36 +627,48 @@ uint32_t socinfo_get_platform_version(void)
static uint32_t socinfo_get_accessory_chip(void)
{
	return socinfo ?
		(socinfo->v1.format >= 5 ? socinfo->v5.accessory_chip : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 5) ?
			socinfo->v0_5.accessory_chip : 0)
		: 0;
}

uint32_t socinfo_get_platform_subtype(void)
{
	return socinfo ?
		(socinfo->v1.format >= 6 ? socinfo->v6.hw_platform_subtype : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 6) ?
			socinfo->v0_6.hw_platform_subtype : 0)
		: 0;
}

static uint32_t socinfo_get_foundry_id(void)
{
	return socinfo ?
		(socinfo->v1.format >= 9 ? socinfo->v9.foundry_id : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 9) ?
			socinfo->v0_9.foundry_id : 0)
		: 0;
}

static uint32_t socinfo_get_serial_number(void)
{
	return socinfo ?
		(socinfo_format >= SOCINFO_VERSION(0, 10) ?
			socinfo->v0_10.serial_number : 0)
		: 0;
}

enum pmic_model socinfo_get_pmic_model(void)
{
	return socinfo ?
		(socinfo->v1.format >= 7 ? socinfo->v7.pmic_model
			: PMIC_MODEL_UNKNOWN)
		(socinfo_format >= SOCINFO_VERSION(0, 7) ?
			socinfo->v0_7.pmic_model : PMIC_MODEL_UNKNOWN)
		: PMIC_MODEL_UNKNOWN;
}

uint32_t socinfo_get_pmic_die_revision(void)
{
	return socinfo ?
		(socinfo->v1.format >= 7 ? socinfo->v7.pmic_die_revision : 0)
		(socinfo_format >= SOCINFO_VERSION(0, 7) ?
			socinfo->v0_7.pmic_die_revision : 0)
		: 0;
}

@@ -647,11 +678,6 @@ static char *socinfo_get_image_version_base_address(void)
				SMEM_IMAGE_VERSION_SIZE, 0, SMEM_ANY_HOST_FLAG);
}

static uint32_t socinfo_get_format(void)
{
	return socinfo ? socinfo->v1.format : 0;
}

enum msm_cpu socinfo_get_msm_cpu(void)
{
	return cur_cpu;
@@ -732,8 +758,7 @@ msm_get_platform_subtype(struct device *dev,
	hw_subtype = socinfo_get_platform_subtype();
	if (HW_PLATFORM_QRD == socinfo_get_platform_type()) {
		if (hw_subtype >= PLATFORM_SUBTYPE_QRD_INVALID) {
			pr_err("%s: Invalid hardware platform sub type for qrd found\n",
				__func__);
			pr_err("Invalid hardware platform sub type for qrd found\n");
			hw_subtype = PLATFORM_SUBTYPE_QRD_INVALID;
		}
		return snprintf(buf, PAGE_SIZE, "%-.32s\n",
@@ -764,6 +789,15 @@ msm_get_foundry_id(struct device *dev,
		socinfo_get_foundry_id());
}

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

static ssize_t
msm_get_pmic_model(struct device *dev,
			struct device_attribute *attr,
@@ -791,8 +825,7 @@ msm_get_image_version(struct device *dev,

	string_address = socinfo_get_image_version_base_address();
	if (IS_ERR_OR_NULL(string_address)) {
		pr_err("%s : Failed to get image version base address",
				__func__);
		pr_err("Failed to get image version base address");
		return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "Unknown");
	}
	string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
@@ -812,8 +845,7 @@ msm_set_image_version(struct device *dev,
		return count;
	store_address = socinfo_get_image_version_base_address();
	if (IS_ERR_OR_NULL(store_address)) {
		pr_err("%s : Failed to get image version base address",
				__func__);
		pr_err("Failed to get image version base address");
		return count;
	}
	store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
@@ -830,8 +862,7 @@ msm_get_image_variant(struct device *dev,

	string_address = socinfo_get_image_version_base_address();
	if (IS_ERR_OR_NULL(string_address)) {
		pr_err("%s : Failed to get image version base address",
				__func__);
		pr_err("Failed to get image version base address");
		return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE,
		"Unknown");
	}
@@ -853,8 +884,7 @@ msm_set_image_variant(struct device *dev,
		return count;
	store_address = socinfo_get_image_version_base_address();
	if (IS_ERR_OR_NULL(store_address)) {
		pr_err("%s : Failed to get image version base address",
				__func__);
		pr_err("Failed to get image version base address");
		return count;
	}
	store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
@@ -872,8 +902,7 @@ msm_get_image_crm_version(struct device *dev,

	string_address = socinfo_get_image_version_base_address();
	if (IS_ERR_OR_NULL(string_address)) {
		pr_err("%s : Failed to get image version base address",
				__func__);
		pr_err("Failed to get image version base address");
		return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "Unknown");
	}
	string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
@@ -894,8 +923,7 @@ msm_set_image_crm_version(struct device *dev,
		return count;
	store_address = socinfo_get_image_version_base_address();
	if (IS_ERR_OR_NULL(store_address)) {
		pr_err("%s : Failed to get image version base address",
				__func__);
		pr_err("Failed to get image version base address");
		return count;
	}
	store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
@@ -969,6 +997,10 @@ static struct device_attribute msm_soc_attr_foundry_id =
	__ATTR(foundry_id, S_IRUGO,
			msm_get_foundry_id, NULL);

static struct device_attribute msm_soc_attr_serial_number =
	__ATTR(serial_number, S_IRUGO,
			msm_get_serial_number, NULL);

static struct device_attribute msm_soc_attr_pmic_model =
	__ATTR(pmic_model, S_IRUGO,
			msm_get_pmic_model, NULL);
@@ -1056,51 +1088,52 @@ static void * __init setup_dummy_socinfo(void)

static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
{
	uint32_t legacy_format = socinfo_get_format();

	device_create_file(msm_soc_device, &msm_soc_attr_vendor);
	device_create_file(msm_soc_device, &image_version);
	device_create_file(msm_soc_device, &image_variant);
	device_create_file(msm_soc_device, &image_crm_version);
	device_create_file(msm_soc_device, &select_image);

	switch (legacy_format) {
	case 10:
	case 9:
	switch (socinfo_format) {
	case SOCINFO_VERSION(0, 10):
		 device_create_file(msm_soc_device,
					&msm_soc_attr_serial_number);
	case SOCINFO_VERSION(0, 9):
		 device_create_file(msm_soc_device,
					&msm_soc_attr_foundry_id);
	case 8:
	case 7:
	case SOCINFO_VERSION(0, 8):
	case SOCINFO_VERSION(0, 7):
		device_create_file(msm_soc_device,
					&msm_soc_attr_pmic_model);
		device_create_file(msm_soc_device,
					&msm_soc_attr_pmic_die_revision);
	case 6:
	case SOCINFO_VERSION(0, 6):
		device_create_file(msm_soc_device,
					&msm_soc_attr_platform_subtype);
		device_create_file(msm_soc_device,
					&msm_soc_attr_platform_subtype_id);
	case 5:
	case SOCINFO_VERSION(0, 5):
		device_create_file(msm_soc_device,
					&msm_soc_attr_accessory_chip);
	case 4:
	case SOCINFO_VERSION(0, 4):
		device_create_file(msm_soc_device,
					&msm_soc_attr_platform_version);
	case 3:
	case SOCINFO_VERSION(0, 3):
		device_create_file(msm_soc_device,
					&msm_soc_attr_hw_platform);
	case 2:
	case SOCINFO_VERSION(0, 2):
		device_create_file(msm_soc_device,
					&msm_soc_attr_raw_id);
		device_create_file(msm_soc_device,
					&msm_soc_attr_raw_version);
	case 1:
	case SOCINFO_VERSION(0, 1):
		device_create_file(msm_soc_device,
					&msm_soc_attr_build_id);
		break;
	default:
		pr_err("%s:Unknown socinfo format:%u\n", __func__,
				legacy_format);
		pr_err("Unknown socinfo format: v%u.%u\n",
				SOCINFO_VERSION_MAJOR(socinfo_format),
				SOCINFO_VERSION_MINOR(socinfo_format));
		break;
	}

@@ -1128,13 +1161,13 @@ static int __init socinfo_init_sysfs(void)
	struct soc_device_attribute *soc_dev_attr;

	if (!socinfo) {
		pr_err("%s: No socinfo found!\n", __func__);
		pr_err("No socinfo found!\n");
		return -ENODEV;
	}

	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
	if (!soc_dev_attr) {
		pr_err("%s: Soc Device alloc failed!\n", __func__);
		pr_err("Soc Device alloc failed!\n");
		return -ENOMEM;
	}

@@ -1142,7 +1175,7 @@ static int __init socinfo_init_sysfs(void)
	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR_OR_NULL(soc_dev)) {
		kfree(soc_dev_attr);
		 pr_err("%s: Soc device register failed\n", __func__);
		 pr_err("Soc device register failed\n");
		 return -EIO;
	}

@@ -1155,194 +1188,159 @@ late_initcall(socinfo_init_sysfs);

static void socinfo_print(void)
{
	switch (socinfo->v1.format) {
	case 1:
		pr_info("%s: v%u, id=%u, ver=%u.%u\n",
			__func__, socinfo->v1.format, socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version));
	uint32_t f_maj = SOCINFO_VERSION_MAJOR(socinfo_format);
	uint32_t f_min = SOCINFO_VERSION_MINOR(socinfo_format);
	uint32_t v_maj = SOCINFO_VERSION_MAJOR(socinfo->v0_1.version);
	uint32_t v_min = SOCINFO_VERSION_MINOR(socinfo->v0_1.version);

	switch (socinfo_format) {
	case SOCINFO_VERSION(0, 1):
		pr_info("v%u.%u, id=%u, ver=%u.%u\n",
			f_maj, f_min, socinfo->v0_1.id, v_maj, v_min);
		break;
	case 2:
		pr_info("%s: v%u, id=%u, ver=%u.%u, "
	case SOCINFO_VERSION(0, 2):
		pr_info("v%u.%u, id=%u, ver=%u.%u, "
			 "raw_id=%u, raw_ver=%u\n",
			__func__, socinfo->v1.format, socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version);
			f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version);
		break;
	case 3:
		pr_info("%s: v%u, id=%u, ver=%u.%u, "
	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",
			__func__, socinfo->v1.format, socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform);
			f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform);
		break;
	case 4:
		pr_info("%s: v%u, id=%u, ver=%u.%u, "
	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",
			__func__, socinfo->v1.format, socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform, socinfo->v4.platform_version);
			f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version);
		break;
	case 5:
		pr_info("%s: v%u, id=%u, ver=%u.%u, "
	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", __func__, socinfo->v1.format,
			socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform, socinfo->v4.platform_version,
			socinfo->v5.accessory_chip);
			" accessory_chip=%u\n",
			f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version,
			socinfo->v0_5.accessory_chip);
		break;
	case 6:
		pr_info("%s: v%u, id=%u, ver=%u.%u, "
	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", __func__,
			socinfo->v1.format,
			socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform, socinfo->v4.platform_version,
			socinfo->v5.accessory_chip,
			socinfo->v6.hw_platform_subtype);
			" accessory_chip=%u hw_plat_subtype=%u\n",
			f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version,
			socinfo->v0_5.accessory_chip,
			socinfo->v0_6.hw_platform_subtype);
		break;
	case 8:
	case 7:
		pr_info("%s: v%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",
			__func__,
			socinfo->v1.format,
			socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform, socinfo->v4.platform_version,
			socinfo->v5.accessory_chip,
			socinfo->v6.hw_platform_subtype,
			socinfo->v7.pmic_model,
			socinfo->v7.pmic_die_revision);
	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->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version,
			socinfo->v0_5.accessory_chip,
			socinfo->v0_6.hw_platform_subtype,
			socinfo->v0_7.pmic_model,
			socinfo->v0_7.pmic_die_revision);
		break;
	case 9:
		pr_info("%s: v%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",
			__func__,
			socinfo->v1.format,
			socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform, socinfo->v4.platform_version,
			socinfo->v5.accessory_chip,
			socinfo->v6.hw_platform_subtype,
			socinfo->v7.pmic_model,
			socinfo->v7.pmic_die_revision,
			socinfo->v9.foundry_id);
	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->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version,
			socinfo->v0_5.accessory_chip,
			socinfo->v0_6.hw_platform_subtype,
			socinfo->v0_7.pmic_model,
			socinfo->v0_7.pmic_die_revision,
			socinfo->v0_9.foundry_id);
		break;
	case 10:
		pr_info("%s: v%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",
			__func__,
			socinfo->v1.format,
			socinfo->v1.id,
			SOCINFO_VERSION_MAJOR(socinfo->v1.version),
			SOCINFO_VERSION_MINOR(socinfo->v1.version),
			socinfo->v2.raw_id, socinfo->v2.raw_version,
			socinfo->v3.hw_platform, socinfo->v4.platform_version,
			socinfo->v5.accessory_chip,
			socinfo->v6.hw_platform_subtype,
			socinfo->v7.pmic_model,
			socinfo->v7.pmic_die_revision,
			socinfo->v9.foundry_id,
			socinfo->v10.serial_number);
	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->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version,
			socinfo->v0_5.accessory_chip,
			socinfo->v0_6.hw_platform_subtype,
			socinfo->v0_7.pmic_model,
			socinfo->v0_7.pmic_die_revision,
			socinfo->v0_9.foundry_id,
			socinfo->v0_10.serial_number);
		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->v0_1.id, v_maj, v_min,
			socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
			socinfo->v0_3.hw_platform,
			socinfo->v0_4.platform_version,
			socinfo->v0_5.accessory_chip,
			socinfo->v0_6.hw_platform_subtype,
			socinfo->v0_7.pmic_model,
			socinfo->v0_7.pmic_die_revision,
			socinfo->v0_9.foundry_id,
			socinfo->v0_10.serial_number,
			socinfo->v0_11.num_pmics);
		break;

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

static void socinfo_select_format(void)
{
	uint32_t f_maj = SOCINFO_VERSION_MAJOR(socinfo->v0_1.format);
	uint32_t f_min = SOCINFO_VERSION_MINOR(socinfo->v0_1.format);

	if (f_maj != 0) {
		pr_err("Unsupported format v%u.%u. Falling back to dummy values.\n",
			f_maj, f_min);
		socinfo = setup_dummy_socinfo();
	}

	if (socinfo->v0_1.format > MAX_SOCINFO_FORMAT) {
		pr_warn("Unsupported format v%u.%u. Falling back to v%u.%u.\n",
			f_maj, f_min, SOCINFO_VERSION_MAJOR(MAX_SOCINFO_FORMAT),
			SOCINFO_VERSION_MINOR(MAX_SOCINFO_FORMAT));
		socinfo_format = MAX_SOCINFO_FORMAT;
	} else {
		socinfo_format = socinfo->v0_1.format;
	}
}

int __init socinfo_init(void)
{
	static bool socinfo_init_done;
	unsigned size;

	if (socinfo_init_done)
		return 0;

	socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v10),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v9),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v8),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v7),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v6),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v5),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v4),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v3),
				0,
	socinfo = smem_get_entry(SMEM_HW_SW_BUILD_ID, &size, 0,
				 SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v2),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo))
		socinfo = smem_find(SMEM_HW_SW_BUILD_ID,
				sizeof(struct socinfo_v1),
				0,
				SMEM_ANY_HOST_FLAG);

	if (IS_ERR_OR_NULL(socinfo)) {
		pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n",
				__func__);
		pr_warn("Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n");
		socinfo = setup_dummy_socinfo();
	}

	socinfo_select_format();

	WARN(!socinfo_get_id(), "Unknown SOC ID!\n");

	if (socinfo_get_id() >= ARRAY_SIZE(cpu_of_id))
		BUG_ON("New IDs added! ID => CPU mapping needs an update.\n");
	else
		cur_cpu = cpu_of_id[socinfo->v1.id].generic_soc_type;
		cur_cpu = cpu_of_id[socinfo->v0_1.id].generic_soc_type;

	boot_stats_init();
	socinfo_print();
+3 −2
Original line number Diff line number Diff line
@@ -28,8 +28,9 @@
 *   1.0 -> 0x00010000
 *   2.3 -> 0x00020003
 */
#define SOCINFO_VERSION_MAJOR(ver) ((ver & 0xffff0000) >> 16)
#define SOCINFO_VERSION_MINOR(ver) (ver & 0x0000ffff)
#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))

#ifdef CONFIG_OF
#define of_board_is_cdp()	of_machine_is_compatible("qcom,cdp")