1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*
3  * Mellanox platform driver
4  *
5  * Copyright (C) 2016-2018 Mellanox Technologies
6  * Copyright (C) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
7  */
8 
9 #include <linux/device.h>
10 #include <linux/dmi.h>
11 #include <linux/i2c.h>
12 #include <linux/i2c-mux.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/platform_data/i2c-mux-reg.h>
17 #include <linux/platform_data/mlxreg.h>
18 #include <linux/regmap.h>
19 
20 #define MLX_PLAT_DEVICE_NAME		"mlxplat"
21 
22 /* LPC bus IO offsets */
23 #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR		0x2000
24 #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR		0x2500
25 #define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET	0x00
26 #define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET	0x01
27 #define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET	0x02
28 #define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET	0x03
29 #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET	0x1d
30 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET	0x1e
31 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET	0x1f
32 #define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET	0x20
33 #define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET	0x21
34 #define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET	0x22
35 #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET	0x23
36 #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET	0x24
37 #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION	0x2a
38 #define MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET	0x2b
39 #define MLXPLAT_CPLD_LPC_REG_GP0_OFFSET		0x2e
40 #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET		0x30
41 #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET		0x31
42 #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET		0x32
43 #define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET		0x33
44 #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET	0x37
45 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET	0x3a
46 #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET	0x3b
47 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET	0x40
48 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET	0x41
49 #define MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET	0x42
50 #define MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET	0x43
51 #define MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET	0x44
52 #define MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET 0x45
53 #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
54 #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET	0x51
55 #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET	0x52
56 #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET		0x58
57 #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET	0x59
58 #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET	0x5a
59 #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET		0x64
60 #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET	0x65
61 #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET	0x66
62 #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET		0x88
63 #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET	0x89
64 #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET	0x8a
65 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET	0xc7
66 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET	0xc8
67 #define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET	0xc9
68 #define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET	0xcb
69 #define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET	0xcd
70 #define MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET	0xce
71 #define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET	0xcf
72 #define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET	0xd1
73 #define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET	0xd2
74 #define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET	0xd3
75 #define MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET	0xe2
76 #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET	0xe3
77 #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET	0xe4
78 #define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET	0xe5
79 #define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET	0xe6
80 #define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET	0xe7
81 #define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET	0xe8
82 #define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET	0xe9
83 #define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET	0xeb
84 #define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET	0xec
85 #define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET	0xed
86 #define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET	0xee
87 #define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET	0xef
88 #define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET	0xf0
89 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET	0xf5
90 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET	0xf6
91 #define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET	0xf7
92 #define MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET	0xf8
93 #define MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET 0xf9
94 #define MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET	0xfb
95 #define MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET	0xfc
96 #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
97 #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF		0xdb
98 #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF		0xda
99 #define MLXPLAT_CPLD_LPC_I2C_CH3_OFF		0xdc
100 
101 #define MLXPLAT_CPLD_LPC_PIO_OFFSET		0x10000UL
102 #define MLXPLAT_CPLD_LPC_REG1	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
103 				  MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
104 				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
105 #define MLXPLAT_CPLD_LPC_REG2	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
106 				  MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \
107 				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
108 #define MLXPLAT_CPLD_LPC_REG3	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
109 				  MLXPLAT_CPLD_LPC_I2C_CH3_OFF) | \
110 				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
111 
112 /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
113 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF	0x04
114 #define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF	0x08
115 #define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF	0x08
116 #define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF	0x40
117 #define MLXPLAT_CPLD_AGGR_MASK_DEF	(MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
118 					 MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
119 					 MLXPLAT_CPLD_AGGR_FAN_MASK_DEF)
120 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG	0x01
121 #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF	0x04
122 #define MLXPLAT_CPLD_AGGR_MASK_COMEX	BIT(0)
123 #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW	0xc1
124 #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C	BIT(6)
125 #define MLXPLAT_CPLD_PSU_MASK		GENMASK(1, 0)
126 #define MLXPLAT_CPLD_PWR_MASK		GENMASK(1, 0)
127 #define MLXPLAT_CPLD_PSU_EXT_MASK	GENMASK(3, 0)
128 #define MLXPLAT_CPLD_PWR_EXT_MASK	GENMASK(3, 0)
129 #define MLXPLAT_CPLD_FAN_MASK		GENMASK(3, 0)
130 #define MLXPLAT_CPLD_ASIC_MASK		GENMASK(1, 0)
131 #define MLXPLAT_CPLD_FAN_NG_MASK	GENMASK(5, 0)
132 #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK	GENMASK(7, 4)
133 #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK	GENMASK(3, 0)
134 #define MLXPLAT_CPLD_VOLTREG_UPD_MASK	GENMASK(5, 4)
135 #define MLXPLAT_CPLD_I2C_CAP_BIT	0x04
136 #define MLXPLAT_CPLD_I2C_CAP_MASK	GENMASK(5, MLXPLAT_CPLD_I2C_CAP_BIT)
137 
138 /* Masks for aggregation for comex carriers */
139 #define MLXPLAT_CPLD_AGGR_MASK_CARRIER	BIT(1)
140 #define MLXPLAT_CPLD_AGGR_MASK_CARR_DEF	(MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
141 					 MLXPLAT_CPLD_AGGR_MASK_CARRIER)
142 #define MLXPLAT_CPLD_LOW_AGGRCX_MASK	0xc1
143 
144 /* Default I2C parent bus number */
145 #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR	1
146 
147 /* Maximum number of possible physical buses equipped on system */
148 #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM	16
149 #define MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM	24
150 
151 /* Number of channels in group */
152 #define MLXPLAT_CPLD_GRP_CHNL_NUM		8
153 
154 /* Start channel numbers */
155 #define MLXPLAT_CPLD_CH1			2
156 #define MLXPLAT_CPLD_CH2			10
157 #define MLXPLAT_CPLD_CH3			18
158 
159 /* Number of LPC attached MUX platform devices */
160 #define MLXPLAT_CPLD_LPC_MUX_DEVS		3
161 
162 /* Hotplug devices adapter numbers */
163 #define MLXPLAT_CPLD_NR_NONE			-1
164 #define MLXPLAT_CPLD_PSU_DEFAULT_NR		10
165 #define MLXPLAT_CPLD_PSU_MSNXXXX_NR		4
166 #define MLXPLAT_CPLD_PSU_MSNXXXX_NR2		3
167 #define MLXPLAT_CPLD_FAN1_DEFAULT_NR		11
168 #define MLXPLAT_CPLD_FAN2_DEFAULT_NR		12
169 #define MLXPLAT_CPLD_FAN3_DEFAULT_NR		13
170 #define MLXPLAT_CPLD_FAN4_DEFAULT_NR		14
171 
172 /* Masks and default values for watchdogs */
173 #define MLXPLAT_CPLD_WD1_CLEAR_MASK	GENMASK(7, 1)
174 #define MLXPLAT_CPLD_WD2_CLEAR_MASK	(GENMASK(7, 0) & ~BIT(1))
175 
176 #define MLXPLAT_CPLD_WD_TYPE1_TO_MASK	GENMASK(7, 4)
177 #define MLXPLAT_CPLD_WD_TYPE2_TO_MASK	0
178 #define MLXPLAT_CPLD_WD_RESET_ACT_MASK	GENMASK(7, 1)
179 #define MLXPLAT_CPLD_WD_FAN_ACT_MASK	(GENMASK(7, 0) & ~BIT(4))
180 #define MLXPLAT_CPLD_WD_COUNT_ACT_MASK	(GENMASK(7, 0) & ~BIT(7))
181 #define MLXPLAT_CPLD_WD_DFLT_TIMEOUT	30
182 #define MLXPLAT_CPLD_WD_MAX_DEVS	2
183 
184 /* mlxplat_priv - platform private data
185  * @pdev_i2c - i2c controller platform device
186  * @pdev_mux - array of mux platform devices
187  * @pdev_hotplug - hotplug platform devices
188  * @pdev_led - led platform devices
189  * @pdev_io_regs - register access platform devices
190  * @pdev_fan - FAN platform devices
191  * @pdev_wd - array of watchdog platform devices
192  * @regmap: device register map
193  */
194 struct mlxplat_priv {
195 	struct platform_device *pdev_i2c;
196 	struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
197 	struct platform_device *pdev_hotplug;
198 	struct platform_device *pdev_led;
199 	struct platform_device *pdev_io_regs;
200 	struct platform_device *pdev_fan;
201 	struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS];
202 	void *regmap;
203 };
204 
205 /* Regions for LPC I2C controller and LPC base register space */
206 static const struct resource mlxplat_lpc_resources[] = {
207 	[0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR,
208 			       MLXPLAT_CPLD_LPC_IO_RANGE,
209 			       "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO),
210 	[1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR,
211 			       MLXPLAT_CPLD_LPC_IO_RANGE,
212 			       "mlxplat_cpld_lpc_regs",
213 			       IORESOURCE_IO),
214 };
215 
216 /* Platform i2c next generation systems data */
217 static struct mlxreg_core_data mlxplat_mlxcpld_i2c_ng_items_data[] = {
218 	{
219 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
220 		.mask = MLXPLAT_CPLD_I2C_CAP_MASK,
221 		.bit = MLXPLAT_CPLD_I2C_CAP_BIT,
222 	},
223 };
224 
225 static struct mlxreg_core_item mlxplat_mlxcpld_i2c_ng_items[] = {
226 	{
227 		.data = mlxplat_mlxcpld_i2c_ng_items_data,
228 	},
229 };
230 
231 /* Platform next generation systems i2c data */
232 static struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_i2c_ng_data = {
233 	.items = mlxplat_mlxcpld_i2c_ng_items,
234 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
235 	.mask = MLXPLAT_CPLD_AGGR_MASK_COMEX,
236 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET,
237 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_I2C,
238 };
239 
240 /* Platform default channels */
241 static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = {
242 	{
243 		MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2,
244 		MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 +
245 		5, MLXPLAT_CPLD_CH1 + 6, MLXPLAT_CPLD_CH1 + 7
246 	},
247 	{
248 		MLXPLAT_CPLD_CH2, MLXPLAT_CPLD_CH2 + 1, MLXPLAT_CPLD_CH2 + 2,
249 		MLXPLAT_CPLD_CH2 + 3, MLXPLAT_CPLD_CH2 + 4, MLXPLAT_CPLD_CH2 +
250 		5, MLXPLAT_CPLD_CH2 + 6, MLXPLAT_CPLD_CH2 + 7
251 	},
252 };
253 
254 /* Platform channels for MSN21xx system family */
255 static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
256 
257 /* Platform mux data */
258 static struct i2c_mux_reg_platform_data mlxplat_default_mux_data[] = {
259 	{
260 		.parent = 1,
261 		.base_nr = MLXPLAT_CPLD_CH1,
262 		.write_only = 1,
263 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
264 		.reg_size = 1,
265 		.idle_in_use = 1,
266 	},
267 	{
268 		.parent = 1,
269 		.base_nr = MLXPLAT_CPLD_CH2,
270 		.write_only = 1,
271 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
272 		.reg_size = 1,
273 		.idle_in_use = 1,
274 	},
275 
276 };
277 
278 /* Platform mux configuration variables */
279 static int mlxplat_max_adap_num;
280 static int mlxplat_mux_num;
281 static struct i2c_mux_reg_platform_data *mlxplat_mux_data;
282 
283 /* Platform extended mux data */
284 static struct i2c_mux_reg_platform_data mlxplat_extended_mux_data[] = {
285 	{
286 		.parent = 1,
287 		.base_nr = MLXPLAT_CPLD_CH1,
288 		.write_only = 1,
289 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
290 		.reg_size = 1,
291 		.idle_in_use = 1,
292 	},
293 	{
294 		.parent = 1,
295 		.base_nr = MLXPLAT_CPLD_CH2,
296 		.write_only = 1,
297 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG3,
298 		.reg_size = 1,
299 		.idle_in_use = 1,
300 	},
301 	{
302 		.parent = 1,
303 		.base_nr = MLXPLAT_CPLD_CH3,
304 		.write_only = 1,
305 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
306 		.reg_size = 1,
307 		.idle_in_use = 1,
308 	},
309 
310 };
311 
312 /* Platform hotplug devices */
313 static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
314 	{
315 		I2C_BOARD_INFO("24c02", 0x51),
316 	},
317 	{
318 		I2C_BOARD_INFO("24c02", 0x50),
319 	},
320 };
321 
322 static struct i2c_board_info mlxplat_mlxcpld_ng_psu[] = {
323 	{
324 		I2C_BOARD_INFO("24c32", 0x51),
325 	},
326 	{
327 		I2C_BOARD_INFO("24c32", 0x50),
328 	},
329 };
330 
331 static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
332 	{
333 		I2C_BOARD_INFO("dps460", 0x59),
334 	},
335 	{
336 		I2C_BOARD_INFO("dps460", 0x58),
337 	},
338 };
339 
340 static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
341 	{
342 		I2C_BOARD_INFO("24c32", 0x50),
343 	},
344 	{
345 		I2C_BOARD_INFO("24c32", 0x50),
346 	},
347 	{
348 		I2C_BOARD_INFO("24c32", 0x50),
349 	},
350 	{
351 		I2C_BOARD_INFO("24c32", 0x50),
352 	},
353 };
354 
355 /* Platform hotplug comex carrier system family data */
356 static struct mlxreg_core_data mlxplat_mlxcpld_comex_psu_items_data[] = {
357 	{
358 		.label = "psu1",
359 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
360 		.mask = BIT(0),
361 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
362 	},
363 	{
364 		.label = "psu2",
365 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
366 		.mask = BIT(1),
367 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
368 	},
369 };
370 
371 /* Platform hotplug default data */
372 static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
373 	{
374 		.label = "psu1",
375 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
376 		.mask = BIT(0),
377 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
378 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
379 	},
380 	{
381 		.label = "psu2",
382 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
383 		.mask = BIT(1),
384 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
385 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
386 	},
387 };
388 
389 static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
390 	{
391 		.label = "pwr1",
392 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
393 		.mask = BIT(0),
394 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
395 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
396 	},
397 	{
398 		.label = "pwr2",
399 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
400 		.mask = BIT(1),
401 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
402 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
403 	},
404 };
405 
406 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
407 	{
408 		.label = "fan1",
409 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
410 		.mask = BIT(0),
411 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
412 		.hpdev.nr = MLXPLAT_CPLD_FAN1_DEFAULT_NR,
413 	},
414 	{
415 		.label = "fan2",
416 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
417 		.mask = BIT(1),
418 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
419 		.hpdev.nr = MLXPLAT_CPLD_FAN2_DEFAULT_NR,
420 	},
421 	{
422 		.label = "fan3",
423 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
424 		.mask = BIT(2),
425 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
426 		.hpdev.nr = MLXPLAT_CPLD_FAN3_DEFAULT_NR,
427 	},
428 	{
429 		.label = "fan4",
430 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
431 		.mask = BIT(3),
432 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
433 		.hpdev.nr = MLXPLAT_CPLD_FAN4_DEFAULT_NR,
434 	},
435 };
436 
437 static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = {
438 	{
439 		.label = "asic1",
440 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
441 		.mask = MLXPLAT_CPLD_ASIC_MASK,
442 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
443 	},
444 };
445 
446 static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
447 	{
448 		.data = mlxplat_mlxcpld_default_psu_items_data,
449 		.aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
450 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
451 		.mask = MLXPLAT_CPLD_PSU_MASK,
452 		.count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
453 		.inversed = 1,
454 		.health = false,
455 	},
456 	{
457 		.data = mlxplat_mlxcpld_default_pwr_items_data,
458 		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
459 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
460 		.mask = MLXPLAT_CPLD_PWR_MASK,
461 		.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
462 		.inversed = 0,
463 		.health = false,
464 	},
465 	{
466 		.data = mlxplat_mlxcpld_default_fan_items_data,
467 		.aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
468 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
469 		.mask = MLXPLAT_CPLD_FAN_MASK,
470 		.count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
471 		.inversed = 1,
472 		.health = false,
473 	},
474 	{
475 		.data = mlxplat_mlxcpld_default_asic_items_data,
476 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
477 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
478 		.mask = MLXPLAT_CPLD_ASIC_MASK,
479 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
480 		.inversed = 0,
481 		.health = true,
482 	},
483 };
484 
485 static struct mlxreg_core_item mlxplat_mlxcpld_comex_items[] = {
486 	{
487 		.data = mlxplat_mlxcpld_comex_psu_items_data,
488 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
489 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
490 		.mask = MLXPLAT_CPLD_PSU_MASK,
491 		.count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
492 		.inversed = 1,
493 		.health = false,
494 	},
495 	{
496 		.data = mlxplat_mlxcpld_default_pwr_items_data,
497 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
498 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
499 		.mask = MLXPLAT_CPLD_PWR_MASK,
500 		.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
501 		.inversed = 0,
502 		.health = false,
503 	},
504 	{
505 		.data = mlxplat_mlxcpld_default_fan_items_data,
506 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
507 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
508 		.mask = MLXPLAT_CPLD_FAN_MASK,
509 		.count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
510 		.inversed = 1,
511 		.health = false,
512 	},
513 	{
514 		.data = mlxplat_mlxcpld_default_asic_items_data,
515 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
516 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
517 		.mask = MLXPLAT_CPLD_ASIC_MASK,
518 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
519 		.inversed = 0,
520 		.health = true,
521 	},
522 };
523 
524 static
525 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
526 	.items = mlxplat_mlxcpld_default_items,
527 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
528 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
529 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
530 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
531 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
532 };
533 
534 static
535 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_comex_data = {
536 	.items = mlxplat_mlxcpld_comex_items,
537 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_comex_items),
538 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
539 	.mask = MLXPLAT_CPLD_AGGR_MASK_CARR_DEF,
540 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET,
541 	.mask_low = MLXPLAT_CPLD_LOW_AGGRCX_MASK,
542 };
543 
544 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = {
545 	{
546 		.label = "pwr1",
547 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
548 		.mask = BIT(0),
549 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
550 	},
551 	{
552 		.label = "pwr2",
553 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
554 		.mask = BIT(1),
555 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
556 	},
557 };
558 
559 /* Platform hotplug MSN21xx system family data */
560 static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
561 	{
562 		.data = mlxplat_mlxcpld_msn21xx_pwr_items_data,
563 		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
564 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
565 		.mask = MLXPLAT_CPLD_PWR_MASK,
566 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_pwr_items_data),
567 		.inversed = 0,
568 		.health = false,
569 	},
570 	{
571 		.data = mlxplat_mlxcpld_default_asic_items_data,
572 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
573 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
574 		.mask = MLXPLAT_CPLD_ASIC_MASK,
575 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
576 		.inversed = 0,
577 		.health = true,
578 	},
579 };
580 
581 static
582 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
583 	.items = mlxplat_mlxcpld_msn21xx_items,
584 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
585 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
586 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
587 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
588 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
589 };
590 
591 /* Platform hotplug msn274x system family data */
592 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data[] = {
593 	{
594 		.label = "psu1",
595 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
596 		.mask = BIT(0),
597 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
598 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
599 	},
600 	{
601 		.label = "psu2",
602 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
603 		.mask = BIT(1),
604 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
605 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
606 	},
607 };
608 
609 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data[] = {
610 	{
611 		.label = "pwr1",
612 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
613 		.mask = BIT(0),
614 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
615 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
616 	},
617 	{
618 		.label = "pwr2",
619 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
620 		.mask = BIT(1),
621 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
622 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
623 	},
624 };
625 
626 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data[] = {
627 	{
628 		.label = "fan1",
629 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
630 		.mask = BIT(0),
631 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
632 	},
633 	{
634 		.label = "fan2",
635 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
636 		.mask = BIT(1),
637 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
638 	},
639 	{
640 		.label = "fan3",
641 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
642 		.mask = BIT(2),
643 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
644 	},
645 	{
646 		.label = "fan4",
647 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
648 		.mask = BIT(3),
649 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
650 	},
651 };
652 
653 static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = {
654 	{
655 		.data = mlxplat_mlxcpld_msn274x_psu_items_data,
656 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
657 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
658 		.mask = MLXPLAT_CPLD_PSU_MASK,
659 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_psu_items_data),
660 		.inversed = 1,
661 		.health = false,
662 	},
663 	{
664 		.data = mlxplat_mlxcpld_default_ng_pwr_items_data,
665 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
666 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
667 		.mask = MLXPLAT_CPLD_PWR_MASK,
668 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
669 		.inversed = 0,
670 		.health = false,
671 	},
672 	{
673 		.data = mlxplat_mlxcpld_msn274x_fan_items_data,
674 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
675 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
676 		.mask = MLXPLAT_CPLD_FAN_MASK,
677 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data),
678 		.inversed = 1,
679 		.health = false,
680 	},
681 	{
682 		.data = mlxplat_mlxcpld_default_asic_items_data,
683 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
684 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
685 		.mask = MLXPLAT_CPLD_ASIC_MASK,
686 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
687 		.inversed = 0,
688 		.health = true,
689 	},
690 };
691 
692 static
693 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = {
694 	.items = mlxplat_mlxcpld_msn274x_items,
695 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
696 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
697 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
698 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
699 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
700 };
701 
702 /* Platform hotplug MSN201x system family data */
703 static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data[] = {
704 	{
705 		.label = "pwr1",
706 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
707 		.mask = BIT(0),
708 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
709 	},
710 	{
711 		.label = "pwr2",
712 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
713 		.mask = BIT(1),
714 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
715 	},
716 };
717 
718 static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
719 	{
720 		.data = mlxplat_mlxcpld_msn201x_pwr_items_data,
721 		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
722 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
723 		.mask = MLXPLAT_CPLD_PWR_MASK,
724 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_pwr_items_data),
725 		.inversed = 0,
726 		.health = false,
727 	},
728 	{
729 		.data = mlxplat_mlxcpld_default_asic_items_data,
730 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
731 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
732 		.mask = MLXPLAT_CPLD_ASIC_MASK,
733 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
734 		.inversed = 0,
735 		.health = true,
736 	},
737 };
738 
739 static
740 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
741 	.items = mlxplat_mlxcpld_msn201x_items,
742 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
743 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
744 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
745 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
746 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
747 };
748 
749 /* Platform hotplug next generation system family data */
750 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data[] = {
751 	{
752 		.label = "psu1",
753 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
754 		.mask = BIT(0),
755 		.hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[0],
756 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
757 	},
758 	{
759 		.label = "psu2",
760 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
761 		.mask = BIT(1),
762 		.hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[1],
763 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
764 	},
765 };
766 
767 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = {
768 	{
769 		.label = "fan1",
770 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
771 		.mask = BIT(0),
772 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
773 		.bit = BIT(0),
774 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
775 	},
776 	{
777 		.label = "fan2",
778 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
779 		.mask = BIT(1),
780 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
781 		.bit = BIT(1),
782 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
783 	},
784 	{
785 		.label = "fan3",
786 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
787 		.mask = BIT(2),
788 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
789 		.bit = BIT(2),
790 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
791 	},
792 	{
793 		.label = "fan4",
794 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
795 		.mask = BIT(3),
796 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
797 		.bit = BIT(3),
798 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
799 	},
800 	{
801 		.label = "fan5",
802 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
803 		.mask = BIT(4),
804 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
805 		.bit = BIT(4),
806 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
807 	},
808 	{
809 		.label = "fan6",
810 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
811 		.mask = BIT(5),
812 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
813 		.bit = BIT(5),
814 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
815 	},
816 };
817 
818 static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = {
819 	{
820 		.data = mlxplat_mlxcpld_default_ng_psu_items_data,
821 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
822 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
823 		.mask = MLXPLAT_CPLD_PSU_MASK,
824 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data),
825 		.inversed = 1,
826 		.health = false,
827 	},
828 	{
829 		.data = mlxplat_mlxcpld_default_ng_pwr_items_data,
830 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
831 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
832 		.mask = MLXPLAT_CPLD_PWR_MASK,
833 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
834 		.inversed = 0,
835 		.health = false,
836 	},
837 	{
838 		.data = mlxplat_mlxcpld_default_ng_fan_items_data,
839 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
840 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
841 		.mask = MLXPLAT_CPLD_FAN_NG_MASK,
842 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
843 		.inversed = 1,
844 		.health = false,
845 	},
846 	{
847 		.data = mlxplat_mlxcpld_default_asic_items_data,
848 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
849 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
850 		.mask = MLXPLAT_CPLD_ASIC_MASK,
851 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
852 		.inversed = 0,
853 		.health = true,
854 	},
855 };
856 
857 static
858 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
859 	.items = mlxplat_mlxcpld_default_ng_items,
860 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
861 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
862 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
863 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
864 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
865 };
866 
867 /* Platform hotplug extended system family data */
868 static struct mlxreg_core_data mlxplat_mlxcpld_ext_psu_items_data[] = {
869 	{
870 		.label = "psu1",
871 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
872 		.mask = BIT(0),
873 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
874 	},
875 	{
876 		.label = "psu2",
877 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
878 		.mask = BIT(1),
879 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
880 	},
881 	{
882 		.label = "psu3",
883 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
884 		.mask = BIT(2),
885 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
886 	},
887 	{
888 		.label = "psu4",
889 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
890 		.mask = BIT(3),
891 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
892 	},
893 };
894 
895 static struct mlxreg_core_data mlxplat_mlxcpld_ext_pwr_items_data[] = {
896 	{
897 		.label = "pwr1",
898 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
899 		.mask = BIT(0),
900 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
901 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
902 	},
903 	{
904 		.label = "pwr2",
905 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
906 		.mask = BIT(1),
907 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
908 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
909 	},
910 	{
911 		.label = "pwr3",
912 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
913 		.mask = BIT(2),
914 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
915 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR2,
916 	},
917 	{
918 		.label = "pwr4",
919 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
920 		.mask = BIT(3),
921 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
922 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR2,
923 	},
924 };
925 
926 static struct mlxreg_core_item mlxplat_mlxcpld_ext_items[] = {
927 	{
928 		.data = mlxplat_mlxcpld_ext_psu_items_data,
929 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
930 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
931 		.mask = MLXPLAT_CPLD_PSU_EXT_MASK,
932 		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
933 		.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
934 		.inversed = 1,
935 		.health = false,
936 	},
937 	{
938 		.data = mlxplat_mlxcpld_ext_pwr_items_data,
939 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
940 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
941 		.mask = MLXPLAT_CPLD_PWR_EXT_MASK,
942 		.capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
943 		.count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
944 		.inversed = 0,
945 		.health = false,
946 	},
947 	{
948 		.data = mlxplat_mlxcpld_default_ng_fan_items_data,
949 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
950 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
951 		.mask = MLXPLAT_CPLD_FAN_NG_MASK,
952 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
953 		.inversed = 1,
954 		.health = false,
955 	},
956 	{
957 		.data = mlxplat_mlxcpld_default_asic_items_data,
958 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
959 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
960 		.mask = MLXPLAT_CPLD_ASIC_MASK,
961 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
962 		.inversed = 0,
963 		.health = true,
964 	},
965 };
966 
967 static
968 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = {
969 	.items = mlxplat_mlxcpld_ext_items,
970 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_ext_items),
971 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
972 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
973 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
974 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
975 };
976 
977 /* Platform led default data */
978 static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
979 	{
980 		.label = "status:green",
981 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
982 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
983 	},
984 	{
985 		.label = "status:red",
986 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
987 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
988 	},
989 	{
990 		.label = "psu:green",
991 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
992 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
993 	},
994 	{
995 		.label = "psu:red",
996 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
997 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
998 	},
999 	{
1000 		.label = "fan1:green",
1001 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1002 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1003 	},
1004 	{
1005 		.label = "fan1:red",
1006 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1007 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1008 	},
1009 	{
1010 		.label = "fan2:green",
1011 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1012 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1013 	},
1014 	{
1015 		.label = "fan2:red",
1016 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1017 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1018 	},
1019 	{
1020 		.label = "fan3:green",
1021 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1022 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1023 	},
1024 	{
1025 		.label = "fan3:red",
1026 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1027 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1028 	},
1029 	{
1030 		.label = "fan4:green",
1031 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1032 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1033 	},
1034 	{
1035 		.label = "fan4:red",
1036 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1037 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1038 	},
1039 };
1040 
1041 static struct mlxreg_core_platform_data mlxplat_default_led_data = {
1042 		.data = mlxplat_mlxcpld_default_led_data,
1043 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
1044 };
1045 
1046 /* Platform led MSN21xx system family data */
1047 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {
1048 	{
1049 		.label = "status:green",
1050 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1051 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1052 	},
1053 	{
1054 		.label = "status:red",
1055 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1056 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
1057 	},
1058 	{
1059 		.label = "fan:green",
1060 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1061 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1062 	},
1063 	{
1064 		.label = "fan:red",
1065 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1066 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1067 	},
1068 	{
1069 		.label = "psu1:green",
1070 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1071 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1072 	},
1073 	{
1074 		.label = "psu1:red",
1075 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1076 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1077 	},
1078 	{
1079 		.label = "psu2:green",
1080 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1081 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1082 	},
1083 	{
1084 		.label = "psu2:red",
1085 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1086 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1087 	},
1088 	{
1089 		.label = "uid:blue",
1090 		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
1091 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1092 	},
1093 };
1094 
1095 static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = {
1096 		.data = mlxplat_mlxcpld_msn21xx_led_data,
1097 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data),
1098 };
1099 
1100 /* Platform led for default data for 200GbE systems */
1101 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
1102 	{
1103 		.label = "status:green",
1104 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1105 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1106 	},
1107 	{
1108 		.label = "status:orange",
1109 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1110 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
1111 	},
1112 	{
1113 		.label = "psu:green",
1114 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1115 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1116 	},
1117 	{
1118 		.label = "psu:orange",
1119 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1120 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1121 	},
1122 	{
1123 		.label = "fan1:green",
1124 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1125 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1126 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1127 		.bit = BIT(0),
1128 	},
1129 	{
1130 		.label = "fan1:orange",
1131 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1132 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1133 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1134 		.bit = BIT(0),
1135 	},
1136 	{
1137 		.label = "fan2:green",
1138 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1139 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1140 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1141 		.bit = BIT(1),
1142 	},
1143 	{
1144 		.label = "fan2:orange",
1145 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1146 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1147 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1148 		.bit = BIT(1),
1149 	},
1150 	{
1151 		.label = "fan3:green",
1152 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1153 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1154 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1155 		.bit = BIT(2),
1156 	},
1157 	{
1158 		.label = "fan3:orange",
1159 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1160 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1161 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1162 		.bit = BIT(2),
1163 	},
1164 	{
1165 		.label = "fan4:green",
1166 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1167 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1168 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1169 		.bit = BIT(3),
1170 	},
1171 	{
1172 		.label = "fan4:orange",
1173 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1174 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1175 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1176 		.bit = BIT(3),
1177 	},
1178 	{
1179 		.label = "fan5:green",
1180 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1181 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1182 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1183 		.bit = BIT(4),
1184 	},
1185 	{
1186 		.label = "fan5:orange",
1187 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1188 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1189 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1190 		.bit = BIT(4),
1191 	},
1192 	{
1193 		.label = "fan6:green",
1194 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1195 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1196 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1197 		.bit = BIT(5),
1198 	},
1199 	{
1200 		.label = "fan6:orange",
1201 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
1202 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1203 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
1204 		.bit = BIT(5),
1205 	},
1206 	{
1207 		.label = "uid:blue",
1208 		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
1209 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1210 	},
1211 };
1212 
1213 static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
1214 		.data = mlxplat_mlxcpld_default_ng_led_data,
1215 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
1216 };
1217 
1218 /* Platform led for Comex based 100GbE systems */
1219 static struct mlxreg_core_data mlxplat_mlxcpld_comex_100G_led_data[] = {
1220 	{
1221 		.label = "status:green",
1222 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1223 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1224 	},
1225 	{
1226 		.label = "status:red",
1227 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1228 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
1229 	},
1230 	{
1231 		.label = "psu:green",
1232 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1233 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1234 	},
1235 	{
1236 		.label = "psu:red",
1237 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
1238 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1239 	},
1240 	{
1241 		.label = "fan1:green",
1242 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1243 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1244 	},
1245 	{
1246 		.label = "fan1:red",
1247 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1248 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1249 	},
1250 	{
1251 		.label = "fan2:green",
1252 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1253 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1254 	},
1255 	{
1256 		.label = "fan2:red",
1257 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
1258 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1259 	},
1260 	{
1261 		.label = "fan3:green",
1262 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1263 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1264 	},
1265 	{
1266 		.label = "fan3:red",
1267 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1268 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1269 	},
1270 	{
1271 		.label = "fan4:green",
1272 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1273 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1274 	},
1275 	{
1276 		.label = "fan4:red",
1277 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
1278 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
1279 	},
1280 	{
1281 		.label = "uid:blue",
1282 		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
1283 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
1284 	},
1285 };
1286 
1287 static struct mlxreg_core_platform_data mlxplat_comex_100G_led_data = {
1288 		.data = mlxplat_mlxcpld_comex_100G_led_data,
1289 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_comex_100G_led_data),
1290 };
1291 
1292 /* Platform register access default */
1293 static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
1294 	{
1295 		.label = "cpld1_version",
1296 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
1297 		.bit = GENMASK(7, 0),
1298 		.mode = 0444,
1299 	},
1300 	{
1301 		.label = "cpld2_version",
1302 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1303 		.bit = GENMASK(7, 0),
1304 		.mode = 0444,
1305 	},
1306 	{
1307 		.label = "reset_long_pb",
1308 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1309 		.mask = GENMASK(7, 0) & ~BIT(0),
1310 		.mode = 0444,
1311 	},
1312 	{
1313 		.label = "reset_short_pb",
1314 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1315 		.mask = GENMASK(7, 0) & ~BIT(1),
1316 		.mode = 0444,
1317 	},
1318 	{
1319 		.label = "reset_aux_pwr_or_ref",
1320 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1321 		.mask = GENMASK(7, 0) & ~BIT(2),
1322 		.mode = 0444,
1323 	},
1324 	{
1325 		.label = "reset_main_pwr_fail",
1326 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1327 		.mask = GENMASK(7, 0) & ~BIT(3),
1328 		.mode = 0444,
1329 	},
1330 	{
1331 		.label = "reset_sw_reset",
1332 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1333 		.mask = GENMASK(7, 0) & ~BIT(4),
1334 		.mode = 0444,
1335 	},
1336 	{
1337 		.label = "reset_fw_reset",
1338 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1339 		.mask = GENMASK(7, 0) & ~BIT(5),
1340 		.mode = 0444,
1341 	},
1342 	{
1343 		.label = "reset_hotswap_or_wd",
1344 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1345 		.mask = GENMASK(7, 0) & ~BIT(6),
1346 		.mode = 0444,
1347 	},
1348 	{
1349 		.label = "reset_asic_thermal",
1350 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1351 		.mask = GENMASK(7, 0) & ~BIT(7),
1352 		.mode = 0444,
1353 	},
1354 	{
1355 		.label = "psu1_on",
1356 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1357 		.mask = GENMASK(7, 0) & ~BIT(0),
1358 		.mode = 0200,
1359 	},
1360 	{
1361 		.label = "psu2_on",
1362 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1363 		.mask = GENMASK(7, 0) & ~BIT(1),
1364 		.mode = 0200,
1365 	},
1366 	{
1367 		.label = "pwr_cycle",
1368 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1369 		.mask = GENMASK(7, 0) & ~BIT(2),
1370 		.mode = 0200,
1371 	},
1372 	{
1373 		.label = "pwr_down",
1374 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1375 		.mask = GENMASK(7, 0) & ~BIT(3),
1376 		.mode = 0200,
1377 	},
1378 	{
1379 		.label = "select_iio",
1380 		.reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1381 		.mask = GENMASK(7, 0) & ~BIT(6),
1382 		.mode = 0644,
1383 	},
1384 	{
1385 		.label = "asic_health",
1386 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1387 		.mask = MLXPLAT_CPLD_ASIC_MASK,
1388 		.bit = 1,
1389 		.mode = 0444,
1390 	},
1391 };
1392 
1393 static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = {
1394 		.data = mlxplat_mlxcpld_default_regs_io_data,
1395 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
1396 };
1397 
1398 /* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
1399 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = {
1400 	{
1401 		.label = "cpld1_version",
1402 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
1403 		.bit = GENMASK(7, 0),
1404 		.mode = 0444,
1405 	},
1406 	{
1407 		.label = "cpld2_version",
1408 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1409 		.bit = GENMASK(7, 0),
1410 		.mode = 0444,
1411 	},
1412 	{
1413 		.label = "reset_long_pb",
1414 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1415 		.mask = GENMASK(7, 0) & ~BIT(0),
1416 		.mode = 0444,
1417 	},
1418 	{
1419 		.label = "reset_short_pb",
1420 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1421 		.mask = GENMASK(7, 0) & ~BIT(1),
1422 		.mode = 0444,
1423 	},
1424 	{
1425 		.label = "reset_aux_pwr_or_ref",
1426 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1427 		.mask = GENMASK(7, 0) & ~BIT(2),
1428 		.mode = 0444,
1429 	},
1430 	{
1431 		.label = "reset_sw_reset",
1432 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1433 		.mask = GENMASK(7, 0) & ~BIT(3),
1434 		.mode = 0444,
1435 	},
1436 	{
1437 		.label = "reset_main_pwr_fail",
1438 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1439 		.mask = GENMASK(7, 0) & ~BIT(4),
1440 		.mode = 0444,
1441 	},
1442 	{
1443 		.label = "reset_asic_thermal",
1444 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1445 		.mask = GENMASK(7, 0) & ~BIT(5),
1446 		.mode = 0444,
1447 	},
1448 	{
1449 		.label = "reset_hotswap_or_halt",
1450 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1451 		.mask = GENMASK(7, 0) & ~BIT(6),
1452 		.mode = 0444,
1453 	},
1454 	{
1455 		.label = "reset_sff_wd",
1456 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1457 		.mask = GENMASK(7, 0) & ~BIT(6),
1458 		.mode = 0444,
1459 	},
1460 	{
1461 		.label = "psu1_on",
1462 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1463 		.mask = GENMASK(7, 0) & ~BIT(0),
1464 		.mode = 0200,
1465 	},
1466 	{
1467 		.label = "psu2_on",
1468 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1469 		.mask = GENMASK(7, 0) & ~BIT(1),
1470 		.mode = 0200,
1471 	},
1472 	{
1473 		.label = "pwr_cycle",
1474 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1475 		.mask = GENMASK(7, 0) & ~BIT(2),
1476 		.mode = 0200,
1477 	},
1478 	{
1479 		.label = "pwr_down",
1480 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1481 		.mask = GENMASK(7, 0) & ~BIT(3),
1482 		.mode = 0200,
1483 	},
1484 	{
1485 		.label = "select_iio",
1486 		.reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1487 		.mask = GENMASK(7, 0) & ~BIT(6),
1488 		.mode = 0644,
1489 	},
1490 	{
1491 		.label = "asic_health",
1492 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1493 		.mask = MLXPLAT_CPLD_ASIC_MASK,
1494 		.bit = 1,
1495 		.mode = 0444,
1496 	},
1497 };
1498 
1499 static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data = {
1500 		.data = mlxplat_mlxcpld_msn21xx_regs_io_data,
1501 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data),
1502 };
1503 
1504 /* Platform register access for next generation systems families data */
1505 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
1506 	{
1507 		.label = "cpld1_version",
1508 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
1509 		.bit = GENMASK(7, 0),
1510 		.mode = 0444,
1511 	},
1512 	{
1513 		.label = "cpld2_version",
1514 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1515 		.bit = GENMASK(7, 0),
1516 		.mode = 0444,
1517 	},
1518 	{
1519 		.label = "cpld3_version",
1520 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
1521 		.bit = GENMASK(7, 0),
1522 		.mode = 0444,
1523 	},
1524 	{
1525 		.label = "cpld4_version",
1526 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
1527 		.bit = GENMASK(7, 0),
1528 		.mode = 0444,
1529 	},
1530 	{
1531 		.label = "reset_long_pb",
1532 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1533 		.mask = GENMASK(7, 0) & ~BIT(0),
1534 		.mode = 0444,
1535 	},
1536 	{
1537 		.label = "reset_short_pb",
1538 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1539 		.mask = GENMASK(7, 0) & ~BIT(1),
1540 		.mode = 0444,
1541 	},
1542 	{
1543 		.label = "reset_aux_pwr_or_ref",
1544 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1545 		.mask = GENMASK(7, 0) & ~BIT(2),
1546 		.mode = 0444,
1547 	},
1548 	{
1549 		.label = "reset_from_comex",
1550 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1551 		.mask = GENMASK(7, 0) & ~BIT(4),
1552 		.mode = 0444,
1553 	},
1554 	{
1555 		.label = "reset_from_asic",
1556 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1557 		.mask = GENMASK(7, 0) & ~BIT(5),
1558 		.mode = 0444,
1559 	},
1560 	{
1561 		.label = "reset_swb_wd",
1562 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1563 		.mask = GENMASK(7, 0) & ~BIT(6),
1564 		.mode = 0444,
1565 	},
1566 	{
1567 		.label = "reset_asic_thermal",
1568 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1569 		.mask = GENMASK(7, 0) & ~BIT(7),
1570 		.mode = 0444,
1571 	},
1572 	{
1573 		.label = "reset_comex_pwr_fail",
1574 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1575 		.mask = GENMASK(7, 0) & ~BIT(3),
1576 		.mode = 0444,
1577 	},
1578 	{
1579 		.label = "reset_platform",
1580 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1581 		.mask = GENMASK(7, 0) & ~BIT(4),
1582 		.mode = 0444,
1583 	},
1584 	{
1585 		.label = "reset_soc",
1586 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1587 		.mask = GENMASK(7, 0) & ~BIT(5),
1588 		.mode = 0444,
1589 	},
1590 	{
1591 		.label = "reset_comex_wd",
1592 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1593 		.mask = GENMASK(7, 0) & ~BIT(6),
1594 		.mode = 0444,
1595 	},
1596 	{
1597 		.label = "reset_voltmon_upgrade_fail",
1598 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1599 		.mask = GENMASK(7, 0) & ~BIT(0),
1600 		.mode = 0444,
1601 	},
1602 	{
1603 		.label = "reset_system",
1604 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1605 		.mask = GENMASK(7, 0) & ~BIT(1),
1606 		.mode = 0444,
1607 	},
1608 	{
1609 		.label = "reset_sw_pwr_off",
1610 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1611 		.mask = GENMASK(7, 0) & ~BIT(2),
1612 		.mode = 0444,
1613 	},
1614 	{
1615 		.label = "reset_comex_thermal",
1616 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1617 		.mask = GENMASK(7, 0) & ~BIT(3),
1618 		.mode = 0444,
1619 	},
1620 	{
1621 		.label = "reset_reload_bios",
1622 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1623 		.mask = GENMASK(7, 0) & ~BIT(5),
1624 		.mode = 0444,
1625 	},
1626 	{
1627 		.label = "reset_ac_pwr_fail",
1628 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1629 		.mask = GENMASK(7, 0) & ~BIT(6),
1630 		.mode = 0444,
1631 	},
1632 	{
1633 		.label = "psu1_on",
1634 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1635 		.mask = GENMASK(7, 0) & ~BIT(0),
1636 		.mode = 0200,
1637 	},
1638 	{
1639 		.label = "psu2_on",
1640 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1641 		.mask = GENMASK(7, 0) & ~BIT(1),
1642 		.mode = 0200,
1643 	},
1644 	{
1645 		.label = "pwr_cycle",
1646 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1647 		.mask = GENMASK(7, 0) & ~BIT(2),
1648 		.mode = 0200,
1649 	},
1650 	{
1651 		.label = "pwr_down",
1652 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1653 		.mask = GENMASK(7, 0) & ~BIT(3),
1654 		.mode = 0200,
1655 	},
1656 	{
1657 		.label = "jtag_enable",
1658 		.reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1659 		.mask = GENMASK(7, 0) & ~BIT(4),
1660 		.mode = 0644,
1661 	},
1662 	{
1663 		.label = "asic_health",
1664 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1665 		.mask = MLXPLAT_CPLD_ASIC_MASK,
1666 		.bit = 1,
1667 		.mode = 0444,
1668 	},
1669 	{
1670 		.label = "fan_dir",
1671 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
1672 		.bit = GENMASK(7, 0),
1673 		.mode = 0444,
1674 	},
1675 	{
1676 		.label = "voltreg_update_status",
1677 		.reg = MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET,
1678 		.mask = MLXPLAT_CPLD_VOLTREG_UPD_MASK,
1679 		.bit = 5,
1680 		.mode = 0444,
1681 	},
1682 	{
1683 		.label = "vpd_wp",
1684 		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
1685 		.mask = GENMASK(7, 0) & ~BIT(3),
1686 		.mode = 0644,
1687 	},
1688 	{
1689 		.label = "pcie_asic_reset_dis",
1690 		.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
1691 		.mask = GENMASK(7, 0) & ~BIT(4),
1692 		.mode = 0644,
1693 	},
1694 	{
1695 		.label = "config1",
1696 		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
1697 		.bit = GENMASK(7, 0),
1698 		.mode = 0444,
1699 	},
1700 	{
1701 		.label = "config2",
1702 		.reg = MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET,
1703 		.bit = GENMASK(7, 0),
1704 		.mode = 0444,
1705 	},
1706 	{
1707 		.label = "ufm_version",
1708 		.reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
1709 		.bit = GENMASK(7, 0),
1710 		.mode = 0444,
1711 	},
1712 };
1713 
1714 static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = {
1715 		.data = mlxplat_mlxcpld_default_ng_regs_io_data,
1716 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_regs_io_data),
1717 };
1718 
1719 /* Platform FAN default */
1720 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
1721 	{
1722 		.label = "pwm1",
1723 		.reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
1724 	},
1725 	{
1726 		.label = "tacho1",
1727 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
1728 		.mask = GENMASK(7, 0),
1729 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1730 		.bit = BIT(0),
1731 	},
1732 	{
1733 		.label = "tacho2",
1734 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
1735 		.mask = GENMASK(7, 0),
1736 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1737 		.bit = BIT(1),
1738 	},
1739 	{
1740 		.label = "tacho3",
1741 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
1742 		.mask = GENMASK(7, 0),
1743 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1744 		.bit = BIT(2),
1745 	},
1746 	{
1747 		.label = "tacho4",
1748 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
1749 		.mask = GENMASK(7, 0),
1750 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1751 		.bit = BIT(3),
1752 	},
1753 	{
1754 		.label = "tacho5",
1755 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
1756 		.mask = GENMASK(7, 0),
1757 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1758 		.bit = BIT(4),
1759 	},
1760 	{
1761 		.label = "tacho6",
1762 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
1763 		.mask = GENMASK(7, 0),
1764 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1765 		.bit = BIT(5),
1766 	},
1767 	{
1768 		.label = "tacho7",
1769 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
1770 		.mask = GENMASK(7, 0),
1771 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1772 		.bit = BIT(6),
1773 	},
1774 	{
1775 		.label = "tacho8",
1776 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
1777 		.mask = GENMASK(7, 0),
1778 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1779 		.bit = BIT(7),
1780 	},
1781 	{
1782 		.label = "tacho9",
1783 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
1784 		.mask = GENMASK(7, 0),
1785 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1786 		.bit = BIT(0),
1787 	},
1788 	{
1789 		.label = "tacho10",
1790 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
1791 		.mask = GENMASK(7, 0),
1792 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1793 		.bit = BIT(1),
1794 	},
1795 	{
1796 		.label = "tacho11",
1797 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
1798 		.mask = GENMASK(7, 0),
1799 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1800 		.bit = BIT(2),
1801 	},
1802 	{
1803 		.label = "tacho12",
1804 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
1805 		.mask = GENMASK(7, 0),
1806 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1807 		.bit = BIT(3),
1808 	},
1809 	{
1810 		.label = "conf",
1811 		.capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET,
1812 	},
1813 };
1814 
1815 static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
1816 		.data = mlxplat_mlxcpld_default_fan_data,
1817 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
1818 };
1819 
1820 /* Watchdog type1: hardware implementation version1
1821  * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
1822  */
1823 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1[] = {
1824 	{
1825 		.label = "action",
1826 		.reg = MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET,
1827 		.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1828 		.bit = 0,
1829 	},
1830 	{
1831 		.label = "timeout",
1832 		.reg = MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET,
1833 		.mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
1834 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1835 	},
1836 	{
1837 		.label = "ping",
1838 		.reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
1839 		.mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
1840 		.bit = 0,
1841 	},
1842 	{
1843 		.label = "reset",
1844 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1845 		.mask = GENMASK(7, 0) & ~BIT(6),
1846 		.bit = 6,
1847 	},
1848 };
1849 
1850 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1[] = {
1851 	{
1852 		.label = "action",
1853 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1854 		.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1855 		.bit = 4,
1856 	},
1857 	{
1858 		.label = "timeout",
1859 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
1860 		.mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
1861 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1862 	},
1863 	{
1864 		.label = "ping",
1865 		.reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
1866 		.mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
1867 		.bit = 1,
1868 	},
1869 };
1870 
1871 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type1[] = {
1872 	{
1873 		.data = mlxplat_mlxcpld_wd_main_regs_type1,
1874 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1),
1875 		.version = MLX_WDT_TYPE1,
1876 		.identity = "mlx-wdt-main",
1877 	},
1878 	{
1879 		.data = mlxplat_mlxcpld_wd_aux_regs_type1,
1880 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1),
1881 		.version = MLX_WDT_TYPE1,
1882 		.identity = "mlx-wdt-aux",
1883 	},
1884 };
1885 
1886 /* Watchdog type2: hardware implementation version 2
1887  * (all systems except (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140).
1888  */
1889 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2[] = {
1890 	{
1891 		.label = "action",
1892 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1893 		.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1894 		.bit = 0,
1895 	},
1896 	{
1897 		.label = "timeout",
1898 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
1899 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1900 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1901 	},
1902 	{
1903 		.label = "timeleft",
1904 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET,
1905 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1906 	},
1907 	{
1908 		.label = "ping",
1909 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1910 		.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1911 		.bit = 0,
1912 	},
1913 	{
1914 		.label = "reset",
1915 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1916 		.mask = GENMASK(7, 0) & ~BIT(6),
1917 		.bit = 6,
1918 	},
1919 };
1920 
1921 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2[] = {
1922 	{
1923 		.label = "action",
1924 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
1925 		.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1926 		.bit = 4,
1927 	},
1928 	{
1929 		.label = "timeout",
1930 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
1931 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1932 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1933 	},
1934 	{
1935 		.label = "timeleft",
1936 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET,
1937 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1938 	},
1939 	{
1940 		.label = "ping",
1941 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
1942 		.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1943 		.bit = 4,
1944 	},
1945 };
1946 
1947 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type2[] = {
1948 	{
1949 		.data = mlxplat_mlxcpld_wd_main_regs_type2,
1950 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2),
1951 		.version = MLX_WDT_TYPE2,
1952 		.identity = "mlx-wdt-main",
1953 	},
1954 	{
1955 		.data = mlxplat_mlxcpld_wd_aux_regs_type2,
1956 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2),
1957 		.version = MLX_WDT_TYPE2,
1958 		.identity = "mlx-wdt-aux",
1959 	},
1960 };
1961 
1962 static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
1963 {
1964 	switch (reg) {
1965 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1966 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1967 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1968 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1969 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1970 	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
1971 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1972 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
1973 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1974 	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
1975 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1976 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1977 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
1978 	case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
1979 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1980 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1981 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1982 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1983 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1984 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1985 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1986 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1987 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
1988 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
1989 	case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
1990 	case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
1991 	case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1992 	case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
1993 	case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1994 	case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
1995 	case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1996 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1997 		return true;
1998 	}
1999 	return false;
2000 }
2001 
2002 static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
2003 {
2004 	switch (reg) {
2005 	case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
2006 	case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
2007 	case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
2008 	case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
2009 	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
2010 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
2011 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
2012 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
2013 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
2014 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
2015 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
2016 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
2017 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
2018 	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
2019 	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
2020 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
2021 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
2022 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
2023 	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
2024 	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
2025 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
2026 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
2027 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
2028 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET:
2029 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
2030 	case MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET:
2031 	case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
2032 	case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
2033 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
2034 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
2035 	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
2036 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
2037 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
2038 	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
2039 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
2040 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
2041 	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
2042 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
2043 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
2044 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
2045 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
2046 	case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
2047 	case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
2048 	case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
2049 	case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
2050 	case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
2051 	case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
2052 	case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
2053 	case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
2054 	case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
2055 	case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
2056 	case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
2057 	case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
2058 	case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
2059 	case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
2060 	case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
2061 	case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
2062 	case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
2063 	case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
2064 	case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
2065 	case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
2066 	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
2067 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
2068 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
2069 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
2070 	case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
2071 	case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
2072 	case MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET:
2073 	case MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET:
2074 	case MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET:
2075 	case MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET:
2076 		return true;
2077 	}
2078 	return false;
2079 }
2080 
2081 static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
2082 {
2083 	switch (reg) {
2084 	case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
2085 	case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
2086 	case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
2087 	case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
2088 	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
2089 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
2090 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
2091 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
2092 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
2093 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
2094 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
2095 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
2096 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
2097 	case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
2098 	case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
2099 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
2100 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
2101 	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
2102 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
2103 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
2104 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
2105 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET:
2106 	case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
2107 	case MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET:
2108 	case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
2109 	case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
2110 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
2111 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
2112 	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
2113 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
2114 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
2115 	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
2116 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
2117 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
2118 	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
2119 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
2120 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
2121 	case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
2122 	case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
2123 	case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
2124 	case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
2125 	case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
2126 	case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
2127 	case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
2128 	case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
2129 	case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
2130 	case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
2131 	case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
2132 	case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
2133 	case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
2134 	case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
2135 	case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
2136 	case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
2137 	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
2138 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
2139 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
2140 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
2141 	case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
2142 	case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
2143 	case MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET:
2144 	case MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET:
2145 	case MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET:
2146 	case MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET:
2147 		return true;
2148 	}
2149 	return false;
2150 }
2151 
2152 static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
2153 	{ MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
2154 	{ MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
2155 	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
2156 	{ MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 },
2157 };
2158 
2159 static const struct reg_default mlxplat_mlxcpld_regmap_ng[] = {
2160 	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
2161 	{ MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 },
2162 };
2163 
2164 static const struct reg_default mlxplat_mlxcpld_regmap_comex_default[] = {
2165 	{ MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET,
2166 	  MLXPLAT_CPLD_LOW_AGGRCX_MASK },
2167 	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
2168 };
2169 
2170 static const struct reg_default mlxplat_mlxcpld_regmap_ng400[] = {
2171 	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
2172 	{ MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
2173 	{ MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
2174 	{ MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
2175 };
2176 
2177 struct mlxplat_mlxcpld_regmap_context {
2178 	void __iomem *base;
2179 };
2180 
2181 static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
2182 
2183 static int
2184 mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
2185 {
2186 	struct mlxplat_mlxcpld_regmap_context *ctx = context;
2187 
2188 	*val = ioread8(ctx->base + reg);
2189 	return 0;
2190 }
2191 
2192 static int
2193 mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
2194 {
2195 	struct mlxplat_mlxcpld_regmap_context *ctx = context;
2196 
2197 	iowrite8(val, ctx->base + reg);
2198 	return 0;
2199 }
2200 
2201 static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
2202 	.reg_bits = 8,
2203 	.val_bits = 8,
2204 	.max_register = 255,
2205 	.cache_type = REGCACHE_FLAT,
2206 	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
2207 	.readable_reg = mlxplat_mlxcpld_readable_reg,
2208 	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
2209 	.reg_defaults = mlxplat_mlxcpld_regmap_default,
2210 	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default),
2211 	.reg_read = mlxplat_mlxcpld_reg_read,
2212 	.reg_write = mlxplat_mlxcpld_reg_write,
2213 };
2214 
2215 static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng = {
2216 	.reg_bits = 8,
2217 	.val_bits = 8,
2218 	.max_register = 255,
2219 	.cache_type = REGCACHE_FLAT,
2220 	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
2221 	.readable_reg = mlxplat_mlxcpld_readable_reg,
2222 	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
2223 	.reg_defaults = mlxplat_mlxcpld_regmap_ng,
2224 	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng),
2225 	.reg_read = mlxplat_mlxcpld_reg_read,
2226 	.reg_write = mlxplat_mlxcpld_reg_write,
2227 };
2228 
2229 static const struct regmap_config mlxplat_mlxcpld_regmap_config_comex = {
2230 	.reg_bits = 8,
2231 	.val_bits = 8,
2232 	.max_register = 255,
2233 	.cache_type = REGCACHE_FLAT,
2234 	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
2235 	.readable_reg = mlxplat_mlxcpld_readable_reg,
2236 	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
2237 	.reg_defaults = mlxplat_mlxcpld_regmap_comex_default,
2238 	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_comex_default),
2239 	.reg_read = mlxplat_mlxcpld_reg_read,
2240 	.reg_write = mlxplat_mlxcpld_reg_write,
2241 };
2242 
2243 static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng400 = {
2244 	.reg_bits = 8,
2245 	.val_bits = 8,
2246 	.max_register = 255,
2247 	.cache_type = REGCACHE_FLAT,
2248 	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
2249 	.readable_reg = mlxplat_mlxcpld_readable_reg,
2250 	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
2251 	.reg_defaults = mlxplat_mlxcpld_regmap_ng400,
2252 	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng400),
2253 	.reg_read = mlxplat_mlxcpld_reg_read,
2254 	.reg_write = mlxplat_mlxcpld_reg_write,
2255 };
2256 
2257 static struct resource mlxplat_mlxcpld_resources[] = {
2258 	[0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
2259 };
2260 
2261 static struct platform_device *mlxplat_dev;
2262 static struct mlxreg_core_hotplug_platform_data *mlxplat_i2c;
2263 static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
2264 static struct mlxreg_core_platform_data *mlxplat_led;
2265 static struct mlxreg_core_platform_data *mlxplat_regs_io;
2266 static struct mlxreg_core_platform_data *mlxplat_fan;
2267 static struct mlxreg_core_platform_data
2268 	*mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS];
2269 static const struct regmap_config *mlxplat_regmap_config;
2270 
2271 static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
2272 {
2273 	int i;
2274 
2275 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
2276 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
2277 	mlxplat_mux_data = mlxplat_default_mux_data;
2278 	for (i = 0; i < mlxplat_mux_num; i++) {
2279 		mlxplat_mux_data[i].values = mlxplat_default_channels[i];
2280 		mlxplat_mux_data[i].n_values =
2281 				ARRAY_SIZE(mlxplat_default_channels[i]);
2282 	}
2283 	mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
2284 	mlxplat_hotplug->deferred_nr =
2285 		mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
2286 	mlxplat_led = &mlxplat_default_led_data;
2287 	mlxplat_regs_io = &mlxplat_default_regs_io_data;
2288 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
2289 
2290 	return 1;
2291 }
2292 
2293 static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
2294 {
2295 	int i;
2296 
2297 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
2298 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
2299 	mlxplat_mux_data = mlxplat_default_mux_data;
2300 	for (i = 0; i < mlxplat_mux_num; i++) {
2301 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
2302 		mlxplat_mux_data[i].n_values =
2303 				ARRAY_SIZE(mlxplat_msn21xx_channels);
2304 	}
2305 	mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
2306 	mlxplat_hotplug->deferred_nr =
2307 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
2308 	mlxplat_led = &mlxplat_msn21xx_led_data;
2309 	mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
2310 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
2311 
2312 	return 1;
2313 }
2314 
2315 static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
2316 {
2317 	int i;
2318 
2319 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
2320 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
2321 	mlxplat_mux_data = mlxplat_default_mux_data;
2322 	for (i = 0; i < mlxplat_mux_num; i++) {
2323 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
2324 		mlxplat_mux_data[i].n_values =
2325 				ARRAY_SIZE(mlxplat_msn21xx_channels);
2326 	}
2327 	mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
2328 	mlxplat_hotplug->deferred_nr =
2329 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
2330 	mlxplat_led = &mlxplat_default_led_data;
2331 	mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
2332 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
2333 
2334 	return 1;
2335 }
2336 
2337 static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
2338 {
2339 	int i;
2340 
2341 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
2342 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
2343 	mlxplat_mux_data = mlxplat_default_mux_data;
2344 	for (i = 0; i < mlxplat_mux_num; i++) {
2345 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
2346 		mlxplat_mux_data[i].n_values =
2347 				ARRAY_SIZE(mlxplat_msn21xx_channels);
2348 	}
2349 	mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
2350 	mlxplat_hotplug->deferred_nr =
2351 		mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
2352 	mlxplat_led = &mlxplat_msn21xx_led_data;
2353 	mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
2354 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
2355 
2356 	return 1;
2357 }
2358 
2359 static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
2360 {
2361 	int i;
2362 
2363 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
2364 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
2365 	mlxplat_mux_data = mlxplat_default_mux_data;
2366 	for (i = 0; i < mlxplat_mux_num; i++) {
2367 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
2368 		mlxplat_mux_data[i].n_values =
2369 				ARRAY_SIZE(mlxplat_msn21xx_channels);
2370 	}
2371 	mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
2372 	mlxplat_hotplug->deferred_nr =
2373 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
2374 	mlxplat_led = &mlxplat_default_ng_led_data;
2375 	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
2376 	mlxplat_fan = &mlxplat_default_fan_data;
2377 	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
2378 		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
2379 	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
2380 	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng;
2381 
2382 	return 1;
2383 }
2384 
2385 static int __init mlxplat_dmi_comex_matched(const struct dmi_system_id *dmi)
2386 {
2387 	int i;
2388 
2389 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM;
2390 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_extended_mux_data);
2391 	mlxplat_mux_data = mlxplat_extended_mux_data;
2392 	for (i = 0; i < mlxplat_mux_num; i++) {
2393 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
2394 		mlxplat_mux_data[i].n_values =
2395 				ARRAY_SIZE(mlxplat_msn21xx_channels);
2396 	}
2397 	mlxplat_hotplug = &mlxplat_mlxcpld_comex_data;
2398 	mlxplat_hotplug->deferred_nr = MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM;
2399 	mlxplat_led = &mlxplat_comex_100G_led_data;
2400 	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
2401 	mlxplat_fan = &mlxplat_default_fan_data;
2402 	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
2403 		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
2404 	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_comex;
2405 
2406 	return 1;
2407 }
2408 
2409 static int __init mlxplat_dmi_ng400_matched(const struct dmi_system_id *dmi)
2410 {
2411 	int i;
2412 
2413 	mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
2414 	mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
2415 	mlxplat_mux_data = mlxplat_default_mux_data;
2416 	for (i = 0; i < mlxplat_mux_num; i++) {
2417 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
2418 		mlxplat_mux_data[i].n_values =
2419 				ARRAY_SIZE(mlxplat_msn21xx_channels);
2420 	}
2421 	mlxplat_hotplug = &mlxplat_mlxcpld_ext_data;
2422 	mlxplat_hotplug->deferred_nr =
2423 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
2424 	mlxplat_led = &mlxplat_default_ng_led_data;
2425 	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
2426 	mlxplat_fan = &mlxplat_default_fan_data;
2427 	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
2428 		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
2429 	mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
2430 	mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
2431 
2432 	return 1;
2433 }
2434 
2435 static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
2436 	{
2437 		.callback = mlxplat_dmi_default_matched,
2438 		.matches = {
2439 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
2440 		},
2441 	},
2442 	{
2443 		.callback = mlxplat_dmi_msn21xx_matched,
2444 		.matches = {
2445 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"),
2446 		},
2447 	},
2448 	{
2449 		.callback = mlxplat_dmi_msn274x_matched,
2450 		.matches = {
2451 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"),
2452 		},
2453 	},
2454 	{
2455 		.callback = mlxplat_dmi_msn201x_matched,
2456 		.matches = {
2457 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"),
2458 		},
2459 	},
2460 	{
2461 		.callback = mlxplat_dmi_qmb7xx_matched,
2462 		.matches = {
2463 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
2464 		},
2465 	},
2466 	{
2467 		.callback = mlxplat_dmi_qmb7xx_matched,
2468 		.matches = {
2469 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0007"),
2470 		},
2471 	},
2472 	{
2473 		.callback = mlxplat_dmi_comex_matched,
2474 		.matches = {
2475 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0009"),
2476 		},
2477 	},
2478 	{
2479 		.callback = mlxplat_dmi_ng400_matched,
2480 		.matches = {
2481 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0010"),
2482 		},
2483 	},
2484 	{
2485 		.callback = mlxplat_dmi_msn274x_matched,
2486 		.matches = {
2487 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2488 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN274"),
2489 		},
2490 	},
2491 	{
2492 		.callback = mlxplat_dmi_default_matched,
2493 		.matches = {
2494 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2495 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"),
2496 		},
2497 	},
2498 	{
2499 		.callback = mlxplat_dmi_default_matched,
2500 		.matches = {
2501 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2502 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"),
2503 		},
2504 	},
2505 	{
2506 		.callback = mlxplat_dmi_default_matched,
2507 		.matches = {
2508 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2509 			DMI_MATCH(DMI_PRODUCT_NAME, "MSB"),
2510 		},
2511 	},
2512 	{
2513 		.callback = mlxplat_dmi_default_matched,
2514 		.matches = {
2515 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2516 			DMI_MATCH(DMI_PRODUCT_NAME, "MSX"),
2517 		},
2518 	},
2519 	{
2520 		.callback = mlxplat_dmi_msn21xx_matched,
2521 		.matches = {
2522 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2523 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"),
2524 		},
2525 	},
2526 	{
2527 		.callback = mlxplat_dmi_msn201x_matched,
2528 		.matches = {
2529 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2530 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN201"),
2531 		},
2532 	},
2533 	{
2534 		.callback = mlxplat_dmi_qmb7xx_matched,
2535 		.matches = {
2536 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2537 			DMI_MATCH(DMI_PRODUCT_NAME, "MQM87"),
2538 		},
2539 	},
2540 	{
2541 		.callback = mlxplat_dmi_qmb7xx_matched,
2542 		.matches = {
2543 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2544 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN37"),
2545 		},
2546 	},
2547 	{
2548 		.callback = mlxplat_dmi_qmb7xx_matched,
2549 		.matches = {
2550 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2551 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"),
2552 		},
2553 	},
2554 	{
2555 		.callback = mlxplat_dmi_qmb7xx_matched,
2556 		.matches = {
2557 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
2558 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"),
2559 		},
2560 	},
2561 	{ }
2562 };
2563 
2564 MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
2565 
2566 static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
2567 {
2568 	struct i2c_adapter *search_adap;
2569 	int shift, i;
2570 
2571 	/* Scan adapters from expected id to verify it is free. */
2572 	*nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
2573 	for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
2574 	     mlxplat_max_adap_num; i++) {
2575 		search_adap = i2c_get_adapter(i);
2576 		if (search_adap) {
2577 			i2c_put_adapter(search_adap);
2578 			continue;
2579 		}
2580 
2581 		/* Return if expected parent adapter is free. */
2582 		if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR)
2583 			return 0;
2584 		break;
2585 	}
2586 
2587 	/* Return with error if free id for adapter is not found. */
2588 	if (i == mlxplat_max_adap_num)
2589 		return -ENODEV;
2590 
2591 	/* Shift adapter ids, since expected parent adapter is not free. */
2592 	*nr = i;
2593 	for (i = 0; i < mlxplat_mux_num; i++) {
2594 		shift = *nr - mlxplat_mux_data[i].parent;
2595 		mlxplat_mux_data[i].parent = *nr;
2596 		mlxplat_mux_data[i].base_nr += shift;
2597 		if (shift > 0)
2598 			mlxplat_hotplug->shift_nr = shift;
2599 	}
2600 
2601 	return 0;
2602 }
2603 
2604 static int __init mlxplat_init(void)
2605 {
2606 	struct mlxplat_priv *priv;
2607 	int i, j, nr, err;
2608 
2609 	if (!dmi_check_system(mlxplat_dmi_table))
2610 		return -ENODEV;
2611 
2612 	mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, -1,
2613 					mlxplat_lpc_resources,
2614 					ARRAY_SIZE(mlxplat_lpc_resources));
2615 
2616 	if (IS_ERR(mlxplat_dev))
2617 		return PTR_ERR(mlxplat_dev);
2618 
2619 	priv = devm_kzalloc(&mlxplat_dev->dev, sizeof(struct mlxplat_priv),
2620 			    GFP_KERNEL);
2621 	if (!priv) {
2622 		err = -ENOMEM;
2623 		goto fail_alloc;
2624 	}
2625 	platform_set_drvdata(mlxplat_dev, priv);
2626 
2627 	mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
2628 			       mlxplat_lpc_resources[1].start, 1);
2629 	if (!mlxplat_mlxcpld_regmap_ctx.base) {
2630 		err = -ENOMEM;
2631 		goto fail_alloc;
2632 	}
2633 
2634 	if (!mlxplat_regmap_config)
2635 		mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config;
2636 
2637 	priv->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
2638 					&mlxplat_mlxcpld_regmap_ctx,
2639 					mlxplat_regmap_config);
2640 	if (IS_ERR(priv->regmap)) {
2641 		err = PTR_ERR(priv->regmap);
2642 		goto fail_alloc;
2643 	}
2644 
2645 	err = mlxplat_mlxcpld_verify_bus_topology(&nr);
2646 	if (nr < 0)
2647 		goto fail_alloc;
2648 
2649 	nr = (nr == mlxplat_max_adap_num) ? -1 : nr;
2650 	if (mlxplat_i2c)
2651 		mlxplat_i2c->regmap = priv->regmap;
2652 	priv->pdev_i2c = platform_device_register_resndata(
2653 					&mlxplat_dev->dev, "i2c_mlxcpld",
2654 					nr, mlxplat_mlxcpld_resources,
2655 					ARRAY_SIZE(mlxplat_mlxcpld_resources),
2656 					mlxplat_i2c, sizeof(*mlxplat_i2c));
2657 	if (IS_ERR(priv->pdev_i2c)) {
2658 		err = PTR_ERR(priv->pdev_i2c);
2659 		goto fail_alloc;
2660 	}
2661 
2662 	for (i = 0; i < mlxplat_mux_num; i++) {
2663 		priv->pdev_mux[i] = platform_device_register_resndata(
2664 						&priv->pdev_i2c->dev,
2665 						"i2c-mux-reg", i, NULL,
2666 						0, &mlxplat_mux_data[i],
2667 						sizeof(mlxplat_mux_data[i]));
2668 		if (IS_ERR(priv->pdev_mux[i])) {
2669 			err = PTR_ERR(priv->pdev_mux[i]);
2670 			goto fail_platform_mux_register;
2671 		}
2672 	}
2673 
2674 	/* Add hotplug driver */
2675 	mlxplat_hotplug->regmap = priv->regmap;
2676 	priv->pdev_hotplug = platform_device_register_resndata(
2677 				&mlxplat_dev->dev, "mlxreg-hotplug",
2678 				PLATFORM_DEVID_NONE,
2679 				mlxplat_mlxcpld_resources,
2680 				ARRAY_SIZE(mlxplat_mlxcpld_resources),
2681 				mlxplat_hotplug, sizeof(*mlxplat_hotplug));
2682 	if (IS_ERR(priv->pdev_hotplug)) {
2683 		err = PTR_ERR(priv->pdev_hotplug);
2684 		goto fail_platform_mux_register;
2685 	}
2686 
2687 	/* Set default registers. */
2688 	for (j = 0; j <  mlxplat_regmap_config->num_reg_defaults; j++) {
2689 		err = regmap_write(priv->regmap,
2690 				   mlxplat_regmap_config->reg_defaults[j].reg,
2691 				   mlxplat_regmap_config->reg_defaults[j].def);
2692 		if (err)
2693 			goto fail_platform_mux_register;
2694 	}
2695 
2696 	/* Add LED driver. */
2697 	mlxplat_led->regmap = priv->regmap;
2698 	priv->pdev_led = platform_device_register_resndata(
2699 				&mlxplat_dev->dev, "leds-mlxreg",
2700 				PLATFORM_DEVID_NONE, NULL, 0,
2701 				mlxplat_led, sizeof(*mlxplat_led));
2702 	if (IS_ERR(priv->pdev_led)) {
2703 		err = PTR_ERR(priv->pdev_led);
2704 		goto fail_platform_hotplug_register;
2705 	}
2706 
2707 	/* Add registers io access driver. */
2708 	if (mlxplat_regs_io) {
2709 		mlxplat_regs_io->regmap = priv->regmap;
2710 		priv->pdev_io_regs = platform_device_register_resndata(
2711 					&mlxplat_dev->dev, "mlxreg-io",
2712 					PLATFORM_DEVID_NONE, NULL, 0,
2713 					mlxplat_regs_io,
2714 					sizeof(*mlxplat_regs_io));
2715 		if (IS_ERR(priv->pdev_io_regs)) {
2716 			err = PTR_ERR(priv->pdev_io_regs);
2717 			goto fail_platform_led_register;
2718 		}
2719 	}
2720 
2721 	/* Add FAN driver. */
2722 	if (mlxplat_fan) {
2723 		mlxplat_fan->regmap = priv->regmap;
2724 		priv->pdev_fan = platform_device_register_resndata(
2725 					&mlxplat_dev->dev, "mlxreg-fan",
2726 					PLATFORM_DEVID_NONE, NULL, 0,
2727 					mlxplat_fan,
2728 					sizeof(*mlxplat_fan));
2729 		if (IS_ERR(priv->pdev_fan)) {
2730 			err = PTR_ERR(priv->pdev_fan);
2731 			goto fail_platform_io_regs_register;
2732 		}
2733 	}
2734 
2735 	/* Add WD drivers. */
2736 	for (j = 0; j < MLXPLAT_CPLD_WD_MAX_DEVS; j++) {
2737 		if (mlxplat_wd_data[j]) {
2738 			mlxplat_wd_data[j]->regmap = priv->regmap;
2739 			priv->pdev_wd[j] = platform_device_register_resndata(
2740 						&mlxplat_dev->dev, "mlx-wdt",
2741 						j, NULL, 0,
2742 						mlxplat_wd_data[j],
2743 						sizeof(*mlxplat_wd_data[j]));
2744 			if (IS_ERR(priv->pdev_wd[j])) {
2745 				err = PTR_ERR(priv->pdev_wd[j]);
2746 				goto fail_platform_wd_register;
2747 			}
2748 		}
2749 	}
2750 
2751 	/* Sync registers with hardware. */
2752 	regcache_mark_dirty(priv->regmap);
2753 	err = regcache_sync(priv->regmap);
2754 	if (err)
2755 		goto fail_platform_wd_register;
2756 
2757 	return 0;
2758 
2759 fail_platform_wd_register:
2760 	while (--j >= 0)
2761 		platform_device_unregister(priv->pdev_wd[j]);
2762 	if (mlxplat_fan)
2763 		platform_device_unregister(priv->pdev_fan);
2764 fail_platform_io_regs_register:
2765 	if (mlxplat_regs_io)
2766 		platform_device_unregister(priv->pdev_io_regs);
2767 fail_platform_led_register:
2768 	platform_device_unregister(priv->pdev_led);
2769 fail_platform_hotplug_register:
2770 	platform_device_unregister(priv->pdev_hotplug);
2771 fail_platform_mux_register:
2772 	while (--i >= 0)
2773 		platform_device_unregister(priv->pdev_mux[i]);
2774 	platform_device_unregister(priv->pdev_i2c);
2775 fail_alloc:
2776 	platform_device_unregister(mlxplat_dev);
2777 
2778 	return err;
2779 }
2780 module_init(mlxplat_init);
2781 
2782 static void __exit mlxplat_exit(void)
2783 {
2784 	struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
2785 	int i;
2786 
2787 	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
2788 		platform_device_unregister(priv->pdev_wd[i]);
2789 	if (priv->pdev_fan)
2790 		platform_device_unregister(priv->pdev_fan);
2791 	if (priv->pdev_io_regs)
2792 		platform_device_unregister(priv->pdev_io_regs);
2793 	platform_device_unregister(priv->pdev_led);
2794 	platform_device_unregister(priv->pdev_hotplug);
2795 
2796 	for (i = mlxplat_mux_num - 1; i >= 0 ; i--)
2797 		platform_device_unregister(priv->pdev_mux[i]);
2798 
2799 	platform_device_unregister(priv->pdev_i2c);
2800 	platform_device_unregister(mlxplat_dev);
2801 }
2802 module_exit(mlxplat_exit);
2803 
2804 MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
2805 MODULE_DESCRIPTION("Mellanox platform driver");
2806 MODULE_LICENSE("Dual BSD/GPL");
2807