platform-driver-x86.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH platform-next v8 0/7] Add support for new systems, amendments
@ 2025-04-12  9:18 Vadim Pasternak
  2025-04-12  9:18 ` [PATCH platform-next v8 1/7] platform/mellanox: Rename field to improve code readability Vadim Pasternak
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Patches #1; #4: Add cosmetic changes - removing spaces, style.
Patches #2; #3; #5; #6 : Introduce systems: new SN428 smart switch
	equipped with DPU for offloading, new 2U systems SN5610 and SN5640,
	new compact system SN2200 OCP rack complained.
Patch #7 - Adds documentation.

Vadim Pasternak (7):
  platform/mellanox: Rename field to improve code readability
  platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU
  platform: mellanox: Introduce support of Nvidia smart switch
  platform: mellanox: Cosmetic changes to improve code style
  platform: mellanox: mlx-platform: Add support for new Nvidia system
  platform: mellanox: nvsw-sn2200: Add support for new system flavour
  Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces

 .../ABI/stable/sysfs-driver-mlxreg-io         |   96 +
 drivers/platform/mellanox/Kconfig             |   12 +
 drivers/platform/mellanox/Makefile            |    1 +
 drivers/platform/mellanox/mlx-platform.c      | 3640 ++++++++++++-----
 drivers/platform/mellanox/mlxreg-dpu.c        |  619 +++
 drivers/platform/mellanox/mlxreg-hotplug.c    |    8 +-
 drivers/platform/mellanox/nvsw-sn2201.c       |  112 +-
 include/linux/platform_data/mlxreg.h          |    4 +-
 8 files changed, 3418 insertions(+), 1074 deletions(-)
 create mode 100644 drivers/platform/mellanox/mlxreg-dpu.c

-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 1/7] platform/mellanox: Rename field to improve code readability
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-12  9:18 ` [PATCH platform-next v8 2/7] platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU Vadim Pasternak
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Rename field 'counter' in 'mlxreg_core_hotplug_platform_data' to count.

Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
v5->v6
- Fix commit text.
  Only structure 'mlxreg_core_hotplug_platform_data' was modified.
  Field 'counter' in structure 'mlxreg_core_platform_data' is not
  renamed, since this change will affect other drivers in different
  subsystems and it will complicate submission.
