From 5c6c1d269943d7ee74bcb799d0177bca46af06f5 Mon Sep 17 00:00:00 2001
From: Nazarii Hnydyn <nazariig@mellanox.com>
Date: Thu, 20 Feb 2020 17:07:03 +0200
Subject: [PATCH] [mellanox]: Add SN4700 patches.

Signed-off-by: Nazarii Hnydyn <nazariig@mellanox.com>
---
 ...-access-to-the-SKU-ID-string-backpor.patch |  88 ++++
 ...-platform-Modify-setting-for-new-sys.patch | 420 +++++++++++++++
 ...-platform-Add-support-for-next-gener.patch | 486 ++++++++++++++++++
 ...upport-for-new-hardware-device-types.patch |  87 ++++
 ...-Fix-validation-for-FW-minor-version.patch |  32 ++
 patch/series                                  |   5 +
 6 files changed, 1118 insertions(+)
 create mode 100644 patch/0053-firmware-dmi-Add-access-to-the-SKU-ID-string-backpor.patch
 create mode 100644 patch/0054-platform-x86-mlx-platform-Modify-setting-for-new-sys.patch
 create mode 100644 patch/0055-platform-x86-mlx-platform-Add-support-for-next-gener.patch
 create mode 100644 patch/0056-mlxsw-core-Add-support-for-new-hardware-device-types.patch
 create mode 100644 patch/0057-mlxsw-minimal-Fix-validation-for-FW-minor-version.patch

