@@ -31,6 +31,25 @@
#define SMEM_HW_SW_BUILD_ID 137
#ifdef CONFIG_DEBUG_FS
+#define SMEM_IMAGE_VERSION_BLOCKS_COUNT 32
+#define SMEM_IMAGE_VERSION_SIZE 4096
+#define SMEM_IMAGE_VERSION_NAME_SIZE 75
+#define SMEM_IMAGE_VERSION_VARIANT_SIZE 20
+#define SMEM_IMAGE_VERSION_OEM_SIZE 32
+
+/*
+ * SMEM Image table indices
+ */
+#define SMEM_IMAGE_TABLE_BOOT_INDEX 0
+#define SMEM_IMAGE_TABLE_TZ_INDEX 1
+#define SMEM_IMAGE_TABLE_RPM_INDEX 3
+#define SMEM_IMAGE_TABLE_APPS_INDEX 10
+#define SMEM_IMAGE_TABLE_MPSS_INDEX 11
+#define SMEM_IMAGE_TABLE_ADSP_INDEX 12
+#define SMEM_IMAGE_TABLE_CNSS_INDEX 13
+#define SMEM_IMAGE_TABLE_VIDEO_INDEX 14
+#define SMEM_IMAGE_VERSION_TABLE 469
+
/* pmic model info */
static const char *const pmic_model[] = {
[0] = "Unknown PMIC model",
@@ -90,11 +109,21 @@ struct socinfo {
__le32 raw_device_num;
};
+#ifdef CONFIG_DEBUG_FS
+struct smem_image_version {
+ char name[SMEM_IMAGE_VERSION_NAME_SIZE];
+ char variant[SMEM_IMAGE_VERSION_VARIANT_SIZE];
+ char pad;
+ char oem[SMEM_IMAGE_VERSION_OEM_SIZE];
+};
+#endif /* CONFIG_DEBUG_FS */
+
struct qcom_socinfo {
struct soc_device *soc_dev;
struct soc_device_attribute attr;
#ifdef CONFIG_DEBUG_FS
struct dentry *dbg_root;
+ struct dentry *boot, *tz, *rpm, *apps, *mpss, *adsp, *cnss, *video;
#endif /* CONFIG_DEBUG_FS */
struct socinfo *socinfo;
};
@@ -298,8 +327,97 @@ QCOM_OPEN(pmic_model, qcom_show_pmic_model);
QCOM_OPEN(platform_subtype, qcom_show_platform_subtype);
QCOM_OPEN(pmic_die_revision, qcom_show_pmic_die_revision);
+#define IMAGE_SHOW_NAME(attr) \
+static int show_ ##attr## _name(struct seq_file *seq, void *p) \
+{ \
+ struct smem_image_version *image_version = seq->private; \
+ seq_puts(seq, image_version->name); \
+ seq_puts(seq, "\n"); \
+ return 0; \
+} \
+static int open_ ##attr## _name(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, show_ ##attr## _name, inode->i_private); \
+} \
+ \
+static const struct file_operations qcom_ ##attr## _name_ops = { \
+ .open = open_ ##attr## _name, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+} \
+
+#define DEBUGFS_IMAGE_NAME(fname, attr, index) \
+debugfs_create_file(__stringify(fname), 0400, qcom_socinfo->attr, \
+ &smem_image_version[index], &qcom_ ##attr## _name_ops)
+
+#define IMAGE_SHOW_VARIANT(attr) \
+static int show_ ##attr## _variant(struct seq_file *seq, void *p) \
+{ \
+ struct smem_image_version *image_version = seq->private; \
+ seq_puts(seq, image_version->variant); \
+ seq_puts(seq, "\n"); \
+ return 0; \
+} \
+static int open_ ##attr## _variant(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, show_ ##attr## _variant, inode->i_private); \
+} \
+ \
+static const struct file_operations qcom_ ##attr## _variant_ops = { \
+ .open = open_ ##attr## _variant, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
+#define DEBUGFS_IMAGE_VARIANT(fname, attr, index) \
+debugfs_create_file(__stringify(fname), 0400, qcom_socinfo->attr, \
+ &smem_image_version[index], &qcom_ ##attr## _variant_ops)
+
+#define IMAGE_SHOW_OEM(attr) \
+static int show_ ##attr## _oem(struct seq_file *seq, void *p) \
+{ \
+ struct smem_image_version *image_version = seq->private; \
+ seq_puts(seq, image_version->oem); \
+ seq_puts(seq, "\n"); \
+ return 0; \
+} \
+static int open_ ##attr## _oem(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, show_ ##attr## _oem, inode->i_private); \
+} \
+ \
+static const struct file_operations qcom_ ##attr## _oem_ops = { \
+ .open = open_ ##attr## _oem, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
+#define DEBUGFS_IMAGE_OEM(fname, attr, index) \
+debugfs_create_file(__stringify(fname), 0400, qcom_socinfo->attr, \
+ &smem_image_version[index], &qcom_ ##attr## _oem_ops)
+
+#define IMAGE_SHOW(name) \
+ IMAGE_SHOW_NAME(name); \
+ IMAGE_SHOW_VARIANT(name); \
+ IMAGE_SHOW_OEM(name) \
+
+IMAGE_SHOW(boot);
+IMAGE_SHOW(tz);
+IMAGE_SHOW(rpm);
+IMAGE_SHOW(apps);
+IMAGE_SHOW(mpss);
+IMAGE_SHOW(adsp);
+IMAGE_SHOW(cnss);
+IMAGE_SHOW(video);
+
static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo)
{
+ struct smem_image_version *smem_image_version;
+ size_t size;
+
qcom_socinfo->dbg_root = debugfs_create_dir("qcom_socinfo", NULL);
DEBUGFS_UINT_ADD(raw_version);
@@ -314,6 +432,66 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo)
DEBUGFS_ADD(pmic_model);
DEBUGFS_ADD(platform_subtype);
DEBUGFS_ADD(pmic_die_revision);
+
+ smem_image_version = qcom_smem_get(QCOM_SMEM_HOST_ANY,
+ SMEM_IMAGE_VERSION_TABLE,
+ &size);
+
+ qcom_socinfo->boot = debugfs_create_dir("boot",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, boot, SMEM_IMAGE_TABLE_BOOT_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, boot, SMEM_IMAGE_TABLE_BOOT_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, boot, SMEM_IMAGE_TABLE_BOOT_INDEX);
+
+ qcom_socinfo->tz = debugfs_create_dir("tz",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, tz, SMEM_IMAGE_TABLE_TZ_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, tz, SMEM_IMAGE_TABLE_TZ_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, tz, SMEM_IMAGE_TABLE_TZ_INDEX);
+
+ qcom_socinfo->rpm = debugfs_create_dir("rpm",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, rpm, SMEM_IMAGE_TABLE_RPM_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, rpm, SMEM_IMAGE_TABLE_RPM_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, rpm, SMEM_IMAGE_TABLE_RPM_INDEX);
+
+ qcom_socinfo->apps = debugfs_create_dir("apps",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, apps, SMEM_IMAGE_TABLE_APPS_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, apps, SMEM_IMAGE_TABLE_APPS_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, apps, SMEM_IMAGE_TABLE_APPS_INDEX);
+
+ qcom_socinfo->mpss = debugfs_create_dir("mpss",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, mpss, SMEM_IMAGE_TABLE_MPSS_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, mpss, SMEM_IMAGE_TABLE_MPSS_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, mpss, SMEM_IMAGE_TABLE_MPSS_INDEX);
+
+ qcom_socinfo->adsp = debugfs_create_dir("adsp",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, adsp, SMEM_IMAGE_TABLE_ADSP_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, adsp, SMEM_IMAGE_TABLE_ADSP_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, adsp, SMEM_IMAGE_TABLE_ADSP_INDEX);
+
+ qcom_socinfo->cnss = debugfs_create_dir("cnss",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, cnss, SMEM_IMAGE_TABLE_CNSS_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, cnss, SMEM_IMAGE_TABLE_CNSS_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, cnss, SMEM_IMAGE_TABLE_CNSS_INDEX);
+
+ qcom_socinfo->video = debugfs_create_dir("video",
+ qcom_socinfo->dbg_root);
+
+ DEBUGFS_IMAGE_NAME(name, video, SMEM_IMAGE_TABLE_VIDEO_INDEX);
+ DEBUGFS_IMAGE_VARIANT(variant, video, SMEM_IMAGE_TABLE_VIDEO_INDEX);
+ DEBUGFS_IMAGE_OEM(oem, video, SMEM_IMAGE_TABLE_VIDEO_INDEX);
}
static void socinfo_debugfs_exit(struct qcom_socinfo *qcom_socinfo)
The socinfo driver provides information about version of the various images loaded in the system. Expose this to user space for debugging purpose. Signed-off-by: Vaishali Thakkar <vaishali.thakkar@linaro.org> --- Changes since v3: - Remove extra debugfs directory creation checks Changes since v2: - None Changes since v1: - None --- drivers/soc/qcom/socinfo.c | 178 +++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) -- 2.17.1