v4->v5
Comments pointed out by Ilpo:
- Fix misspelling in submit text.
- Fix structures names to 'count'.
---
 drivers/platform/mellanox/mlx-platform.c   | 26 +++++++++++-----------
 drivers/platform/mellanox/mlxreg-hotplug.c |  8 +++----
 drivers/platform/mellanox/nvsw-sn2201.c    |  2 +-
 include/linux/platform_data/mlxreg.h       |  4 ++--
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
index bd3bb06ff8f2..2334b740267c 100644
--- a/drivers/platform/mellanox/mlx-platform.c
+++ b/drivers/platform/mellanox/mlx-platform.c
@@ -852,7 +852,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_comex_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
 	.items = mlxplat_mlxcpld_default_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -892,7 +892,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_wc_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_wc_data = {
 	.items = mlxplat_mlxcpld_default_wc_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_wc_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_default_wc_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -902,7 +902,7 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_wc_data = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_comex_data = {
 	.items = mlxplat_mlxcpld_comex_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_comex_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_comex_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_CARR_DEF,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET,
@@ -949,7 +949,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
 	.items = mlxplat_mlxcpld_msn21xx_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -1058,7 +1058,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = {
 	.items = mlxplat_mlxcpld_msn274x_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -1105,7 +1105,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
 	.items = mlxplat_mlxcpld_msn201x_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -1229,7 +1229,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
 	.items = mlxplat_mlxcpld_default_ng_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -1389,7 +1389,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_ng800_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = {
 	.items = mlxplat_mlxcpld_ext_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_ext_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -1399,7 +1399,7 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ng800_data = {
 	.items = mlxplat_mlxcpld_ng800_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_ng800_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_ng800_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -2240,7 +2240,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_modular_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_modular_data = {
 	.items = mlxplat_mlxcpld_modular_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_modular_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_modular_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_MODULAR,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -2272,7 +2272,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_chassis_blade_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_chassis_blade_data = {
 	.items = mlxplat_mlxcpld_chassis_blade_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_chassis_blade_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_chassis_blade_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_COMEX,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -2363,7 +2363,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_rack_switch_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_rack_switch_data = {
 	.items = mlxplat_mlxcpld_rack_switch_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_rack_switch_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_rack_switch_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
@@ -2518,7 +2518,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_l1_switch_events_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_l1_switch_data = {
 	.items = mlxplat_mlxcpld_l1_switch_events_items,
-	.counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_events_items),
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_events_items),
 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
index 0ce9fff1f7d4..550378c2881a 100644
--- a/drivers/platform/mellanox/mlxreg-hotplug.c
+++ b/drivers/platform/mellanox/mlxreg-hotplug.c
@@ -262,7 +262,7 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
 	item = pdata->items;
 
 	/* Go over all kinds of items - psu, pwr, fan. */
-	for (i = 0; i < pdata->counter; i++, item++) {
+	for (i = 0; i < pdata->count; i++, item++) {
 		if (item->capability) {
 			/*
 			 * Read group capability register to get actual number
@@ -541,7 +541,7 @@ static void mlxreg_hotplug_work_handler(struct work_struct *work)
 		goto unmask_event;
 
 	/* Handle topology and health configuration changes. */
-	for (i = 0; i < pdata->counter; i++, item++) {
+	for (i = 0; i < pdata->count; i++, item++) {
 		if (aggr_asserted & item->aggr_mask) {
 			if (item->health)
 				mlxreg_hotplug_health_work_helper(priv, item);
@@ -590,7 +590,7 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
 	pdata = dev_get_platdata(&priv->pdev->dev);
 	item = pdata->items;
 
-	for (i = 0; i < pdata->counter; i++, item++) {
+	for (i = 0; i < pdata->count; i++, item++) {
 		/* Clear group presense event. */
 		ret = regmap_write(priv->regmap, item->reg +
 				   MLXREG_HOTPLUG_EVENT_OFF, 0);
@@ -674,7 +674,7 @@ static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv)
 		     0);
 
 	/* Clear topology configurations. */
-	for (i = 0; i < pdata->counter; i++, item++) {
+	for (i = 0; i < pdata->count; i++, item++) {
 		data = item->data;
 		/* Mask group presense event. */
 		regmap_write(priv->regmap, data->reg + MLXREG_HOTPLUG_MASK_OFF,
diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c
index abe7be602f84..451d64c35c23 100644
--- a/drivers/platform/mellanox/nvsw-sn2201.c
+++ b/drivers/platform/mellanox/nvsw-sn2201.c
@@ -517,7 +517,7 @@ static struct mlxreg_core_item nvsw_sn2201_items[] = {
 static
 struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = {
 	.items = nvsw_sn2201_items,
-	.counter = ARRAY_SIZE(nvsw_sn2201_items),
+	.count = ARRAY_SIZE(nvsw_sn2201_items),
 	.cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET,
 	.mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF,
 };
diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h
index 0b9f81a6f753..f6cca7a035c7 100644
--- a/include/linux/platform_data/mlxreg.h
+++ b/include/linux/platform_data/mlxreg.h
@@ -209,7 +209,7 @@ struct mlxreg_core_platform_data {
  * @items: same type components with the hotplug capability;
  * @irq: platform interrupt number;
  * @regmap: register map of parent device;
- * @counter: number of the components with the hotplug capability;
+ * @count: number of the components with the hotplug capability;
  * @cell: location of top aggregation interrupt register;
  * @mask: top aggregation interrupt common mask;
  * @cell_low: location of low aggregation interrupt register;
@@ -224,7 +224,7 @@ struct mlxreg_core_hotplug_platform_data {
 	struct mlxreg_core_item *items;
 	int irq;
 	void *regmap;
-	int counter;
+	int count;
 	u32 cell;
 	u32 mask;
 	u32 cell_low;
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 2/7] platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
  2025-04-12  9:18 ` [PATCH platform-next v8 1/7] platform/mellanox: Rename field to improve code readability Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-15 14:32   ` Ilpo Järvinen
  2025-04-12  9:18 ` [PATCH platform-next v8 3/7] platform: mellanox: Introduce support of Nvidia smart switch Vadim Pasternak
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Provide platform support for Nvidia (DPU) Data Processor Unit for the
Smart Switch SN4280.

The Smart Switch equipped with:
- Nvidia COME module based on AMD EPYC™ Embedded 3451 CPU.
- Nvidia Spectrum-3 ASIC.
- Four DPUs, each equipped with Nvidia BF3 ARM based processor and
  with Lattice LFD2NX-40 FPGA device.
- 28xQSFP-DD external ports.
- Two power supplies.
- Four cooling drawers.

Drivers provides support for the platform management and monitoring
of DPU components.
It includes support for health events, resets and boot progress
indications logic, implemented by FPGA device.

Reviewed-by: Ciju Rajan K <crajank@nvidia.com>
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
v6->v7
Changes added by Vadim:
- Fix few registers setting.
v5->v6
Comments pointed out by Ilpo:
- Fix structure title to conform to kerneldoc formatting.
- Remove unnecessary comments.
v4->v5
Comments pointed out by Ilpo:
- Add empty line in mlxreg_dpu_config_init().
- Include 'dev_printk.h' from dev_err().
- Remove unnecessary comments from mlxreg_dpu_config_exit().
- Put defer probing test in mlxreg_dpu_probe() before allocation.
- Remove unnecessary comments from mlxreg_dpu_probe().

v3->v4
Comments pointed out by Ilpo:
- Fix method of duplication data.
- Rename 'count' to 'item_count'.

v2->v3
Comments pointed out by Ilpo:
- Fix s/pltaform/platform.
- Remove semicolon from structure description.
- In routine mlxreg_dpu_copy_hotplug_data() use 'const struct' for the
  third argument.
- In mlxreg_dpu_copy_hotplug_data() remove redunadant devm_kmemdup()
  call.
- Fix identifications in mlxreg_dpu_config_init().
- Remove label 'fail_register_io" from error flow.
- One line for devm_regmap_init_i2c() call in mlxreg_dpu_probe().
---
 drivers/platform/mellanox/Kconfig      |  12 +
 drivers/platform/mellanox/Makefile     |   1 +
 drivers/platform/mellanox/mlxreg-dpu.c | 619 +++++++++++++++++++++++++
 3 files changed, 632 insertions(+)
 create mode 100644 drivers/platform/mellanox/mlxreg-dpu.c

diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig
index aa760f064a17..7da0fc46b1e7 100644
--- a/drivers/platform/mellanox/Kconfig
+++ b/drivers/platform/mellanox/Kconfig
@@ -27,6 +27,18 @@ config MLX_PLATFORM
 
 	  If you have a Mellanox system, say Y or M here.
 
+config MLXREG_DPU
+	tristate "Nvidia Data Processor Unit platform driver support"
+	select REGMAP_I2C
+	help
+	  This driver provides support for the Nvidia BF3 Data Processor Units,
+	  which are the part of SN4280 Ethernet smart switch systems
+	  providing a high performance switching solution for Enterprise Data
+	  Centers (EDC) for building Ethernet based clusters, High-Performance
+	  Computing (HPC) and embedded environments.
+
+	  If you have a Nvidia smart swicth system, say Y or M here.
+
 config MLXREG_HOTPLUG
 	tristate "Mellanox platform hotplug driver support"
 	depends on HWMON
diff --git a/drivers/platform/mellanox/Makefile b/drivers/platform/mellanox/Makefile
index ba56485cbe8c..e86723b44c2e 100644
--- a/drivers/platform/mellanox/Makefile
+++ b/drivers/platform/mellanox/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MLX_PLATFORM)	+= mlx-platform.o
 obj-$(CONFIG_MLXBF_BOOTCTL)	+= mlxbf-bootctl.o
 obj-$(CONFIG_MLXBF_PMC)		+= mlxbf-pmc.o
 obj-$(CONFIG_MLXBF_TMFIFO)	+= mlxbf-tmfifo.o
+obj-$(CONFIG_MLXREG_DPU)	+= mlxreg-dpu.o
 obj-$(CONFIG_MLXREG_HOTPLUG)	+= mlxreg-hotplug.o
 obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
 obj-$(CONFIG_MLXREG_LC) += mlxreg-lc.o
diff --git a/drivers/platform/mellanox/mlxreg-dpu.c b/drivers/platform/mellanox/mlxreg-dpu.c
new file mode 100644
index 000000000000..5245b7a14af3
--- /dev/null
+++ b/drivers/platform/mellanox/mlxreg-dpu.c
@@ -0,0 +1,619 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Nvidia Data Processor Unit platform driver
+ *
+ * Copyright (C) 2025 Nvidia Technologies Ltd.
+ */
+
+#include <linux/device.h>
+#include <linux/dev_printk.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/platform_data/mlxcpld.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/* I2C bus IO offsets */
+#define MLXREG_DPU_REG_FPGA1_VER_OFFSET			0x2400
+#define MLXREG_DPU_REG_FPGA1_PN_OFFSET			0x2404
+#define MLXREG_DPU_REG_FPGA1_PN1_OFFSET			0x2405
+#define MLXREG_DPU_REG_PG_OFFSET			0x2414
+#define MLXREG_DPU_REG_PG_EVENT_OFFSET			0x2415
+#define MLXREG_DPU_REG_PG_MASK_OFFSET			0x2416
+#define MLXREG_DPU_REG_RESET_GP1_OFFSET			0x2417
+#define MLXREG_DPU_REG_RST_CAUSE1_OFFSET		0x241e
+#define MLXREG_DPU_REG_GP0_RO_OFFSET			0x242b
+#define MLXREG_DPU_REG_GP0_OFFSET			0x242e
+#define MLXREG_DPU_REG_GP1_OFFSET			0x242c
+#define MLXREG_DPU_REG_GP4_OFFSET			0x2438
+#define MLXREG_DPU_REG_AGGRCO_OFFSET			0x2442
+#define MLXREG_DPU_REG_AGGRCO_MASK_OFFSET		0x2443
+#define MLXREG_DPU_REG_HEALTH_OFFSET			0x244d
+#define MLXREG_DPU_REG_HEALTH_EVENT_OFFSET		0x244e
+#define MLXREG_DPU_REG_HEALTH_MASK_OFFSET		0x244f
+#define MLXREG_DPU_REG_FPGA1_MVER_OFFSET		0x24de
+#define MLXREG_DPU_REG_CONFIG3_OFFSET			0x24fd
+#define MLXREG_DPU_REG_MAX				0x3fff
+
+/* Power Good event masks. */
+#define MLXREG_DPU_PG_VDDIO_MASK			BIT(0)
+#define MLXREG_DPU_PG_VDD_CPU_MASK			BIT(1)
+#define MLXREG_DPU_PG_VDD_MASK				BIT(2)
+#define MLXREG_DPU_PG_1V8_MASK				BIT(3)
+#define MLXREG_DPU_PG_COMPARATOR_MASK			BIT(4)
+#define MLXREG_DPU_PG_VDDQ_MASK				BIT(5)
+#define MLXREG_DPU_PG_HVDD_MASK				BIT(6)
+#define MLXREG_DPU_PG_DVDD_MASK				BIT(7)
+#define MLXREG_DPU_PG_MASK				(MLXREG_DPU_PG_DVDD_MASK | \
+							 MLXREG_DPU_PG_HVDD_MASK | \
+							 MLXREG_DPU_PG_VDDQ_MASK | \
+							 MLXREG_DPU_PG_COMPARATOR_MASK | \
+							 MLXREG_DPU_PG_1V8_MASK | \
+							 MLXREG_DPU_PG_VDD_CPU_MASK | \
+							 MLXREG_DPU_PG_VDD_MASK | \
+							 MLXREG_DPU_PG_VDDIO_MASK)
+
+/* Health event masks. */
+#define MLXREG_DPU_HLTH_THERMAL_TRIP_MASK		BIT(0)
+#define MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK		BIT(1)
+#define MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK		BIT(2)
+#define MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK		BIT(3)
+#define MLXREG_DPU_HLTH_VDDQ_ALERT_MASK			BIT(4)
+#define MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK		BIT(5)
+#define MLXREG_DPU_HEALTH_MASK				(MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK | \
+							 MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK | \
+							 MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK | \
+							 MLXREG_DPU_HLTH_VDDQ_ALERT_MASK | \
+							 MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK | \
+							 MLXREG_DPU_HLTH_THERMAL_TRIP_MASK)
+
+/* Hotplug aggregation masks. */
+#define MLXREG_DPU_HEALTH_AGGR_MASK			BIT(0)
+#define MLXREG_DPU_PG_AGGR_MASK				BIT(1)
+#define MLXREG_DPU_AGGR_MASK				(MLXREG_DPU_HEALTH_AGGR_MASK | \
+							 MLXREG_DPU_PG_AGGR_MASK)
+
+/* Voltage regulator firmware update status mask. */
+#define MLXREG_DPU_VOLTREG_UPD_MASK			GENMASK(5, 4)
+
+#define MLXREG_DPU_NR_NONE				(-1)
+
+/*
+ * enum mlxreg_dpu_type - Data Processor Unit types
+ *
+ * @MLXREG_DPU_BF3: DPU equipped with BF3 SoC;
+ */
+enum mlxreg_dpu_type {
+	MLXREG_DPU_BF3 = 0x0050,
+};
+
+/* Default register access data. */
+static struct mlxreg_core_data mlxreg_dpu_io_data[] = {
+	{
+		.label = "fpga1_version",
+		.reg = MLXREG_DPU_REG_FPGA1_VER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "fpga1_pn",
+		.reg = MLXREG_DPU_REG_FPGA1_PN_OFFSET,
+		.bit = GENMASK(15, 0),
+		.mode = 0444,
+		.regnum = 2,
+	},
+	{
+		.label = "fpga1_version_min",
+		.reg = MLXREG_DPU_REG_FPGA1_MVER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "perst_rst",
+		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0644,
+	},
+	{
+		.label = "usbphy_rst",
+		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0644,
+	},
+	{
+		.label = "phy_rst",
+		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0644,
+	},
+	{
+		.label = "tpm_rst",
+		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(6),
+		.mode = 0644,
+	},
+	{
+		.label = "reset_from_main_board",
+		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_aux_pwr_or_reload",
+		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_comex_pwr_fail",
+		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_dpu_thermal",
+		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(6),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_pwr_off",
+		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(7),
+		.mode = 0444,
+	},
+	{
+		.label = "dpu_id",
+		.reg = MLXREG_DPU_REG_GP0_RO_OFFSET,
+		.bit = GENMASK(3, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "voltreg_update_status",
+		.reg = MLXREG_DPU_REG_GP0_RO_OFFSET,
+		.mask = MLXREG_DPU_VOLTREG_UPD_MASK,
+		.bit = 5,
+		.mode = 0444,
+	},
+	{
+		.label = "boot_progress",
+		.reg = MLXREG_DPU_REG_GP1_OFFSET,
+		.mask = GENMASK(3, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "ufm_upgrade",
+		.reg = MLXREG_DPU_REG_GP4_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0644,
+	},
+};
+
+static struct mlxreg_core_platform_data mlxreg_dpu_default_regs_io_data = {
+		.data = mlxreg_dpu_io_data,
+		.counter = ARRAY_SIZE(mlxreg_dpu_io_data),
+};
+
+/* Default hotplug data. */
+static struct mlxreg_core_data mlxreg_dpu_power_events_items_data[] = {
+	{
+		.label = "pg_vddio",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_VDDIO_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_vdd_cpu",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_VDD_CPU_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_vdd",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_VDD_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_1v8",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_1V8_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_comparator",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_COMPARATOR_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_vddq",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_VDDQ_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_hvdd",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_HVDD_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "pg_dvdd",
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_DVDD_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+};
+
+static struct mlxreg_core_data mlxreg_dpu_health_events_items_data[] = {
+	{
+		.label = "thermal_trip",
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HLTH_THERMAL_TRIP_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "ufm_upgrade_done",
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "vddq_hot_alert",
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "vdd_cpu_hot_alert",
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "vddq_alert",
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HLTH_VDDQ_ALERT_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+	{
+		.label = "vdd_cpu_alert",
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK,
+		.hpdev.nr = MLXREG_DPU_NR_NONE,
+	},
+};
+
+static struct mlxreg_core_item mlxreg_dpu_hotplug_items[] = {
+	{
+		.data = mlxreg_dpu_power_events_items_data,
+		.aggr_mask = MLXREG_DPU_PG_AGGR_MASK,
+		.reg = MLXREG_DPU_REG_PG_OFFSET,
+		.mask = MLXREG_DPU_PG_MASK,
+		.count = ARRAY_SIZE(mlxreg_dpu_power_events_items_data),
+		.health = false,
+		.inversed = 0,
+	},
+	{
+		.data = mlxreg_dpu_health_events_items_data,
+		.aggr_mask = MLXREG_DPU_HEALTH_AGGR_MASK,
+		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
+		.mask = MLXREG_DPU_HEALTH_MASK,
+		.count = ARRAY_SIZE(mlxreg_dpu_health_events_items_data),
+		.health = false,
+		.inversed = 0,
+	},
+};
+
+static
+struct mlxreg_core_hotplug_platform_data mlxreg_dpu_default_hotplug_data = {
+	.items = mlxreg_dpu_hotplug_items,
+	.count = ARRAY_SIZE(mlxreg_dpu_hotplug_items),
+	.cell = MLXREG_DPU_REG_AGGRCO_OFFSET,
+	.mask = MLXREG_DPU_AGGR_MASK,
+};
+
+/**
+ * struct mlxreg_dpu - device private data
+ * @dev: platform device
+ * @data: platform core data
+ * @io_data: register access platform data
+ * @io_regs: register access device
+ * @hotplug_data: hotplug platform data
+ * @hotplug: hotplug device
+ */
+struct mlxreg_dpu {
+	struct device *dev;
+	struct mlxreg_core_data *data;
+	struct mlxreg_core_platform_data *io_data;
+	struct platform_device *io_regs;
+	struct mlxreg_core_hotplug_platform_data *hotplug_data;
+	struct platform_device *hotplug;
+};
+
+static bool mlxreg_dpu_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MLXREG_DPU_REG_PG_EVENT_OFFSET:
+	case MLXREG_DPU_REG_PG_MASK_OFFSET:
+	case MLXREG_DPU_REG_RESET_GP1_OFFSET:
+	case MLXREG_DPU_REG_GP0_OFFSET:
+	case MLXREG_DPU_REG_GP1_OFFSET:
+	case MLXREG_DPU_REG_GP4_OFFSET:
+	case MLXREG_DPU_REG_AGGRCO_OFFSET:
+	case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_MASK_OFFSET:
+		return true;
+	}
+	return false;
+}
+
+static bool mlxreg_dpu_readable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MLXREG_DPU_REG_FPGA1_VER_OFFSET:
+	case MLXREG_DPU_REG_FPGA1_PN_OFFSET:
+	case MLXREG_DPU_REG_FPGA1_PN1_OFFSET:
+	case MLXREG_DPU_REG_PG_OFFSET:
+	case MLXREG_DPU_REG_PG_EVENT_OFFSET:
+	case MLXREG_DPU_REG_PG_MASK_OFFSET:
+	case MLXREG_DPU_REG_RESET_GP1_OFFSET:
+	case MLXREG_DPU_REG_RST_CAUSE1_OFFSET:
+	case MLXREG_DPU_REG_GP0_RO_OFFSET:
+	case MLXREG_DPU_REG_GP0_OFFSET:
+	case MLXREG_DPU_REG_GP1_OFFSET:
+	case MLXREG_DPU_REG_GP4_OFFSET:
+	case MLXREG_DPU_REG_AGGRCO_OFFSET:
+	case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_MASK_OFFSET:
+	case MLXREG_DPU_REG_FPGA1_MVER_OFFSET:
+	case MLXREG_DPU_REG_CONFIG3_OFFSET:
+		return true;
+	}
+	return false;
+}
+
+static bool mlxreg_dpu_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MLXREG_DPU_REG_FPGA1_VER_OFFSET:
+	case MLXREG_DPU_REG_FPGA1_PN_OFFSET:
+	case MLXREG_DPU_REG_FPGA1_PN1_OFFSET:
+	case MLXREG_DPU_REG_PG_OFFSET:
+	case MLXREG_DPU_REG_PG_EVENT_OFFSET:
+	case MLXREG_DPU_REG_PG_MASK_OFFSET:
+	case MLXREG_DPU_REG_RESET_GP1_OFFSET:
+	case MLXREG_DPU_REG_RST_CAUSE1_OFFSET:
+	case MLXREG_DPU_REG_GP0_RO_OFFSET:
+	case MLXREG_DPU_REG_GP0_OFFSET:
+	case MLXREG_DPU_REG_GP1_OFFSET:
+	case MLXREG_DPU_REG_GP4_OFFSET:
+	case MLXREG_DPU_REG_AGGRCO_OFFSET:
+	case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET:
+	case MLXREG_DPU_REG_HEALTH_MASK_OFFSET:
+	case MLXREG_DPU_REG_FPGA1_MVER_OFFSET:
+	case MLXREG_DPU_REG_CONFIG3_OFFSET:
+		return true;
+	}
+	return false;
+}
+
+/* Configuration for the register map of a device with 2 bytes address space. */
+static const struct regmap_config mlxreg_dpu_regmap_conf = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.max_register = MLXREG_DPU_REG_MAX,
+	.cache_type = REGCACHE_FLAT,
+	.writeable_reg = mlxreg_dpu_writeable_reg,
+	.readable_reg = mlxreg_dpu_readable_reg,
+	.volatile_reg = mlxreg_dpu_volatile_reg,
+};
+
+static int
+mlxreg_dpu_copy_hotplug_data(struct device *dev, struct mlxreg_dpu *mlxreg_dpu,
+			     const struct mlxreg_core_hotplug_platform_data *hotplug_data)
+{
+	struct mlxreg_core_item *item;
+	int i;
+
+	mlxreg_dpu->hotplug_data = devm_kmemdup(dev, hotplug_data,
+						sizeof(*mlxreg_dpu->hotplug_data), GFP_KERNEL);
+	if (!mlxreg_dpu->hotplug_data)
+		return -ENOMEM;
+
+	mlxreg_dpu->hotplug_data->items = devm_kmemdup(dev, hotplug_data->items,
+						       mlxreg_dpu->hotplug_data->count *
+						       sizeof(*mlxreg_dpu->hotplug_data->items),
+						       GFP_KERNEL);
+	if (!mlxreg_dpu->hotplug_data->items)
+		return -ENOMEM;
+
+	item = mlxreg_dpu->hotplug_data->items;
+	for (i = 0; i < hotplug_data->count; i++, item++) {
+		item->data = devm_kmemdup(dev, hotplug_data->items[i].data,
+					  hotplug_data->items[i].count * sizeof(*item->data),
+					  GFP_KERNEL);
+		if (!item->data)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int mlxreg_dpu_config_init(struct mlxreg_dpu *mlxreg_dpu, void *regmap,
+				  struct mlxreg_core_data *data, int irq)
+{
+	struct device *dev = &data->hpdev.client->dev;
+	u32 regval;
+	int err;
+
+	/* Validate DPU type. */
+	err = regmap_read(regmap, MLXREG_DPU_REG_CONFIG3_OFFSET, &regval);
+	if (err)
+		return err;
+
+	switch (regval) {
+	case MLXREG_DPU_BF3:
+		/* Copy platform specific hotplug data. */
+		err = mlxreg_dpu_copy_hotplug_data(dev, mlxreg_dpu,
+						   &mlxreg_dpu_default_hotplug_data);
+		if (err)
+			return err;
+
+		mlxreg_dpu->io_data = &mlxreg_dpu_default_regs_io_data;
+
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	/* Register IO access driver. */
+	if (mlxreg_dpu->io_data) {
+		mlxreg_dpu->io_data->regmap = regmap;
+		mlxreg_dpu->io_regs =
+			platform_device_register_resndata(dev, "mlxreg-io",
+							  data->slot, NULL, 0,
+							  mlxreg_dpu->io_data,
+							  sizeof(*mlxreg_dpu->io_data));
+		if (IS_ERR(mlxreg_dpu->io_regs)) {
+			dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
+				data->hpdev.brdinfo->type, data->hpdev.nr,
+				data->hpdev.brdinfo->addr);
+			return PTR_ERR(mlxreg_dpu->io_regs);
+		}
+	}
+
+	/* Register hotplug driver. */
+	if (mlxreg_dpu->hotplug_data && irq) {
+		mlxreg_dpu->hotplug_data->regmap = regmap;
+		mlxreg_dpu->hotplug_data->irq = irq;
+		mlxreg_dpu->hotplug =
+			platform_device_register_resndata(dev, "mlxreg-hotplug",
+							  data->slot, NULL, 0,
+							  mlxreg_dpu->hotplug_data,
+							  sizeof(*mlxreg_dpu->hotplug_data));
+		if (IS_ERR(mlxreg_dpu->hotplug)) {
+			err = PTR_ERR(mlxreg_dpu->hotplug);
+			goto fail_register_hotplug;
+		}
+	}
+
+	return 0;
+
+fail_register_hotplug:
+	platform_device_unregister(mlxreg_dpu->io_regs);
+
+	return err;
+}
+
+static void mlxreg_dpu_config_exit(struct mlxreg_dpu *mlxreg_dpu)
+{
+	platform_device_unregister(mlxreg_dpu->hotplug);
+	platform_device_unregister(mlxreg_dpu->io_regs);
+}
+
+static int mlxreg_dpu_probe(struct platform_device *pdev)
+{
+	struct mlxreg_core_data *data;
+	struct mlxreg_dpu *mlxreg_dpu;
+	void *regmap;
+	int err;
+
+	data = dev_get_platdata(&pdev->dev);
+	if (!data || !data->hpdev.brdinfo)
+		return -EINVAL;
+
+	data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
+	if (!data->hpdev.adapter)
+		return -EPROBE_DEFER;
+
+	mlxreg_dpu = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_dpu), GFP_KERNEL);
+	if (!mlxreg_dpu)
+		return -ENOMEM;
+
+	/* Create device at the top of DPU I2C tree.*/
+	data->hpdev.client = i2c_new_client_device(data->hpdev.adapter,
+						   data->hpdev.brdinfo);
+	if (IS_ERR(data->hpdev.client)) {
+		dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
+			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
+		err = PTR_ERR(data->hpdev.client);
+		goto i2c_new_device_fail;
+	}
+
+	regmap = devm_regmap_init_i2c(data->hpdev.client, &mlxreg_dpu_regmap_conf);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
+			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
+		err = PTR_ERR(regmap);
+		goto devm_regmap_init_i2c_fail;
+	}
+
+	/* Sync registers with hardware. */
+	regcache_mark_dirty(regmap);
+	err = regcache_sync(regmap);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
+			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
+		err = PTR_ERR(regmap);
+		goto regcache_sync_fail;
+	}
+
+	mlxreg_dpu->data = data;
+	mlxreg_dpu->dev = &pdev->dev;
+	platform_set_drvdata(pdev, mlxreg_dpu);
+
+	err = mlxreg_dpu_config_init(mlxreg_dpu, regmap, data, data->hpdev.brdinfo->irq);
+	if (err)
+		goto mlxreg_dpu_config_init_fail;
+
+	return err;
+
+mlxreg_dpu_config_init_fail:
+regcache_sync_fail:
+devm_regmap_init_i2c_fail:
+	if (data->hpdev.client) {
+		i2c_unregister_device(data->hpdev.client);
+		data->hpdev.client = NULL;
+	}
+i2c_new_device_fail:
+	i2c_put_adapter(data->hpdev.adapter);
+	data->hpdev.adapter = NULL;
+	return err;
+}
+
+static void mlxreg_dpu_remove(struct platform_device *pdev)
+{
+	struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
+	struct mlxreg_dpu *mlxreg_dpu = platform_get_drvdata(pdev);
+
+	mlxreg_dpu_config_exit(mlxreg_dpu);
+	if (data->hpdev.client) {
+		i2c_unregister_device(data->hpdev.client);
+		data->hpdev.client = NULL;
+		i2c_put_adapter(data->hpdev.adapter);
+		data->hpdev.adapter = NULL;
+	}
+}
+
+static struct platform_driver mlxreg_dpu_driver = {
+	.probe = mlxreg_dpu_probe,
+	.remove = mlxreg_dpu_remove,
+	.driver = {
+		.name = "mlxreg-dpu",
+	},
+};
+
+module_platform_driver(mlxreg_dpu_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>");
+MODULE_DESCRIPTION("Nvidia Data Processor Unit platform driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:mlxreg-dpu");
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 3/7] platform: mellanox: Introduce support of Nvidia smart switch
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
  2025-04-12  9:18 ` [PATCH platform-next v8 1/7] platform/mellanox: Rename field to improve code readability Vadim Pasternak
  2025-04-12  9:18 ` [PATCH platform-next v8 2/7] platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-15 14:38   ` Ilpo Järvinen
  2025-04-12  9:18 ` [PATCH platform-next v8 4/7] platform: mellanox: Cosmetic changes to improve code style Vadim Pasternak
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Provide platform support for Nvidia Smart Switch SN4280.

The Smart Switch equipped with:
- Nvidia COME module based on AMD EPYC™ Embedded 3451 CPU.
- Nvidia Spectrum-3 ASIC.
- Four DPUs, each equipped with Nvidia BF3 ARM based processor and
  with Lattice LFD2NX-40 FPGA device.
- 28xQSFP-DD external ports.
- Two power supplies.
- Four cooling drawers.

Reviewed-by: Ciju Rajan K <crajank@nvidia.com>
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
v6->v7
Changes added by Vadim:
- Remove 'capability_mask' field.
- Fix configuration for dpu.

v5->v6
Comments pointed out by Ilpo:
- Add missing coma in structure 'mlxplat_mlxcpld_xdr_led_data'.
- Merge lines in structure 'mlxplat_mlxcpld_regmap_smart_switch'.
- s/int/unsigned int/ in 'mlxplat_dmi_smart_switch_matched'.

v4->v5
Comments pointed out by Ilpo:
- Add blank lines in mlxplat_dmi_smart_switch_matched().
- Style fixes: remove empty space after the condition fix while() loop.
---
 drivers/platform/mellanox/mlx-platform.c | 1924 +++++++++++++++++++---
 1 file changed, 1670 insertions(+), 254 deletions(-)

diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
index 2334b740267c..29d938265676 100644
--- a/drivers/platform/mellanox/mlx-platform.c
+++ b/drivers/platform/mellanox/mlx-platform.c
@@ -38,6 +38,7 @@
 #define MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET	0x0b
 #define MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET	0x17
 #define MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET	0x19
+#define MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET	0x1b
 #define MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET	0x1c
 #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET	0x1d
 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET	0x1e
@@ -49,9 +50,11 @@
 #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET	0x24
 #define MLXPLAT_CPLD_LPC_REG_LED6_OFFSET	0x25
 #define MLXPLAT_CPLD_LPC_REG_LED7_OFFSET	0x26
+#define MLXPLAT_CPLD_LPC_REG_LED8_OFFSET	0x27
 #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION	0x2a
 #define MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET	0x2b
 #define MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET	0x2d
+#define MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET	0x2c
 #define MLXPLAT_CPLD_LPC_REG_GP0_OFFSET		0x2e
 #define MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET	0x2f
 #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET		0x30
@@ -71,12 +74,14 @@
 #define MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET	0x43
 #define MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET	0x44
 #define MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET 0x45
+#define MLXPLAT_CPLD_LPC_REG_GP3_OFFSET		0x46
 #define MLXPLAT_CPLD_LPC_REG_BRD_OFFSET		0x47
 #define MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET	0x48
 #define MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET	0x49
 #define MLXPLAT_CPLD_LPC_REG_GWP_OFFSET		0x4a
 #define MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET	0x4b
 #define MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET	0x4c
+#define MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET	0x4e
 #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
 #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET	0x51
 #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET	0x52
@@ -88,15 +93,20 @@
 #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET		0x58
 #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET	0x59
 #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET	0x5a
+#define MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET	0x5e
 #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET		0x64
 #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET	0x65
 #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET	0x66
+#define MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET	0x6a
 #define MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET	0x70
 #define MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET	0x71
 #define MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET	0x72
 #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET		0x88
 #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET	0x89
 #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET	0x8a
+#define MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET	0x8b
+#define MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET	0x8c
+#define MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET	0x8d
 #define MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET	0x8e
 #define MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET	0x8f
 #define MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET	0x90
@@ -128,10 +138,15 @@
 #define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET	0xaa
 #define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET	0xab
 #define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON		0xb2
+#define MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET	0xb4
+#define MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET	0xb5
 #define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET	0xb6
 #define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET	0xb7
 #define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET	0xb8
 #define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET	0xb9
+#define MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET	0xba
+#define MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET	0xbb
+#define MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET	0xc1
 #define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET	0xc2
 #define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT	0xc3
 #define MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET	0xc4
@@ -182,6 +197,9 @@
 #define MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET	0xfb
 #define MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET	0xfc
 #define MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET	0xfd
+#define MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET	0xfe
+#define MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET	0xff
+
 #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
 
 #define MLXPLAT_CPLD_LPC_PIO_OFFSET		0x10000UL
@@ -210,9 +228,15 @@
 #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF	0x04
 #define MLXPLAT_CPLD_AGGR_MASK_COMEX	BIT(0)
 #define MLXPLAT_CPLD_AGGR_MASK_LC	BIT(3)
+#define MLXPLAT_CPLD_AGGR_MASK_DPU_BRD	BIT(4)
+#define MLXPLAT_CPLD_AGGR_MASK_DPU_CORE	BIT(5)
 #define MLXPLAT_CPLD_AGGR_MASK_MODULAR	(MLXPLAT_CPLD_AGGR_MASK_NG_DEF | \
 					 MLXPLAT_CPLD_AGGR_MASK_COMEX | \
 					 MLXPLAT_CPLD_AGGR_MASK_LC)
+#define MLXPLAT_CPLD_AGGR_MASK_SMART_SW	(MLXPLAT_CPLD_AGGR_MASK_COMEX | \
+					 MLXPLAT_CPLD_AGGR_MASK_NG_DEF | \
+					 MLXPLAT_CPLD_AGGR_MASK_DPU_BRD | \
+					 MLXPLAT_CPLD_AGGR_MASK_DPU_CORE)
 #define MLXPLAT_CPLD_AGGR_MASK_LC_PRSNT	BIT(0)
 #define MLXPLAT_CPLD_AGGR_MASK_LC_RDY	BIT(1)
 #define MLXPLAT_CPLD_AGGR_MASK_LC_PG	BIT(2)
@@ -235,15 +259,21 @@
 #define MLXPLAT_CPLD_PWR_MASK		GENMASK(1, 0)
 #define MLXPLAT_CPLD_PSU_EXT_MASK	GENMASK(3, 0)
 #define MLXPLAT_CPLD_PWR_EXT_MASK	GENMASK(3, 0)
+#define MLXPLAT_CPLD_PSU_XDR_MASK	GENMASK(7, 0)
+#define MLXPLAT_CPLD_PWR_XDR_MASK	GENMASK(7, 0)
 #define MLXPLAT_CPLD_FAN_MASK		GENMASK(3, 0)
 #define MLXPLAT_CPLD_ASIC_MASK		GENMASK(1, 0)
+#define MLXPLAT_CPLD_ASIC_XDR_MASK	GENMASK(3, 0)
 #define MLXPLAT_CPLD_FAN_NG_MASK	GENMASK(6, 0)
+#define MLXPLAT_CPLD_FAN_XDR_MASK	GENMASK(7, 0)
 #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK	GENMASK(7, 4)
 #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK	GENMASK(3, 0)
 #define MLXPLAT_CPLD_VOLTREG_UPD_MASK	GENMASK(5, 4)
 #define MLXPLAT_CPLD_GWP_MASK		GENMASK(0, 0)
 #define MLXPLAT_CPLD_EROT_MASK		GENMASK(1, 0)
 #define MLXPLAT_CPLD_FU_CAP_MASK	GENMASK(1, 0)
+#define MLXPLAT_CPLD_BIOS_STATUS_MASK	GENMASK(3, 1)
+#define MLXPLAT_CPLD_DPU_MASK		GENMASK(3, 0)
 #define MLXPLAT_CPLD_PWR_BUTTON_MASK	BIT(0)
 #define MLXPLAT_CPLD_LATCH_RST_MASK	BIT(6)
 #define MLXPLAT_CPLD_THERMAL1_PDB_MASK	BIT(3)
@@ -267,6 +297,9 @@
 /* Masks for aggregation for modular systems */
 #define MLXPLAT_CPLD_LPC_LC_MASK	GENMASK(7, 0)
 
+/* Masks for aggregation for smart switch systems */
+#define MLXPLAT_CPLD_LPC_SM_SW_MASK	GENMASK(7, 0)
+
 #define MLXPLAT_CPLD_HALT_MASK		BIT(3)
 #define MLXPLAT_CPLD_RESET_MASK		GENMASK(7, 1)
 
@@ -297,15 +330,18 @@
 #define MLXPLAT_CPLD_NR_NONE			-1
 #define MLXPLAT_CPLD_PSU_DEFAULT_NR		10
 #define MLXPLAT_CPLD_PSU_MSNXXXX_NR		4
+#define MLXPLAT_CPLD_PSU_XDR_NR			3
 #define MLXPLAT_CPLD_FAN1_DEFAULT_NR		11
 #define MLXPLAT_CPLD_FAN2_DEFAULT_NR		12
 #define MLXPLAT_CPLD_FAN3_DEFAULT_NR		13
 #define MLXPLAT_CPLD_FAN4_DEFAULT_NR		14
 #define MLXPLAT_CPLD_NR_ASIC			3
 #define MLXPLAT_CPLD_NR_LC_BASE			34
+#define MLXPLAT_CPLD_NR_DPU_BASE		18
 
 #define MLXPLAT_CPLD_NR_LC_SET(nr)	(MLXPLAT_CPLD_NR_LC_BASE + (nr))
 #define MLXPLAT_CPLD_LC_ADDR		0x32
+#define MLXPLAT_CPLD_DPU_ADDR		0x68
 
 /* Masks and default values for watchdogs */
 #define MLXPLAT_CPLD_WD1_CLEAR_MASK	GENMASK(7, 1)
@@ -320,6 +356,7 @@
 #define MLXPLAT_CPLD_WD_DFLT_TIMEOUT	30
 #define MLXPLAT_CPLD_WD3_DFLT_TIMEOUT	600
 #define MLXPLAT_CPLD_WD_MAX_DEVS	2
+#define MLXPLAT_CPLD_DPU_MAX_DEVS	4
 
 #define MLXPLAT_CPLD_LPC_SYSIRQ		17
 
@@ -346,6 +383,7 @@
  * @pdev_io_regs - register access platform devices
  * @pdev_fan - FAN platform devices
  * @pdev_wd - array of watchdog platform devices
+ * pdev_dpu - array of Data Processor Unit platform devices
  * @regmap: device register map
  * @hotplug_resources: system hotplug resources
  * @hotplug_resources_size: size of system hotplug resources
@@ -360,6 +398,7 @@
 	struct platform_device *pdev_io_regs;
 	struct platform_device *pdev_fan;
 	struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS];
+	struct platform_device *pdev_dpu[MLXPLAT_CPLD_DPU_MAX_DEVS];
 	void *regmap;
 	struct resource *hotplug_resources;
 	unsigned int hotplug_resources_size;
@@ -626,6 +665,21 @@
 	},
 };
 
+static struct i2c_board_info mlxplat_mlxcpld_xdr_pwr[] = {
+	{
+		I2C_BOARD_INFO("dps460", 0x5d),
+	},
+	{
+		I2C_BOARD_INFO("dps460", 0x5c),
+	},
+	{
+		I2C_BOARD_INFO("dps460", 0x5e),
+	},
+	{
+		I2C_BOARD_INFO("dps460", 0x5f),
+	},
+};
+
 static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
 	{
 		I2C_BOARD_INFO("24c32", 0x50),
@@ -2370,6 +2424,427 @@
 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
 };
 
+/* Platform hotplug XDR and smart switch system family data */
+static struct mlxreg_core_data mlxplat_mlxcpld_xdr_psu_items_data[] = {
+	{
+		.label = "psu1",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(0),
+		.slot = 1,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu2",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(1),
+		.slot = 2,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu3",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(2),
+		.slot = 3,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu4",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(3),
+		.slot = 4,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu5",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(4),
+		.slot = 5,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu6",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(5),
+		.slot = 6,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu7",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(6),
+		.slot = 7,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "psu8",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(7),
+		.slot = 8,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_xdr_pwr_items_data[] = {
+	{
+		.label = "pwr1",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(0),
+		.slot = 1,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
+	},
+	{
+		.label = "pwr2",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(1),
+		.slot = 2,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
+	},
+	{
+		.label = "pwr3",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(2),
+		.slot = 3,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[0],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
+	},
+	{
+		.label = "pwr4",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(3),
+		.slot = 4,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[1],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
+	},
+	{
+		.label = "pwr5",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(4),
+		.slot = 5,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[0],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
+	},
+	{
+		.label = "pwr6",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(5),
+		.slot = 6,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[1],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
+	},
+	{
+		.label = "pwr7",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(6),
+		.slot = 7,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[2],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
+	},
+	{
+		.label = "pwr8",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(7),
+		.slot = 8,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[3],
+		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_xdr_fan_items_data[] = {
+	{
+		.label = "fan1",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(0),
+		.slot = 1,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(0),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan2",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(1),
+		.slot = 2,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(1),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan3",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(2),
+		.slot = 3,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(2),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan4",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(3),
+		.slot = 4,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(3),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan5",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(4),
+		.slot = 5,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(4),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan6",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(5),
+		.slot = 6,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(5),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan7",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(6),
+		.slot = 7,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(6),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "fan8",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(7),
+		.slot = 8,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.bit = BIT(7),
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_xdr_asic1_items_data[] = {
+	{
+		.label = "asic1",
+		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+		.mask = MLXPLAT_CPLD_ASIC_MASK,
+		.slot = 1,
+		.capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	}
+};
+
+/* Platform hotplug for smart switch systems families data */
+static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_dpu_ready_data[] = {
+	{
+		.label = "dpu1_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
+		.mask = BIT(0),
+		.slot = 1,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "dpu2_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
+		.mask = BIT(1),
+		.slot = 2,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "dpu3_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
+		.mask = BIT(2),
+		.slot = 3,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "dpu4_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
+		.mask = BIT(3),
+		.slot = 4,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_dpu_shtdn_ready_data[] = {
+	{
+		.label = "dpu1_shtdn_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
+		.mask = BIT(0),
+		.slot = 1,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "dpu2_shtdn_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
+		.mask = BIT(1),
+		.slot = 2,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "dpu3_shtdn_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
+		.mask = BIT(2),
+		.slot = 3,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+	{
+		.label = "dpu4_shtdn_ready",
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
+		.mask = BIT(3),
+		.slot = 4,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+	},
+};
+
+static struct mlxreg_core_item mlxplat_mlxcpld_smart_switch_items[] = {
+	{
+		.data = mlxplat_mlxcpld_xdr_psu_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = MLXPLAT_CPLD_PSU_XDR_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_psu_items_data),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_xdr_pwr_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = MLXPLAT_CPLD_PWR_XDR_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_pwr_items_data),
+		.inversed = 0,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_xdr_fan_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = MLXPLAT_CPLD_FAN_XDR_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_items_data),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_xdr_asic1_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+		.mask = MLXPLAT_CPLD_ASIC_XDR_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_asic1_items_data),
+		.inversed = 0,
+		.health = true,
+	},
+	{
+		.data = mlxplat_mlxcpld_smart_switch_dpu_ready_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DPU_CORE,
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
+		.mask = MLXPLAT_CPLD_DPU_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_dpu_ready_data),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_smart_switch_dpu_shtdn_ready_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DPU_CORE,
+		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
+		.mask = MLXPLAT_CPLD_DPU_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_dpu_shtdn_ready_data),
+		.inversed = 1,
+		.health = false,
+	},
+};
+
+static
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_smart_switch_data = {
+	.items = mlxplat_mlxcpld_smart_switch_items,
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_items),
+	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX |
+		MLXPLAT_CPLD_AGGR_MASK_DPU_BRD | MLXPLAT_CPLD_AGGR_MASK_DPU_CORE,
+	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
+	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
+};
+
+/* Smart switch data  processor units data */
+static struct i2c_board_info mlxplat_mlxcpld_smart_switch_dpu_devs[] = {
+	{
+		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
+		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
+	},
+	{
+		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
+		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
+	},
+	{
+		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
+		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
+	},
+	{
+		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
+		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_dpu_data[] = {
+	{
+		.label = "dpu1",
+		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[0],
+		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE,
+		.slot = 1,
+	},
+	{
+		.label = "dpu2",
+		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[1],
+		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE + 1,
+		.slot = 2,
+	},
+	{
+		.label = "dpu3",
+		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[2],
+		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE + 2,
+		.slot = 3,
+	},
+	{
+		.label = "dpu4",
+		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[3],
+		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE + 3,
+		.slot = 4,
+	},
+};
+
 /* Callback performs graceful shutdown after notification about power button event */
 static int
 mlxplat_mlxcpld_l1_switch_pwr_events_handler(void *handle, enum mlxreg_hotplug_kind kind,
@@ -3162,6 +3637,180 @@
 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_led_data),
 };
 
+/* Platform led data for XDR and smart switch systems */
+static struct mlxreg_core_data mlxplat_mlxcpld_xdr_led_data[] = {
+	{
+		.label = "status:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+	},
+	{
+		.label = "status:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+	},
+	{
+		.label = "psu:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+	},
+	{
+		.label = "psu:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+	},
+	{
+		.label = "fan1:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 1,
+	},
+	{
+		.label = "fan1:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 1,
+	},
+	{
+		.label = "fan2:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 2,
+	},
+	{
+		.label = "fan2:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 2,
+	},
+	{
+		.label = "fan3:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 3,
+	},
+	{
+		.label = "fan3:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 3,
+	},
+	{
+		.label = "fan4:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 4,
+	},
+	{
+		.label = "fan4:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 4,
+	},
+	{
+		.label = "fan5:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 5,
+	},
+	{
+		.label = "fan5:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 5,
+	},
+	{
+		.label = "fan6:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 6,
+	},
+	{
+		.label = "fan6:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 6,
+	},
+	{
+		.label = "fan7:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 7,
+	},
+	{
+		.label = "fan7:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 7,
+	},
+	{
+		.label = "fan8:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 8,
+	},
+	{
+		.label = "fan8:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 8,
+	},
+	{
+		.label = "fan9:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 9,
+	},
+	{
+		.label = "fan9:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 9,
+	},
+	{
+		.label = "fan10:green",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED8_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 10,
+	},
+	{
+		.label = "fan10:orange",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED8_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.slot = 10,
+	},
+	{
+		.label = "uid:blue",
+		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
+		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+	},
+};
+
+static struct mlxreg_core_platform_data mlxplat_xdr_led_data = {
+		.data = mlxplat_mlxcpld_xdr_led_data,
+		.counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_led_data),
+};
+
 /* Platform register access default */
 static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
 	{
@@ -4610,6 +5259,480 @@
 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_chassis_blade_regs_io_data),
 };
 
+/* Platform register access for smart switch systems families data */
+static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_regs_io_data[] = {
+	{
+		.label = "cpld1_version",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "cpld2_version",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "cpld3_version",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "cpld1_pn",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
+		.bit = GENMASK(15, 0),
+		.mode = 0444,
+		.regnum = 2,
+	},
+	{
+		.label = "cpld2_pn",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET,
+		.bit = GENMASK(15, 0),
+		.mode = 0444,
+		.regnum = 2,
+	},
+	{
+		.label = "cpld3_pn",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET,
+		.bit = GENMASK(15, 0),
+		.mode = 0444,
+		.regnum = 2,
+	},
+	{
+		.label = "cpld1_version_min",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "cpld2_version_min",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "cpld3_version_min",
+		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "kexec_activated",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0644,
+	},
+	{
+		.label = "asic_reset",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0644,
+	},
+	{
+		.label = "eth_switch_reset",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(4),
+		.mode = 0644,
+	},
+	{
+		.label = "dpu1_rst",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu2_rst",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu3_rst",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu4_rst",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu1_pwr",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu2_pwr",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu3_pwr",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu4_pwr",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0200,
+	},
+	{
+		.label = "reset_long_pb",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_short_pb",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_aux_pwr_or_ref",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_swb_dc_dc_pwr_fail",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_swb_wd",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(6),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_asic_thermal",
+		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(7),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_sw_reset",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_aux_pwr_or_reload",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_comex_pwr_fail",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_platform",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(4),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_soc",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(5),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_pwr",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(7),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_pwr_converter_fail",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_system",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_sw_pwr_off",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_comex_thermal",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0444,
+	},
+	{
+		.label = "reset_ac_pwr_fail",
+		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(6),
+		.mode = 0444,
+	},
+	{
+		.label = "voltreg_update_status",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET,
+		.mask = MLXPLAT_CPLD_VOLTREG_UPD_MASK,
+		.bit = 5,
+		.mode = 0444,
+	},
+	{
+		.label = "port80",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "bios_status",
+		.reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
+		.mask = MLXPLAT_CPLD_BIOS_STATUS_MASK,
+		.bit = 2,
+		.mode = 0444,
+	},
+	{
+		.label = "bios_start_retry",
+		.reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(4),
+		.mode = 0444,
+	},
+	{
+		.label = "bios_active_image",
+		.reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(5),
+		.mode = 0444,
+	},
+	{
+		.label = "vpd_wp",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0644,
+	},
+	{
+		.label = "pcie_asic_reset_dis",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(4),
+		.mode = 0644,
+	},
+	{
+		.label = "shutdown_unlock",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(5),
+		.mode = 0644,
+	},
+	{
+		.label = "fan_dir",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "dpu1_rst_en",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu2_rst_en",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu3_rst_en",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu4_rst_en",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0200,
+	},
+	{
+		.label = "psu1_on",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0200,
+	},
+	{
+		.label = "psu2_on",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0200,
+	},
+	{
+		.label = "pwr_cycle",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0200,
+	},
+	{
+		.label = "pwr_down",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0200,
+	},
+	{
+		.label = "jtag_cap",
+		.reg = MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET,
+		.mask = MLXPLAT_CPLD_FU_CAP_MASK,
+		.bit = 1,
+		.mode = 0444,
+	},
+	{
+		.label = "jtag_enable",
+		.reg = MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE,
+		.mask = GENMASK(1, 0),
+		.bit = 1,
+		.mode = 0644,
+	},
+	{
+		.label = "non_active_bios_select",
+		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(4),
+		.mode = 0644,
+	},
+	{
+	    .label = "bios_upgrade_fail",
+		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(5),
+		.mode = 0444,
+	},
+	{
+		.label = "bios_image_invert",
+		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(6),
+		.mode = 0644,
+	},
+	{
+		.label = "me_reboot",
+		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(7),
+		.mode = 0644,
+	},
+	{
+		.label = "dpu1_pwr_force",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu2_pwr_force",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu3_pwr_force",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(2),
+		.mode = 0200,
+	},
+	{
+		.label = "dpu4_pwr_force",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(3),
+		.mode = 0200,
+	},
+	{
+		.label = "ufm_done",
+		.reg = MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "asic_health",
+		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+		.mask = MLXPLAT_CPLD_ASIC_MASK,
+		.bit = 1,
+		.mode = 0444,
+	},
+	{
+		.label = "psu1_ac_ok",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0644,
+	},
+	{
+		.label = "psu2_ac_ok",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0644,
+	},
+	{
+		.label = "psu1_no_alert",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(0),
+		.mode = 0644,
+	},
+	{
+		.label = "psu2_no_alert",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(1),
+		.mode = 0644,
+	},
+	{
+		.label = "asic_pg_fail",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(7),
+		.mode = 0444,
+	},
+	{
+		.label = "spi_chnl_select",
+		.reg = MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT,
+		.mask = GENMASK(7, 0),
+		.bit = 1,
+		.mode = 0644,
+	},
+	{
+		.label = "config1",
+		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "config2",
+		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "config3",
+		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+	{
+		.label = "ufm_version",
+		.reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
+		.bit = GENMASK(7, 0),
+		.mode = 0444,
+	},
+};
+
+static struct mlxreg_core_platform_data mlxplat_smart_switch_regs_io_data = {
+		.data = mlxplat_mlxcpld_smart_switch_regs_io_data,
+		.counter = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_regs_io_data),
+};
+
 /* Platform FAN default */
 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
 	{
@@ -4751,6 +5874,185 @@
 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
 };
 
+/* XDR and smart switch platform fan data */
+static struct mlxreg_core_data mlxplat_mlxcpld_xdr_fan_data[] = {
+	{
+		.label = "pwm1",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
+	},
+	{
+		.label = "tacho1",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 1,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho2",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 2,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho3",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 3,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho4",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 4,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho5",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 5,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho6",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 6,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho7",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 7,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho8",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 8,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho9",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 9,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho10",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 10,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho11",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 11,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho12",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 12,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho13",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 13,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho14",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 14,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho15",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 15,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho16",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 16,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+	},
+	{
+		.label = "tacho17",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 17,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
+	},
+	{
+		.label = "tacho18",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 18,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
+	},
+	{
+		.label = "tacho19",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 19,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
+	},
+	{
+		.label = "tacho20",
+		.reg = MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET,
+		.mask = GENMASK(7, 0),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
+		.slot = 20,
+		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
+	},
+	{
+		.label = "conf",
+		.capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET,
+	},
+};
+
+static struct mlxreg_core_platform_data mlxplat_xdr_fan_data = {
+		.data = mlxplat_mlxcpld_xdr_fan_data,
+		.counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_data),
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.version = 1,
+};
+
 /* Watchdog type1: hardware implementation version1
  * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
  */
@@ -4975,6 +6277,8 @@
 {
 	switch (reg) {
 	case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
@@ -4983,12 +6287,14 @@
 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GP3_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
 	case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
 	case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
@@ -5012,10 +6318,14 @@
 	case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
@@ -5083,6 +6393,8 @@
 	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
@@ -5094,15 +6406,18 @@
 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
 	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GP3_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
 	case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
 	case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
@@ -5122,6 +6437,7 @@
 	case MLXPLAT_CPLD_LPC_REG_GWP_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
@@ -5134,12 +6450,17 @@
 	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
@@ -5213,6 +6534,13 @@
 	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
@@ -5248,6 +6576,8 @@
 	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
@@ -5259,13 +6589,16 @@
 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
 	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GP3_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
 	case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
 	case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
@@ -5285,6 +6618,7 @@
 	case MLXPLAT_CPLD_LPC_REG_GWP_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
@@ -5297,9 +6631,11 @@
 	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
@@ -5370,6 +6706,13 @@
 	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
@@ -5431,6 +6774,14 @@
 	  MLXPLAT_CPLD_AGGR_MASK_LC_LOW },
 };
 
+static const struct reg_default mlxplat_mlxcpld_regmap_smart_switch[] = {
+	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
+	{ MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
+	{ MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
+	{ MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
+	{ MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET, MLXPLAT_CPLD_LPC_SM_SW_MASK },
+};
+
 struct mlxplat_mlxcpld_regmap_context {
 	void __iomem *base;
 };
@@ -5539,6 +6890,20 @@
 	.reg_write = mlxplat_mlxcpld_reg_write,
 };
 
+static const struct regmap_config mlxplat_mlxcpld_regmap_config_smart_switch = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 255,
+	.cache_type = REGCACHE_FLAT,
+	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
+	.readable_reg = mlxplat_mlxcpld_readable_reg,
+	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
+	.reg_defaults = mlxplat_mlxcpld_regmap_smart_switch,
+	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_smart_switch),
+	.reg_read = mlxplat_mlxcpld_reg_read,
+	.reg_write = mlxplat_mlxcpld_reg_write,
+};
+
 static struct resource mlxplat_mlxcpld_resources[] = {
 	[0] = DEFINE_RES_IRQ_NAMED(MLXPLAT_CPLD_LPC_SYSIRQ, "mlxreg-hotplug"),
 };
@@ -5550,6 +6915,7 @@
 static struct mlxreg_core_platform_data *mlxplat_fan;
 static struct mlxreg_core_platform_data
 	*mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS];
+static struct mlxreg_core_data *mlxplat_dpu_data[MLXPLAT_CPLD_DPU_MAX_DEVS];
 static const struct regmap_config *mlxplat_regmap_config;
 static struct pci_dev *lpc_bridge;
 static struct pci_dev *i2c_bridge;
@@ -5921,6 +7287,31 @@
 	return mlxplat_register_platform_device();
 }
 
+static int __init mlxplat_dmi_smart_switch_matched(const struct dmi_system_id *dmi)
+{
+	int i;
+
+	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
+	mlxplat_mux_num = ARRAY_SIZE(mlxplat_ng800_mux_data);
+	mlxplat_mux_data = mlxplat_ng800_mux_data;
+	mlxplat_hotplug = &mlxplat_mlxcpld_smart_switch_data;
+	mlxplat_hotplug->deferred_nr =
+		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+	mlxplat_led = &mlxplat_xdr_led_data;
+	mlxplat_regs_io = &mlxplat_smart_switch_regs_io_data;
+	mlxplat_fan = &mlxplat_xdr_fan_data;
+
+	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
+		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
+	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_dpu_data); i++)
+		mlxplat_dpu_data[i] = &mlxplat_mlxcpld_smart_switch_dpu_data[i];
+
+	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
+	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_smart_switch;
+
+	return mlxplat_register_platform_device();
+}
+
 static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
 	{
 		.callback = mlxplat_dmi_default_wc_matched,
@@ -6016,6 +7407,12 @@
 		},
 	},
 	{
+		.callback = mlxplat_dmi_smart_switch_matched,
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "VMOD0019"),
+		},
+	},
+	{
 		.callback = mlxplat_dmi_msn274x_matched,
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
@@ -6390,8 +7787,25 @@
 		}
 	}
 
+	/* Add DPU drivers. */
+	for (i = 0; i < MLXPLAT_CPLD_DPU_MAX_DEVS; i++) {
+		if (mlxplat_dpu_data[i]) {
+			priv->pdev_dpu[i] =
+				platform_device_register_resndata(&mlxplat_dev->dev, "mlxreg-dpu",
+								  i, NULL, 0, mlxplat_dpu_data[i],
+								  sizeof(*mlxplat_dpu_data[i]));
+			if (IS_ERR(priv->pdev_dpu[i])) {
+				err = PTR_ERR(priv->pdev_dpu[i]);
+				goto fail_platform_dpu_register;
+			}
+		}
+	}
+
 	return 0;
 
+fail_platform_dpu_register:
+	while (i--)
+		platform_device_unregister(priv->pdev_dpu[i]);
 fail_platform_wd_register:
 	while (--i >= 0)
 		platform_device_unregister(priv->pdev_wd[i]);
@@ -6412,6 +7826,8 @@
 {
 	int i;
 
+	for (i = MLXPLAT_CPLD_DPU_MAX_DEVS - 1; i >= 0; i--)
+		platform_device_unregister(priv->pdev_dpu[i]);
 	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
 		platform_device_unregister(priv->pdev_wd[i]);
 	if (priv->pdev_fan)

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 4/7] platform: mellanox: Cosmetic changes to improve code style
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
                   ` (2 preceding siblings ...)
  2025-04-12  9:18 ` [PATCH platform-next v8 3/7] platform: mellanox: Introduce support of Nvidia smart switch Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-15 14:40   ` Ilpo Järvinen
  2025-04-12  9:18 ` [PATCH platform-next v8 5/7] platform: mellanox: mlx-platform: Add support for new Nvidia system Vadim Pasternak
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Replace in 'for' loop - /i >= 0 ; i--/i >= 0 ;i--/.
Replace in 'while' loop - /(--i >= 0)/(--i)/.

Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
v5->v6
Comments pointed out by Ilpo:
- Fix 'while' loop in erro flow.
---
 drivers/platform/mellanox/mlx-platform.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
index 29d938265676..4c7ff22117a6 100644
--- a/drivers/platform/mellanox/mlx-platform.c
+++ b/drivers/platform/mellanox/mlx-platform.c
@@ -7807,7 +7807,7 @@ static int mlxplat_platdevs_init(struct mlxplat_priv *priv)
 	while (i--)
 		platform_device_unregister(priv->pdev_dpu[i]);
 fail_platform_wd_register:
-	while (--i >= 0)
+	while (i--)
 		platform_device_unregister(priv->pdev_wd[i]);
 fail_platform_fan_register:
 	if (mlxplat_regs_io)
@@ -7828,7 +7828,7 @@ static void mlxplat_platdevs_exit(struct mlxplat_priv *priv)
 
 	for (i = MLXPLAT_CPLD_DPU_MAX_DEVS - 1; i >= 0; i--)
 		platform_device_unregister(priv->pdev_dpu[i]);
-	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
+	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0; i--)
 		platform_device_unregister(priv->pdev_wd[i]);
 	if (priv->pdev_fan)
 		platform_device_unregister(priv->pdev_fan);
@@ -7873,7 +7873,7 @@ static int mlxplat_i2c_mux_topology_init(struct mlxplat_priv *priv)
 	return mlxplat_i2c_mux_complition_notify(priv, NULL, NULL);
 
 fail_platform_mux_register:
-	while (--i >= 0)
+	while (i--)
 		platform_device_unregister(priv->pdev_mux[i]);
 	return err;
 }
@@ -7882,7 +7882,7 @@ static void mlxplat_i2c_mux_topology_exit(struct mlxplat_priv *priv)
 {
 	int i;
 
-	for (i = mlxplat_mux_num - 1; i >= 0 ; i--) {
+	for (i = mlxplat_mux_num - 1; i >= 0; i--) {
 		if (priv->pdev_mux[i])
 			platform_device_unregister(priv->pdev_mux[i]);
 	}
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 5/7] platform: mellanox: mlx-platform: Add support for new Nvidia system
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
                   ` (3 preceding siblings ...)
  2025-04-12  9:18 ` [PATCH platform-next v8 4/7] platform: mellanox: Cosmetic changes to improve code style Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-15 14:48   ` Ilpo Järvinen
  2025-04-12  9:18 ` [PATCH platform-next v8 6/7] platform: mellanox: nvsw-sn2200: Add support for new system flavour Vadim Pasternak
  2025-04-12  9:18 ` [PATCH platform-next v8 7/7] Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces Vadim Pasternak
  6 siblings, 1 reply; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Add support for SN5640 and SN5610 Nvidia switch.

SN5640 is a 51.2Tbps switch based on Nvidia SPC-5 ASIC.
It provides up-to 400Gbps full bidirectional bandwidth per port.
The system supports 64 OSFP cages and fits into standard 2U racks.

SN5640 Features:
- 64 OSFP ports supporting 2.5Gbps - 400Gbps speeds.
- Air-cooled with 4 + 1 redundant fan units.
- 2 + 2 redundant 2000W PSUs.
- System management board based on AMD CPU with secure-boot support.

SN5610 is a 51.2Tbps switch based on Nvidia SPC-4 ASIC.
It provides up-to 800Gbps full bidirectional bandwidth per port.
The system supports 64 OSFP cages and fits into standard 2U racks.

SN5610 Features:
 - 64 OSFP ports supporting 10Gbps - 800Gbps speeds.
 - Air-cooled with 4 + 1 redundant fan units.
 - 2 + 2 redundant 2000W PSUs.
 - System management board based on AMD CPU with secure-boot support.

Reviewed-by: Oleksandr Shamray <oleksandrs@nvidia.com>
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
v6->v7
Changes added bt Vadim:
- Remove 'capability_mask' field.

v5->v6
Comments pointed out by Ilpo:
- Change 'int' to 'unsigned int' in mlxplat_dmi_ng400_hi171_matched().

v2->v3
Comments pointed out by Ilpo:
- Add empty lines for visibility in mlxplat_dmi_ng400_hi171_matched().
---
 drivers/platform/mellanox/mlx-platform.c | 96 ++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
index 4c7ff22117a6..9b8b430070b6 100644
--- a/drivers/platform/mellanox/mlx-platform.c
+++ b/drivers/platform/mellanox/mlx-platform.c
@@ -3000,6 +3000,59 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_l1_switch_data = {
 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT,
 };
 
+/* Platform hotplug for next-generation 800G systems family data  */
+static struct mlxreg_core_item mlxplat_mlxcpld_ng800_hi171_items[] = {
+	{
+		.data = mlxplat_mlxcpld_ext_psu_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = MLXPLAT_CPLD_PSU_EXT_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_modular_pwr_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = MLXPLAT_CPLD_PWR_EXT_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
+		.inversed = 0,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_xdr_fan_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = MLXPLAT_CPLD_FAN_XDR_MASK,
+		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_items_data),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_default_asic_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+		.mask = MLXPLAT_CPLD_ASIC_MASK,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
+		.inversed = 0,
+		.health = true,
+	},
+};
+
+static
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ng800_hi171_data = {
+	.items = mlxplat_mlxcpld_ng800_hi171_items,
+	.count = ARRAY_SIZE(mlxplat_mlxcpld_ng800_hi171_items),
+	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
+	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
+	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2,
+};
+
 /* Platform led default data */
 static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
 	{
@@ -4486,6 +4539,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
 		.mask = GENMASK(7, 0) & ~BIT(4),
 		.mode = 0644,
 	},
+	{
+		.label = "shutdown_unlock",
+		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
+		.mask = GENMASK(7, 0) & ~BIT(5),
+		.mode = 0644,
+	},
 	{
 		.label = "erot1_ap_reset",
 		.reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
@@ -7312,6 +7371,29 @@ static int __init mlxplat_dmi_smart_switch_matched(const struct dmi_system_id *d
 	return mlxplat_register_platform_device();
 }
 
+static int __init mlxplat_dmi_ng400_hi171_matched(const struct dmi_system_id *dmi)
+{
+	unsigned int i;
+
+	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
+	mlxplat_mux_num = ARRAY_SIZE(mlxplat_ng800_mux_data);
+	mlxplat_mux_data = mlxplat_ng800_mux_data;
+	mlxplat_hotplug = &mlxplat_mlxcpld_ng800_hi171_data;
+	mlxplat_hotplug->deferred_nr =
+		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+	mlxplat_led = &mlxplat_default_ng_led_data;
+	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
+	mlxplat_fan = &mlxplat_xdr_fan_data;
+
+	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type3); i++)
+		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type3[i];
+
+	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
+	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
+
+	return mlxplat_register_platform_device();
+}
+
 static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
 	{
 		.callback = mlxplat_dmi_default_wc_matched,
@@ -7412,6 +7494,20 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0019"),
 		},
 	},
+	{
+		.callback = mlxplat_dmi_ng400_hi171_matched,
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "VMOD0022"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI171"),
+		},
+	},
+	{
+		.callback = mlxplat_dmi_ng400_hi171_matched,
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "VMOD0022"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI172"),
+		},
+	},
 	{
 		.callback = mlxplat_dmi_msn274x_matched,
 		.matches = {
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 6/7] platform: mellanox: nvsw-sn2200: Add support for new system flavour
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
                   ` (4 preceding siblings ...)
  2025-04-12  9:18 ` [PATCH platform-next v8 5/7] platform: mellanox: mlx-platform: Add support for new Nvidia system Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-15 15:00   ` Ilpo Järvinen
  2025-04-12  9:18 ` [PATCH platform-next v8 7/7] Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces Vadim Pasternak
  6 siblings, 1 reply; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Add support for SN2201 system flavour, which is fitting OCP rack
form-factor and feeded from external power source through the rack
standard busbar interface.

Validate system type through DMI decode.
For new system flavour:
- Skip internal power supply configuration.
- Attach power hotswap device.

Reviewed-by: Michael Shych <michaelsh@nvidia.com>
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
 drivers/platform/mellanox/nvsw-sn2201.c | 110 +++++++++++++++++++++++-
 1 file changed, 107 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c
index 451d64c35c23..6f643e6ddb99 100644
--- a/drivers/platform/mellanox/nvsw-sn2201.c
+++ b/drivers/platform/mellanox/nvsw-sn2201.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/dmi.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -104,6 +105,9 @@
 	| NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \
 	| NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \
 	| NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)
+#define NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF \
+	(NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \
+	| NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)
 
 #define NVSW_SN2201_CPLD_ASIC_MASK		GENMASK(3, 1)
 #define NVSW_SN2201_CPLD_PSU_MASK		GENMASK(1, 0)
@@ -132,6 +136,7 @@
  * @cpld_devs: I2C devices for cpld;
  * @cpld_devs_num: number of I2C devices for cpld;
  * @main_mux_deferred_nr: I2C adapter number must be exist prior creating devices execution;
+ * @ext_pwr_source: 1 if system powered by external power supply; 0 - by internal;
  */
 struct nvsw_sn2201 {
 	struct device *dev;
@@ -152,6 +157,7 @@ struct nvsw_sn2201 {
 	struct mlxreg_hotplug_device *cpld_devs;
 	int cpld_devs_num;
 	int main_mux_deferred_nr;
+	u8 ext_pwr_source;
 };
 
 static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg)
@@ -522,6 +528,35 @@ struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = {
 	.mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF,
 };
 
+static struct mlxreg_core_item nvsw_sn2201_busbar_items[] = {
+	{
+		.data = nvsw_sn2201_fan_items_data,
+		.aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF,
+		.reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
+		.mask = NVSW_SN2201_CPLD_FAN_MASK,
+		.count = ARRAY_SIZE(nvsw_sn2201_fan_items_data),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = nvsw_sn2201_sys_items_data,
+		.aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF,
+		.reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
+		.mask = NVSW_SN2201_CPLD_ASIC_MASK,
+		.count = ARRAY_SIZE(nvsw_sn2201_sys_items_data),
+		.inversed = 1,
+		.health = false,
+	},
+};
+
+static
+struct mlxreg_core_hotplug_platform_data nvsw_sn2201_busbar_hotplug = {
+	.items = nvsw_sn2201_items,
+	.count = ARRAY_SIZE(nvsw_sn2201_busbar_items),
+	.cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET,
+	.mask = NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF,
+};
+
 /* SN2201 static devices. */
 static struct i2c_board_info nvsw_sn2201_static_devices[] = {
 	{
@@ -557,6 +592,9 @@ static struct i2c_board_info nvsw_sn2201_static_devices[] = {
 	{
 		I2C_BOARD_INFO("pmbus", 0x40),
 	},
+	{
+		I2C_BOARD_INFO("lm5066i", 0x15),
+	},
 };
 
 /* SN2201 default static board info. */
@@ -607,6 +645,58 @@ static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = {
 	},
 };
 
+/* SN2201 default basbar static board info. */
+static struct mlxreg_hotplug_device nvsw_sn2201_busbar_static_brdinfo[] = {
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[0],
+		.nr = NVSW_SN2201_MAIN_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[1],
+		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[2],
+		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[3],
+		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[4],
+		.nr = NVSW_SN2201_MAIN_MUX_CH3_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[5],
+		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[6],
+		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[7],
+		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[8],
+		.nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[9],
+		.nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[10],
+		.nr = NVSW_SN2201_MAIN_MUX_CH7_NR,
+	},
+	{
+		.brdinfo = &nvsw_sn2201_static_devices[11],
+		.nr = NVSW_SN2201_MAIN_MUX_CH1_NR,
+	},
+};
+
 /* LED default data. */
 static struct mlxreg_core_data nvsw_sn2201_led_data[] = {
 	{
@@ -981,7 +1071,10 @@ static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap
 	nvsw_sn2201->io_data = &nvsw_sn2201_regs_io;
 	nvsw_sn2201->led_data = &nvsw_sn2201_led;
 	nvsw_sn2201->wd_data = &nvsw_sn2201_wd;
-	nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug;
+	if (nvsw_sn2201->ext_pwr_source)
+		nvsw_sn2201->hotplug_data = &nvsw_sn2201_busbar_hotplug;
+	else
+		nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug;
 
 	/* Register IO access driver. */
 	if (nvsw_sn2201->io_data) {
@@ -1198,12 +1291,18 @@ static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201)
 static int nvsw_sn2201_probe(struct platform_device *pdev)
 {
 	struct nvsw_sn2201 *nvsw_sn2201;
+	const char *sku;
 	int ret;
 
 	nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL);
 	if (!nvsw_sn2201)
 		return -ENOMEM;
 
+	/* Validate system powering type. */
+	sku = dmi_get_system_info(DMI_PRODUCT_SKU);
+	if (!strcmp(sku, "HI168"))
+		nvsw_sn2201->ext_pwr_source = 1;
+
 	nvsw_sn2201->dev = &pdev->dev;
 	platform_set_drvdata(pdev, nvsw_sn2201);
 	ret = platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources,
@@ -1214,8 +1313,13 @@ static int nvsw_sn2201_probe(struct platform_device *pdev)
 	nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR;
 	nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo;
 	nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo;
-	nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo;
-	nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo);
+	if (nvsw_sn2201->ext_pwr_source) {
+		nvsw_sn2201->sn2201_devs = nvsw_sn2201_busbar_static_brdinfo;
+		nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_busbar_static_brdinfo);
+	} else {
+		nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo;
+		nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo);
+	}
 
 	return nvsw_sn2201_config_pre_init(nvsw_sn2201);
 }
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH platform-next v8 7/7] Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces
  2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
                   ` (5 preceding siblings ...)
  2025-04-12  9:18 ` [PATCH platform-next v8 6/7] platform: mellanox: nvsw-sn2200: Add support for new system flavour Vadim Pasternak
@ 2025-04-12  9:18 ` Vadim Pasternak
  2025-04-15 15:02   ` Ilpo Järvinen
  6 siblings, 1 reply; 14+ messages in thread
From: Vadim Pasternak @ 2025-04-12  9:18 UTC (permalink / raw)
  To: hdegoede, ilpo.jarvinen
  Cc: michaelsh, crajank, fradensky, oleksandrs, platform-driver-x86,
	Vadim Pasternak

Add documentation for the new attributes:
- Request and response for access to protetced flashes:
  "global_wp_request", "global_wp_response".
  Only for systems equipped with BMC - grant can be provided only by
  BMC in case its security policy allows to grant access.
- Request to unlock ASICs, which has been shutdown due-to ASIC thermal
  event: "shutdown_unlock".
- Data processor Units (DPU) boot progress: "boot_progress".
- DPU reset causes: "reset_aux_pwr_or_reload", "reset_dpu_thermal",
  "reset_from_main_board".
- Reset control for DPU components: "perst_rst", "phy_rst", "tpm_rst",
  "usbphy_rst".
- DPU Unified Fabric Manager upgrade - "ufm_upgrade".
- Hardware Id of Data Process Unit board - "dpu_id".

Reviewed-by: Michael Shych <michaelsh@nvidia.com>
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
v7->v8
Added by Vadim:
- Fix dates.
v5->v6
Comments pointed out by Ilpo:
- Fix dates.
---
 .../ABI/stable/sysfs-driver-mlxreg-io         | 96 +++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
index 2cdfd09123da..acc0c9a9ac29 100644
--- a/Documentation/ABI/stable/sysfs-driver-mlxreg-io
+++ b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
@@ -715,3 +715,99 @@ Description:	This file shows 1 in case the system reset happened due to the
 		switch board.
 
 		The file is read only.
+
+What:		/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/global_wp_request
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	This file when written 1 activates request to allow access to
+		the write protected flashes. Such request can be performed only
+		for system equipped with BMC (Board Management Controller),
+		which can grant access to protected flashes. In case BMC allows
+		access - it will respond with "global_wp_response". BMC decides
+		regarding time window of granted access. After granted window is
+		expired, BMC will change value back to 0.
+		Default value is 0.
+
+		The file is read/write.
+
+What:		/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/global_wp_response
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	This file, when set 1, indicates that access to protected
+		flashes have been granted to host CPU by BMC.
+		Default value is 0.
+
+		The file is read only.
+
+What:		/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/shutdown_unlock
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak vadimp@nvidia.com
+Description:	When ASICs are getting overheated, system protection
+		hardware mechanism enforces system reboot. After system
+		reboot ASICs come up in locked state. To unlock ASICs,
+		this file should be written 1
+		Default value is 0.
+
+		The file is read/write.
+
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/boot_progress
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	These files show the Data Process Unit board boot progress
+		state. Valid states are:
+		- 4 : OS starting.
+		- 5 : OS running.
+		- 6 : Low-Power Standby.
+
+		The file is read only.
+
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/dpu_id
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	This file shows hardware Id of Data Process Unit board.
+
+		The file is read only.
+
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/reset_aux_pwr_or_reload
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/reset_dpu_thermal
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/reset_from_main_board
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	These files show the Data Process Unit board reset cause, as
+		following: reset due to power auxiliary outage or power reload, reset
+		due to thermal shutdown, reset due to request from main board.
+		Value 1 in file means this is reset cause, 0 - otherwise. Only one of
+		the above causes could be 1 at the same time, representing only last
+		reset cause.
+
+		The files are read only.
+
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/perst_rst
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/phy_rst
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/tpm_rst
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/usbphy_rst
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	These files allow to reset hardware components of Data Process
+		Unit board. Respectively PCI, Ethernet PHY, TPM and USB PHY
+		resets.
+		Default values for all the attributes is 1. Writing 0 will
+		cause reset of the related component.
+
+		The files are read/write.
+
+What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/ufm_upgrade
+Date:		April 2025
+KernelVersion:	6.15
+Contact:	Vadim Pasternak <vadimp@nvidia.com>
+Description:	These files show status of Unified Fabric Manager upgrade.
+		state. 0 - means upgrade is done, 1 - otherwise.
+
+		The file is read only.
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH platform-next v8 2/7] platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU
  2025-04-12  9:18 ` [PATCH platform-next v8 2/7] platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU Vadim Pasternak
@ 2025-04-15 14:32   ` Ilpo Järvinen
  0 siblings, 0 replies; 14+ messages in thread
From: Ilpo Järvinen @ 2025-04-15 14:32 UTC (permalink / raw)
  To: Vadim Pasternak
  Cc: Hans de Goede, michaelsh, crajank, fradensky, oleksandrs,
	platform-driver-x86

[-- Attachment #1: Type: text/plain, Size: 24246 bytes --]

Hi Vadim,

I took the first patch into the review-ilpo-next branch.

On Sat, 12 Apr 2025, Vadim Pasternak wrote:

> Provide platform support for Nvidia (DPU) Data Processor Unit for the
> Smart Switch SN4280.
> 
> The Smart Switch equipped with:
> - Nvidia COME module based on AMD EPYC™ Embedded 3451 CPU.
> - Nvidia Spectrum-3 ASIC.
> - Four DPUs, each equipped with Nvidia BF3 ARM based processor and
>   with Lattice LFD2NX-40 FPGA device.
> - 28xQSFP-DD external ports.
> - Two power supplies.
> - Four cooling drawers.
> 
> Drivers provides support for the platform management and monitoring
> of DPU components.
> It includes support for health events, resets and boot progress

Please reflow this paragraph.

> indications logic, implemented by FPGA device.
> 
> Reviewed-by: Ciju Rajan K <crajank@nvidia.com>
> Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
> v6->v7
> Changes added by Vadim:
> - Fix few registers setting.
> v5->v6
> Comments pointed out by Ilpo:
> - Fix structure title to conform to kerneldoc formatting.
> - Remove unnecessary comments.
> v4->v5
> Comments pointed out by Ilpo:
> - Add empty line in mlxreg_dpu_config_init().
> - Include 'dev_printk.h' from dev_err().
> - Remove unnecessary comments from mlxreg_dpu_config_exit().
> - Put defer probing test in mlxreg_dpu_probe() before allocation.
> - Remove unnecessary comments from mlxreg_dpu_probe().
> 
> v3->v4
> Comments pointed out by Ilpo:
> - Fix method of duplication data.
> - Rename 'count' to 'item_count'.
> 
> v2->v3
> Comments pointed out by Ilpo:
> - Fix s/pltaform/platform.
> - Remove semicolon from structure description.
> - In routine mlxreg_dpu_copy_hotplug_data() use 'const struct' for the
>   third argument.
> - In mlxreg_dpu_copy_hotplug_data() remove redunadant devm_kmemdup()
>   call.
> - Fix identifications in mlxreg_dpu_config_init().
> - Remove label 'fail_register_io" from error flow.
> - One line for devm_regmap_init_i2c() call in mlxreg_dpu_probe().
> ---
>  drivers/platform/mellanox/Kconfig      |  12 +
>  drivers/platform/mellanox/Makefile     |   1 +
>  drivers/platform/mellanox/mlxreg-dpu.c | 619 +++++++++++++++++++++++++
>  3 files changed, 632 insertions(+)
>  create mode 100644 drivers/platform/mellanox/mlxreg-dpu.c
> 
> diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig
> index aa760f064a17..7da0fc46b1e7 100644
> --- a/drivers/platform/mellanox/Kconfig
> +++ b/drivers/platform/mellanox/Kconfig
> @@ -27,6 +27,18 @@ config MLX_PLATFORM
>  
>  	  If you have a Mellanox system, say Y or M here.
>  
> +config MLXREG_DPU
> +	tristate "Nvidia Data Processor Unit platform driver support"
> +	select REGMAP_I2C
> +	help
> +	  This driver provides support for the Nvidia BF3 Data Processor Units,
> +	  which are the part of SN4280 Ethernet smart switch systems
> +	  providing a high performance switching solution for Enterprise Data
> +	  Centers (EDC) for building Ethernet based clusters, High-Performance
> +	  Computing (HPC) and embedded environments.
> +
> +	  If you have a Nvidia smart swicth system, say Y or M here.

swicth -> switch

(I'd have fixed that myself while applying but then I noticed the 
error/rollback oddities marked below.)

> +
>  config MLXREG_HOTPLUG
>  	tristate "Mellanox platform hotplug driver support"
>  	depends on HWMON
> diff --git a/drivers/platform/mellanox/Makefile b/drivers/platform/mellanox/Makefile
> index ba56485cbe8c..e86723b44c2e 100644
> --- a/drivers/platform/mellanox/Makefile
> +++ b/drivers/platform/mellanox/Makefile
> @@ -7,6 +7,7 @@ obj-$(CONFIG_MLX_PLATFORM)	+= mlx-platform.o
>  obj-$(CONFIG_MLXBF_BOOTCTL)	+= mlxbf-bootctl.o
>  obj-$(CONFIG_MLXBF_PMC)		+= mlxbf-pmc.o
>  obj-$(CONFIG_MLXBF_TMFIFO)	+= mlxbf-tmfifo.o
> +obj-$(CONFIG_MLXREG_DPU)	+= mlxreg-dpu.o
>  obj-$(CONFIG_MLXREG_HOTPLUG)	+= mlxreg-hotplug.o
>  obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
>  obj-$(CONFIG_MLXREG_LC) += mlxreg-lc.o
> diff --git a/drivers/platform/mellanox/mlxreg-dpu.c b/drivers/platform/mellanox/mlxreg-dpu.c
> new file mode 100644
> index 000000000000..5245b7a14af3
> --- /dev/null
> +++ b/drivers/platform/mellanox/mlxreg-dpu.c
> @@ -0,0 +1,619 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Nvidia Data Processor Unit platform driver
> + *
> + * Copyright (C) 2025 Nvidia Technologies Ltd.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/dev_printk.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/platform_data/mlxcpld.h>
> +#include <linux/platform_data/mlxreg.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +/* I2C bus IO offsets */
> +#define MLXREG_DPU_REG_FPGA1_VER_OFFSET			0x2400
> +#define MLXREG_DPU_REG_FPGA1_PN_OFFSET			0x2404
> +#define MLXREG_DPU_REG_FPGA1_PN1_OFFSET			0x2405
> +#define MLXREG_DPU_REG_PG_OFFSET			0x2414
> +#define MLXREG_DPU_REG_PG_EVENT_OFFSET			0x2415
> +#define MLXREG_DPU_REG_PG_MASK_OFFSET			0x2416
> +#define MLXREG_DPU_REG_RESET_GP1_OFFSET			0x2417
> +#define MLXREG_DPU_REG_RST_CAUSE1_OFFSET		0x241e
> +#define MLXREG_DPU_REG_GP0_RO_OFFSET			0x242b
> +#define MLXREG_DPU_REG_GP0_OFFSET			0x242e
> +#define MLXREG_DPU_REG_GP1_OFFSET			0x242c
> +#define MLXREG_DPU_REG_GP4_OFFSET			0x2438
> +#define MLXREG_DPU_REG_AGGRCO_OFFSET			0x2442
> +#define MLXREG_DPU_REG_AGGRCO_MASK_OFFSET		0x2443
> +#define MLXREG_DPU_REG_HEALTH_OFFSET			0x244d
> +#define MLXREG_DPU_REG_HEALTH_EVENT_OFFSET		0x244e
> +#define MLXREG_DPU_REG_HEALTH_MASK_OFFSET		0x244f
> +#define MLXREG_DPU_REG_FPGA1_MVER_OFFSET		0x24de
> +#define MLXREG_DPU_REG_CONFIG3_OFFSET			0x24fd
> +#define MLXREG_DPU_REG_MAX				0x3fff
> +
> +/* Power Good event masks. */
> +#define MLXREG_DPU_PG_VDDIO_MASK			BIT(0)
> +#define MLXREG_DPU_PG_VDD_CPU_MASK			BIT(1)
> +#define MLXREG_DPU_PG_VDD_MASK				BIT(2)
> +#define MLXREG_DPU_PG_1V8_MASK				BIT(3)
> +#define MLXREG_DPU_PG_COMPARATOR_MASK			BIT(4)
> +#define MLXREG_DPU_PG_VDDQ_MASK				BIT(5)
> +#define MLXREG_DPU_PG_HVDD_MASK				BIT(6)
> +#define MLXREG_DPU_PG_DVDD_MASK				BIT(7)
> +#define MLXREG_DPU_PG_MASK				(MLXREG_DPU_PG_DVDD_MASK | \
> +							 MLXREG_DPU_PG_HVDD_MASK | \
> +							 MLXREG_DPU_PG_VDDQ_MASK | \
> +							 MLXREG_DPU_PG_COMPARATOR_MASK | \
> +							 MLXREG_DPU_PG_1V8_MASK | \
> +							 MLXREG_DPU_PG_VDD_CPU_MASK | \
> +							 MLXREG_DPU_PG_VDD_MASK | \
> +							 MLXREG_DPU_PG_VDDIO_MASK)
> +
> +/* Health event masks. */
> +#define MLXREG_DPU_HLTH_THERMAL_TRIP_MASK		BIT(0)
> +#define MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK		BIT(1)
> +#define MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK		BIT(2)
> +#define MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK		BIT(3)
> +#define MLXREG_DPU_HLTH_VDDQ_ALERT_MASK			BIT(4)
> +#define MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK		BIT(5)
> +#define MLXREG_DPU_HEALTH_MASK				(MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK | \
> +							 MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK | \
> +							 MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK | \
> +							 MLXREG_DPU_HLTH_VDDQ_ALERT_MASK | \
> +							 MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK | \
> +							 MLXREG_DPU_HLTH_THERMAL_TRIP_MASK)
> +
> +/* Hotplug aggregation masks. */
> +#define MLXREG_DPU_HEALTH_AGGR_MASK			BIT(0)
> +#define MLXREG_DPU_PG_AGGR_MASK				BIT(1)
> +#define MLXREG_DPU_AGGR_MASK				(MLXREG_DPU_HEALTH_AGGR_MASK | \
> +							 MLXREG_DPU_PG_AGGR_MASK)
> +
> +/* Voltage regulator firmware update status mask. */
> +#define MLXREG_DPU_VOLTREG_UPD_MASK			GENMASK(5, 4)
> +
> +#define MLXREG_DPU_NR_NONE				(-1)
> +
> +/*
> + * enum mlxreg_dpu_type - Data Processor Unit types
> + *
> + * @MLXREG_DPU_BF3: DPU equipped with BF3 SoC;
> + */
> +enum mlxreg_dpu_type {
> +	MLXREG_DPU_BF3 = 0x0050,
> +};
> +
> +/* Default register access data. */
> +static struct mlxreg_core_data mlxreg_dpu_io_data[] = {
> +	{
> +		.label = "fpga1_version",
> +		.reg = MLXREG_DPU_REG_FPGA1_VER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "fpga1_pn",
> +		.reg = MLXREG_DPU_REG_FPGA1_PN_OFFSET,
> +		.bit = GENMASK(15, 0),
> +		.mode = 0444,
> +		.regnum = 2,
> +	},
> +	{
> +		.label = "fpga1_version_min",
> +		.reg = MLXREG_DPU_REG_FPGA1_MVER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "perst_rst",
> +		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "usbphy_rst",
> +		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "phy_rst",
> +		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "tpm_rst",
> +		.reg = MLXREG_DPU_REG_RESET_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(6),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "reset_from_main_board",
> +		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_aux_pwr_or_reload",
> +		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_comex_pwr_fail",
> +		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_dpu_thermal",
> +		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(6),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_pwr_off",
> +		.reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(7),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "dpu_id",
> +		.reg = MLXREG_DPU_REG_GP0_RO_OFFSET,
> +		.bit = GENMASK(3, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "voltreg_update_status",
> +		.reg = MLXREG_DPU_REG_GP0_RO_OFFSET,
> +		.mask = MLXREG_DPU_VOLTREG_UPD_MASK,
> +		.bit = 5,
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "boot_progress",
> +		.reg = MLXREG_DPU_REG_GP1_OFFSET,
> +		.mask = GENMASK(3, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "ufm_upgrade",
> +		.reg = MLXREG_DPU_REG_GP4_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0644,
> +	},
> +};
> +
> +static struct mlxreg_core_platform_data mlxreg_dpu_default_regs_io_data = {
> +		.data = mlxreg_dpu_io_data,
> +		.counter = ARRAY_SIZE(mlxreg_dpu_io_data),
> +};
> +
> +/* Default hotplug data. */
> +static struct mlxreg_core_data mlxreg_dpu_power_events_items_data[] = {
> +	{
> +		.label = "pg_vddio",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_VDDIO_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_vdd_cpu",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_VDD_CPU_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_vdd",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_VDD_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_1v8",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_1V8_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_comparator",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_COMPARATOR_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_vddq",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_VDDQ_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_hvdd",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_HVDD_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "pg_dvdd",
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_DVDD_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +};
> +
> +static struct mlxreg_core_data mlxreg_dpu_health_events_items_data[] = {
> +	{
> +		.label = "thermal_trip",
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HLTH_THERMAL_TRIP_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "ufm_upgrade_done",
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "vddq_hot_alert",
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "vdd_cpu_hot_alert",
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "vddq_alert",
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HLTH_VDDQ_ALERT_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +	{
> +		.label = "vdd_cpu_alert",
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK,
> +		.hpdev.nr = MLXREG_DPU_NR_NONE,
> +	},
> +};
> +
> +static struct mlxreg_core_item mlxreg_dpu_hotplug_items[] = {
> +	{
> +		.data = mlxreg_dpu_power_events_items_data,
> +		.aggr_mask = MLXREG_DPU_PG_AGGR_MASK,
> +		.reg = MLXREG_DPU_REG_PG_OFFSET,
> +		.mask = MLXREG_DPU_PG_MASK,
> +		.count = ARRAY_SIZE(mlxreg_dpu_power_events_items_data),
> +		.health = false,
> +		.inversed = 0,
> +	},
> +	{
> +		.data = mlxreg_dpu_health_events_items_data,
> +		.aggr_mask = MLXREG_DPU_HEALTH_AGGR_MASK,
> +		.reg = MLXREG_DPU_REG_HEALTH_OFFSET,
> +		.mask = MLXREG_DPU_HEALTH_MASK,
> +		.count = ARRAY_SIZE(mlxreg_dpu_health_events_items_data),
> +		.health = false,
> +		.inversed = 0,
> +	},
> +};
> +
> +static
> +struct mlxreg_core_hotplug_platform_data mlxreg_dpu_default_hotplug_data = {
> +	.items = mlxreg_dpu_hotplug_items,
> +	.count = ARRAY_SIZE(mlxreg_dpu_hotplug_items),
> +	.cell = MLXREG_DPU_REG_AGGRCO_OFFSET,
> +	.mask = MLXREG_DPU_AGGR_MASK,
> +};
> +
> +/**
> + * struct mlxreg_dpu - device private data
> + * @dev: platform device
> + * @data: platform core data
> + * @io_data: register access platform data
> + * @io_regs: register access device
> + * @hotplug_data: hotplug platform data
> + * @hotplug: hotplug device
> + */
> +struct mlxreg_dpu {
> +	struct device *dev;
> +	struct mlxreg_core_data *data;
> +	struct mlxreg_core_platform_data *io_data;
> +	struct platform_device *io_regs;
> +	struct mlxreg_core_hotplug_platform_data *hotplug_data;
> +	struct platform_device *hotplug;
> +};
> +
> +static bool mlxreg_dpu_writeable_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case MLXREG_DPU_REG_PG_EVENT_OFFSET:
> +	case MLXREG_DPU_REG_PG_MASK_OFFSET:
> +	case MLXREG_DPU_REG_RESET_GP1_OFFSET:
> +	case MLXREG_DPU_REG_GP0_OFFSET:
> +	case MLXREG_DPU_REG_GP1_OFFSET:
> +	case MLXREG_DPU_REG_GP4_OFFSET:
> +	case MLXREG_DPU_REG_AGGRCO_OFFSET:
> +	case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_MASK_OFFSET:
> +		return true;
> +	}
> +	return false;
> +}
> +
> +static bool mlxreg_dpu_readable_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case MLXREG_DPU_REG_FPGA1_VER_OFFSET:
> +	case MLXREG_DPU_REG_FPGA1_PN_OFFSET:
> +	case MLXREG_DPU_REG_FPGA1_PN1_OFFSET:
> +	case MLXREG_DPU_REG_PG_OFFSET:
> +	case MLXREG_DPU_REG_PG_EVENT_OFFSET:
> +	case MLXREG_DPU_REG_PG_MASK_OFFSET:
> +	case MLXREG_DPU_REG_RESET_GP1_OFFSET:
> +	case MLXREG_DPU_REG_RST_CAUSE1_OFFSET:
> +	case MLXREG_DPU_REG_GP0_RO_OFFSET:
> +	case MLXREG_DPU_REG_GP0_OFFSET:
> +	case MLXREG_DPU_REG_GP1_OFFSET:
> +	case MLXREG_DPU_REG_GP4_OFFSET:
> +	case MLXREG_DPU_REG_AGGRCO_OFFSET:
> +	case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_MASK_OFFSET:
> +	case MLXREG_DPU_REG_FPGA1_MVER_OFFSET:
> +	case MLXREG_DPU_REG_CONFIG3_OFFSET:
> +		return true;
> +	}
> +	return false;
> +}
> +
> +static bool mlxreg_dpu_volatile_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case MLXREG_DPU_REG_FPGA1_VER_OFFSET:
> +	case MLXREG_DPU_REG_FPGA1_PN_OFFSET:
> +	case MLXREG_DPU_REG_FPGA1_PN1_OFFSET:
> +	case MLXREG_DPU_REG_PG_OFFSET:
> +	case MLXREG_DPU_REG_PG_EVENT_OFFSET:
> +	case MLXREG_DPU_REG_PG_MASK_OFFSET:
> +	case MLXREG_DPU_REG_RESET_GP1_OFFSET:
> +	case MLXREG_DPU_REG_RST_CAUSE1_OFFSET:
> +	case MLXREG_DPU_REG_GP0_RO_OFFSET:
> +	case MLXREG_DPU_REG_GP0_OFFSET:
> +	case MLXREG_DPU_REG_GP1_OFFSET:
> +	case MLXREG_DPU_REG_GP4_OFFSET:
> +	case MLXREG_DPU_REG_AGGRCO_OFFSET:
> +	case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET:
> +	case MLXREG_DPU_REG_HEALTH_MASK_OFFSET:
> +	case MLXREG_DPU_REG_FPGA1_MVER_OFFSET:
> +	case MLXREG_DPU_REG_CONFIG3_OFFSET:
> +		return true;
> +	}
> +	return false;
> +}
> +
> +/* Configuration for the register map of a device with 2 bytes address space. */
> +static const struct regmap_config mlxreg_dpu_regmap_conf = {
> +	.reg_bits = 16,
> +	.val_bits = 8,
> +	.max_register = MLXREG_DPU_REG_MAX,
> +	.cache_type = REGCACHE_FLAT,
> +	.writeable_reg = mlxreg_dpu_writeable_reg,
> +	.readable_reg = mlxreg_dpu_readable_reg,
> +	.volatile_reg = mlxreg_dpu_volatile_reg,
> +};
> +
> +static int
> +mlxreg_dpu_copy_hotplug_data(struct device *dev, struct mlxreg_dpu *mlxreg_dpu,
> +			     const struct mlxreg_core_hotplug_platform_data *hotplug_data)
> +{
> +	struct mlxreg_core_item *item;
> +	int i;
> +
> +	mlxreg_dpu->hotplug_data = devm_kmemdup(dev, hotplug_data,
> +						sizeof(*mlxreg_dpu->hotplug_data), GFP_KERNEL);
> +	if (!mlxreg_dpu->hotplug_data)
> +		return -ENOMEM;
> +
> +	mlxreg_dpu->hotplug_data->items = devm_kmemdup(dev, hotplug_data->items,
> +						       mlxreg_dpu->hotplug_data->count *
> +						       sizeof(*mlxreg_dpu->hotplug_data->items),
> +						       GFP_KERNEL);
> +	if (!mlxreg_dpu->hotplug_data->items)
> +		return -ENOMEM;
> +
> +	item = mlxreg_dpu->hotplug_data->items;
> +	for (i = 0; i < hotplug_data->count; i++, item++) {
> +		item->data = devm_kmemdup(dev, hotplug_data->items[i].data,
> +					  hotplug_data->items[i].count * sizeof(*item->data),
> +					  GFP_KERNEL);
> +		if (!item->data)
> +			return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mlxreg_dpu_config_init(struct mlxreg_dpu *mlxreg_dpu, void *regmap,
> +				  struct mlxreg_core_data *data, int irq)
> +{
> +	struct device *dev = &data->hpdev.client->dev;
> +	u32 regval;
> +	int err;
> +
> +	/* Validate DPU type. */
> +	err = regmap_read(regmap, MLXREG_DPU_REG_CONFIG3_OFFSET, &regval);
> +	if (err)
> +		return err;
> +
> +	switch (regval) {
> +	case MLXREG_DPU_BF3:
> +		/* Copy platform specific hotplug data. */
> +		err = mlxreg_dpu_copy_hotplug_data(dev, mlxreg_dpu,
> +						   &mlxreg_dpu_default_hotplug_data);
> +		if (err)
> +			return err;
> +
> +		mlxreg_dpu->io_data = &mlxreg_dpu_default_regs_io_data;
> +
> +		break;
> +	default:
> +		return -ENODEV;
> +	}
> +
> +	/* Register IO access driver. */
> +	if (mlxreg_dpu->io_data) {
> +		mlxreg_dpu->io_data->regmap = regmap;
> +		mlxreg_dpu->io_regs =
> +			platform_device_register_resndata(dev, "mlxreg-io",
> +							  data->slot, NULL, 0,
> +							  mlxreg_dpu->io_data,
> +							  sizeof(*mlxreg_dpu->io_data));
> +		if (IS_ERR(mlxreg_dpu->io_regs)) {
> +			dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
> +				data->hpdev.brdinfo->type, data->hpdev.nr,
> +				data->hpdev.brdinfo->addr);
> +			return PTR_ERR(mlxreg_dpu->io_regs);
> +		}
> +	}
> +
> +	/* Register hotplug driver. */
> +	if (mlxreg_dpu->hotplug_data && irq) {
> +		mlxreg_dpu->hotplug_data->regmap = regmap;
> +		mlxreg_dpu->hotplug_data->irq = irq;
> +		mlxreg_dpu->hotplug =
> +			platform_device_register_resndata(dev, "mlxreg-hotplug",
> +							  data->slot, NULL, 0,
> +							  mlxreg_dpu->hotplug_data,
> +							  sizeof(*mlxreg_dpu->hotplug_data));
> +		if (IS_ERR(mlxreg_dpu->hotplug)) {
> +			err = PTR_ERR(mlxreg_dpu->hotplug);
> +			goto fail_register_hotplug;
> +		}
> +	}
> +
> +	return 0;
> +
> +fail_register_hotplug:
> +	platform_device_unregister(mlxreg_dpu->io_regs);
> +
> +	return err;
> +}
> +
> +static void mlxreg_dpu_config_exit(struct mlxreg_dpu *mlxreg_dpu)
> +{
> +	platform_device_unregister(mlxreg_dpu->hotplug);
> +	platform_device_unregister(mlxreg_dpu->io_regs);
> +}
> +
> +static int mlxreg_dpu_probe(struct platform_device *pdev)
> +{
> +	struct mlxreg_core_data *data;
> +	struct mlxreg_dpu *mlxreg_dpu;
> +	void *regmap;
> +	int err;
> +
> +	data = dev_get_platdata(&pdev->dev);
> +	if (!data || !data->hpdev.brdinfo)
> +		return -EINVAL;
> +
> +	data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
> +	if (!data->hpdev.adapter)
> +		return -EPROBE_DEFER;
> +
> +	mlxreg_dpu = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_dpu), GFP_KERNEL);
> +	if (!mlxreg_dpu)
> +		return -ENOMEM;
> +
> +	/* Create device at the top of DPU I2C tree.*/

Missing space.

> +	data->hpdev.client = i2c_new_client_device(data->hpdev.adapter,
> +						   data->hpdev.brdinfo);
> +	if (IS_ERR(data->hpdev.client)) {
> +		dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
> +			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
> +		err = PTR_ERR(data->hpdev.client);
> +		goto i2c_new_device_fail;
> +	}
> +
> +	regmap = devm_regmap_init_i2c(data->hpdev.client, &mlxreg_dpu_regmap_conf);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
> +			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
> +		err = PTR_ERR(regmap);
> +		goto devm_regmap_init_i2c_fail;
> +	}
> +
> +	/* Sync registers with hardware. */
> +	regcache_mark_dirty(regmap);
> +	err = regcache_sync(regmap);
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
> +			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
> +		err = PTR_ERR(regmap);
> +		goto regcache_sync_fail;
> +	}
> +
> +	mlxreg_dpu->data = data;
> +	mlxreg_dpu->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, mlxreg_dpu);
> +
> +	err = mlxreg_dpu_config_init(mlxreg_dpu, regmap, data, data->hpdev.brdinfo->irq);
> +	if (err)
> +		goto mlxreg_dpu_config_init_fail;
> +
> +	return err;
> +
> +mlxreg_dpu_config_init_fail:
> +regcache_sync_fail:
> +devm_regmap_init_i2c_fail:
> +	if (data->hpdev.client) {

How can this be NULL at this point?

> +		i2c_unregister_device(data->hpdev.client);
> +		data->hpdev.client = NULL;

Why is this needed?

> +	}
> +i2c_new_device_fail:
> +	i2c_put_adapter(data->hpdev.adapter);
> +	data->hpdev.adapter = NULL;

Why is this needed?

> +	return err;
> +}
> +
> +static void mlxreg_dpu_remove(struct platform_device *pdev)
> +{
> +	struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
> +	struct mlxreg_dpu *mlxreg_dpu = platform_get_drvdata(pdev);
> +
> +	mlxreg_dpu_config_exit(mlxreg_dpu);
> +	if (data->hpdev.client) {

Same here, how can this be NULL?

> +		i2c_unregister_device(data->hpdev.client);
> +		data->hpdev.client = NULL;
> +		i2c_put_adapter(data->hpdev.adapter);
> +		data->hpdev.adapter = NULL;

Are these two NULL assignments necessary here? Why?

> +	}
> +}
> +
> +static struct platform_driver mlxreg_dpu_driver = {
> +	.probe = mlxreg_dpu_probe,
> +	.remove = mlxreg_dpu_remove,
> +	.driver = {
> +		.name = "mlxreg-dpu",
> +	},
> +};
> +
> +module_platform_driver(mlxreg_dpu_driver);
> +
> +MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>");
> +MODULE_DESCRIPTION("Nvidia Data Processor Unit platform driver");
> +MODULE_LICENSE("Dual BSD/GPL");
> +MODULE_ALIAS("platform:mlxreg-dpu");
> 

-- 
 i.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH platform-next v8 3/7] platform: mellanox: Introduce support of Nvidia smart switch
  2025-04-12  9:18 ` [PATCH platform-next v8 3/7] platform: mellanox: Introduce support of Nvidia smart switch Vadim Pasternak
@ 2025-04-15 14:38   ` Ilpo Järvinen
  0 siblings, 0 replies; 14+ messages in thread
