Message ID | 20241030091336.3901440-1-alice.guo@oss.nxp.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v3] soc: imx: Add SoC device register for i.MX9 | expand |
Am Mittwoch, 30. Oktober 2024, 10:13:36 CET schrieb alice.guo@oss.nxp.com: > From: "alice.guo" <alice.guo@nxp.com> > > i.MX9 SoCs have SoC ID, SoC revision number and chip unique identifier > which are provided by the corresponding ARM trusted firmware API. This > patch intends to use SMC call to obtain these information and then > register i.MX9 SoC as a device. > > Signed-off-by: alice.guo <alice.guo@nxp.com> I was able to successfully this on two boards: $ grep . /sys/bus/soc/devices/soc0/* 2> /dev/null /sys/bus/soc/devices/soc0/family:Freescale i.MX /sys/bus/soc/devices/soc0/machine:TQ-Systems i.MX93 TQMa93xxLA/TQMa93xxCA on MBa93xxCA starter kit /sys/bus/soc/devices/soc0/revision:1.1 /sys/bus/soc/devices/soc0/serial_number:3d0f41f05242fc17baca88b84febf6de /sys/bus/soc/devices/soc0/soc_id:i.MX93 $ grep . /sys/bus/soc/devices/soc0/* 2> /dev/null /sys/bus/soc/devices/soc0/family:Freescale i.MX /sys/bus/soc/devices/soc0/machine:TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 /sys/bus/soc/devices/soc0/revision:1.1 /sys/bus/soc/devices/soc0/serial_number:64955bc2d946b9c3f11984a9522b2822 /sys/bus/soc/devices/soc0/soc_id:i.MX95 Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> Thanks Alexander > --- > > Changes for v2: > - refine error log print > Changes for v3: > - return -EINVAL when arm_smccc_smc failed > - fix the build warning caused by pr_err("%s: SMC failed: %d\n", __func__, res.a0); > - drop the pr_err in imx9_soc_init > - free the memory in the reverse order of allocation > - use of_match_node instead of of_machine_is_compatible > > drivers/soc/imx/Makefile | 2 +- > drivers/soc/imx/soc-imx9.c | 106 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 107 insertions(+), 1 deletion(-) > create mode 100644 drivers/soc/imx/soc-imx9.c > > diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile > index 3ad321ca608a..ca6a5fa1618f 100644 > --- a/drivers/soc/imx/Makefile > +++ b/drivers/soc/imx/Makefile > @@ -3,4 +3,4 @@ ifeq ($(CONFIG_ARM),y) > obj-$(CONFIG_ARCH_MXC) += soc-imx.o > endif > obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o > -obj-$(CONFIG_SOC_IMX9) += imx93-src.o > +obj-$(CONFIG_SOC_IMX9) += imx93-src.o soc-imx9.o > diff --git a/drivers/soc/imx/soc-imx9.c b/drivers/soc/imx/soc-imx9.c > new file mode 100644 > index 000000000000..823395584533 > --- /dev/null > +++ b/drivers/soc/imx/soc-imx9.c > @@ -0,0 +1,106 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2024 NXP > + */ > + > +#include <linux/arm-smccc.h> > +#include <linux/init.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/slab.h> > +#include <linux/sys_soc.h> > + > +#define IMX_SIP_GET_SOC_INFO 0xc2000006 > +#define SOC_ID(x) (((x) & 0xFFFF) >> 8) > +#define SOC_REV_MAJOR(x) ((((x) >> 28) & 0xF) - 0x9) > +#define SOC_REV_MINOR(x) (((x) >> 24) & 0xF) > + > +static int imx9_soc_device_register(void) > +{ > + struct soc_device_attribute *attr; > + struct arm_smccc_res res; > + struct soc_device *sdev; > + u32 soc_id, rev_major, rev_minor; > + u64 uid127_64, uid63_0; > + int err; > + > + attr = kzalloc(sizeof(*attr), GFP_KERNEL); > + if (!attr) > + return -ENOMEM; > + > + err = of_property_read_string(of_root, "model", &attr->machine); > + if (err) { > + pr_err("%s: missing model property: %d\n", __func__, err); > + goto attr; > + } > + > + attr->family = kasprintf(GFP_KERNEL, "Freescale i.MX"); > + > + /* > + * Retrieve the soc id, rev & uid info: > + * res.a1[31:16]: soc revision; > + * res.a1[15:0]: soc id; > + * res.a2: uid[127:64]; > + * res.a3: uid[63:0]; > + */ > + arm_smccc_smc(IMX_SIP_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res); > + if (res.a0 != SMCCC_RET_SUCCESS) { > + pr_err("%s: SMC failed: 0x%lx\n", __func__, res.a0); > + err = -EINVAL; > + goto family; > + } > + > + soc_id = SOC_ID(res.a1); > + rev_major = SOC_REV_MAJOR(res.a1); > + rev_minor = SOC_REV_MINOR(res.a1); > + > + attr->soc_id = kasprintf(GFP_KERNEL, "i.MX%2x", soc_id); > + attr->revision = kasprintf(GFP_KERNEL, "%d.%d", rev_major, rev_minor); > + > + uid127_64 = res.a2; > + uid63_0 = res.a3; > + attr->serial_number = kasprintf(GFP_KERNEL, "%016llx%016llx", uid127_64, uid63_0); > + > + sdev = soc_device_register(attr); > + if (IS_ERR(sdev)) { > + err = PTR_ERR(sdev); > + pr_err("%s failed to register SoC as a device: %d\n", __func__, err); > + goto serial_number; > + } > + > + return 0; > + > +serial_number: > + kfree(attr->serial_number); > + kfree(attr->revision); > + kfree(attr->soc_id); > +family: > + kfree(attr->family); > +attr: > + kfree(attr); > + return err; > +} > + > +static const struct of_device_id imx9_soc_match[] = { > + { .compatible = "fsl,imx93", }, > + { .compatible = "fsl,imx95", }, > + { } > +}; > + > +static int __init imx9_soc_init(void) > +{ > + int ret; > + > + /* No match means it is not an i.MX 9 series SoC, do nothing. */ > + if (!of_match_node(imx9_soc_match, of_root)) > + return 0; > + > + ret = imx9_soc_device_register(); > + > + return ret; > +} > +device_initcall(imx9_soc_init); > + > +MODULE_AUTHOR("NXP"); > +MODULE_DESCRIPTION("NXP i.MX9 SoC"); > +MODULE_LICENSE("GPL"); >
Hi Alice, Am 30.10.24 um 10:13 schrieb alice.guo@oss.nxp.com: > From: "alice.guo" <alice.guo@nxp.com> > > i.MX9 SoCs have SoC ID, SoC revision number and chip unique identifier > which are provided by the corresponding ARM trusted firmware API. This > patch intends to use SMC call to obtain these information and then > register i.MX9 SoC as a device. > > Signed-off-by: alice.guo <alice.guo@nxp.com> > --- > > Changes for v2: > - refine error log print > Changes for v3: > - return -EINVAL when arm_smccc_smc failed > - fix the build warning caused by pr_err("%s: SMC failed: %d\n", __func__, res.a0); > - drop the pr_err in imx9_soc_init > - free the memory in the reverse order of allocation > - use of_match_node instead of of_machine_is_compatible > > drivers/soc/imx/Makefile | 2 +- > drivers/soc/imx/soc-imx9.c | 106 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 107 insertions(+), 1 deletion(-) > create mode 100644 drivers/soc/imx/soc-imx9.c > > diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile > index 3ad321ca608a..ca6a5fa1618f 100644 > --- a/drivers/soc/imx/Makefile > +++ b/drivers/soc/imx/Makefile > @@ -3,4 +3,4 @@ ifeq ($(CONFIG_ARM),y) > obj-$(CONFIG_ARCH_MXC) += soc-imx.o > endif > obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o > -obj-$(CONFIG_SOC_IMX9) += imx93-src.o > +obj-$(CONFIG_SOC_IMX9) += imx93-src.o soc-imx9.o > diff --git a/drivers/soc/imx/soc-imx9.c b/drivers/soc/imx/soc-imx9.c > new file mode 100644 > index 000000000000..823395584533 > --- /dev/null > +++ b/drivers/soc/imx/soc-imx9.c > @@ -0,0 +1,106 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2024 NXP > + */ > + > +#include <linux/arm-smccc.h> > +#include <linux/init.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/slab.h> > +#include <linux/sys_soc.h> > + > +#define IMX_SIP_GET_SOC_INFO 0xc2000006 > +#define SOC_ID(x) (((x) & 0xFFFF) >> 8) > +#define SOC_REV_MAJOR(x) ((((x) >> 28) & 0xF) - 0x9) > +#define SOC_REV_MINOR(x) (((x) >> 24) & 0xF) > + > +static int imx9_soc_device_register(void) > +{ > + struct soc_device_attribute *attr; > + struct arm_smccc_res res; > + struct soc_device *sdev; > + u32 soc_id, rev_major, rev_minor; > + u64 uid127_64, uid63_0; > + int err; > + > + attr = kzalloc(sizeof(*attr), GFP_KERNEL); > + if (!attr) > + return -ENOMEM; > + > + err = of_property_read_string(of_root, "model", &attr->machine); > + if (err) { > + pr_err("%s: missing model property: %d\n", __func__, err); > + goto attr; > + } > + > + attr->family = kasprintf(GFP_KERNEL, "Freescale i.MX"); > + > + /* > + * Retrieve the soc id, rev & uid info: > + * res.a1[31:16]: soc revision; > + * res.a1[15:0]: soc id; > + * res.a2: uid[127:64]; > + * res.a3: uid[63:0]; > + */ > + arm_smccc_smc(IMX_SIP_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res); > + if (res.a0 != SMCCC_RET_SUCCESS) { > + pr_err("%s: SMC failed: 0x%lx\n", __func__, res.a0); > + err = -EINVAL; > + goto family; > + } > + > + soc_id = SOC_ID(res.a1); > + rev_major = SOC_REV_MAJOR(res.a1); > + rev_minor = SOC_REV_MINOR(res.a1); > + > + attr->soc_id = kasprintf(GFP_KERNEL, "i.MX%2x", soc_id); > + attr->revision = kasprintf(GFP_KERNEL, "%d.%d", rev_major, rev_minor); > + > + uid127_64 = res.a2; > + uid63_0 = res.a3; > + attr->serial_number = kasprintf(GFP_KERNEL, "%016llx%016llx", uid127_64, uid63_0); > + > + sdev = soc_device_register(attr); > + if (IS_ERR(sdev)) { > + err = PTR_ERR(sdev); > + pr_err("%s failed to register SoC as a device: %d\n", __func__, err); > + goto serial_number; > + } > + > + return 0; > + > +serial_number: > + kfree(attr->serial_number); > + kfree(attr->revision); > + kfree(attr->soc_id); > +family: > + kfree(attr->family); > +attr: > + kfree(attr); > + return err; > +} > + > +static const struct of_device_id imx9_soc_match[] = { > + { .compatible = "fsl,imx93", }, > + { .compatible = "fsl,imx95", }, What happend to fsl,imx91 ? Best regards
Hi Stefan, > -----邮件原件----- > 发件人: Stefan Wahren <wahrenst@gmx.net> > 发送时间: 2024年10月30日 19:54 > 收件人: Alice Guo (OSS) <alice.guo@oss.nxp.com>; > alexander.stein@ew.tq-group.com; shawnguo@kernel.org; > s.hauer@pengutronix.de; kernel@pengutronix.de; festevam@gmail.com > 抄送: imx@lists.linux.dev; linux-arm-kernel@lists.infradead.org; > linux-kernel@vger.kernel.org; Alice Guo <alice.guo@nxp.com> > 主题: [EXT] Re: [PATCH v3] soc: imx: Add SoC device register for i.MX9 > > Caution: This is an external email. Please take care when clicking links or > opening attachments. When in doubt, report the message using the 'Report > this email' button > > > Hi Alice, > > Am 30.10.24 um 10:13 schrieb alice.guo@oss.nxp.com: > > From: "alice.guo" <alice.guo@nxp.com> > > > > i.MX9 SoCs have SoC ID, SoC revision number and chip unique identifier > > which are provided by the corresponding ARM trusted firmware API. This > > patch intends to use SMC call to obtain these information and then > > register i.MX9 SoC as a device. > > > > Signed-off-by: alice.guo <alice.guo@nxp.com> > > --- > > > > Changes for v2: > > - refine error log print > > Changes for v3: > > - return -EINVAL when arm_smccc_smc failed > > - fix the build warning caused by pr_err("%s: SMC failed: %d\n", __func__, > res.a0); > > - drop the pr_err in imx9_soc_init > > - free the memory in the reverse order of allocation > > - use of_match_node instead of of_machine_is_compatible > > > > drivers/soc/imx/Makefile | 2 +- > > drivers/soc/imx/soc-imx9.c | 106 > +++++++++++++++++++++++++++++++++++++ > > 2 files changed, 107 insertions(+), 1 deletion(-) > > create mode 100644 drivers/soc/imx/soc-imx9.c > > > > diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index > > 3ad321ca608a..ca6a5fa1618f 100644 > > --- a/drivers/soc/imx/Makefile > > +++ b/drivers/soc/imx/Makefile > > @@ -3,4 +3,4 @@ ifeq ($(CONFIG_ARM),y) > > obj-$(CONFIG_ARCH_MXC) += soc-imx.o > > endif > > obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o > > -obj-$(CONFIG_SOC_IMX9) += imx93-src.o > > +obj-$(CONFIG_SOC_IMX9) += imx93-src.o soc-imx9.o > > diff --git a/drivers/soc/imx/soc-imx9.c b/drivers/soc/imx/soc-imx9.c > > new file mode 100644 index 000000000000..823395584533 > > --- /dev/null > > +++ b/drivers/soc/imx/soc-imx9.c > > @@ -0,0 +1,106 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright 2024 NXP > > + */ > > + > > +#include <linux/arm-smccc.h> > > +#include <linux/init.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/slab.h> > > +#include <linux/sys_soc.h> > > + > > +#define IMX_SIP_GET_SOC_INFO 0xc2000006 > > +#define SOC_ID(x) (((x) & 0xFFFF) >> 8) > > +#define SOC_REV_MAJOR(x) ((((x) >> 28) & 0xF) - 0x9) > > +#define SOC_REV_MINOR(x) (((x) >> 24) & 0xF) > > + > > +static int imx9_soc_device_register(void) { > > + struct soc_device_attribute *attr; > > + struct arm_smccc_res res; > > + struct soc_device *sdev; > > + u32 soc_id, rev_major, rev_minor; > > + u64 uid127_64, uid63_0; > > + int err; > > + > > + attr = kzalloc(sizeof(*attr), GFP_KERNEL); > > + if (!attr) > > + return -ENOMEM; > > + > > + err = of_property_read_string(of_root, "model", &attr->machine); > > + if (err) { > > + pr_err("%s: missing model property: %d\n", __func__, err); > > + goto attr; > > + } > > + > > + attr->family = kasprintf(GFP_KERNEL, "Freescale i.MX"); > > + > > + /* > > + * Retrieve the soc id, rev & uid info: > > + * res.a1[31:16]: soc revision; > > + * res.a1[15:0]: soc id; > > + * res.a2: uid[127:64]; > > + * res.a3: uid[63:0]; > > + */ > > + arm_smccc_smc(IMX_SIP_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res); > > + if (res.a0 != SMCCC_RET_SUCCESS) { > > + pr_err("%s: SMC failed: 0x%lx\n", __func__, res.a0); > > + err = -EINVAL; > > + goto family; > > + } > > + > > + soc_id = SOC_ID(res.a1); > > + rev_major = SOC_REV_MAJOR(res.a1); > > + rev_minor = SOC_REV_MINOR(res.a1); > > + > > + attr->soc_id = kasprintf(GFP_KERNEL, "i.MX%2x", soc_id); > > + attr->revision = kasprintf(GFP_KERNEL, "%d.%d", rev_major, > > + rev_minor); > > + > > + uid127_64 = res.a2; > > + uid63_0 = res.a3; > > + attr->serial_number = kasprintf(GFP_KERNEL, "%016llx%016llx", > > + uid127_64, uid63_0); > > + > > + sdev = soc_device_register(attr); > > + if (IS_ERR(sdev)) { > > + err = PTR_ERR(sdev); > > + pr_err("%s failed to register SoC as a device: %d\n", __func__, > err); > > + goto serial_number; > > + } > > + > > + return 0; > > + > > +serial_number: > > + kfree(attr->serial_number); > > + kfree(attr->revision); > > + kfree(attr->soc_id); > > +family: > > + kfree(attr->family); > > +attr: > > + kfree(attr); > > + return err; > > +} > > + > > +static const struct of_device_id imx9_soc_match[] = { > > + { .compatible = "fsl,imx93", }, > > + { .compatible = "fsl,imx95", }, > What happend to fsl,imx91 ? I forgot to mention this change in change log. The code about i.MX91 will be public later. Best Regards, Alice Guo > Best regards
Am 30.10.24 um 10:13 schrieb alice.guo@oss.nxp.com: > From: "alice.guo" <alice.guo@nxp.com> > > i.MX9 SoCs have SoC ID, SoC revision number and chip unique identifier > which are provided by the corresponding ARM trusted firmware API. This > patch intends to use SMC call to obtain these information and then > register i.MX9 SoC as a device. > > Signed-off-by: alice.guo <alice.guo@nxp.com> Reviewed-by: Stefan Wahren <wahrenst@gmx.net>
Hi, kernel test robot noticed the following build warnings: [auto build test WARNING on shawnguo/for-next] [also build test WARNING on linus/master v6.12-rc5 next-20241030] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/alice-guo-oss-nxp-com/soc-imx-Add-SoC-device-register-for-i-MX9/20241030-171525 base: https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next patch link: https://lore.kernel.org/r/20241030091336.3901440-1-alice.guo%40oss.nxp.com patch subject: [PATCH v3] soc: imx: Add SoC device register for i.MX9 config: x86_64-buildonly-randconfig-002-20241030 (https://download.01.org/0day-ci/archive/20241031/202410310126.WFKQ7LtM-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241031/202410310126.WFKQ7LtM-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202410310126.WFKQ7LtM-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/soc/imx/soc-imx9.c:84:34: warning: 'imx9_soc_match' defined but not used [-Wunused-const-variable=] 84 | static const struct of_device_id imx9_soc_match[] = { | ^~~~~~~~~~~~~~ vim +/imx9_soc_match +84 drivers/soc/imx/soc-imx9.c 83 > 84 static const struct of_device_id imx9_soc_match[] = { 85 { .compatible = "fsl,imx93", }, 86 { .compatible = "fsl,imx95", }, 87 { } 88 }; 89
Hi, kernel test robot noticed the following build warnings: [auto build test WARNING on shawnguo/for-next] [also build test WARNING on linus/master v6.12-rc5 next-20241030] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/alice-guo-oss-nxp-com/soc-imx-Add-SoC-device-register-for-i-MX9/20241030-171525 base: https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next patch link: https://lore.kernel.org/r/20241030091336.3901440-1-alice.guo%40oss.nxp.com patch subject: [PATCH v3] soc: imx: Add SoC device register for i.MX9 config: hexagon-randconfig-001-20241031 (https://download.01.org/0day-ci/archive/20241031/202410311056.PBPPOYmg-lkp@intel.com/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241031/202410311056.PBPPOYmg-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202410311056.PBPPOYmg-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/soc/imx/soc-imx9.c:84:34: warning: unused variable 'imx9_soc_match' [-Wunused-const-variable] static const struct of_device_id imx9_soc_match[] = { ^ 1 warning generated. vim +/imx9_soc_match +84 drivers/soc/imx/soc-imx9.c 83 > 84 static const struct of_device_id imx9_soc_match[] = { 85 { .compatible = "fsl,imx93", }, 86 { .compatible = "fsl,imx95", }, 87 { } 88 }; 89
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index 3ad321ca608a..ca6a5fa1618f 100644 --- a/drivers/soc/imx/Makefile +++ b/drivers/soc/imx/Makefile @@ -3,4 +3,4 @@ ifeq ($(CONFIG_ARM),y) obj-$(CONFIG_ARCH_MXC) += soc-imx.o endif obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o -obj-$(CONFIG_SOC_IMX9) += imx93-src.o +obj-$(CONFIG_SOC_IMX9) += imx93-src.o soc-imx9.o diff --git a/drivers/soc/imx/soc-imx9.c b/drivers/soc/imx/soc-imx9.c new file mode 100644 index 000000000000..823395584533 --- /dev/null +++ b/drivers/soc/imx/soc-imx9.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2024 NXP + */ + +#include <linux/arm-smccc.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/slab.h> +#include <linux/sys_soc.h> + +#define IMX_SIP_GET_SOC_INFO 0xc2000006 +#define SOC_ID(x) (((x) & 0xFFFF) >> 8) +#define SOC_REV_MAJOR(x) ((((x) >> 28) & 0xF) - 0x9) +#define SOC_REV_MINOR(x) (((x) >> 24) & 0xF) + +static int imx9_soc_device_register(void) +{ + struct soc_device_attribute *attr; + struct arm_smccc_res res; + struct soc_device *sdev; + u32 soc_id, rev_major, rev_minor; + u64 uid127_64, uid63_0; + int err; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) + return -ENOMEM; + + err = of_property_read_string(of_root, "model", &attr->machine); + if (err) { + pr_err("%s: missing model property: %d\n", __func__, err); + goto attr; + } + + attr->family = kasprintf(GFP_KERNEL, "Freescale i.MX"); + + /* + * Retrieve the soc id, rev & uid info: + * res.a1[31:16]: soc revision; + * res.a1[15:0]: soc id; + * res.a2: uid[127:64]; + * res.a3: uid[63:0]; + */ + arm_smccc_smc(IMX_SIP_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res); + if (res.a0 != SMCCC_RET_SUCCESS) { + pr_err("%s: SMC failed: 0x%lx\n", __func__, res.a0); + err = -EINVAL; + goto family; + } + + soc_id = SOC_ID(res.a1); + rev_major = SOC_REV_MAJOR(res.a1); + rev_minor = SOC_REV_MINOR(res.a1); + + attr->soc_id = kasprintf(GFP_KERNEL, "i.MX%2x", soc_id); + attr->revision = kasprintf(GFP_KERNEL, "%d.%d", rev_major, rev_minor); + + uid127_64 = res.a2; + uid63_0 = res.a3; + attr->serial_number = kasprintf(GFP_KERNEL, "%016llx%016llx", uid127_64, uid63_0); + + sdev = soc_device_register(attr); + if (IS_ERR(sdev)) { + err = PTR_ERR(sdev); + pr_err("%s failed to register SoC as a device: %d\n", __func__, err); + goto serial_number; + } + + return 0; + +serial_number: + kfree(attr->serial_number); + kfree(attr->revision); + kfree(attr->soc_id); +family: + kfree(attr->family); +attr: + kfree(attr); + return err; +} + +static const struct of_device_id imx9_soc_match[] = { + { .compatible = "fsl,imx93", }, + { .compatible = "fsl,imx95", }, + { } +}; + +static int __init imx9_soc_init(void) +{ + int ret; + + /* No match means it is not an i.MX 9 series SoC, do nothing. */ + if (!of_match_node(imx9_soc_match, of_root)) + return 0; + + ret = imx9_soc_device_register(); + + return ret; +} +device_initcall(imx9_soc_init); + +MODULE_AUTHOR("NXP"); +MODULE_DESCRIPTION("NXP i.MX9 SoC"); +MODULE_LICENSE("GPL");