diff mbox series

[v3,2/3] soc: mediatek: mtk-socinfo: Add driver for getting chip information

Message ID 20231220103901.22180-3-william-tw.lin@mediatek.com (mailing list archive)
State New
Delegated to: Matthias Brugger
Headers show
Series mtk-socinfo driver implementation | expand

Commit Message

William-tw Lin (林鼎崴) Dec. 20, 2023, 10:39 a.m. UTC
Add driver for socinfo retrieval. This patch includes the following:
1. mtk-socinfo driver for chip info retrieval
2. Related changes to Makefile and Kconfig

Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
---
 drivers/soc/mediatek/Kconfig       |   8 ++
 drivers/soc/mediatek/Makefile      |   1 +
 drivers/soc/mediatek/mtk-socinfo.c | 186 +++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-socinfo.c

Comments

AngeloGioacchino Del Regno Dec. 20, 2023, 10:53 a.m. UTC | #1
Il 20/12/23 11:39, William-tw Lin ha scritto:
> Add driver for socinfo retrieval. This patch includes the following:
> 1. mtk-socinfo driver for chip info retrieval
> 2. Related changes to Makefile and Kconfig
> 
> Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
> ---
>   drivers/soc/mediatek/Kconfig       |   8 ++
>   drivers/soc/mediatek/Makefile      |   1 +
>   drivers/soc/mediatek/mtk-socinfo.c | 186 +++++++++++++++++++++++++++++
>   3 files changed, 195 insertions(+)
>   create mode 100644 drivers/soc/mediatek/mtk-socinfo.c
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0810b5b0c688..f34d93977ba6 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -68,4 +68,12 @@ config MTK_SVS
>   	  chip process corner, temperatures and other factors. Then DVFS
>   	  driver could apply SVS bank voltage to PMIC/Buck.
>   
> +config MTK_SOCINFO
> +	tristate "MediaTek SoC Information"
> +	default y

Add the dependency please.

	depends on NVMEM_MTK_EFUSE