From: Ilpo Järvinen @ 2025-04-15 14:38 UTC (permalink / raw)
  To: Vadim Pasternak
  Cc: Hans de Goede, michaelsh, crajank, fradensky, oleksandrs,
	platform-driver-x86

[-- Attachment #1: Type: text/plain, Size: 59045 bytes --]

On Sat, 12 Apr 2025, Vadim Pasternak wrote:

> Provide platform support for Nvidia Smart Switch SN4280.
> 
> The Smart Switch equipped with:
> - Nvidia COME module based on AMD EPYC™ Embedded 3451 CPU.
> - Nvidia Spectrum-3 ASIC.
> - Four DPUs, each equipped with Nvidia BF3 ARM based processor and
>   with Lattice LFD2NX-40 FPGA device.
> - 28xQSFP-DD external ports.
> - Two power supplies.
> - Four cooling drawers.
> 
> Reviewed-by: Ciju Rajan K <crajank@nvidia.com>
> Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
> ---
> v6->v7
> Changes added by Vadim:
> - Remove 'capability_mask' field.
> - Fix configuration for dpu.
> 
> v5->v6
> Comments pointed out by Ilpo:
> - Add missing coma in structure 'mlxplat_mlxcpld_xdr_led_data'.
> - Merge lines in structure 'mlxplat_mlxcpld_regmap_smart_switch'.
> - s/int/unsigned int/ in 'mlxplat_dmi_smart_switch_matched'.
> 
> v4->v5
> Comments pointed out by Ilpo:
> - Add blank lines in mlxplat_dmi_smart_switch_matched().
> - Style fixes: remove empty space after the condition fix while() loop.
> ---
>  drivers/platform/mellanox/mlx-platform.c | 1924 +++++++++++++++++++---
>  1 file changed, 1670 insertions(+), 254 deletions(-)
> 
> diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
> index 2334b740267c..29d938265676 100644
> --- a/drivers/platform/mellanox/mlx-platform.c
> +++ b/drivers/platform/mellanox/mlx-platform.c
> @@ -38,6 +38,7 @@
>  #define MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET	0x0b
>  #define MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET	0x17
>  #define MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET	0x19
> +#define MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET	0x1b
>  #define MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET	0x1c
>  #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET	0x1d
>  #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET	0x1e
> @@ -49,9 +50,11 @@
>  #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET	0x24
>  #define MLXPLAT_CPLD_LPC_REG_LED6_OFFSET	0x25
>  #define MLXPLAT_CPLD_LPC_REG_LED7_OFFSET	0x26
> +#define MLXPLAT_CPLD_LPC_REG_LED8_OFFSET	0x27
>  #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION	0x2a
>  #define MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET	0x2b
>  #define MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET	0x2d
> +#define MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET	0x2c
>  #define MLXPLAT_CPLD_LPC_REG_GP0_OFFSET		0x2e
>  #define MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET	0x2f
>  #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET		0x30
> @@ -71,12 +74,14 @@
>  #define MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET	0x43
>  #define MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET	0x44
>  #define MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET 0x45
> +#define MLXPLAT_CPLD_LPC_REG_GP3_OFFSET		0x46
>  #define MLXPLAT_CPLD_LPC_REG_BRD_OFFSET		0x47
>  #define MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET	0x48
>  #define MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET	0x49
>  #define MLXPLAT_CPLD_LPC_REG_GWP_OFFSET		0x4a
>  #define MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET	0x4b
>  #define MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET	0x4c
> +#define MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET	0x4e
>  #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
>  #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET	0x51
>  #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET	0x52
> @@ -88,15 +93,20 @@
>  #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET		0x58
>  #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET	0x59
>  #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET	0x5a
> +#define MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET	0x5e
>  #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET		0x64
>  #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET	0x65
>  #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET	0x66
> +#define MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET	0x6a
>  #define MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET	0x70
>  #define MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET	0x71
>  #define MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET	0x72
>  #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET		0x88
>  #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET	0x89
>  #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET	0x8a
> +#define MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET	0x8b
> +#define MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET	0x8c
> +#define MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET	0x8d
>  #define MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET	0x8e
>  #define MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET	0x8f
>  #define MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET	0x90
> @@ -128,10 +138,15 @@
>  #define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET	0xaa
>  #define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET	0xab
>  #define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON		0xb2
> +#define MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET	0xb4
> +#define MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET	0xb5
>  #define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET	0xb6
>  #define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET	0xb7
>  #define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET	0xb8
>  #define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET	0xb9
> +#define MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET	0xba
> +#define MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET	0xbb
> +#define MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET	0xc1
>  #define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET	0xc2
>  #define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT	0xc3
>  #define MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET	0xc4
> @@ -182,6 +197,9 @@
>  #define MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET	0xfb
>  #define MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET	0xfc
>  #define MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET	0xfd
> +#define MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET	0xfe
> +#define MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET	0xff
> +
>  #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
>  
>  #define MLXPLAT_CPLD_LPC_PIO_OFFSET		0x10000UL
> @@ -210,9 +228,15 @@
>  #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF	0x04
>  #define MLXPLAT_CPLD_AGGR_MASK_COMEX	BIT(0)
>  #define MLXPLAT_CPLD_AGGR_MASK_LC	BIT(3)
> +#define MLXPLAT_CPLD_AGGR_MASK_DPU_BRD	BIT(4)
> +#define MLXPLAT_CPLD_AGGR_MASK_DPU_CORE	BIT(5)
>  #define MLXPLAT_CPLD_AGGR_MASK_MODULAR	(MLXPLAT_CPLD_AGGR_MASK_NG_DEF | \
>  					 MLXPLAT_CPLD_AGGR_MASK_COMEX | \
>  					 MLXPLAT_CPLD_AGGR_MASK_LC)
> +#define MLXPLAT_CPLD_AGGR_MASK_SMART_SW	(MLXPLAT_CPLD_AGGR_MASK_COMEX | \
> +					 MLXPLAT_CPLD_AGGR_MASK_NG_DEF | \
> +					 MLXPLAT_CPLD_AGGR_MASK_DPU_BRD | \
> +					 MLXPLAT_CPLD_AGGR_MASK_DPU_CORE)
>  #define MLXPLAT_CPLD_AGGR_MASK_LC_PRSNT	BIT(0)
>  #define MLXPLAT_CPLD_AGGR_MASK_LC_RDY	BIT(1)
>  #define MLXPLAT_CPLD_AGGR_MASK_LC_PG	BIT(2)
> @@ -235,15 +259,21 @@
>  #define MLXPLAT_CPLD_PWR_MASK		GENMASK(1, 0)
>  #define MLXPLAT_CPLD_PSU_EXT_MASK	GENMASK(3, 0)
>  #define MLXPLAT_CPLD_PWR_EXT_MASK	GENMASK(3, 0)
> +#define MLXPLAT_CPLD_PSU_XDR_MASK	GENMASK(7, 0)
> +#define MLXPLAT_CPLD_PWR_XDR_MASK	GENMASK(7, 0)
>  #define MLXPLAT_CPLD_FAN_MASK		GENMASK(3, 0)
>  #define MLXPLAT_CPLD_ASIC_MASK		GENMASK(1, 0)
> +#define MLXPLAT_CPLD_ASIC_XDR_MASK	GENMASK(3, 0)
>  #define MLXPLAT_CPLD_FAN_NG_MASK	GENMASK(6, 0)
> +#define MLXPLAT_CPLD_FAN_XDR_MASK	GENMASK(7, 0)
>  #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK	GENMASK(7, 4)
>  #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK	GENMASK(3, 0)
>  #define MLXPLAT_CPLD_VOLTREG_UPD_MASK	GENMASK(5, 4)
>  #define MLXPLAT_CPLD_GWP_MASK		GENMASK(0, 0)
>  #define MLXPLAT_CPLD_EROT_MASK		GENMASK(1, 0)
>  #define MLXPLAT_CPLD_FU_CAP_MASK	GENMASK(1, 0)
> +#define MLXPLAT_CPLD_BIOS_STATUS_MASK	GENMASK(3, 1)
> +#define MLXPLAT_CPLD_DPU_MASK		GENMASK(3, 0)
>  #define MLXPLAT_CPLD_PWR_BUTTON_MASK	BIT(0)
>  #define MLXPLAT_CPLD_LATCH_RST_MASK	BIT(6)
>  #define MLXPLAT_CPLD_THERMAL1_PDB_MASK	BIT(3)
> @@ -267,6 +297,9 @@
>  /* Masks for aggregation for modular systems */
>  #define MLXPLAT_CPLD_LPC_LC_MASK	GENMASK(7, 0)
>  
> +/* Masks for aggregation for smart switch systems */
> +#define MLXPLAT_CPLD_LPC_SM_SW_MASK	GENMASK(7, 0)
> +
>  #define MLXPLAT_CPLD_HALT_MASK		BIT(3)
>  #define MLXPLAT_CPLD_RESET_MASK		GENMASK(7, 1)
>  
> @@ -297,15 +330,18 @@
>  #define MLXPLAT_CPLD_NR_NONE			-1
>  #define MLXPLAT_CPLD_PSU_DEFAULT_NR		10
>  #define MLXPLAT_CPLD_PSU_MSNXXXX_NR		4
> +#define MLXPLAT_CPLD_PSU_XDR_NR			3
>  #define MLXPLAT_CPLD_FAN1_DEFAULT_NR		11
>  #define MLXPLAT_CPLD_FAN2_DEFAULT_NR		12
>  #define MLXPLAT_CPLD_FAN3_DEFAULT_NR		13
>  #define MLXPLAT_CPLD_FAN4_DEFAULT_NR		14
>  #define MLXPLAT_CPLD_NR_ASIC			3
>  #define MLXPLAT_CPLD_NR_LC_BASE			34
> +#define MLXPLAT_CPLD_NR_DPU_BASE		18
>  
>  #define MLXPLAT_CPLD_NR_LC_SET(nr)	(MLXPLAT_CPLD_NR_LC_BASE + (nr))
>  #define MLXPLAT_CPLD_LC_ADDR		0x32
> +#define MLXPLAT_CPLD_DPU_ADDR		0x68
>  
>  /* Masks and default values for watchdogs */
>  #define MLXPLAT_CPLD_WD1_CLEAR_MASK	GENMASK(7, 1)
> @@ -320,6 +356,7 @@
>  #define MLXPLAT_CPLD_WD_DFLT_TIMEOUT	30
>  #define MLXPLAT_CPLD_WD3_DFLT_TIMEOUT	600
>  #define MLXPLAT_CPLD_WD_MAX_DEVS	2
> +#define MLXPLAT_CPLD_DPU_MAX_DEVS	4
>  
>  #define MLXPLAT_CPLD_LPC_SYSIRQ		17
>  
> @@ -346,6 +383,7 @@
>   * @pdev_io_regs - register access platform devices
>   * @pdev_fan - FAN platform devices
>   * @pdev_wd - array of watchdog platform devices
> + * pdev_dpu - array of Data Processor Unit platform devices
>   * @regmap: device register map
>   * @hotplug_resources: system hotplug resources
>   * @hotplug_resources_size: size of system hotplug resources
> @@ -360,6 +398,7 @@
>  	struct platform_device *pdev_io_regs;
>  	struct platform_device *pdev_fan;
>  	struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS];
> +	struct platform_device *pdev_dpu[MLXPLAT_CPLD_DPU_MAX_DEVS];
>  	void *regmap;
>  	struct resource *hotplug_resources;
>  	unsigned int hotplug_resources_size;
> @@ -626,6 +665,21 @@
>  	},
>  };
>  
> +static struct i2c_board_info mlxplat_mlxcpld_xdr_pwr[] = {
> +	{
> +		I2C_BOARD_INFO("dps460", 0x5d),
> +	},
> +	{
> +		I2C_BOARD_INFO("dps460", 0x5c),
> +	},
> +	{
> +		I2C_BOARD_INFO("dps460", 0x5e),
> +	},
> +	{
> +		I2C_BOARD_INFO("dps460", 0x5f),
> +	},
> +};
> +
>  static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
>  	{
>  		I2C_BOARD_INFO("24c32", 0x50),
> @@ -2370,6 +2424,427 @@
>  	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
>  };
>  
> +/* Platform hotplug XDR and smart switch system family data */
> +static struct mlxreg_core_data mlxplat_mlxcpld_xdr_psu_items_data[] = {
> +	{
> +		.label = "psu1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(0),
> +		.slot = 1,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu2",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(1),
> +		.slot = 2,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu3",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(2),
> +		.slot = 3,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu4",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(3),
> +		.slot = 4,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu5",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(4),
> +		.slot = 5,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu6",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(5),
> +		.slot = 6,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu7",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(6),
> +		.slot = 7,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "psu8",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = BIT(7),
> +		.slot = 8,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +};
> +
> +static struct mlxreg_core_data mlxplat_mlxcpld_xdr_pwr_items_data[] = {
> +	{
> +		.label = "pwr1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(0),
> +		.slot = 1,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
> +	},
> +	{
> +		.label = "pwr2",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(1),
> +		.slot = 2,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
> +	},
> +	{
> +		.label = "pwr3",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(2),
> +		.slot = 3,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[0],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
> +	},
> +	{
> +		.label = "pwr4",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(3),
> +		.slot = 4,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[1],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
> +	},
> +	{
> +		.label = "pwr5",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(4),
> +		.slot = 5,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[0],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
> +	},
> +	{
> +		.label = "pwr6",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(5),
> +		.slot = 6,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[1],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
> +	},
> +	{
> +		.label = "pwr7",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(6),
> +		.slot = 7,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[2],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
> +	},
> +	{
> +		.label = "pwr8",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = BIT(7),
> +		.slot = 8,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[3],
> +		.hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR,
> +	},
> +};
> +
> +static struct mlxreg_core_data mlxplat_mlxcpld_xdr_fan_items_data[] = {
> +	{
> +		.label = "fan1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(0),
> +		.slot = 1,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(0),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan2",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(1),
> +		.slot = 2,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(1),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan3",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(2),
> +		.slot = 3,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(2),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan4",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(3),
> +		.slot = 4,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(3),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan5",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(4),
> +		.slot = 5,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(4),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan6",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(5),
> +		.slot = 6,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(5),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan7",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(6),
> +		.slot = 7,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(6),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "fan8",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = BIT(7),
> +		.slot = 8,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.bit = BIT(7),
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +};
> +
> +static struct mlxreg_core_data mlxplat_mlxcpld_xdr_asic1_items_data[] = {
> +	{
> +		.label = "asic1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
> +		.mask = MLXPLAT_CPLD_ASIC_MASK,
> +		.slot = 1,
> +		.capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	}
> +};
> +
> +/* Platform hotplug for smart switch systems families data */
> +static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_dpu_ready_data[] = {
> +	{
> +		.label = "dpu1_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
> +		.mask = BIT(0),
> +		.slot = 1,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "dpu2_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
> +		.mask = BIT(1),
> +		.slot = 2,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "dpu3_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
> +		.mask = BIT(2),
> +		.slot = 3,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "dpu4_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
> +		.mask = BIT(3),
> +		.slot = 4,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +};
> +
> +static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_dpu_shtdn_ready_data[] = {
> +	{
> +		.label = "dpu1_shtdn_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
> +		.mask = BIT(0),
> +		.slot = 1,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "dpu2_shtdn_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
> +		.mask = BIT(1),
> +		.slot = 2,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "dpu3_shtdn_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
> +		.mask = BIT(2),
> +		.slot = 3,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +	{
> +		.label = "dpu4_shtdn_ready",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
> +		.mask = BIT(3),
> +		.slot = 4,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
> +	},
> +};
> +
> +static struct mlxreg_core_item mlxplat_mlxcpld_smart_switch_items[] = {
> +	{
> +		.data = mlxplat_mlxcpld_xdr_psu_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = MLXPLAT_CPLD_PSU_XDR_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_psu_items_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_xdr_pwr_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = MLXPLAT_CPLD_PWR_XDR_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_pwr_items_data),
> +		.inversed = 0,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_xdr_fan_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = MLXPLAT_CPLD_FAN_XDR_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_items_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_xdr_asic1_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
> +		.mask = MLXPLAT_CPLD_ASIC_XDR_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_asic1_items_data),
> +		.inversed = 0,
> +		.health = true,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_smart_switch_dpu_ready_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DPU_CORE,
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
> +		.mask = MLXPLAT_CPLD_DPU_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_dpu_ready_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_smart_switch_dpu_shtdn_ready_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DPU_CORE,
> +		.reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
> +		.mask = MLXPLAT_CPLD_DPU_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_dpu_shtdn_ready_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +};
> +
> +static
> +struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_smart_switch_data = {
> +	.items = mlxplat_mlxcpld_smart_switch_items,
> +	.count = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_items),
> +	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
> +	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX |
> +		MLXPLAT_CPLD_AGGR_MASK_DPU_BRD | MLXPLAT_CPLD_AGGR_MASK_DPU_CORE,
> +	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
> +	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
> +};
> +
> +/* Smart switch data  processor units data */
> +static struct i2c_board_info mlxplat_mlxcpld_smart_switch_dpu_devs[] = {
> +	{
> +		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
> +		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
> +	},
> +	{
> +		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
> +		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
> +	},
> +	{
> +		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
> +		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
> +	},
> +	{
> +		I2C_BOARD_INFO("mlxreg-dpu", MLXPLAT_CPLD_DPU_ADDR),
> +		.irq = MLXPLAT_CPLD_LPC_SYSIRQ,
> +	},
> +};
> +
> +static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_dpu_data[] = {
> +	{
> +		.label = "dpu1",
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[0],
> +		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE,
> +		.slot = 1,
> +	},
> +	{
> +		.label = "dpu2",
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[1],
> +		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE + 1,
> +		.slot = 2,
> +	},
> +	{
> +		.label = "dpu3",
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[2],
> +		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE + 2,
> +		.slot = 3,
> +	},
> +	{
> +		.label = "dpu4",
> +		.hpdev.brdinfo = &mlxplat_mlxcpld_smart_switch_dpu_devs[3],
> +		.hpdev.nr = MLXPLAT_CPLD_NR_DPU_BASE + 3,
> +		.slot = 4,
> +	},
> +};
> +
>  /* Callback performs graceful shutdown after notification about power button event */
>  static int
>  mlxplat_mlxcpld_l1_switch_pwr_events_handler(void *handle, enum mlxreg_hotplug_kind kind,
> @@ -3162,6 +3637,180 @@
>  		.counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_led_data),
>  };
>  
> +/* Platform led data for XDR and smart switch systems */
> +static struct mlxreg_core_data mlxplat_mlxcpld_xdr_led_data[] = {
> +	{
> +		.label = "status:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +	},
> +	{
> +		.label = "status:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +	},
> +	{
> +		.label = "psu:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +	},
> +	{
> +		.label = "psu:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +	},
> +	{
> +		.label = "fan1:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 1,
> +	},
> +	{
> +		.label = "fan1:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 1,
> +	},
> +	{
> +		.label = "fan2:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 2,
> +	},
> +	{
> +		.label = "fan2:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 2,
> +	},
> +	{
> +		.label = "fan3:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 3,
> +	},
> +	{
> +		.label = "fan3:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 3,
> +	},
> +	{
> +		.label = "fan4:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 4,
> +	},
> +	{
> +		.label = "fan4:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 4,
> +	},
> +	{
> +		.label = "fan5:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 5,
> +	},
> +	{
> +		.label = "fan5:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 5,
> +	},
> +	{
> +		.label = "fan6:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 6,
> +	},
> +	{
> +		.label = "fan6:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 6,
> +	},
> +	{
> +		.label = "fan7:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 7,
> +	},
> +	{
> +		.label = "fan7:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 7,
> +	},
> +	{
> +		.label = "fan8:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 8,
> +	},
> +	{
> +		.label = "fan8:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 8,
> +	},
> +	{
> +		.label = "fan9:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 9,
> +	},
> +	{
> +		.label = "fan9:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 9,
> +	},
> +	{
> +		.label = "fan10:green",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED8_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 10,
> +	},
> +	{
> +		.label = "fan10:orange",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED8_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.slot = 10,
> +	},
> +	{
> +		.label = "uid:blue",
> +		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
> +		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
> +	},
> +};
> +
> +static struct mlxreg_core_platform_data mlxplat_xdr_led_data = {
> +		.data = mlxplat_mlxcpld_xdr_led_data,
> +		.counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_led_data),
> +};
> +
>  /* Platform register access default */
>  static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
>  	{
> @@ -4610,6 +5259,480 @@
>  		.counter = ARRAY_SIZE(mlxplat_mlxcpld_chassis_blade_regs_io_data),
>  };
>  
> +/* Platform register access for smart switch systems families data */
> +static struct mlxreg_core_data mlxplat_mlxcpld_smart_switch_regs_io_data[] = {
> +	{
> +		.label = "cpld1_version",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "cpld2_version",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "cpld3_version",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "cpld1_pn",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
> +		.bit = GENMASK(15, 0),
> +		.mode = 0444,
> +		.regnum = 2,
> +	},
> +	{
> +		.label = "cpld2_pn",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET,
> +		.bit = GENMASK(15, 0),
> +		.mode = 0444,
> +		.regnum = 2,
> +	},
> +	{
> +		.label = "cpld3_pn",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET,
> +		.bit = GENMASK(15, 0),
> +		.mode = 0444,
> +		.regnum = 2,
> +	},
> +	{
> +		.label = "cpld1_version_min",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "cpld2_version_min",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "cpld3_version_min",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "kexec_activated",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "asic_reset",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "eth_switch_reset",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(4),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "dpu1_rst",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu2_rst",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu3_rst",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu4_rst",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu1_pwr",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu2_pwr",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu3_pwr",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu4_pwr",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "reset_long_pb",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_short_pb",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_aux_pwr_or_ref",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_swb_dc_dc_pwr_fail",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_swb_wd",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(6),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_asic_thermal",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(7),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_sw_reset",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_aux_pwr_or_reload",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_comex_pwr_fail",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_platform",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(4),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_soc",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(5),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_pwr",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(7),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_pwr_converter_fail",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_system",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_sw_pwr_off",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_comex_thermal",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "reset_ac_pwr_fail",
> +		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(6),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "voltreg_update_status",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET,
> +		.mask = MLXPLAT_CPLD_VOLTREG_UPD_MASK,
> +		.bit = 5,
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "port80",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "bios_status",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
> +		.mask = MLXPLAT_CPLD_BIOS_STATUS_MASK,
> +		.bit = 2,
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "bios_start_retry",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(4),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "bios_active_image",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(5),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "vpd_wp",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "pcie_asic_reset_dis",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(4),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "shutdown_unlock",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(5),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "fan_dir",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "dpu1_rst_en",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu2_rst_en",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu3_rst_en",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu4_rst_en",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "psu1_on",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "psu2_on",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "pwr_cycle",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "pwr_down",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "jtag_cap",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET,
> +		.mask = MLXPLAT_CPLD_FU_CAP_MASK,
> +		.bit = 1,
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "jtag_enable",
> +		.reg = MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE,
> +		.mask = GENMASK(1, 0),
> +		.bit = 1,
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "non_active_bios_select",
> +		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(4),
> +		.mode = 0644,
> +	},
> +	{
> +	    .label = "bios_upgrade_fail",
> +		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(5),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "bios_image_invert",
> +		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(6),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "me_reboot",
> +		.reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(7),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "dpu1_pwr_force",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu2_pwr_force",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu3_pwr_force",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(2),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "dpu4_pwr_force",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP3_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(3),
> +		.mode = 0200,
> +	},
> +	{
> +		.label = "ufm_done",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "asic_health",
> +		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
> +		.mask = MLXPLAT_CPLD_ASIC_MASK,
> +		.bit = 1,
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "psu1_ac_ok",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "psu2_ac_ok",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "psu1_no_alert",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(0),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "psu2_no_alert",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(1),
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "asic_pg_fail",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(7),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "spi_chnl_select",
> +		.reg = MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT,
> +		.mask = GENMASK(7, 0),
> +		.bit = 1,
> +		.mode = 0644,
> +	},
> +	{
> +		.label = "config1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "config2",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "config3",
> +		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +	{
> +		.label = "ufm_version",
> +		.reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
> +		.bit = GENMASK(7, 0),
> +		.mode = 0444,
> +	},
> +};
> +
> +static struct mlxreg_core_platform_data mlxplat_smart_switch_regs_io_data = {
> +		.data = mlxplat_mlxcpld_smart_switch_regs_io_data,
> +		.counter = ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_regs_io_data),
> +};
> +
>  /* Platform FAN default */
>  static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
>  	{
> @@ -4751,6 +5874,185 @@
>  		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
>  };
>  
> +/* XDR and smart switch platform fan data */
> +static struct mlxreg_core_data mlxplat_mlxcpld_xdr_fan_data[] = {
> +	{
> +		.label = "pwm1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
> +	},
> +	{
> +		.label = "tacho1",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 1,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho2",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 2,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho3",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 3,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho4",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 4,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho5",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 5,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho6",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 6,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho7",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 7,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho8",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 8,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho9",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 9,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho10",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 10,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho11",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 11,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho12",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 12,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho13",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 13,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho14",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 14,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho15",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 15,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho16",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 16,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +	},
> +	{
> +		.label = "tacho17",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 17,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
> +	},
> +	{
> +		.label = "tacho18",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 18,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
> +	},
> +	{
> +		.label = "tacho19",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 19,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
> +	},
> +	{
> +		.label = "tacho20",
> +		.reg = MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET,
> +		.mask = GENMASK(7, 0),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
> +		.slot = 20,
> +		.reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET,
> +	},
> +	{
> +		.label = "conf",
> +		.capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET,
> +	},
> +};
> +
> +static struct mlxreg_core_platform_data mlxplat_xdr_fan_data = {
> +		.data = mlxplat_mlxcpld_xdr_fan_data,
> +		.counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_data),
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.version = 1,
> +};
> +
>  /* Watchdog type1: hardware implementation version1
>   * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
>   */
> @@ -4975,6 +6277,8 @@
>  {
>  	switch (reg) {
>  	case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
> @@ -4983,12 +6287,14 @@
>  	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GP3_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
>  	case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
>  	case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
> @@ -5012,10 +6318,14 @@
>  	case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
> @@ -5083,6 +6393,8 @@
>  	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
> @@ -5094,15 +6406,18 @@
>  	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
>  	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GP3_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
>  	case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
>  	case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
> @@ -5122,6 +6437,7 @@
>  	case MLXPLAT_CPLD_LPC_REG_GWP_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
> @@ -5134,12 +6450,17 @@
>  	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
> @@ -5213,6 +6534,13 @@
>  	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
> @@ -5248,6 +6576,8 @@
>  	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_RESET_GP3_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
> @@ -5259,13 +6589,16 @@
>  	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
>  	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GP1_RO_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GP3_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
>  	case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
>  	case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
> @@ -5285,6 +6618,7 @@
>  	case MLXPLAT_CPLD_LPC_REG_GWP_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_GPI_MASK_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
> @@ -5297,9 +6631,11 @@
>  	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_PSU_AC_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_PSU_ALERT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
> @@ -5370,6 +6706,13 @@
>  	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET:
> +	case MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
>  	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
> @@ -5431,6 +6774,14 @@
>  	  MLXPLAT_CPLD_AGGR_MASK_LC_LOW },
>  };
>  
> +static const struct reg_default mlxplat_mlxcpld_regmap_smart_switch[] = {
> +	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
> +	{ MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
> +	{ MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
> +	{ MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
> +	{ MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET, MLXPLAT_CPLD_LPC_SM_SW_MASK },
> +};
> +
>  struct mlxplat_mlxcpld_regmap_context {
>  	void __iomem *base;
>  };
> @@ -5539,6 +6890,20 @@
>  	.reg_write = mlxplat_mlxcpld_reg_write,
>  };
>  
> +static const struct regmap_config mlxplat_mlxcpld_regmap_config_smart_switch = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = 255,
> +	.cache_type = REGCACHE_FLAT,
> +	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
> +	.readable_reg = mlxplat_mlxcpld_readable_reg,
> +	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
> +	.reg_defaults = mlxplat_mlxcpld_regmap_smart_switch,
> +	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_smart_switch),
> +	.reg_read = mlxplat_mlxcpld_reg_read,
> +	.reg_write = mlxplat_mlxcpld_reg_write,
> +};
> +
>  static struct resource mlxplat_mlxcpld_resources[] = {
>  	[0] = DEFINE_RES_IRQ_NAMED(MLXPLAT_CPLD_LPC_SYSIRQ, "mlxreg-hotplug"),
>  };
> @@ -5550,6 +6915,7 @@
>  static struct mlxreg_core_platform_data *mlxplat_fan;
>  static struct mlxreg_core_platform_data
>  	*mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS];
> +static struct mlxreg_core_data *mlxplat_dpu_data[MLXPLAT_CPLD_DPU_MAX_DEVS];
>  static const struct regmap_config *mlxplat_regmap_config;
>  static struct pci_dev *lpc_bridge;
>  static struct pci_dev *i2c_bridge;
> @@ -5921,6 +7287,31 @@
>  	return mlxplat_register_platform_device();
>  }
>  
> +static int __init mlxplat_dmi_smart_switch_matched(const struct dmi_system_id *dmi)
> +{
> +	int i;
> +
> +	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
> +	mlxplat_mux_num = ARRAY_SIZE(mlxplat_ng800_mux_data);
> +	mlxplat_mux_data = mlxplat_ng800_mux_data;
> +	mlxplat_hotplug = &mlxplat_mlxcpld_smart_switch_data;
> +	mlxplat_hotplug->deferred_nr =
> +		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
> +	mlxplat_led = &mlxplat_xdr_led_data;
> +	mlxplat_regs_io = &mlxplat_smart_switch_regs_io_data;
> +	mlxplat_fan = &mlxplat_xdr_fan_data;
> +
> +	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
> +		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
> +	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_smart_switch_dpu_data); i++)
> +		mlxplat_dpu_data[i] = &mlxplat_mlxcpld_smart_switch_dpu_data[i];
> +
> +	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
> +	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_smart_switch;
> +
> +	return mlxplat_register_platform_device();
> +}
> +
>  static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
>  	{
>  		.callback = mlxplat_dmi_default_wc_matched,
> @@ -6016,6 +7407,12 @@
>  		},
>  	},
>  	{
> +		.callback = mlxplat_dmi_smart_switch_matched,
> +		.matches = {
> +			DMI_MATCH(DMI_BOARD_NAME, "VMOD0019"),
> +		},
> +	},
> +	{
>  		.callback = mlxplat_dmi_msn274x_matched,
>  		.matches = {
>  			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
> @@ -6390,8 +7787,25 @@
>  		}
>  	}
>  
> +	/* Add DPU drivers. */
> +	for (i = 0; i < MLXPLAT_CPLD_DPU_MAX_DEVS; i++) {
> +		if (mlxplat_dpu_data[i]) {

Since you need to respin starting from patch 2 of this series, please 
reverse the logic and use continue.

With that changed,

Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

> +			priv->pdev_dpu[i] =
> +				platform_device_register_resndata(&mlxplat_dev->dev, "mlxreg-dpu",
> +								  i, NULL, 0, mlxplat_dpu_data[i],
> +								  sizeof(*mlxplat_dpu_data[i]));
> +			if (IS_ERR(priv->pdev_dpu[i])) {
> +				err = PTR_ERR(priv->pdev_dpu[i]);
> +				goto fail_platform_dpu_register;
> +			}
> +		}
> +	}
> +
>  	return 0;
>  
> +fail_platform_dpu_register:
> +	while (i--)
> +		platform_device_unregister(priv->pdev_dpu[i]);
>  fail_platform_wd_register:
>  	while (--i >= 0)
>  		platform_device_unregister(priv->pdev_wd[i]);
> @@ -6412,6 +7826,8 @@
>  {
>  	int i;
>  
> +	for (i = MLXPLAT_CPLD_DPU_MAX_DEVS - 1; i >= 0; i--)
> +		platform_device_unregister(priv->pdev_dpu[i]);
>  	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
>  		platform_device_unregister(priv->pdev_wd[i]);
>  	if (priv->pdev_fan)
> 

-- 
 i.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH platform-next v8 4/7] platform: mellanox: Cosmetic changes to improve code style
  2025-04-12  9:18 ` [PATCH platform-next v8 4/7] platform: mellanox: Cosmetic changes to improve code style Vadim Pasternak
@ 2025-04-15 14:40   ` Ilpo Järvinen
  0 siblings, 0 replies; 14+ messages in thread
