diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index a74600d9f2d7..1c7084b0b8d7 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -18,10 +18,12 @@ static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
 bool __ro_after_init smccc_trng_available = false;
 s32 __ro_after_init smccc_soc_id_version = SMCCC_RET_NOT_SUPPORTED;
 s32 __ro_after_init smccc_soc_id_revision = SMCCC_RET_NOT_SUPPORTED;
+char __ro_after_init smccc_soc_id_name[136] = "";
 
 void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
 {
 	struct arm_smccc_res res;
+	struct arm_smccc_1_2_regs regs_1_2;
 
 	smccc_version = version;
 	smccc_conduit = conduit;
@@ -37,6 +39,66 @@ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
 			smccc_soc_id_version = (s32)res.a0;
 			arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
 			smccc_soc_id_revision = (s32)res.a0;
+
+			/* Issue Number 1.6 of the Arm SMC Calling Convention
+			 * specification introduces an optional "name" string
+			 * to the ARM_SMCCC_ARCH_SOC_ID function.  Fetch it if
+			 * available.
+			 */
+			regs_1_2.a0 = ARM_SMCCC_ARCH_SOC_ID;
+			regs_1_2.a1 = 2;	/* SOC_ID name */
+			arm_smccc_1_2_smc(
+				(const struct arm_smccc_1_2_regs *)&regs_1_2,
+				(struct arm_smccc_1_2_regs *)&regs_1_2);
+
+			if ((u32)regs_1_2.a0 == 0) {
+				unsigned long *destination =
+					(unsigned long *)smccc_soc_id_name;
+
+				/*
+				 * Copy regs_1_2.a1..regs_1_2.a17 to the
+				 * smccc_soc_id_name string with consideration
+				 * to the endianness of the values in a1..a17.
+				 * As per Issue 1.6 of the Arm SMC Calling
+				 * Convention, the string will be NUL terminated
+				 * and padded, from the end of the string to
+				 * the end of the 136 byte buffer, with NULs.
+				 */
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a1);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a2);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a3);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a4);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a5);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a6);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a7);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a8);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a9);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a10);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a11);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a12);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a13);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a14);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a15);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a16);
+				*destination++ =
+				    cpu_to_le64p((const __u64 *)&regs_1_2.a17);
+			}
 		}
 	}
 }
@@ -67,6 +129,14 @@ s32 arm_smccc_get_soc_id_revision(void)
 }
 EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
 
+char *arm_smccc_get_soc_id_name(void)
+{
+	if (strnlen(smccc_soc_id_name, sizeof(smccc_soc_id_name)))
+		return smccc_soc_id_name;
+
+	return NULL;
+}
+
 static int __init smccc_devices_init(void)
 {
 	struct platform_device *pdev;
diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c
index 1990263fbba0..6f698c703868 100644
--- a/drivers/firmware/smccc/soc_id.c
+++ b/drivers/firmware/smccc/soc_id.c
@@ -72,6 +72,7 @@ static int __init smccc_soc_init(void)
 	soc_dev_attr->soc_id = soc_id_str;
 	soc_dev_attr->revision = soc_id_rev_str;
 	soc_dev_attr->family = soc_id_jep106_id_str;
+	soc_dev_attr->machine = arm_smccc_get_soc_id_name();
 
 	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev)) {
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..5935cf636135 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -333,6 +333,16 @@ s32 arm_smccc_get_soc_id_version(void);
  */
 s32 arm_smccc_get_soc_id_revision(void);
 
+/**
+ * arm_smccc_get_soc_id_name()
+ *
+ * Returns the SOC ID name.
+ *
+ * When ARM_SMCCC_ARCH_SOC_ID name is not present, returns NULL.
+ */
+char *arm_smccc_get_soc_id_name(void);
+
+
 /**
  * struct arm_smccc_res - Result from SMC/HVC call
  * @a0-a3 result values from registers 0 to 3