> +	help
> +	  The MediaTek SoC Information (mtk-socinfo) driver provides
> +	  information about the SoC to the userspace including the
> +	  manufacturer name, marketing name and soc name.
> +
>   endmenu
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 9d3ce7878c5c..6830512848fd 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_REGULATOR_COUPLER) += mtk-regulator-coupler.o
>   obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
>   obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
>   obj-$(CONFIG_MTK_SVS) += mtk-svs.o
> +obj-$(CONFIG_MTK_SOCINFO) += mtk-socinfo.o
> diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c
> new file mode 100644
> index 000000000000..4a257b5c8eda
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-socinfo.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/device.h>
> +#include <linux/debugfs.h>
> +#include <linux/seq_file.h>
> +#include <linux/string.h>
> +#include <linux/sys_soc.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +
> +#define MTK_SOCINFO_ENTRY(_soc_name, _segment_name, _marketing_name, _cell_data1, _cell_data2) {\
> +	.soc_name = _soc_name,									\
> +	.segment_name = _segment_name,								\
> +	.marketing_name = _marketing_name,							\
> +	.cell_data = {_cell_data1, _cell_data2}							\
> +}
> +#define CELL_NOT_USED (0xFFFFFFFF)
> +#define MAX_CELLS (2)
> +
> +struct mtk_socinfo {
> +	struct device *dev;
> +	struct name_data *name_data;
> +	struct socinfo_data *socinfo_data;
> +	struct soc_device *soc_dev;
> +};
> +
> +struct socinfo_data {
> +	char *soc_name;
> +	char *segment_name;
> +	char *marketing_name;
> +	u32 cell_data[MAX_CELLS];
> +};
> +
> +static const char *cell_names[MAX_CELLS] = {"socinfo-data1", "socinfo-data2"};
> +
> +static struct socinfo_data socinfo_data_table[] = {
> +	MTK_SOCINFO_ENTRY("MT8173", "MT8173V/AC", "MT8173", 0x6CA20004, 0x10000000),
> +	MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000840),
> +	MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520", 0x81861001, CELL_NOT_USED),
> +	MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED),
> +	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830", 0x81880000, 0x00000010),
> +	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830", 0x81880000, 0x00000011),
> +	MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080),
> +	MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0),
> +	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED),
> +	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED),
> +	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED),
> +	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED),
> +};
> +
> +static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop)
> +{
> +	struct soc_device_attribute *attrs;
> +	static char machine[30] = {0};
> +	static const char *soc_manufacturer = "MediaTek";
> +
> +	attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs), GFP_KERNEL);
> +	if (!attrs)
> +		return -ENOMEM;
> +
> +	snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop->socinfo_data->marketing_name,
> +		mtk_socinfop->socinfo_data->soc_name);
> +	attrs->family = soc_manufacturer;
> +	attrs->machine = machine;
> +
> +	mtk_socinfop->soc_dev = soc_device_register(attrs);
> +	if (IS_ERR(mtk_socinfop->soc_dev))
> +		return PTR_ERR(mtk_socinfop->soc_dev);
> +
> +	dev_info(mtk_socinfop->dev, "%s %s SoC detected.\n", soc_manufacturer, attrs->machine);
> +	return 0;
> +}
> +
> +static u32 mtk_socinfo_read_cell(struct device *dev, const char *name)
> +{
> +	struct nvmem_device *nvmemp;
> +	struct device_node *np = dev->of_node;
> +	u32 offset;
> +	u32 cell_val = CELL_NOT_USED;
> +
> +	nvmemp = devm_nvmem_device_get(dev, "mtk-efuse0");

Are you sure that this is supposed to be "mtk-efuse0" and not "mtk-efuse"?
Looks strange.

Everything else looks ok.

Cheers,
Angelo
Krzysztof Kozlowski Dec. 20, 2023, 11:34 a.m. UTC | #2
On 20/12/2023 11:39, William-tw Lin wrote:
> Add driver for socinfo retrieval. This patch includes the following:
> 1. mtk-socinfo driver for chip info retrieval
> 2. Related changes to Makefile and Kconfig
> 
> Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>

...

> +static struct platform_driver mtk_socinfo = {
> +	.probe = mtk_socinfo_probe,
> +	.remove_new = mtk_socinfo_remove,
> +	.driver = {
> +		.name = "mtk-socinfo",
> +	},
> +};
> +builtin_platform_driver(mtk_socinfo);

module platform driver, because this is tristate and because this should
be a module.

Best regards,
Krzysztof
AngeloGioacchino Del Regno Dec. 20, 2023, 1:13 p.m. UTC | #3
Il 20/12/23 12:34, Krzysztof Kozlowski ha scritto:
> On 20/12/2023 11:39, William-tw Lin wrote:
>> Add driver for socinfo retrieval. This patch includes the following:
>> 1. mtk-socinfo driver for chip info retrieval
>> 2. Related changes to Makefile and Kconfig
>>
>> Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
> 
> ...
> 
>> +static struct platform_driver mtk_socinfo = {
>> +	.probe = mtk_socinfo_probe,
>> +	.remove_new = mtk_socinfo_remove,
>> +	.driver = {
>> +		.name = "mtk-socinfo",
>> +	},
>> +};
>> +builtin_platform_driver(mtk_socinfo);
> 
> module platform driver, because this is tristate and because this should
> be a module.
> 

Oh! Yes, right! Thanks for catching that, it totally slipped off my brain.

Cheers,
Angelo
William-tw Lin (林鼎崴) Dec. 22, 2023, 8:03 a.m. UTC | #4
Hi Krzysztof,

Thank you for the comments. The fix regarding module_platform_driver
will be provided in the next version of patches. Thanks a lot!

Best regards,
William
On Wed, 2023-12-20 at 12:34 +0100, Krzysztof Kozlowski wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On 20/12/2023 11:39, William-tw Lin wrote:
> > Add driver for socinfo retrieval. This patch includes the
> following:
> > 1. mtk-socinfo driver for chip info retrieval
> > 2. Related changes to Makefile and Kconfig
> > 
> > Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
> 
> ...
> 
> > +static struct platform_driver mtk_socinfo = {
> > +.probe = mtk_socinfo_probe,
> > +.remove_new = mtk_socinfo_remove,
> > +.driver = {
> > +.name = "mtk-socinfo",
> > +},
> > +};
> > +builtin_platform_driver(mtk_socinfo);
> 
> module platform driver, because this is tristate and because this
> should
> be a module.
> 
> Best regards,
> Krzysztof
William-tw Lin (林鼎崴) Dec. 22, 2023, 8:03 a.m. UTC | #5
On Wed, 2023-12-20 at 11:53 +0100, AngeloGioacchino Del Regno wrote:
> Il 20/12/23 11:39, William-tw Lin ha scritto:
> > Add driver for socinfo retrieval. This patch includes the
> > following:
> > 1. mtk-socinfo driver for chip info retrieval
> > 2. Related changes to Makefile and Kconfig
> > 
> > Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
> > ---
> >   drivers/soc/mediatek/Kconfig       |   8 ++
> >   drivers/soc/mediatek/Makefile      |   1 +
> >   drivers/soc/mediatek/mtk-socinfo.c | 186
> > +++++++++++++++++++++++++++++
> >   3 files changed, 195 insertions(+)
> >   create mode 100644 drivers/soc/mediatek/mtk-socinfo.c
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig
> > b/drivers/soc/mediatek/Kconfig
> > index 0810b5b0c688..f34d93977ba6 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -68,4 +68,12 @@ config MTK_SVS
> >   	  chip process corner, temperatures and other factors. Then
> > DVFS
> >   	  driver could apply SVS bank voltage to PMIC/Buck.
> >   
> > +config MTK_SOCINFO
> > +	tristate "MediaTek SoC Information"
> > +	default y
> 
> Add the dependency please.
> 
> 	depends on NVMEM_MTK_EFUSE
> 
> > +	help
> > +	  The MediaTek SoC Information (mtk-socinfo) driver provides
> > +	  information about the SoC to the userspace including the
> > +	  manufacturer name, marketing name and soc name.
> > +
> >   endmenu
> > diff --git a/drivers/soc/mediatek/Makefile
> > b/drivers/soc/mediatek/Makefile
> > index 9d3ce7878c5c..6830512848fd 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_REGULATOR_COUPLER) += mtk-
> > regulator-coupler.o
> >   obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
> >   obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
> >   obj-$(CONFIG_MTK_SVS) += mtk-svs.o
> > +obj-$(CONFIG_MTK_SOCINFO) += mtk-socinfo.o
> > diff --git a/drivers/soc/mediatek/mtk-socinfo.c
> > b/drivers/soc/mediatek/mtk-socinfo.c
> > new file mode 100644
> > index 000000000000..4a257b5c8eda
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-socinfo.c
> > @@ -0,0 +1,186 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2023 MediaTek Inc.
> > + */
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/nvmem-consumer.h>
> > +#include <linux/device.h>
> > +#include <linux/debugfs.h>
> > +#include <linux/seq_file.h>
> > +#include <linux/string.h>
> > +#include <linux/sys_soc.h>
> > +#include <linux/slab.h>
> > +#include <linux/platform_device.h>
> > +
> > +#define MTK_SOCINFO_ENTRY(_soc_name, _segment_name,
> > _marketing_name, _cell_data1, _cell_data2) {\
> > +	.soc_name = _soc_name,						
> > 			\
> > +	.segment_name = _segment_name,					
> > 			\
> > +	.marketing_name = _marketing_name,					
> > 		\
> > +	.cell_data = {_cell_data1, _cell_data2}				
> > 			\
> > +}
> > +#define CELL_NOT_USED (0xFFFFFFFF)
> > +#define MAX_CELLS (2)
> > +
> > +struct mtk_socinfo {
> > +	struct device *dev;
> > +	struct name_data *name_data;
> > +	struct socinfo_data *socinfo_data;
> > +	struct soc_device *soc_dev;
> > +};
> > +
> > +struct socinfo_data {
> > +	char *soc_name;
> > +	char *segment_name;
> > +	char *marketing_name;
> > +	u32 cell_data[MAX_CELLS];
> > +};
> > +
> > +static const char *cell_names[MAX_CELLS] = {"socinfo-data1",
> > "socinfo-data2"};
> > +
> > +static struct socinfo_data socinfo_data_table[] = {
> > +	MTK_SOCINFO_ENTRY("MT8173", "MT8173V/AC", "MT8173", 0x6CA20004,
> > 0x10000000),
> > +	MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500",
> > 0x00010043, 0x00000840),
> > +	MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520",
> > 0x81861001, CELL_NOT_USED),
> > +	MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528",
> > 0x81862001, CELL_NOT_USED),
> > +	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830",
> > 0x81880000, 0x00000010),
> > +	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830",
> > 0x81880000, 0x00000011),
> > +	MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820",
> > 0x00001100, 0x00040080),
> > +	MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828",
> > 0x00000100, 0x000400C0),
> > +	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200",
> > 0x81950300, CELL_NOT_USED),
> > +	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200",
> > 0x81950304, CELL_NOT_USED),
> > +	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380",
> > 0x81950400, CELL_NOT_USED),
> > +	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380",
> > 0x81950404, CELL_NOT_USED),
> > +};
> > +
> > +static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo
> > *mtk_socinfop)
> > +{
> > +	struct soc_device_attribute *attrs;
> > +	static char machine[30] = {0};
> > +	static const char *soc_manufacturer = "MediaTek";
> > +
> > +	attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs),
> > GFP_KERNEL);
> > +	if (!attrs)
> > +		return -ENOMEM;
> > +
> > +	snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop-
> > >socinfo_data->marketing_name,
> > +		mtk_socinfop->socinfo_data->soc_name);
> > +	attrs->family = soc_manufacturer;
> > +	attrs->machine = machine;
> > +
> > +	mtk_socinfop->soc_dev = soc_device_register(attrs);
> > +	if (IS_ERR(mtk_socinfop->soc_dev))
> > +		return PTR_ERR(mtk_socinfop->soc_dev);
> > +
> > +	dev_info(mtk_socinfop->dev, "%s %s SoC detected.\n",
> > soc_manufacturer, attrs->machine);
> > +	return 0;
> > +}
> > +
> > +static u32 mtk_socinfo_read_cell(struct device *dev, const char
> > *name)
> > +{
> > +	struct nvmem_device *nvmemp;
> > +	struct device_node *np = dev->of_node;
> > +	u32 offset;
> > +	u32 cell_val = CELL_NOT_USED;
> > +
> > +	nvmemp = devm_nvmem_device_get(dev, "mtk-efuse0");
> 
> Are you sure that this is supposed to be "mtk-efuse0" and not "mtk-
> efuse"?
> Looks strange.
> 
> Everything else looks ok.
> 
> Cheers,
> Angelo
> 
> 
Hi Angelo,

Thank you for the comments! I can confirm that the node for mtk-efuse
is "mtk-efuse0" since nvmem_regsiter() automatically appends an id to
the name. The changes for the other comments will be addressed in the
next version of patches. Thank you so much!

Best regards,
William
diff mbox series

Patch

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0810b5b0c688..f34d93977ba6 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -68,4 +68,12 @@  config MTK_SVS
 	  chip process corner, temperatures and other factors. Then DVFS
 	  driver could apply SVS bank voltage to PMIC/Buck.
 
+config MTK_SOCINFO
+	tristate "MediaTek SoC Information"
+	default y
+	help
+	  The MediaTek SoC Information (mtk-socinfo) driver provides
+	  information about the SoC to the userspace including the
+	  manufacturer name, marketing name and soc name.
+
 endmenu
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 9d3ce7878c5c..6830512848fd 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -7,3 +7,4 @@  obj-$(CONFIG_MTK_REGULATOR_COUPLER) += mtk-regulator-coupler.o
 obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
 obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
 obj-$(CONFIG_MTK_SVS) += mtk-svs.o
+obj-$(CONFIG_MTK_SOCINFO) += mtk-socinfo.o
diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c
new file mode 100644
index 000000000000..4a257b5c8eda
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-socinfo.c
@@ -0,0 +1,186 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+#include <linux/sys_soc.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#define MTK_SOCINFO_ENTRY(_soc_name, _segment_name, _marketing_name, _cell_data1, _cell_data2) {\
+	.soc_name = _soc_name,									\
+	.segment_name = _segment_name,								\
+	.marketing_name = _marketing_name,							\
+	.cell_data = {_cell_data1, _cell_data2}							\
+}
+#define CELL_NOT_USED (0xFFFFFFFF)
+#define MAX_CELLS (2)
+
+struct mtk_socinfo {
+	struct device *dev;
+	struct name_data *name_data;
+	struct socinfo_data *socinfo_data;
+	struct soc_device *soc_dev;
+};
+
+struct socinfo_data {
+	char *soc_name;
+	char *segment_name;
+	char *marketing_name;
+	u32 cell_data[MAX_CELLS];
+};
+
+static const char *cell_names[MAX_CELLS] = {"socinfo-data1", "socinfo-data2"};
+
+static struct socinfo_data socinfo_data_table[] = {
+	MTK_SOCINFO_ENTRY("MT8173", "MT8173V/AC", "MT8173", 0x6CA20004, 0x10000000),
+	MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000840),
+	MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520", 0x81861001, CELL_NOT_USED),
+	MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED),
+	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830", 0x81880000, 0x00000010),
+	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830", 0x81880000, 0x00000011),
+	MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080),
+	MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0),
+	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED),
+	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED),
+	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED),
+	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED),
+};
+
+static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop)
+{
+	struct soc_device_attribute *attrs;
+	static char machine[30] = {0};
+	static const char *soc_manufacturer = "MediaTek";
+
+	attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs), GFP_KERNEL);
+	if (!attrs)
+		return -ENOMEM;
+
+	snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop->socinfo_data->marketing_name,
+		mtk_socinfop->socinfo_data->soc_name);
+	attrs->family = soc_manufacturer;
+	attrs->machine = machine;
+
+	mtk_socinfop->soc_dev = soc_device_register(attrs);
+	if (IS_ERR(mtk_socinfop->soc_dev))
+		return PTR_ERR(mtk_socinfop->soc_dev);
+
+	dev_info(mtk_socinfop->dev, "%s %s SoC detected.\n", soc_manufacturer, attrs->machine);
+	return 0;
+}
+
+static u32 mtk_socinfo_read_cell(struct device *dev, const char *name)
+{
+	struct nvmem_device *nvmemp;
+	struct device_node *np = dev->of_node;
+	u32 offset;
+	u32 cell_val = CELL_NOT_USED;
+
+	nvmemp = devm_nvmem_device_get(dev, "mtk-efuse0");
+	if (IS_ERR(nvmemp))
+		goto out;
+
+	np = of_find_node_by_name(NULL, name);
+	if (!np)
+		goto out;
+
+	if (of_property_read_u32_index(np, "reg", 0, &offset))
+		goto out;
+
+	nvmem_device_read(nvmemp, offset, sizeof(cell_val), &cell_val);
+
+	nvmem_device_put(nvmemp);
+
+out:
+	return cell_val;
+}
+
+static int mtk_socinfo_get_socinfo_data(struct mtk_socinfo *mtk_socinfop)
+{
+	unsigned int i, j;
+	unsigned int num_cell_data = 0;
+	u32 cell_data[MAX_CELLS] = {0};
+	bool match_socinfo;
+	int match_socinfo_index = -1;
+
+	for (i = 0; i < MAX_CELLS; i++) {
+		cell_data[i] = mtk_socinfo_read_cell(mtk_socinfop->dev, cell_names[i]);
+		if (cell_data[i] != CELL_NOT_USED)
+			num_cell_data++;
+		else
+			break;
+	}
+
+	if (!num_cell_data)
+		return -ENOENT;
+
+	for (i = 0; i < ARRAY_SIZE(socinfo_data_table); i++) {
+		match_socinfo = true;
+		for (j = 0; j < num_cell_data; j++) {
+			if (cell_data[j] != socinfo_data_table[i].cell_data[j]) {
+				match_socinfo = false;
+				break;
+			}
+		}
+		if (match_socinfo) {
+			mtk_socinfop->socinfo_data = &(socinfo_data_table[i]);
+			match_socinfo_index = i;
+			break;
+		}
+	}
+
+	return match_socinfo_index >= 0 ? match_socinfo_index : -ENOENT;
+}
+
+static int mtk_socinfo_probe(struct platform_device *pdev)
+{
+	struct mtk_socinfo *mtk_socinfop;
+	int ret;
+
+	mtk_socinfop = devm_kzalloc(&pdev->dev, sizeof(*mtk_socinfop), GFP_KERNEL);
+	if (!mtk_socinfop)
+		return -ENOMEM;
+
+	mtk_socinfop->dev = &pdev->dev;
+
+	ret = mtk_socinfo_get_socinfo_data(mtk_socinfop);
+	if (ret < 0)
+		return dev_err_probe(mtk_socinfop->dev, ret, "Failed to get socinfo data\n");
+
+	ret = mtk_socinfo_create_socinfo_node(mtk_socinfop);
+	if (ret)
+		return dev_err_probe(mtk_socinfop->dev, ret, "Cannot create node\n");
+
+	platform_set_drvdata(pdev, mtk_socinfop);
+	return 0;
+}
+
+static void mtk_socinfo_remove(struct platform_device *pdev)
+{
+	struct mtk_socinfo *mtk_socinfop = platform_get_drvdata(pdev);
+
+	soc_device_unregister(mtk_socinfop->soc_dev);
+}
+
+static struct platform_driver mtk_socinfo = {
+	.probe = mtk_socinfo_probe,
+	.remove_new = mtk_socinfo_remove,
+	.driver = {
+		.name = "mtk-socinfo",
+	},
+};
+builtin_platform_driver(mtk_socinfo);
+
+MODULE_AUTHOR("William-TW LIN <william-tw.lin@mediatek.com>");
+MODULE_DESCRIPTION("MediaTek socinfo driver");
+MODULE_LICENSE("GPL");