From: Ilpo Järvinen @ 2025-04-15 14:40 UTC (permalink / raw)
  To: Vadim Pasternak
  Cc: Hans de Goede, michaelsh, crajank, fradensky, oleksandrs,
	platform-driver-x86

[-- Attachment #1: Type: text/plain, Size: 2188 bytes --]

On Sat, 12 Apr 2025, Vadim Pasternak wrote:

> Replace in 'for' loop - /i >= 0 ; i--/i >= 0 ;i--/.

Space is in the wrong place in the replace part.

> Replace in 'while' loop - /(--i >= 0)/(--i)/.
> 
> Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>

Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

-- 
 i.

> ---
> v5->v6
> Comments pointed out by Ilpo:
> - Fix 'while' loop in erro flow.
> ---
>  drivers/platform/mellanox/mlx-platform.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
> index 29d938265676..4c7ff22117a6 100644
> --- a/drivers/platform/mellanox/mlx-platform.c
> +++ b/drivers/platform/mellanox/mlx-platform.c
> @@ -7807,7 +7807,7 @@ static int mlxplat_platdevs_init(struct mlxplat_priv *priv)
>  	while (i--)
>  		platform_device_unregister(priv->pdev_dpu[i]);
>  fail_platform_wd_register:
> -	while (--i >= 0)
> +	while (i--)
>  		platform_device_unregister(priv->pdev_wd[i]);
>  fail_platform_fan_register:
>  	if (mlxplat_regs_io)
> @@ -7828,7 +7828,7 @@ static void mlxplat_platdevs_exit(struct mlxplat_priv *priv)
>  
>  	for (i = MLXPLAT_CPLD_DPU_MAX_DEVS - 1; i >= 0; i--)
>  		platform_device_unregister(priv->pdev_dpu[i]);
> -	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
> +	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0; i--)
>  		platform_device_unregister(priv->pdev_wd[i]);
>  	if (priv->pdev_fan)
>  		platform_device_unregister(priv->pdev_fan);
> @@ -7873,7 +7873,7 @@ static int mlxplat_i2c_mux_topology_init(struct mlxplat_priv *priv)
>  	return mlxplat_i2c_mux_complition_notify(priv, NULL, NULL);
>  
>  fail_platform_mux_register:
> -	while (--i >= 0)
> +	while (i--)
>  		platform_device_unregister(priv->pdev_mux[i]);
>  	return err;
>  }
> @@ -7882,7 +7882,7 @@ static void mlxplat_i2c_mux_topology_exit(struct mlxplat_priv *priv)
>  {
>  	int i;
>  
> -	for (i = mlxplat_mux_num - 1; i >= 0 ; i--) {
> +	for (i = mlxplat_mux_num - 1; i >= 0; i--) {
>  		if (priv->pdev_mux[i])
>  			platform_device_unregister(priv->pdev_mux[i]);
>  	}
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH platform-next v8 5/7] platform: mellanox: mlx-platform: Add support for new Nvidia system
  2025-04-12  9:18 ` [PATCH platform-next v8 5/7] platform: mellanox: mlx-platform: Add support for new Nvidia system Vadim Pasternak
@ 2025-04-15 14:48   ` Ilpo Järvinen
  0 siblings, 0 replies; 14+ messages in thread
From: Ilpo Järvinen @ 2025-04-15 14:48 UTC (permalink / raw)
  To: Vadim Pasternak
  Cc: Hans de Goede, michaelsh, crajank, fradensky, oleksandrs,
	platform-driver-x86

On Sat, 12 Apr 2025, Vadim Pasternak wrote:

> Add support for SN5640 and SN5610 Nvidia switch.
> 
> SN5640 is a 51.2Tbps switch based on Nvidia SPC-5 ASIC.
> It provides up-to 400Gbps full bidirectional bandwidth per port.
> The system supports 64 OSFP cages and fits into standard 2U racks.
> 
> SN5640 Features:
> - 64 OSFP ports supporting 2.5Gbps - 400Gbps speeds.
> - Air-cooled with 4 + 1 redundant fan units.
> - 2 + 2 redundant 2000W PSUs.
> - System management board based on AMD CPU with secure-boot support.
> 
> SN5610 is a 51.2Tbps switch based on Nvidia SPC-4 ASIC.
> It provides up-to 800Gbps full bidirectional bandwidth per port.
> The system supports 64 OSFP cages and fits into standard 2U racks.
> 
> SN5610 Features:
>  - 64 OSFP ports supporting 10Gbps - 800Gbps speeds.
>  - Air-cooled with 4 + 1 redundant fan units.
>  - 2 + 2 redundant 2000W PSUs.
>  - System management board based on AMD CPU with secure-boot support.

There's quite much duplication and repetition in the above. Could you 
simplify such that most repetition is eliminated.

There also seems to be details that are pretty irrelevant from the point 
of view of this change and look more like marketting material. Please try 
to drop such extra details (why would the kernel care if it fits to 2U :-)).