diff --git a/patch/0053-firmware-dmi-Add-access-to-the-SKU-ID-string-backpor.patch b/patch/0053-firmware-dmi-Add-access-to-the-SKU-ID-string-backpor.patch
new file mode 100644
index 000000000..2ac84540d
--- /dev/null
+++ b/patch/0053-firmware-dmi-Add-access-to-the-SKU-ID-string-backpor.patch
@@ -0,0 +1,88 @@
+From acc9225e1db4bfc710c83c25f34b2b226060c350 Mon Sep 17 00:00:00 2001
+From: Vadim Pasternak <vadimp@mellanox.com>
+Date: Thu, 23 Jan 2020 14:58:38 +0200
+Subject: [PATCH backport] firmware: dmi: Add access to the SKU ID string
+ backport
+
+Backport of two below upstream commits.
+
+commit b23908d3c48a37c46c6a26df2cdeab1610b360ba
+Author: Simon Glass <sjg@chromium.org>
+Date:   Sun Jun 17 14:09:42 2018 +0200
+
+    firmware: dmi: Add access to the SKU ID string
+
+    This is used in some systems from user space for determining the
+identity
+    of the device.
+
+    Expose this as a file so that that user-space tools don't need to
+read
+    from /sys/firmware/dmi/tables/DMI
+
+    Signed-off-by: Simon Glass <sjg@chromium.org>
+    Signed-off-by: Jean Delvare <jdelvare@suse.de>
+
+commit b23908d3c48a37c46c6a26df2cdeab1610b360ba
+Author: Simon Glass <sjg@chromium.org>
+Date:   Sun Jun 17 14:09:42 2018 +0200
+
+firmware: dmi: Add access to the SKU ID string
+
+    This is used in some systems from user space for determining the
+identity
+    of the device.
+
+    Expose this as a file so that that user-space tools don't need to
+read
+    from /sys/firmware/dmi/tables/DMI
+
+    Signed-off-by: Simon Glass <sjg@chromium.org>
+    Signed-off-by: Jean Delvare <jdelvare@suse.de>
+
+Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
+---
+ drivers/firmware/dmi-id.c       | 1 +
+ drivers/firmware/dmi_scan.c     | 1 +
+ include/linux/mod_devicetable.h | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
+index dc269cb288c2..5c864ebe1127 100644
+--- a/drivers/firmware/dmi-id.c
++++ b/drivers/firmware/dmi-id.c
+@@ -47,6 +47,7 @@ DEFINE_DMI_ATTR_WITH_SHOW(product_name,		0444, DMI_PRODUCT_NAME);
+ DEFINE_DMI_ATTR_WITH_SHOW(product_version,	0444, DMI_PRODUCT_VERSION);
+ DEFINE_DMI_ATTR_WITH_SHOW(product_serial,	0400, DMI_PRODUCT_SERIAL);
+ DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,		0400, DMI_PRODUCT_UUID);
++DEFINE_DMI_ATTR_WITH_SHOW(product_sku,		0444, DMI_PRODUCT_SKU);
+ DEFINE_DMI_ATTR_WITH_SHOW(product_family,	0400, DMI_PRODUCT_FAMILY);
+ DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,		0444, DMI_BOARD_VENDOR);
+ DEFINE_DMI_ATTR_WITH_SHOW(board_name,		0444, DMI_BOARD_NAME);
+diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
+index 150b923ef86d..d2a85a2e5b08 100644
+--- a/drivers/firmware/dmi_scan.c
++++ b/drivers/firmware/dmi_scan.c
+@@ -426,6 +426,7 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
+ 		dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
+ 		dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
+ 		dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8);
++		dmi_save_ident(dm, DMI_PRODUCT_SKU, 25);
+ 		dmi_save_ident(dm, DMI_PRODUCT_FAMILY, 26);
+ 		break;
+ 	case 2:		/* Base Board Information */
+diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
+index 616b31a1495d..103c14049a76 100644
+--- a/include/linux/mod_devicetable.h
++++ b/include/linux/mod_devicetable.h
+@@ -456,6 +456,7 @@ enum dmi_field {
+ 	DMI_PRODUCT_VERSION,
+ 	DMI_PRODUCT_SERIAL,
+ 	DMI_PRODUCT_UUID,
++	DMI_PRODUCT_SKU,
+ 	DMI_PRODUCT_FAMILY,
+ 	DMI_BOARD_VENDOR,
+ 	DMI_BOARD_NAME,
+-- 
+2.20.1
+
diff --git a/patch/0054-platform-x86-mlx-platform-Modify-setting-for-new-sys.patch b/patch/0054-platform-x86-mlx-platform-Modify-setting-for-new-sys.patch
new file mode 100644
index 000000000..d4b9a98f2
--- /dev/null
+++ b/patch/0054-platform-x86-mlx-platform-Modify-setting-for-new-sys.patch
@@ -0,0 +1,420 @@
+From 7facfc1c55a37b8f28d75d0f2ddf51a0f892730a Mon Sep 17 00:00:00 2001
+From: Vadim Pasternak <vadimp@mellanox.com>
+Date: Tue, 17 Dec 2019 15:50:22 +0000
+Subject: [PATCH platform backport 1/2] platform/x86: mlx-platform: Modify
+ setting for new system type
+
+Modify setting for new Mellanox system types of basic class VMOD0009,
+containing Mellanox systems equipped with the switch devices
+Spectrum 1 (32x100GbE Ethernet switch) and Switch-IB/Switch-IB2
+(36x100Gbe InfiniBand switch).
+These are the Top of the Rack system, equipped with Mellanox Comex
+card.
+
+Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
+---
+ drivers/platform/x86/mlx-platform.c | 194 ++++++++++++++++++++++++++++++------
+ 1 file changed, 165 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
+index 765baf99de60..1a4fecb770ad 100644
+--- a/drivers/platform/x86/mlx-platform.c
++++ b/drivers/platform/x86/mlx-platform.c
+@@ -90,6 +90,7 @@
+ #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
+ #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF		0xdb
+ #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF		0xda
++#define MLXPLAT_CPLD_LPC_I2C_CH3_OFF		0xdc
+ 
+ #define MLXPLAT_CPLD_LPC_PIO_OFFSET		0x10000UL
+ #define MLXPLAT_CPLD_LPC_REG1	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
+@@ -98,6 +99,9 @@
+ #define MLXPLAT_CPLD_LPC_REG2	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
+ 				  MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \
+ 				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
++#define MLXPLAT_CPLD_LPC_REG3	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
++				  MLXPLAT_CPLD_LPC_I2C_CH3_OFF) | \
++				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
+ 
+ /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
+ #define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF	0x04
+@@ -110,7 +114,7 @@
+ #define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG	0x01
+ #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF	0x04
+ #define MLXPLAT_CPLD_AGGR_MASK_COMEX	BIT(0)
+-#define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW	0xe1
++#define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW	0xc1
+ #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C	BIT(6)
+ #define MLXPLAT_CPLD_PSU_MASK		GENMASK(1, 0)
+ #define MLXPLAT_CPLD_PWR_MASK		GENMASK(1, 0)
+@@ -131,6 +135,7 @@
+ 
+ /* Maximum number of possible physical buses equipped on system */
+ #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM	16
++#define MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM	24
+ 
+ /* Number of channels in group */
+ #define MLXPLAT_CPLD_GRP_CHNL_NUM		8
+@@ -138,9 +143,10 @@
+ /* Start channel numbers */
+ #define MLXPLAT_CPLD_CH1			2
+ #define MLXPLAT_CPLD_CH2			10
++#define MLXPLAT_CPLD_CH3			18
+ 
+ /* Number of LPC attached MUX platform devices */
+-#define MLXPLAT_CPLD_LPC_MUX_DEVS		2
++#define MLXPLAT_CPLD_LPC_MUX_DEVS		3
+ 
+ /* Hotplug devices adapter numbers */
+ #define MLXPLAT_CPLD_NR_NONE			-1
+@@ -221,7 +227,7 @@ static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = {
+ static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ 
+ /* Platform mux data */
+-static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
++static struct i2c_mux_reg_platform_data mlxplat_default_mux_data[] = {
+ 	{
+ 		.parent = 1,
+ 		.base_nr = MLXPLAT_CPLD_CH1,
+@@ -241,6 +247,40 @@ static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
+ 
+ };
+ 
++/* Platform mux configuration variables */
++static int mlxplat_max_adap_num;
++static int mlxplat_mux_num;
++static struct i2c_mux_reg_platform_data *mlxplat_mux_data;
++
++/* Platform extended mux data */
++static struct i2c_mux_reg_platform_data mlxplat_extended_mux_data[] = {
++	{
++		.parent = 1,
++		.base_nr = MLXPLAT_CPLD_CH1,
++		.write_only = 1,
++		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
++		.reg_size = 1,
++		.idle_in_use = 1,
++	},
++	{
++		.parent = 1,
++		.base_nr = MLXPLAT_CPLD_CH2,
++		.write_only = 1,
++		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG3,
++		.reg_size = 1,
++		.idle_in_use = 1,
++	},
++	{
++		.parent = 1,
++		.base_nr = MLXPLAT_CPLD_CH3,
++		.write_only = 1,
++		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
++		.reg_size = 1,
++		.idle_in_use = 1,
++	},
++
++};
++
+ /* Platform hotplug devices */
+ static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
+ 	{
+@@ -1037,6 +1077,80 @@ static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
+ 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
+ };
+ 
++/* Platform led for Comex based 100GbE systems */
++static struct mlxreg_core_data mlxplat_mlxcpld_comex_100G_led_data[] = {
++	{
++		.label = "status:green",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
++	},
++	{
++		.label = "status:red",
++		.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:red",
++		.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,
++	},
++	{
++		.label = "fan1:red",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
++	},
++	{
++		.label = "fan2:green",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
++	},
++	{
++		.label = "fan2:red",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
++	},
++	{
++		.label = "fan3:green",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
++	},
++	{
++		.label = "fan3:red",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
++	},
++	{
++		.label = "fan4:green",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
++	},
++	{
++		.label = "fan4:red",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
++	},
++	{
++		.label = "uid:blue",
++		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
++		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
++	},
++};
++
++static struct mlxreg_core_platform_data mlxplat_comex_100G_led_data = {
++		.data = mlxplat_mlxcpld_comex_100G_led_data,
++		.counter = ARRAY_SIZE(mlxplat_mlxcpld_comex_100G_led_data),
++};
++
+ /* Platform register access default */
+ static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
+ 	{
+@@ -1661,6 +1775,7 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+@@ -1710,6 +1825,8 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
+@@ -1779,6 +1896,8 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
+@@ -1920,7 +2039,10 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
++	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
++	mlxplat_mux_data = mlxplat_default_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		mlxplat_mux_data[i].values = mlxplat_default_channels[i];
+ 		mlxplat_mux_data[i].n_values =
+ 				ARRAY_SIZE(mlxplat_default_channels[i]);
+@@ -1933,13 +2055,16 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
+ 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
+ 
+ 	return 1;
+-};
++}
+ 
+ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
++	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
++	mlxplat_mux_data = mlxplat_default_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
+ 		mlxplat_mux_data[i].n_values =
+ 				ARRAY_SIZE(mlxplat_msn21xx_channels);
+@@ -1952,13 +2077,16 @@ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
+ 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
+ 
+ 	return 1;
+-};
++}
+ 
+ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
++	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
++	mlxplat_mux_data = mlxplat_default_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
+ 		mlxplat_mux_data[i].n_values =
+ 				ARRAY_SIZE(mlxplat_msn21xx_channels);
+@@ -1971,13 +2099,16 @@ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
+ 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
+ 
+ 	return 1;
+-};
++}
+ 
+ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
++	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
++	mlxplat_mux_data = mlxplat_default_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
+ 		mlxplat_mux_data[i].n_values =
+ 				ARRAY_SIZE(mlxplat_msn21xx_channels);
+@@ -1990,13 +2121,16 @@ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
+ 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
+ 
+ 	return 1;
+-};
++}
+ 
+ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
++	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
++	mlxplat_mux_data = mlxplat_default_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
+ 		mlxplat_mux_data[i].n_values =
+ 				ARRAY_SIZE(mlxplat_msn21xx_channels);
+@@ -2013,27 +2147,31 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
+ 	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng;
+ 
+ 	return 1;
+-};
++}
+ 
+ static int __init mlxplat_dmi_comex_matched(const struct dmi_system_id *dmi)
+ {
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM;
++	mlxplat_mux_num = ARRAY_SIZE(mlxplat_extended_mux_data);
++	mlxplat_mux_data = mlxplat_extended_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
+ 		mlxplat_mux_data[i].n_values =
+ 				ARRAY_SIZE(mlxplat_msn21xx_channels);
+ 	}
+ 	mlxplat_hotplug = &mlxplat_mlxcpld_comex_data;
+-	mlxplat_hotplug->deferred_nr =
+-			mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+-	mlxplat_led = &mlxplat_default_led_data;
+-	mlxplat_regs_io = &mlxplat_default_regs_io_data;
++	mlxplat_hotplug->deferred_nr = MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM;
++	mlxplat_led = &mlxplat_comex_100G_led_data;
++	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
+ 	mlxplat_fan = &mlxplat_default_fan_data;
++	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
++		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
+ 	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_comex;
+ 
+ 	return 1;
+-};
++}
+ 
+ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
+ 	{
+@@ -2168,7 +2306,7 @@ static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
+ 	/* Scan adapters from expected id to verify it is free. */
+ 	*nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
+ 	for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
+-	     MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; i++) {
++	     mlxplat_max_adap_num; i++) {
+ 		search_adap = i2c_get_adapter(i);
+ 		if (search_adap) {
+ 			i2c_put_adapter(search_adap);
+@@ -2182,12 +2320,12 @@ static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
+ 	}
+ 
+ 	/* Return with error if free id for adapter is not found. */
+-	if (i == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM)
++	if (i == mlxplat_max_adap_num)
+ 		return -ENODEV;
+ 
+ 	/* Shift adapter ids, since expected parent adapter is not free. */
+ 	*nr = i;
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		shift = *nr - mlxplat_mux_data[i].parent;
+ 		mlxplat_mux_data[i].parent = *nr;
+ 		mlxplat_mux_data[i].base_nr += shift;
+@@ -2243,7 +2381,7 @@ static int __init mlxplat_init(void)
+ 	if (nr < 0)
+ 		goto fail_alloc;
+ 
+-	nr = (nr == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) ? -1 : nr;
++	nr = (nr == mlxplat_max_adap_num) ? -1 : nr;
+ 	if (mlxplat_i2c)
+ 		mlxplat_i2c->regmap = priv->regmap;
+ 	priv->pdev_i2c = platform_device_register_resndata(
+@@ -2256,7 +2394,7 @@ static int __init mlxplat_init(void)
+ 		goto fail_alloc;
+ 	}
+ 
+-	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
++	for (i = 0; i < mlxplat_mux_num; i++) {
+ 		priv->pdev_mux[i] = platform_device_register_resndata(
+ 						&priv->pdev_i2c->dev,
+ 						"i2c-mux-reg", i, NULL,
+@@ -2381,10 +2519,8 @@ static void __exit mlxplat_exit(void)
+ 	struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
+ 	int i;
+ 
+-	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--) {
+-		if (mlxplat_wd_data[i])
+-			platform_device_unregister(priv->pdev_wd[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);
+ 	if (priv->pdev_io_regs)
+@@ -2392,7 +2528,7 @@ static void __exit mlxplat_exit(void)
+ 	platform_device_unregister(priv->pdev_led);
+ 	platform_device_unregister(priv->pdev_hotplug);
+ 
+-	for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
++	for (i = mlxplat_mux_num - 1; i >= 0 ; i--)
+ 		platform_device_unregister(priv->pdev_mux[i]);
+ 
+ 	platform_device_unregister(priv->pdev_i2c);
+-- 
+2.11.0
+
diff --git a/patch/0055-platform-x86-mlx-platform-Add-support-for-next-gener.patch b/patch/0055-platform-x86-mlx-platform-Add-support-for-next-gener.patch
new file mode 100644
index 000000000..13cd1bd46
--- /dev/null
+++ b/patch/0055-platform-x86-mlx-platform-Add-support-for-next-gener.patch
@@ -0,0 +1,486 @@
+From 4da715b3bea946b1f9d43a7c95c54be4dcb057f2 Mon Sep 17 00:00:00 2001
+From: Vadim Pasternak <vadimp@mellanox.com>
+Date: Thu, 2 Jan 2020 06:58:09 +0000
+Subject: [PATCH platform] platform/x86: mlx-platform: Add support for next
+ generation systems
+
+Add support for new Mellanox system types of basic class VMOD0010,
+containing new Mellanox systems equipped with new switch device
+Spectrum 3 (32x400GbE/64x200G/128x100G Ethernet switch).
+These are the Top of the Rack 1U/2U/4U systems, equipped with
+Mellanox Comex card and with the switch board with Mellanox Spectrum-3
+device.
+This class of devices can be equipped with two PS units for 1U/2U or
+with four PS units for 4U systems.
+
+Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
+---
+ drivers/platform/mellanox/mlxreg-hotplug.c |  14 ++
+ drivers/platform/x86/mlx-platform.c        | 265 +++++++++++++++++++++++++++++
+ include/linux/platform_data/mlxreg.h       |   2 +
+ 3 files changed, 281 insertions(+)
+
+diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
+index f85a1b9d129b..bd34aac2426e 100644
+--- a/drivers/platform/mellanox/mlxreg-hotplug.c
++++ b/drivers/platform/mellanox/mlxreg-hotplug.c
+@@ -504,6 +504,20 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
+ 	item = pdata->items;
+ 
+ 	for (i = 0; i < pdata->counter; i++, item++) {
++		if (item->capability) {
++			/*
++			 * Read group capability register to get actual number
++			 * of interrupt capable components and set group mask
++			 * accordingly.
++			 */
++			ret = regmap_read(priv->regmap, item->capability,
++					  &regval);
++			if (ret)
++				goto out;
++
++			item->mask = GENMASK((regval & item->mask) - 1, 0);
++		}
++
+ 		/* Clear group presense event. */
+ 		ret = regmap_write(priv->regmap, item->reg +
+ 				   MLXREG_HOTPLUG_EVENT_OFF, 0);
+diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
+index 1a4fecb770ad..c27548fd386a 100644
+--- a/drivers/platform/x86/mlx-platform.c
++++ b/drivers/platform/x86/mlx-platform.c
+@@ -35,6 +35,8 @@
+ #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET	0x23
+ #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET	0x24
+ #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION	0x2a
++#define MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET	0x2b
++#define MLXPLAT_CPLD_LPC_REG_GP0_OFFSET		0x2e
+ #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET		0x30
+ #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET		0x31
+ #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET		0x32
+@@ -70,6 +72,7 @@
+ #define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET	0xd1
+ #define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET	0xd2
+ #define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET	0xd3
++#define MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET	0xe2
+ #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET	0xe3
+ #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET	0xe4
+ #define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET	0xe5
+@@ -87,6 +90,9 @@
+ #define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET	0xf6
+ #define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET	0xf7
+ #define MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET	0xf8
++#define MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET 0xf9
++#define MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET	0xfb
++#define MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET	0xfc
+ #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
+ #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF		0xdb
+ #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF		0xda
+@@ -118,11 +124,16 @@
+ #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C	BIT(6)
+ #define MLXPLAT_CPLD_PSU_MASK		GENMASK(1, 0)
+ #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_FAN_MASK		GENMASK(3, 0)
+ #define MLXPLAT_CPLD_ASIC_MASK		GENMASK(1, 0)
+ #define MLXPLAT_CPLD_FAN_NG_MASK	GENMASK(5, 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_I2C_CAP_BIT	0x04
++#define MLXPLAT_CPLD_I2C_CAP_MASK	GENMASK(5, MLXPLAT_CPLD_I2C_CAP_BIT)
+ 
+ /* Masks for aggregation for comex carriers */
+ #define MLXPLAT_CPLD_AGGR_MASK_CARRIER	BIT(1)
+@@ -152,6 +163,7 @@
+ #define MLXPLAT_CPLD_NR_NONE			-1
+ #define MLXPLAT_CPLD_PSU_DEFAULT_NR		10
+ #define MLXPLAT_CPLD_PSU_MSNXXXX_NR		4
++#define MLXPLAT_CPLD_PSU_MSNXXXX_NR2		3
+ #define MLXPLAT_CPLD_FAN1_DEFAULT_NR		11
+ #define MLXPLAT_CPLD_FAN2_DEFAULT_NR		12
+ #define MLXPLAT_CPLD_FAN3_DEFAULT_NR		13
+@@ -201,8 +213,24 @@ static const struct resource mlxplat_lpc_resources[] = {
+ 			       IORESOURCE_IO),
+ };
+ 
++/* Platform i2c next generation systems data */
++static struct mlxreg_core_data mlxplat_mlxcpld_i2c_ng_items_data[] = {
++	{
++		.reg = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
++		.mask = MLXPLAT_CPLD_I2C_CAP_MASK,
++		.bit = MLXPLAT_CPLD_I2C_CAP_BIT,
++	},
++};
++
++static struct mlxreg_core_item mlxplat_mlxcpld_i2c_ng_items[] = {
++	{
++		.data = mlxplat_mlxcpld_i2c_ng_items_data,
++	},
++};
++
+ /* Platform next generation systems i2c data */
+ static struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_i2c_ng_data = {
++	.items = mlxplat_mlxcpld_i2c_ng_items,
+ 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+ 	.mask = MLXPLAT_CPLD_AGGR_MASK_COMEX,
+ 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET,
+@@ -836,6 +864,116 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
+ 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
+ };
+ 
++/* Platform hotplug extended system family data */
++static struct mlxreg_core_data mlxplat_mlxcpld_ext_psu_items_data[] = {
++	{
++		.label = "psu1",
++		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
++		.mask = BIT(0),
++		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
++	},
++	{
++		.label = "psu2",
++		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
++		.mask = BIT(1),
++		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
++	},
++	{
++		.label = "psu3",
++		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
++		.mask = BIT(2),
++		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
++	},
++	{
++		.label = "psu4",
++		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
++		.mask = BIT(3),
++		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
++	},
++};
++
++static struct mlxreg_core_data mlxplat_mlxcpld_ext_pwr_items_data[] = {
++	{
++		.label = "pwr1",
++		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
++		.mask = BIT(0),
++		.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),
++		.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),
++		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
++		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR2,
++	},
++	{
++		.label = "pwr4",
++		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
++		.mask = BIT(3),
++		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
++		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR2,
++	},
++};
++
++static struct mlxreg_core_item mlxplat_mlxcpld_ext_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_ext_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_default_ng_fan_items_data,
++		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
++		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
++		.mask = MLXPLAT_CPLD_FAN_NG_MASK,
++		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_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_ext_data = {
++	.items = mlxplat_mlxcpld_ext_items,
++	.counter = 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,
++	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
++};
++
+ /* Platform led default data */
+ static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
+ 	{
+@@ -1344,6 +1482,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = {
+ 		.mode = 0200,
+ 	},
+ 	{
++		.label = "select_iio",
++		.reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
++		.mask = GENMASK(7, 0) & ~BIT(6),
++		.mode = 0644,
++	},
++	{
+ 		.label = "asic_health",
+ 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+ 		.mask = MLXPLAT_CPLD_ASIC_MASK,
+@@ -1432,6 +1576,18 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
+ 		.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_comex_wd",
+ 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
+ 		.mask = GENMASK(7, 0) & ~BIT(6),
+@@ -1468,6 +1624,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
+ 		.mode = 0444,
+ 	},
+ 	{
++		.label = "reset_ac_pwr_fail",
++		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
++		.mask = GENMASK(7, 0) & ~BIT(6),
++		.mode = 0444,
++	},
++	{
+ 		.label = "psu1_on",
+ 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+ 		.mask = GENMASK(7, 0) & ~BIT(0),
+@@ -1510,6 +1672,43 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
+ 		.bit = GENMASK(7, 0),
+ 		.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 = "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 = "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 = "ufm_version",
++		.reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
++		.bit = GENMASK(7, 0),
++		.mode = 0444,
++	},
+ };
+ 
+ static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = {
+@@ -1768,6 +1967,7 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
+@@ -1815,6 +2015,8 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
++	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
+@@ -1867,6 +2069,10 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET:
+ 		return true;
+ 	}
+ 	return false;
+@@ -1888,6 +2094,8 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
++	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
+@@ -1932,6 +2140,10 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
+ 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
+ 	case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET:
++	case MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET:
+ 		return true;
+ 	}
+ 	return false;
+@@ -1955,6 +2167,13 @@ static const struct reg_default mlxplat_mlxcpld_regmap_comex_default[] = {
+ 	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
+ };
+ 
++static const struct reg_default mlxplat_mlxcpld_regmap_ng400[] = {
++	{ 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 },
++};
++
+ struct mlxplat_mlxcpld_regmap_context {
+ 	void __iomem *base;
+ };
+@@ -2021,6 +2240,20 @@ static const struct regmap_config mlxplat_mlxcpld_regmap_config_comex = {
+ 	.reg_write = mlxplat_mlxcpld_reg_write,
+ };
+ 
++static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng400 = {
++	.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_ng400,
++	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng400),
++	.reg_read = mlxplat_mlxcpld_reg_read,
++	.reg_write = mlxplat_mlxcpld_reg_write,
++};
++
+ static struct resource mlxplat_mlxcpld_resources[] = {
+ 	[0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
+ };
+@@ -2173,6 +2406,32 @@ static int __init mlxplat_dmi_comex_matched(const struct dmi_system_id *dmi)
+ 	return 1;
+ }
+ 
++static int __init mlxplat_dmi_ng400_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_default_mux_data);
++	mlxplat_mux_data = mlxplat_default_mux_data;
++	for (i = 0; i < mlxplat_mux_num; i++) {
++		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
++		mlxplat_mux_data[i].n_values =
++				ARRAY_SIZE(mlxplat_msn21xx_channels);
++	}
++	mlxplat_hotplug = &mlxplat_mlxcpld_ext_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_default_fan_data;
++	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
++		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
++	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
++	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
++
++	return 1;
++}
++
+ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
+ 	{
+ 		.callback = mlxplat_dmi_default_matched,
+@@ -2217,6 +2476,12 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
+ 		},
+ 	},
+ 	{
++		.callback = mlxplat_dmi_ng400_matched,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_NAME, "VMOD0010"),
++		},
++	},
++	{
+ 		.callback = mlxplat_dmi_msn274x_matched,
+ 		.matches = {
+ 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
+diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h
+index 6d54fe3bcac9..b8da8aef2446 100644
+--- a/include/linux/platform_data/mlxreg.h
++++ b/include/linux/platform_data/mlxreg.h
+@@ -101,6 +101,7 @@ struct mlxreg_core_data {
+  * @aggr_mask: group aggregation mask;
+  * @reg: group interrupt status register;
+  * @mask: group interrupt mask;
++ * @capability: group capability register;
+  * @cache: last status value for elements fro the same group;
+  * @count: number of available elements in the group;
+  * @ind: element's index inside the group;
+@@ -112,6 +113,7 @@ struct mlxreg_core_item {
+ 	u32 aggr_mask;
+ 	u32 reg;
+ 	u32 mask;
++	u32 capability;
+ 	u32 cache;
+ 	u8 count;
+ 	u8 ind;
+-- 
+2.11.0
+
diff --git a/patch/0056-mlxsw-core-Add-support-for-new-hardware-device-types.patch b/patch/0056-mlxsw-core-Add-support-for-new-hardware-device-types.patch
new file mode 100644
index 000000000..8f64b9baf
--- /dev/null
+++ b/patch/0056-mlxsw-core-Add-support-for-new-hardware-device-types.patch
@@ -0,0 +1,87 @@
+From 78c5e6e6d39427868a33d86cc83c1646503a1d78 Mon Sep 17 00:00:00 2001
+From: Vadim Pasternak <vadimp@mellanox.com>
+Date: Thu, 23 Jan 2020 20:17:36 +0000
+Subject: [PATCH mlxsw] mlxsw: core: Add support for new hardware device types
+
+Add validation for new device types, provided by MGPIR
+register.
+
+Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
+---
+ drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c   | 6 ++++--
+ drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 8 ++++++--
+ drivers/net/ethernet/mellanox/mlxsw/reg.h          | 3 +++
+ 3 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+index 9cb19ec47e4d..cd1d371edfcf 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+@@ -575,6 +575,7 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
+ 
+ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
+ {
++	enum mlxsw_reg_mgpir_device_type device_type;
+ 	int index, max_index, sensor_index;
+ 	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
+ 	char mtmp_pl[MLXSW_REG_MTMP_LEN];
+@@ -586,8 +587,9 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
+ 	if (err)
+ 		return 0;
+ 
+-	mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, NULL, NULL, NULL);
+-	if (!gbox_num)
++	mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL);
++	if ((device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE) ||
++	    !gbox_num)
+ 		return 0;
+ 
+ 	index = mlxsw_hwmon->module_sensor_count;
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+index f234416305fd..690ae0f1820e 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+@@ -920,8 +920,10 @@ static int
+ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
+ 			     struct mlxsw_thermal *thermal)
+ {
++	enum mlxsw_reg_mgpir_device_type device_type;
+ 	struct mlxsw_thermal_module *gearbox_tz;
+ 	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
++	u8 num_of_device;
+ 	int i;
+ 	int err;
+ 
+@@ -933,11 +935,13 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
+ 	if (err)
+ 		return 0;
+ 
+-	mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL,
++	mlxsw_reg_mgpir_unpack(mgpir_pl, &num_of_device, &device_type, NULL,
+ 			       NULL);
+-	if (!thermal->tz_gearbox_num)
++	if ((device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE) ||
++	    !num_of_device)
+ 		return 0;
+ 
++	thermal->tz_gearbox_num = num_of_device;
+ 	thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
+ 					  sizeof(*thermal->tz_gearbox_arr),
+ 					  GFP_KERNEL);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
+index 8d7a58472799..43e73701a125 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
++++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
+@@ -8601,6 +8601,9 @@ MLXSW_REG_DEFINE(mgpir, MLXSW_REG_MGPIR_ID, MLXSW_REG_MGPIR_LEN);
+ enum mlxsw_reg_mgpir_device_type {
+ 	MLXSW_REG_MGPIR_DEVICE_TYPE_NONE,
+ 	MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE,
++	MLXSW_REG_MGPIR_DEVICE_TYPE_TILE,
++	MLXSW_REG_MGPIR_DEVICE_TYPE_AGBM,
++	MLXSW_REG_MGPIR_DEVICE_TYPE_XM,
+ };
+ 
+ /* device_type
+-- 
+2.11.0
+
diff --git a/patch/0057-mlxsw-minimal-Fix-validation-for-FW-minor-version.patch b/patch/0057-mlxsw-minimal-Fix-validation-for-FW-minor-version.patch
new file mode 100644
index 000000000..9bda4b1d2
--- /dev/null
+++ b/patch/0057-mlxsw-minimal-Fix-validation-for-FW-minor-version.patch
@@ -0,0 +1,32 @@
+From d4689cb7a12bd37ac0ace709b87dd91dd316bfd9 Mon Sep 17 00:00:00 2001
+From: Vadim Pasternak <vadimp@mellanox.com>
+Date: Mon, 10 Feb 2020 06:44:16 +0000
+Subject: [net] mlxsw: minimal: Fix validation for FW minor version
+
+Fix validation for FW minor version in order to prevent driver initialization
+in case FW minor version is older than expected.
+
+Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
+---
+ drivers/net/ethernet/mellanox/mlxsw/minimal.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+index 504db124ee2f..8cc969758f2f 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+@@ -127,8 +127,9 @@ static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)
+ 	dev_info(mlxsw_m->bus_info->dev, "The firmware version %d.%d.%d\n",
+ 		 rev->major, rev->minor, rev->subminor);
+ 	/* Validate driver & FW are compatible */
+-	if (rev->minor >= MLXSW_M_FWREV_MINOR &&
+-	    rev->subminor >= MLXSW_M_FWREV_SUBMINOR)
++	if ((rev->minor > MLXSW_M_FWREV_MINOR) ||
++	    (rev->minor == MLXSW_M_FWREV_MINOR &&
++	     rev->subminor >= MLXSW_M_FWREV_SUBMINOR))
+ 		return 0;
+ 
+ 	dev_info(mlxsw_m->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver (required >= %d.%d.%d)\n",
+-- 
+2.11.0
+
diff --git a/patch/series b/patch/series
index 51c7d303d..305115616 100755
--- a/patch/series
+++ b/patch/series
@@ -90,6 +90,11 @@ linux-4.13-thermal-intel_pch_thermal-Fix-enable-check-on.patch
 0050-mlxsw-core-Drop-creation-of-thermal-to-hwmon-sysfs-i.patch
 0051-mlxsw-core-Skip-thermal-zones-threshold-setting-duri.patch
 0052-platform-x86-mlx-platform-Add-more-detention-for-sys.patch
+0053-firmware-dmi-Add-access-to-the-SKU-ID-string-backpor.patch
+0054-platform-x86-mlx-platform-Modify-setting-for-new-sys.patch
+0055-platform-x86-mlx-platform-Add-support-for-next-gener.patch
+0056-mlxsw-core-Add-support-for-new-hardware-device-types.patch
+0057-mlxsw-minimal-Fix-validation-for-FW-minor-version.patch
 linux-4.16-firmware-dmi-handle-missing-DMI-data-gracefully.patch
 mellanox-backport-introduce-psample-a-new-genetlink-channel.patch
 mellanox-backport-introduce-tc-sample-action.patch