> 
> Reviewed-by: Oleksandr Shamray <oleksandrs@nvidia.com>
> Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
> ---
> v6->v7
> Changes added bt Vadim:
> - Remove 'capability_mask' field.
> 
> v5->v6
> Comments pointed out by Ilpo:
> - Change 'int' to 'unsigned int' in mlxplat_dmi_ng400_hi171_matched().
> 
> v2->v3
> Comments pointed out by Ilpo:
> - Add empty lines for visibility in mlxplat_dmi_ng400_hi171_matched().
> ---
>  drivers/platform/mellanox/mlx-platform.c | 96 ++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
> 
> diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
> index 4c7ff22117a6..9b8b430070b6 100644
> --- a/drivers/platform/mellanox/mlx-platform.c
> +++ b/drivers/platform/mellanox/mlx-platform.c
> @@ -3000,6 +3000,59 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_l1_switch_data = {
>  	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT,
>  };
>  
> +/* Platform hotplug for next-generation 800G systems family data  */

"next-generation" is soon going to be the current and then past 
generation so preferrably avoid such wordings.

Other than that, the code change seemed fine.

> +static struct mlxreg_core_item mlxplat_mlxcpld_ng800_hi171_items[] = {
> +	{
> +		.data = mlxplat_mlxcpld_ext_psu_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
> +		.mask = MLXPLAT_CPLD_PSU_EXT_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_modular_pwr_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
> +		.mask = MLXPLAT_CPLD_PWR_EXT_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
> +		.inversed = 0,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_xdr_fan_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
> +		.mask = MLXPLAT_CPLD_FAN_XDR_MASK,
> +		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_items_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +	{
> +		.data = mlxplat_mlxcpld_default_asic_items_data,
> +		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
> +		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
> +		.mask = MLXPLAT_CPLD_ASIC_MASK,
> +		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
> +		.inversed = 0,
> +		.health = true,
> +	},
> +};
> +
> +static
> +struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ng800_hi171_data = {
> +	.items = mlxplat_mlxcpld_ng800_hi171_items,
> +	.count = ARRAY_SIZE(mlxplat_mlxcpld_ng800_hi171_items),
> +	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
> +	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
> +	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
> +	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2,
> +};
> +
>  /* Platform led default data */
>  static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
>  	{
> @@ -4486,6 +4539,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
>  		.mask = GENMASK(7, 0) & ~BIT(4),
>  		.mode = 0644,
>  	},
> +	{
> +		.label = "shutdown_unlock",
> +		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
> +		.mask = GENMASK(7, 0) & ~BIT(5),
> +		.mode = 0644,
> +	},
>  	{
>  		.label = "erot1_ap_reset",
>  		.reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
> @@ -7312,6 +7371,29 @@ static int __init mlxplat_dmi_smart_switch_matched(const struct dmi_system_id *d
>  	return mlxplat_register_platform_device();
>  }
>  
> +static int __init mlxplat_dmi_ng400_hi171_matched(const struct dmi_system_id *dmi)
> +{
> +	unsigned int i;
> +
> +	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
> +	mlxplat_mux_num = ARRAY_SIZE(mlxplat_ng800_mux_data);
> +	mlxplat_mux_data = mlxplat_ng800_mux_data;
> +	mlxplat_hotplug = &mlxplat_mlxcpld_ng800_hi171_data;
> +	mlxplat_hotplug->deferred_nr =
> +		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
> +	mlxplat_led = &mlxplat_default_ng_led_data;
> +	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
> +	mlxplat_fan = &mlxplat_xdr_fan_data;
> +
> +	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type3); i++)
> +		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type3[i];
> +
> +	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
> +	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
> +
> +	return mlxplat_register_platform_device();
> +}
> +
>  static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
>  	{
>  		.callback = mlxplat_dmi_default_wc_matched,
> @@ -7412,6 +7494,20 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
>  			DMI_MATCH(DMI_BOARD_NAME, "VMOD0019"),
>  		},
>  	},
> +	{
> +		.callback = mlxplat_dmi_ng400_hi171_matched,
> +		.matches = {
> +			DMI_MATCH(DMI_BOARD_NAME, "VMOD0022"),
> +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI171"),
> +		},
> +	},
> +	{
> +		.callback = mlxplat_dmi_ng400_hi171_matched,
> +		.matches = {
> +			DMI_MATCH(DMI_BOARD_NAME, "VMOD0022"),
> +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI172"),
> +		},
> +	},
>  	{
>  		.callback = mlxplat_dmi_msn274x_matched,
>  		.matches = {
> 

-- 
 i.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH platform-next v8 6/7] platform: mellanox: nvsw-sn2200: Add support for new system flavour
  2025-04-12  9:18 ` [PATCH platform-next v8 6/7] platform: mellanox: nvsw-sn2200: Add support for new system flavour Vadim Pasternak
@ 2025-04-15 15:00   ` Ilpo Järvinen
  0 siblings, 0 replies; 14+ messages in thread
From: Ilpo Järvinen @ 2025-04-15 15:00 UTC (permalink / raw)
  To: Vadim Pasternak
  Cc: Hans de Goede, michaelsh, crajank, fradensky, oleksandrs,
	platform-driver-x86

On Sat, 12 Apr 2025, Vadim Pasternak wrote:

> Add support for SN2201 system flavour, which is fitting OCP rack
> form-factor and feeded from external power source through the rack
> standard busbar interface.
> 
> Validate system type through DMI decode.
> For new system flavour:
> - Skip internal power supply configuration.
> - Attach power hotswap device.
> 
> Reviewed-by: Michael Shych <michaelsh@nvidia.com>
> Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
> ---
>  drivers/platform/mellanox/nvsw-sn2201.c | 110 +++++++++++++++++++++++-
>  1 file changed, 107 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c
> index 451d64c35c23..6f643e6ddb99 100644
> --- a/drivers/platform/mellanox/nvsw-sn2201.c
> +++ b/drivers/platform/mellanox/nvsw-sn2201.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/device.h>
> +#include <linux/dmi.h>
>  #include <linux/i2c.h>
>  #include <linux/interrupt.h>
>  #include <linux/irq.h>
> @@ -104,6 +105,9 @@
>  	| NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \
>  	| NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \
>  	| NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)
> +#define NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF \
> +	(NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \
> +	| NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)
>  
>  #define NVSW_SN2201_CPLD_ASIC_MASK		GENMASK(3, 1)
>  #define NVSW_SN2201_CPLD_PSU_MASK		GENMASK(1, 0)
> @@ -132,6 +136,7 @@
>   * @cpld_devs: I2C devices for cpld;
>   * @cpld_devs_num: number of I2C devices for cpld;
>   * @main_mux_deferred_nr: I2C adapter number must be exist prior creating devices execution;
> + * @ext_pwr_source: 1 if system powered by external power supply; 0 - by internal;
>   */
>  struct nvsw_sn2201 {
>  	struct device *dev;
> @@ -152,6 +157,7 @@ struct nvsw_sn2201 {
>  	struct mlxreg_hotplug_device *cpld_devs;
>  	int cpld_devs_num;
>  	int main_mux_deferred_nr;
> +	u8 ext_pwr_source;

Why is this u8? Wouldn't bool make more sense?

>  };
>  
>  static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg)
> @@ -522,6 +528,35 @@ struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = {
>  	.mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF,
>  };
>  
> +static struct mlxreg_core_item nvsw_sn2201_busbar_items[] = {
> +	{
> +		.data = nvsw_sn2201_fan_items_data,
> +		.aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF,
> +		.reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
> +		.mask = NVSW_SN2201_CPLD_FAN_MASK,
> +		.count = ARRAY_SIZE(nvsw_sn2201_fan_items_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +	{
> +		.data = nvsw_sn2201_sys_items_data,
> +		.aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF,
> +		.reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
> +		.mask = NVSW_SN2201_CPLD_ASIC_MASK,
> +		.count = ARRAY_SIZE(nvsw_sn2201_sys_items_data),
> +		.inversed = 1,
> +		.health = false,
> +	},
> +};
> +
> +static
> +struct mlxreg_core_hotplug_platform_data nvsw_sn2201_busbar_hotplug = {
> +	.items = nvsw_sn2201_items,
> +	.count = ARRAY_SIZE(nvsw_sn2201_busbar_items),
> +	.cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET,
> +	.mask = NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF,
> +};
> +
>  /* SN2201 static devices. */
>  static struct i2c_board_info nvsw_sn2201_static_devices[] = {
>  	{
> @@ -557,6 +592,9 @@ static struct i2c_board_info nvsw_sn2201_static_devices[] = {
>  	{
>  		I2C_BOARD_INFO("pmbus", 0x40),
>  	},
> +	{
> +		I2C_BOARD_INFO("lm5066i", 0x15),
> +	},
>  };
>  
>  /* SN2201 default static board info. */
> @@ -607,6 +645,58 @@ static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = {
>  	},
>  };
>  
> +/* SN2201 default basbar static board info. */
> +static struct mlxreg_hotplug_device nvsw_sn2201_busbar_static_brdinfo[] = {
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[0],
> +		.nr = NVSW_SN2201_MAIN_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[1],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[2],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[3],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[4],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH3_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[5],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[6],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[7],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[8],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[9],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[10],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH7_NR,
> +	},
> +	{
> +		.brdinfo = &nvsw_sn2201_static_devices[11],
> +		.nr = NVSW_SN2201_MAIN_MUX_CH1_NR,
> +	},
> +};
> +
>  /* LED default data. */
>  static struct mlxreg_core_data nvsw_sn2201_led_data[] = {
>  	{
> @@ -981,7 +1071,10 @@ static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap
>  	nvsw_sn2201->io_data = &nvsw_sn2201_regs_io;
>  	nvsw_sn2201->led_data = &nvsw_sn2201_led;
>  	nvsw_sn2201->wd_data = &nvsw_sn2201_wd;
> -	nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug;
> +	if (nvsw_sn2201->ext_pwr_source)
> +		nvsw_sn2201->hotplug_data = &nvsw_sn2201_busbar_hotplug;
> +	else
> +		nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug;
>  
>  	/* Register IO access driver. */
>  	if (nvsw_sn2201->io_data) {
> @@ -1198,12 +1291,18 @@ static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201)
>  static int nvsw_sn2201_probe(struct platform_device *pdev)
>  {
>  	struct nvsw_sn2201 *nvsw_sn2201;
> +	const char *sku;
>  	int ret;
>  
>  	nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL);
>  	if (!nvsw_sn2201)
>  		return -ENOMEM;
>  
> +	/* Validate system powering type. */
> +	sku = dmi_get_system_info(DMI_PRODUCT_SKU);
> +	if (!strcmp(sku, "HI168"))

Will one entry suffice or should this be table based right from the start?

> +		nvsw_sn2201->ext_pwr_source = 1;
> +
>  	nvsw_sn2201->dev = &pdev->dev;
>  	platform_set_drvdata(pdev, nvsw_sn2201);
>  	ret = platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources,
> @@ -1214,8 +1313,13 @@ static int nvsw_sn2201_probe(struct platform_device *pdev)
>  	nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR;
>  	nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo;
>  	nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo;
> -	nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo;
> -	nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo);
> +	if (nvsw_sn2201->ext_pwr_source) {
> +		nvsw_sn2201->sn2201_devs = nvsw_sn2201_busbar_static_brdinfo;
> +		nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_busbar_static_brdinfo);
> +	} else {
> +		nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo;
> +		nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo);
> +	}
>  
>  	return nvsw_sn2201_config_pre_init(nvsw_sn2201);
>  }
> 

Unrelated to this patch, .acpi_match_table is misindented in this file.

-- 
 i.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH platform-next v8 7/7] Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces
  2025-04-12  9:18 ` [PATCH platform-next v8 7/7] Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces Vadim Pasternak
@ 2025-04-15 15:02   ` Ilpo Järvinen
  0 siblings, 0 replies; 14+ messages in thread
From: Ilpo Järvinen @ 2025-04-15 15:02 UTC (permalink / raw)
  To: Vadim Pasternak
  Cc: Hans de Goede, michaelsh, crajank, fradensky, oleksandrs,
	platform-driver-x86

On Sat, 12 Apr 2025, Vadim Pasternak wrote:

> Add documentation for the new attributes:
> - Request and response for access to protetced flashes:
>   "global_wp_request", "global_wp_response".
>   Only for systems equipped with BMC - grant can be provided only by
>   BMC in case its security policy allows to grant access.
> - Request to unlock ASICs, which has been shutdown due-to ASIC thermal
>   event: "shutdown_unlock".
> - Data processor Units (DPU) boot progress: "boot_progress".
> - DPU reset causes: "reset_aux_pwr_or_reload", "reset_dpu_thermal",
>   "reset_from_main_board".
> - Reset control for DPU components: "perst_rst", "phy_rst", "tpm_rst",
>   "usbphy_rst".
> - DPU Unified Fabric Manager upgrade - "ufm_upgrade".
> - Hardware Id of Data Process Unit board - "dpu_id".
> 
> Reviewed-by: Michael Shych <michaelsh@nvidia.com>
> Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
> ---
> v7->v8
> Added by Vadim:
> - Fix dates.
> v5->v6
> Comments pointed out by Ilpo:
> - Fix dates.
> ---
>  .../ABI/stable/sysfs-driver-mlxreg-io         | 96 +++++++++++++++++++
>  1 file changed, 96 insertions(+)
> 
> diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
> index 2cdfd09123da..acc0c9a9ac29 100644
> --- a/Documentation/ABI/stable/sysfs-driver-mlxreg-io
> +++ b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
> @@ -715,3 +715,99 @@ Description:	This file shows 1 in case the system reset happened due to the
>  		switch board.
>  
>  		The file is read only.
> +
> +What:		/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/global_wp_request
> +Date:		April 2025
> +KernelVersion:	6.15

I really wish we wouldn't need to do this... Once again, these are 
outdated.

-- 
 i.

> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	This file when written 1 activates request to allow access to
> +		the write protected flashes. Such request can be performed only
> +		for system equipped with BMC (Board Management Controller),
> +		which can grant access to protected flashes. In case BMC allows
> +		access - it will respond with "global_wp_response". BMC decides
> +		regarding time window of granted access. After granted window is
> +		expired, BMC will change value back to 0.
> +		Default value is 0.
> +
> +		The file is read/write.
> +
> +What:		/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/global_wp_response
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	This file, when set 1, indicates that access to protected
> +		flashes have been granted to host CPU by BMC.
> +		Default value is 0.
> +
> +		The file is read only.
> +
> +What:		/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/shutdown_unlock
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak vadimp@nvidia.com
> +Description:	When ASICs are getting overheated, system protection
> +		hardware mechanism enforces system reboot. After system
> +		reboot ASICs come up in locked state. To unlock ASICs,
> +		this file should be written 1
> +		Default value is 0.
> +
> +		The file is read/write.
> +
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/boot_progress
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	These files show the Data Process Unit board boot progress
> +		state. Valid states are:
> +		- 4 : OS starting.
> +		- 5 : OS running.
> +		- 6 : Low-Power Standby.
> +
> +		The file is read only.
> +
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/dpu_id
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	This file shows hardware Id of Data Process Unit board.
> +
> +		The file is read only.
> +
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/reset_aux_pwr_or_reload
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/reset_dpu_thermal
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/reset_from_main_board
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	These files show the Data Process Unit board reset cause, as
> +		following: reset due to power auxiliary outage or power reload, reset
> +		due to thermal shutdown, reset due to request from main board.
> +		Value 1 in file means this is reset cause, 0 - otherwise. Only one of
> +		the above causes could be 1 at the same time, representing only last
> +		reset cause.
> +
> +		The files are read only.
> +
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/perst_rst
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/phy_rst
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/tpm_rst
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/usbphy_rst
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	These files allow to reset hardware components of Data Process
> +		Unit board. Respectively PCI, Ethernet PHY, TPM and USB PHY
> +		resets.
> +		Default values for all the attributes is 1. Writing 0 will
> +		cause reset of the related component.
> +
> +		The files are read/write.
> +
> +What:		/sys/devices/platform/mlxplat/i2c_mlxcpld.*/i2c-*/i2c-*/*-00**/mlxreg-io.*/hwmon/hwmon*/ufm_upgrade
> +Date:		April 2025
> +KernelVersion:	6.15
> +Contact:	Vadim Pasternak <vadimp@nvidia.com>
> +Description:	These files show status of Unified Fabric Manager upgrade.
> +		state. 0 - means upgrade is done, 1 - otherwise.
> +
> +		The file is read only.
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-04-15 15:02 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-12  9:18 [PATCH platform-next v8 0/7] Add support for new systems, amendments Vadim Pasternak
2025-04-12  9:18 ` [PATCH platform-next v8 1/7] platform/mellanox: Rename field to improve code readability Vadim Pasternak
2025-04-12  9:18 ` [PATCH platform-next v8 2/7] platform/mellanox: mlxreg-dpu: Add initial support for Nvidia DPU Vadim Pasternak
2025-04-15 14:32   ` Ilpo Järvinen
2025-04-12  9:18 ` [PATCH platform-next v8 3/7] platform: mellanox: Introduce support of Nvidia smart switch Vadim Pasternak
2025-04-15 14:38   ` Ilpo Järvinen
2025-04-12  9:18 ` [PATCH platform-next v8 4/7] platform: mellanox: Cosmetic changes to improve code style Vadim Pasternak
2025-04-15 14:40   ` Ilpo Järvinen
2025-04-12  9:18 ` [PATCH platform-next v8 5/7] platform: mellanox: mlx-platform: Add support for new Nvidia system Vadim Pasternak
2025-04-15 14:48   ` Ilpo Järvinen
2025-04-12  9:18 ` [PATCH platform-next v8 6/7] platform: mellanox: nvsw-sn2200: Add support for new system flavour Vadim Pasternak
2025-04-15 15:00   ` Ilpo Järvinen
2025-04-12  9:18 ` [PATCH platform-next v8 7/7] Documentation/ABI: Add new attribute for mlxreg-io sysfs interfaces Vadim Pasternak
2025-04-15 15:02   ` Ilpo Järvinen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).