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_GP1_OFFSET		0x30
39 #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET		0x31
40 #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET		0x32
41 #define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET		0x33
42 #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET	0x37
43 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET	0x3a
44 #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET	0x3b
45 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET	0x40
46 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET	0x41
47 #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
48 #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET	0x51
49 #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET	0x52
50 #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET		0x58
51 #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET	0x59
52 #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET	0x5a
53 #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET		0x64
54 #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET	0x65
55 #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET	0x66
56 #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET		0x88
57 #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET	0x89
58 #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET	0x8a
59 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET	0xc7
60 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET	0xc8
61 #define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET	0xc9
62 #define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET	0xcb
63 #define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET	0xcd
64 #define MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET	0xce
65 #define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET	0xcf
66 #define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET	0xd1
67 #define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET	0xd2
68 #define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET	0xd3
69 #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET	0xe3
70 #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET	0xe4
71 #define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET	0xe5
72 #define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET	0xe6
73 #define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET	0xe7
74 #define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET	0xe8
75 #define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET	0xe9
76 #define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET	0xeb
77 #define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET	0xec
78 #define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET	0xed
79 #define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET	0xee
80 #define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET	0xef
81 #define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET	0xf0
82 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET	0xf5
83 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET	0xf6
84 #define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET	0xf7
85 #define MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET	0xf8
86 #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
87 #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF		0xdb
88 #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF		0xda
89 
90 #define MLXPLAT_CPLD_LPC_PIO_OFFSET		0x10000UL
91 #define MLXPLAT_CPLD_LPC_REG1	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
92 				  MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
93 				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
94 #define MLXPLAT_CPLD_LPC_REG2	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
95 				  MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \
96 				  MLXPLAT_CPLD_LPC_PIO_OFFSET)
97 
98 /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
99 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF	0x04
100 #define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF	0x08
101 #define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF	0x08
102 #define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF	0x40
103 #define MLXPLAT_CPLD_AGGR_MASK_DEF	(MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
104 					 MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
105 					 MLXPLAT_CPLD_AGGR_FAN_MASK_DEF)
106 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG	0x01
107 #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF	0x04
108 #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW	0xc1
109 #define MLXPLAT_CPLD_PSU_MASK		GENMASK(1, 0)
110 #define MLXPLAT_CPLD_PWR_MASK		GENMASK(1, 0)
111 #define MLXPLAT_CPLD_FAN_MASK		GENMASK(3, 0)
112 #define MLXPLAT_CPLD_ASIC_MASK		GENMASK(1, 0)
113 #define MLXPLAT_CPLD_FAN_NG_MASK	GENMASK(5, 0)
114 #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK	GENMASK(7, 4)
115 #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK	GENMASK(3, 0)
116 
117 /* Default I2C parent bus number */
118 #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR	1
119 
120 /* Maximum number of possible physical buses equipped on system */
121 #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM	16
122 
123 /* Number of channels in group */
124 #define MLXPLAT_CPLD_GRP_CHNL_NUM		8
125 
126 /* Start channel numbers */
127 #define MLXPLAT_CPLD_CH1			2
128 #define MLXPLAT_CPLD_CH2			10
129 
130 /* Number of LPC attached MUX platform devices */
131 #define MLXPLAT_CPLD_LPC_MUX_DEVS		2
132 
133 /* Hotplug devices adapter numbers */
134 #define MLXPLAT_CPLD_NR_NONE			-1
135 #define MLXPLAT_CPLD_PSU_DEFAULT_NR		10
136 #define MLXPLAT_CPLD_PSU_MSNXXXX_NR		4
137 #define MLXPLAT_CPLD_FAN1_DEFAULT_NR		11
138 #define MLXPLAT_CPLD_FAN2_DEFAULT_NR		12
139 #define MLXPLAT_CPLD_FAN3_DEFAULT_NR		13
140 #define MLXPLAT_CPLD_FAN4_DEFAULT_NR		14
141 
142 /* Masks and default values for watchdogs */
143 #define MLXPLAT_CPLD_WD1_CLEAR_MASK	GENMASK(7, 1)
144 #define MLXPLAT_CPLD_WD2_CLEAR_MASK	(GENMASK(7, 0) & ~BIT(1))
145 
146 #define MLXPLAT_CPLD_WD_TYPE1_TO_MASK	GENMASK(7, 4)
147 #define MLXPLAT_CPLD_WD_TYPE2_TO_MASK	0
148 #define MLXPLAT_CPLD_WD_RESET_ACT_MASK	GENMASK(7, 1)
149 #define MLXPLAT_CPLD_WD_FAN_ACT_MASK	(GENMASK(7, 0) & ~BIT(4))
150 #define MLXPLAT_CPLD_WD_COUNT_ACT_MASK	(GENMASK(7, 0) & ~BIT(7))
151 #define MLXPLAT_CPLD_WD_DFLT_TIMEOUT	30
152 #define MLXPLAT_CPLD_WD_MAX_DEVS	2
153 
154 /* mlxplat_priv - platform private data
155  * @pdev_i2c - i2c controller platform device
156  * @pdev_mux - array of mux platform devices
157  * @pdev_hotplug - hotplug platform devices
158  * @pdev_led - led platform devices
159  * @pdev_io_regs - register access platform devices
160  * @pdev_fan - FAN platform devices
161  * @pdev_wd - array of watchdog platform devices
162  */
163 struct mlxplat_priv {
164 	struct platform_device *pdev_i2c;
165 	struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
166 	struct platform_device *pdev_hotplug;
167 	struct platform_device *pdev_led;
168 	struct platform_device *pdev_io_regs;
169 	struct platform_device *pdev_fan;
170 	struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS];
171 };
172 
173 /* Regions for LPC I2C controller and LPC base register space */
174 static const struct resource mlxplat_lpc_resources[] = {
175 	[0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR,
176 			       MLXPLAT_CPLD_LPC_IO_RANGE,
177 			       "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO),
178 	[1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR,
179 			       MLXPLAT_CPLD_LPC_IO_RANGE,
180 			       "mlxplat_cpld_lpc_regs",
181 			       IORESOURCE_IO),
182 };
183 
184 /* Platform default channels */
185 static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = {
186 	{
187 		MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2,
188 		MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 +
189 		5, MLXPLAT_CPLD_CH1 + 6, MLXPLAT_CPLD_CH1 + 7
190 	},
191 	{
192 		MLXPLAT_CPLD_CH2, MLXPLAT_CPLD_CH2 + 1, MLXPLAT_CPLD_CH2 + 2,
193 		MLXPLAT_CPLD_CH2 + 3, MLXPLAT_CPLD_CH2 + 4, MLXPLAT_CPLD_CH2 +
194 		5, MLXPLAT_CPLD_CH2 + 6, MLXPLAT_CPLD_CH2 + 7
195 	},
196 };
197 
198 /* Platform channels for MSN21xx system family */
199 static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
200 
201 /* Platform mux data */
202 static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
203 	{
204 		.parent = 1,
205 		.base_nr = MLXPLAT_CPLD_CH1,
206 		.write_only = 1,
207 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
208 		.reg_size = 1,
209 		.idle_in_use = 1,
210 	},
211 	{
212 		.parent = 1,
213 		.base_nr = MLXPLAT_CPLD_CH2,
214 		.write_only = 1,
215 		.reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
216 		.reg_size = 1,
217 		.idle_in_use = 1,
218 	},
219 
220 };
221 
222 /* Platform hotplug devices */
223 static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
224 	{
225 		I2C_BOARD_INFO("24c02", 0x51),
226 	},
227 	{
228 		I2C_BOARD_INFO("24c02", 0x50),
229 	},
230 };
231 
232 static struct i2c_board_info mlxplat_mlxcpld_ng_psu[] = {
233 	{
234 		I2C_BOARD_INFO("24c32", 0x51),
235 	},
236 	{
237 		I2C_BOARD_INFO("24c32", 0x50),
238 	},
239 };
240 
241 static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
242 	{
243 		I2C_BOARD_INFO("dps460", 0x59),
244 	},
245 	{
246 		I2C_BOARD_INFO("dps460", 0x58),
247 	},
248 };
249 
250 static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
251 	{
252 		I2C_BOARD_INFO("24c32", 0x50),
253 	},
254 	{
255 		I2C_BOARD_INFO("24c32", 0x50),
256 	},
257 	{
258 		I2C_BOARD_INFO("24c32", 0x50),
259 	},
260 	{
261 		I2C_BOARD_INFO("24c32", 0x50),
262 	},
263 };
264 
265 /* Platform hotplug default data */
266 static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
267 	{
268 		.label = "psu1",
269 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
270 		.mask = BIT(0),
271 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
272 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
273 	},
274 	{
275 		.label = "psu2",
276 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
277 		.mask = BIT(1),
278 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
279 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
280 	},
281 };
282 
283 static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
284 	{
285 		.label = "pwr1",
286 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
287 		.mask = BIT(0),
288 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
289 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
290 	},
291 	{
292 		.label = "pwr2",
293 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
294 		.mask = BIT(1),
295 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
296 		.hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
297 	},
298 };
299 
300 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
301 	{
302 		.label = "fan1",
303 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
304 		.mask = BIT(0),
305 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
306 		.hpdev.nr = MLXPLAT_CPLD_FAN1_DEFAULT_NR,
307 	},
308 	{
309 		.label = "fan2",
310 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
311 		.mask = BIT(1),
312 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
313 		.hpdev.nr = MLXPLAT_CPLD_FAN2_DEFAULT_NR,
314 	},
315 	{
316 		.label = "fan3",
317 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
318 		.mask = BIT(2),
319 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
320 		.hpdev.nr = MLXPLAT_CPLD_FAN3_DEFAULT_NR,
321 	},
322 	{
323 		.label = "fan4",
324 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
325 		.mask = BIT(3),
326 		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
327 		.hpdev.nr = MLXPLAT_CPLD_FAN4_DEFAULT_NR,
328 	},
329 };
330 
331 static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = {
332 	{
333 		.label = "asic1",
334 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
335 		.mask = MLXPLAT_CPLD_ASIC_MASK,
336 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
337 	},
338 };
339 
340 static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
341 	{
342 		.data = mlxplat_mlxcpld_default_psu_items_data,
343 		.aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
344 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
345 		.mask = MLXPLAT_CPLD_PSU_MASK,
346 		.count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
347 		.inversed = 1,
348 		.health = false,
349 	},
350 	{
351 		.data = mlxplat_mlxcpld_default_pwr_items_data,
352 		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
353 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
354 		.mask = MLXPLAT_CPLD_PWR_MASK,
355 		.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
356 		.inversed = 0,
357 		.health = false,
358 	},
359 	{
360 		.data = mlxplat_mlxcpld_default_fan_items_data,
361 		.aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
362 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
363 		.mask = MLXPLAT_CPLD_FAN_MASK,
364 		.count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
365 		.inversed = 1,
366 		.health = false,
367 	},
368 	{
369 		.data = mlxplat_mlxcpld_default_asic_items_data,
370 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
371 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
372 		.mask = MLXPLAT_CPLD_ASIC_MASK,
373 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
374 		.inversed = 0,
375 		.health = true,
376 	},
377 };
378 
379 static
380 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
381 	.items = mlxplat_mlxcpld_default_items,
382 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
383 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
384 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
385 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
386 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
387 };
388 
389 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = {
390 	{
391 		.label = "pwr1",
392 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
393 		.mask = BIT(0),
394 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
395 	},
396 	{
397 		.label = "pwr2",
398 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
399 		.mask = BIT(1),
400 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
401 	},
402 };
403 
404 /* Platform hotplug MSN21xx system family data */
405 static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
406 	{
407 		.data = mlxplat_mlxcpld_msn21xx_pwr_items_data,
408 		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
409 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
410 		.mask = MLXPLAT_CPLD_PWR_MASK,
411 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_pwr_items_data),
412 		.inversed = 0,
413 		.health = false,
414 	},
415 	{
416 		.data = mlxplat_mlxcpld_default_asic_items_data,
417 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
418 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
419 		.mask = MLXPLAT_CPLD_ASIC_MASK,
420 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
421 		.inversed = 0,
422 		.health = true,
423 	},
424 };
425 
426 static
427 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
428 	.items = mlxplat_mlxcpld_msn21xx_items,
429 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
430 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
431 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
432 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
433 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
434 };
435 
436 /* Platform hotplug msn274x system family data */
437 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data[] = {
438 	{
439 		.label = "psu1",
440 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
441 		.mask = BIT(0),
442 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
443 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
444 	},
445 	{
446 		.label = "psu2",
447 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
448 		.mask = BIT(1),
449 		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
450 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
451 	},
452 };
453 
454 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data[] = {
455 	{
456 		.label = "pwr1",
457 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
458 		.mask = BIT(0),
459 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
460 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
461 	},
462 	{
463 		.label = "pwr2",
464 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
465 		.mask = BIT(1),
466 		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
467 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
468 	},
469 };
470 
471 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data[] = {
472 	{
473 		.label = "fan1",
474 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
475 		.mask = BIT(0),
476 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
477 	},
478 	{
479 		.label = "fan2",
480 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
481 		.mask = BIT(1),
482 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
483 	},
484 	{
485 		.label = "fan3",
486 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
487 		.mask = BIT(2),
488 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
489 	},
490 	{
491 		.label = "fan4",
492 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
493 		.mask = BIT(3),
494 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
495 	},
496 };
497 
498 static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = {
499 	{
500 		.data = mlxplat_mlxcpld_msn274x_psu_items_data,
501 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
502 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
503 		.mask = MLXPLAT_CPLD_PSU_MASK,
504 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_psu_items_data),
505 		.inversed = 1,
506 		.health = false,
507 	},
508 	{
509 		.data = mlxplat_mlxcpld_default_ng_pwr_items_data,
510 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
511 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
512 		.mask = MLXPLAT_CPLD_PWR_MASK,
513 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
514 		.inversed = 0,
515 		.health = false,
516 	},
517 	{
518 		.data = mlxplat_mlxcpld_msn274x_fan_items_data,
519 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
520 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
521 		.mask = MLXPLAT_CPLD_FAN_MASK,
522 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data),
523 		.inversed = 1,
524 		.health = false,
525 	},
526 	{
527 		.data = mlxplat_mlxcpld_default_asic_items_data,
528 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
529 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
530 		.mask = MLXPLAT_CPLD_ASIC_MASK,
531 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
532 		.inversed = 0,
533 		.health = true,
534 	},
535 };
536 
537 static
538 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = {
539 	.items = mlxplat_mlxcpld_msn274x_items,
540 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
541 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
542 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
543 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
544 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
545 };
546 
547 /* Platform hotplug MSN201x system family data */
548 static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data[] = {
549 	{
550 		.label = "pwr1",
551 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
552 		.mask = BIT(0),
553 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
554 	},
555 	{
556 		.label = "pwr2",
557 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
558 		.mask = BIT(1),
559 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
560 	},
561 };
562 
563 static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
564 	{
565 		.data = mlxplat_mlxcpld_msn201x_pwr_items_data,
566 		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
567 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
568 		.mask = MLXPLAT_CPLD_PWR_MASK,
569 		.count = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_pwr_items_data),
570 		.inversed = 0,
571 		.health = false,
572 	},
573 	{
574 		.data = mlxplat_mlxcpld_default_asic_items_data,
575 		.aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
576 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
577 		.mask = MLXPLAT_CPLD_ASIC_MASK,
578 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
579 		.inversed = 0,
580 		.health = true,
581 	},
582 };
583 
584 static
585 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
586 	.items = mlxplat_mlxcpld_msn201x_items,
587 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
588 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
589 	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
590 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
591 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
592 };
593 
594 /* Platform hotplug next generation system family data */
595 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data[] = {
596 	{
597 		.label = "psu1",
598 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
599 		.mask = BIT(0),
600 		.hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[0],
601 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
602 	},
603 	{
604 		.label = "psu2",
605 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
606 		.mask = BIT(1),
607 		.hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[1],
608 		.hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
609 	},
610 };
611 
612 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = {
613 	{
614 		.label = "fan1",
615 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
616 		.mask = BIT(0),
617 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
618 		.bit = BIT(0),
619 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
620 	},
621 	{
622 		.label = "fan2",
623 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
624 		.mask = BIT(1),
625 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
626 		.bit = BIT(1),
627 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
628 	},
629 	{
630 		.label = "fan3",
631 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
632 		.mask = BIT(2),
633 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
634 		.bit = BIT(2),
635 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
636 	},
637 	{
638 		.label = "fan4",
639 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
640 		.mask = BIT(3),
641 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
642 		.bit = BIT(3),
643 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
644 	},
645 	{
646 		.label = "fan5",
647 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
648 		.mask = BIT(4),
649 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
650 		.bit = BIT(4),
651 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
652 	},
653 	{
654 		.label = "fan6",
655 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
656 		.mask = BIT(5),
657 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
658 		.bit = BIT(5),
659 		.hpdev.nr = MLXPLAT_CPLD_NR_NONE,
660 	},
661 };
662 
663 static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = {
664 	{
665 		.data = mlxplat_mlxcpld_default_ng_psu_items_data,
666 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
667 		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
668 		.mask = MLXPLAT_CPLD_PSU_MASK,
669 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data),
670 		.inversed = 1,
671 		.health = false,
672 	},
673 	{
674 		.data = mlxplat_mlxcpld_default_ng_pwr_items_data,
675 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
676 		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
677 		.mask = MLXPLAT_CPLD_PWR_MASK,
678 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
679 		.inversed = 0,
680 		.health = false,
681 	},
682 	{
683 		.data = mlxplat_mlxcpld_default_ng_fan_items_data,
684 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
685 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
686 		.mask = MLXPLAT_CPLD_FAN_NG_MASK,
687 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
688 		.inversed = 1,
689 		.health = false,
690 	},
691 	{
692 		.data = mlxplat_mlxcpld_default_asic_items_data,
693 		.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
694 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
695 		.mask = MLXPLAT_CPLD_ASIC_MASK,
696 		.count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
697 		.inversed = 0,
698 		.health = true,
699 	},
700 };
701 
702 static
703 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
704 	.items = mlxplat_mlxcpld_default_ng_items,
705 	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
706 	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
707 	.mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
708 	.cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
709 	.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
710 };
711 
712 /* Platform led default data */
713 static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
714 	{
715 		.label = "status:green",
716 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
717 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
718 	},
719 	{
720 		.label = "status:red",
721 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
722 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
723 	},
724 	{
725 		.label = "psu:green",
726 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
727 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
728 	},
729 	{
730 		.label = "psu:red",
731 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
732 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
733 	},
734 	{
735 		.label = "fan1:green",
736 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
737 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
738 	},
739 	{
740 		.label = "fan1:red",
741 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
742 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
743 	},
744 	{
745 		.label = "fan2:green",
746 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
747 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
748 	},
749 	{
750 		.label = "fan2:red",
751 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
752 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
753 	},
754 	{
755 		.label = "fan3:green",
756 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
757 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
758 	},
759 	{
760 		.label = "fan3:red",
761 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
762 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
763 	},
764 	{
765 		.label = "fan4:green",
766 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
767 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
768 	},
769 	{
770 		.label = "fan4:red",
771 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
772 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
773 	},
774 };
775 
776 static struct mlxreg_core_platform_data mlxplat_default_led_data = {
777 		.data = mlxplat_mlxcpld_default_led_data,
778 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
779 };
780 
781 /* Platform led MSN21xx system family data */
782 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {
783 	{
784 		.label = "status:green",
785 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
786 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
787 	},
788 	{
789 		.label = "status:red",
790 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
791 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
792 	},
793 	{
794 		.label = "fan:green",
795 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
796 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
797 	},
798 	{
799 		.label = "fan:red",
800 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
801 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
802 	},
803 	{
804 		.label = "psu1:green",
805 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
806 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
807 	},
808 	{
809 		.label = "psu1:red",
810 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
811 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
812 	},
813 	{
814 		.label = "psu2:green",
815 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
816 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
817 	},
818 	{
819 		.label = "psu2:red",
820 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
821 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
822 	},
823 	{
824 		.label = "uid:blue",
825 		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
826 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
827 	},
828 };
829 
830 static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = {
831 		.data = mlxplat_mlxcpld_msn21xx_led_data,
832 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data),
833 };
834 
835 /* Platform led for default data for 200GbE systems */
836 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
837 	{
838 		.label = "status:green",
839 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
840 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
841 	},
842 	{
843 		.label = "status:orange",
844 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
845 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
846 	},
847 	{
848 		.label = "psu:green",
849 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
850 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
851 	},
852 	{
853 		.label = "psu:orange",
854 		.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
855 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
856 	},
857 	{
858 		.label = "fan1:green",
859 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
860 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
861 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
862 		.bit = BIT(0),
863 	},
864 	{
865 		.label = "fan1:orange",
866 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
867 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
868 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
869 		.bit = BIT(0),
870 	},
871 	{
872 		.label = "fan2:green",
873 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
874 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
875 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
876 		.bit = BIT(1),
877 	},
878 	{
879 		.label = "fan2:orange",
880 		.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
881 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
882 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
883 		.bit = BIT(1),
884 	},
885 	{
886 		.label = "fan3:green",
887 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
888 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
889 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
890 		.bit = BIT(2),
891 	},
892 	{
893 		.label = "fan3:orange",
894 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
895 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
896 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
897 		.bit = BIT(2),
898 	},
899 	{
900 		.label = "fan4:green",
901 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
902 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
903 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
904 		.bit = BIT(3),
905 	},
906 	{
907 		.label = "fan4:orange",
908 		.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
909 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
910 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
911 		.bit = BIT(3),
912 	},
913 	{
914 		.label = "fan5:green",
915 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
916 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
917 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
918 		.bit = BIT(4),
919 	},
920 	{
921 		.label = "fan5:orange",
922 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
923 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
924 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
925 		.bit = BIT(4),
926 	},
927 	{
928 		.label = "fan6:green",
929 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
930 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
931 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
932 		.bit = BIT(5),
933 	},
934 	{
935 		.label = "fan6:orange",
936 		.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
937 		.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
938 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
939 		.bit = BIT(5),
940 	},
941 	{
942 		.label = "uid:blue",
943 		.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
944 		.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
945 	},
946 };
947 
948 static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
949 		.data = mlxplat_mlxcpld_default_ng_led_data,
950 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
951 };
952 
953 /* Platform register access default */
954 static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
955 	{
956 		.label = "cpld1_version",
957 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
958 		.bit = GENMASK(7, 0),
959 		.mode = 0444,
960 	},
961 	{
962 		.label = "cpld2_version",
963 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
964 		.bit = GENMASK(7, 0),
965 		.mode = 0444,
966 	},
967 	{
968 		.label = "reset_long_pb",
969 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
970 		.mask = GENMASK(7, 0) & ~BIT(0),
971 		.mode = 0444,
972 	},
973 	{
974 		.label = "reset_short_pb",
975 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
976 		.mask = GENMASK(7, 0) & ~BIT(1),
977 		.mode = 0444,
978 	},
979 	{
980 		.label = "reset_aux_pwr_or_ref",
981 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
982 		.mask = GENMASK(7, 0) & ~BIT(2),
983 		.mode = 0444,
984 	},
985 	{
986 		.label = "reset_main_pwr_fail",
987 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
988 		.mask = GENMASK(7, 0) & ~BIT(3),
989 		.mode = 0444,
990 	},
991 	{
992 		.label = "reset_sw_reset",
993 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
994 		.mask = GENMASK(7, 0) & ~BIT(4),
995 		.mode = 0444,
996 	},
997 	{
998 		.label = "reset_fw_reset",
999 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1000 		.mask = GENMASK(7, 0) & ~BIT(5),
1001 		.mode = 0444,
1002 	},
1003 	{
1004 		.label = "reset_hotswap_or_wd",
1005 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1006 		.mask = GENMASK(7, 0) & ~BIT(6),
1007 		.mode = 0444,
1008 	},
1009 	{
1010 		.label = "reset_asic_thermal",
1011 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1012 		.mask = GENMASK(7, 0) & ~BIT(7),
1013 		.mode = 0444,
1014 	},
1015 	{
1016 		.label = "psu1_on",
1017 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1018 		.mask = GENMASK(7, 0) & ~BIT(0),
1019 		.mode = 0200,
1020 	},
1021 	{
1022 		.label = "psu2_on",
1023 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1024 		.mask = GENMASK(7, 0) & ~BIT(1),
1025 		.mode = 0200,
1026 	},
1027 	{
1028 		.label = "pwr_cycle",
1029 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1030 		.mask = GENMASK(7, 0) & ~BIT(2),
1031 		.mode = 0200,
1032 	},
1033 	{
1034 		.label = "pwr_down",
1035 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1036 		.mask = GENMASK(7, 0) & ~BIT(3),
1037 		.mode = 0200,
1038 	},
1039 	{
1040 		.label = "select_iio",
1041 		.reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1042 		.mask = GENMASK(7, 0) & ~BIT(6),
1043 		.mode = 0644,
1044 	},
1045 	{
1046 		.label = "asic_health",
1047 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1048 		.mask = MLXPLAT_CPLD_ASIC_MASK,
1049 		.bit = 1,
1050 		.mode = 0444,
1051 	},
1052 };
1053 
1054 static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = {
1055 		.data = mlxplat_mlxcpld_default_regs_io_data,
1056 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
1057 };
1058 
1059 /* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
1060 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = {
1061 	{
1062 		.label = "cpld1_version",
1063 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
1064 		.bit = GENMASK(7, 0),
1065 		.mode = 0444,
1066 	},
1067 	{
1068 		.label = "cpld2_version",
1069 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1070 		.bit = GENMASK(7, 0),
1071 		.mode = 0444,
1072 	},
1073 	{
1074 		.label = "reset_long_pb",
1075 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1076 		.mask = GENMASK(7, 0) & ~BIT(0),
1077 		.mode = 0444,
1078 	},
1079 	{
1080 		.label = "reset_short_pb",
1081 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1082 		.mask = GENMASK(7, 0) & ~BIT(1),
1083 		.mode = 0444,
1084 	},
1085 	{
1086 		.label = "reset_aux_pwr_or_ref",
1087 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1088 		.mask = GENMASK(7, 0) & ~BIT(2),
1089 		.mode = 0444,
1090 	},
1091 	{
1092 		.label = "reset_sw_reset",
1093 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1094 		.mask = GENMASK(7, 0) & ~BIT(3),
1095 		.mode = 0444,
1096 	},
1097 	{
1098 		.label = "reset_main_pwr_fail",
1099 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1100 		.mask = GENMASK(7, 0) & ~BIT(4),
1101 		.mode = 0444,
1102 	},
1103 	{
1104 		.label = "reset_asic_thermal",
1105 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1106 		.mask = GENMASK(7, 0) & ~BIT(5),
1107 		.mode = 0444,
1108 	},
1109 	{
1110 		.label = "reset_hotswap_or_halt",
1111 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1112 		.mask = GENMASK(7, 0) & ~BIT(6),
1113 		.mode = 0444,
1114 	},
1115 	{
1116 		.label = "psu1_on",
1117 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1118 		.mask = GENMASK(7, 0) & ~BIT(0),
1119 		.mode = 0200,
1120 	},
1121 	{
1122 		.label = "psu2_on",
1123 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1124 		.mask = GENMASK(7, 0) & ~BIT(1),
1125 		.mode = 0200,
1126 	},
1127 	{
1128 		.label = "pwr_cycle",
1129 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1130 		.mask = GENMASK(7, 0) & ~BIT(2),
1131 		.mode = 0200,
1132 	},
1133 	{
1134 		.label = "pwr_down",
1135 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1136 		.mask = GENMASK(7, 0) & ~BIT(3),
1137 		.mode = 0200,
1138 	},
1139 	{
1140 		.label = "asic_health",
1141 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1142 		.mask = MLXPLAT_CPLD_ASIC_MASK,
1143 		.bit = 1,
1144 		.mode = 0444,
1145 	},
1146 };
1147 
1148 static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data = {
1149 		.data = mlxplat_mlxcpld_msn21xx_regs_io_data,
1150 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data),
1151 };
1152 
1153 /* Platform register access for next generation systems families data */
1154 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
1155 	{
1156 		.label = "cpld1_version",
1157 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
1158 		.bit = GENMASK(7, 0),
1159 		.mode = 0444,
1160 	},
1161 	{
1162 		.label = "cpld2_version",
1163 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1164 		.bit = GENMASK(7, 0),
1165 		.mode = 0444,
1166 	},
1167 	{
1168 		.label = "cpld3_version",
1169 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
1170 		.bit = GENMASK(7, 0),
1171 		.mode = 0444,
1172 	},
1173 	{
1174 		.label = "cpld4_version",
1175 		.reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
1176 		.bit = GENMASK(7, 0),
1177 		.mode = 0444,
1178 	},
1179 	{
1180 		.label = "reset_long_pb",
1181 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1182 		.mask = GENMASK(7, 0) & ~BIT(0),
1183 		.mode = 0444,
1184 	},
1185 	{
1186 		.label = "reset_short_pb",
1187 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1188 		.mask = GENMASK(7, 0) & ~BIT(1),
1189 		.mode = 0444,
1190 	},
1191 	{
1192 		.label = "reset_aux_pwr_or_ref",
1193 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1194 		.mask = GENMASK(7, 0) & ~BIT(2),
1195 		.mode = 0444,
1196 	},
1197 	{
1198 		.label = "reset_from_comex",
1199 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1200 		.mask = GENMASK(7, 0) & ~BIT(4),
1201 		.mode = 0444,
1202 	},
1203 	{
1204 		.label = "reset_asic_thermal",
1205 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1206 		.mask = GENMASK(7, 0) & ~BIT(7),
1207 		.mode = 0444,
1208 	},
1209 	{
1210 		.label = "reset_comex_pwr_fail",
1211 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1212 		.mask = GENMASK(7, 0) & ~BIT(3),
1213 		.mode = 0444,
1214 	},
1215 	{
1216 		.label = "reset_voltmon_upgrade_fail",
1217 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1218 		.mask = GENMASK(7, 0) & ~BIT(0),
1219 		.mode = 0444,
1220 	},
1221 	{
1222 		.label = "reset_system",
1223 		.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1224 		.mask = GENMASK(7, 0) & ~BIT(1),
1225 		.mode = 0444,
1226 	},
1227 	{
1228 		.label = "psu1_on",
1229 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1230 		.mask = GENMASK(7, 0) & ~BIT(0),
1231 		.mode = 0200,
1232 	},
1233 	{
1234 		.label = "psu2_on",
1235 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1236 		.mask = GENMASK(7, 0) & ~BIT(1),
1237 		.mode = 0200,
1238 	},
1239 	{
1240 		.label = "pwr_cycle",
1241 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1242 		.mask = GENMASK(7, 0) & ~BIT(2),
1243 		.mode = 0200,
1244 	},
1245 	{
1246 		.label = "pwr_down",
1247 		.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1248 		.mask = GENMASK(7, 0) & ~BIT(3),
1249 		.mode = 0200,
1250 	},
1251 	{
1252 		.label = "jtag_enable",
1253 		.reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1254 		.mask = GENMASK(7, 0) & ~BIT(4),
1255 		.mode = 0644,
1256 	},
1257 	{
1258 		.label = "asic_health",
1259 		.reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1260 		.mask = MLXPLAT_CPLD_ASIC_MASK,
1261 		.bit = 1,
1262 		.mode = 0444,
1263 	},
1264 	{
1265 		.label = "fan_dir",
1266 		.reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
1267 		.bit = GENMASK(7, 0),
1268 		.mode = 0444,
1269 	},
1270 };
1271 
1272 static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = {
1273 		.data = mlxplat_mlxcpld_default_ng_regs_io_data,
1274 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_regs_io_data),
1275 };
1276 
1277 /* Platform FAN default */
1278 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
1279 	{
1280 		.label = "pwm1",
1281 		.reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
1282 	},
1283 	{
1284 		.label = "tacho1",
1285 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
1286 		.mask = GENMASK(7, 0),
1287 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1288 		.bit = BIT(0),
1289 	},
1290 	{
1291 		.label = "tacho2",
1292 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
1293 		.mask = GENMASK(7, 0),
1294 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1295 		.bit = BIT(1),
1296 	},
1297 	{
1298 		.label = "tacho3",
1299 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
1300 		.mask = GENMASK(7, 0),
1301 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1302 		.bit = BIT(2),
1303 	},
1304 	{
1305 		.label = "tacho4",
1306 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
1307 		.mask = GENMASK(7, 0),
1308 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1309 		.bit = BIT(3),
1310 	},
1311 	{
1312 		.label = "tacho5",
1313 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
1314 		.mask = GENMASK(7, 0),
1315 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1316 		.bit = BIT(4),
1317 	},
1318 	{
1319 		.label = "tacho6",
1320 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
1321 		.mask = GENMASK(7, 0),
1322 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1323 		.bit = BIT(5),
1324 	},
1325 	{
1326 		.label = "tacho7",
1327 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
1328 		.mask = GENMASK(7, 0),
1329 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1330 		.bit = BIT(6),
1331 	},
1332 	{
1333 		.label = "tacho8",
1334 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
1335 		.mask = GENMASK(7, 0),
1336 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1337 		.bit = BIT(7),
1338 	},
1339 	{
1340 		.label = "tacho9",
1341 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
1342 		.mask = GENMASK(7, 0),
1343 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1344 		.bit = BIT(0),
1345 	},
1346 	{
1347 		.label = "tacho10",
1348 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
1349 		.mask = GENMASK(7, 0),
1350 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1351 		.bit = BIT(1),
1352 	},
1353 	{
1354 		.label = "tacho11",
1355 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
1356 		.mask = GENMASK(7, 0),
1357 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1358 		.bit = BIT(2),
1359 	},
1360 	{
1361 		.label = "tacho12",
1362 		.reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
1363 		.mask = GENMASK(7, 0),
1364 		.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1365 		.bit = BIT(3),
1366 	},
1367 	{
1368 		.label = "conf",
1369 		.capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET,
1370 	},
1371 };
1372 
1373 static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
1374 		.data = mlxplat_mlxcpld_default_fan_data,
1375 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
1376 };
1377 
1378 /* Watchdog type1: hardware implementation version1
1379  * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
1380  */
1381 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1[] = {
1382 	{
1383 		.label = "action",
1384 		.reg = MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET,
1385 		.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1386 		.bit = 0,
1387 	},
1388 	{
1389 		.label = "timeout",
1390 		.reg = MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET,
1391 		.mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
1392 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1393 	},
1394 	{
1395 		.label = "ping",
1396 		.reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
1397 		.mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
1398 		.bit = 0,
1399 	},
1400 	{
1401 		.label = "reset",
1402 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1403 		.mask = GENMASK(7, 0) & ~BIT(6),
1404 		.bit = 6,
1405 	},
1406 };
1407 
1408 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1[] = {
1409 	{
1410 		.label = "action",
1411 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1412 		.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1413 		.bit = 4,
1414 	},
1415 	{
1416 		.label = "timeout",
1417 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
1418 		.mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
1419 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1420 	},
1421 	{
1422 		.label = "ping",
1423 		.reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
1424 		.mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
1425 		.bit = 1,
1426 	},
1427 };
1428 
1429 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type1[] = {
1430 	{
1431 		.data = mlxplat_mlxcpld_wd_main_regs_type1,
1432 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1),
1433 		.version = MLX_WDT_TYPE1,
1434 		.identity = "mlx-wdt-main",
1435 	},
1436 	{
1437 		.data = mlxplat_mlxcpld_wd_aux_regs_type1,
1438 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1),
1439 		.version = MLX_WDT_TYPE1,
1440 		.identity = "mlx-wdt-aux",
1441 	},
1442 };
1443 
1444 /* Watchdog type2: hardware implementation version 2
1445  * (all systems except (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140).
1446  */
1447 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2[] = {
1448 	{
1449 		.label = "action",
1450 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1451 		.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1452 		.bit = 0,
1453 	},
1454 	{
1455 		.label = "timeout",
1456 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
1457 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1458 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1459 	},
1460 	{
1461 		.label = "timeleft",
1462 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET,
1463 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1464 	},
1465 	{
1466 		.label = "ping",
1467 		.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1468 		.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1469 		.bit = 0,
1470 	},
1471 	{
1472 		.label = "reset",
1473 		.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1474 		.mask = GENMASK(7, 0) & ~BIT(6),
1475 		.bit = 6,
1476 	},
1477 };
1478 
1479 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2[] = {
1480 	{
1481 		.label = "action",
1482 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
1483 		.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1484 		.bit = 4,
1485 	},
1486 	{
1487 		.label = "timeout",
1488 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
1489 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1490 		.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1491 	},
1492 	{
1493 		.label = "timeleft",
1494 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET,
1495 		.mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1496 	},
1497 	{
1498 		.label = "ping",
1499 		.reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
1500 		.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1501 		.bit = 4,
1502 	},
1503 };
1504 
1505 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type2[] = {
1506 	{
1507 		.data = mlxplat_mlxcpld_wd_main_regs_type2,
1508 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2),
1509 		.version = MLX_WDT_TYPE2,
1510 		.identity = "mlx-wdt-main",
1511 	},
1512 	{
1513 		.data = mlxplat_mlxcpld_wd_aux_regs_type2,
1514 		.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2),
1515 		.version = MLX_WDT_TYPE2,
1516 		.identity = "mlx-wdt-aux",
1517 	},
1518 };
1519 
1520 static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
1521 {
1522 	switch (reg) {
1523 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1524 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1525 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1526 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1527 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1528 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1529 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
1530 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1531 	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
1532 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1533 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1534 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1535 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1536 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1537 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1538 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1539 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1540 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1541 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1542 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
1543 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
1544 	case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
1545 	case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
1546 	case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1547 	case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
1548 	case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1549 	case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
1550 	case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1551 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1552 		return true;
1553 	}
1554 	return false;
1555 }
1556 
1557 static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
1558 {
1559 	switch (reg) {
1560 	case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
1561 	case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
1562 	case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
1563 	case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
1564 	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
1565 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
1566 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
1567 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1568 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1569 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1570 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1571 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1572 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
1573 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1574 	case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
1575 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1576 	case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
1577 	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
1578 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1579 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
1580 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1581 	case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
1582 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1583 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1584 	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
1585 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1586 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1587 	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
1588 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1589 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1590 	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
1591 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1592 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1593 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
1594 	case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
1595 	case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
1596 	case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
1597 	case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1598 	case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
1599 	case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
1600 	case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1601 	case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
1602 	case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
1603 	case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1604 	case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
1605 	case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
1606 	case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
1607 	case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
1608 	case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
1609 	case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
1610 	case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
1611 	case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
1612 	case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
1613 	case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
1614 	case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
1615 	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
1616 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1617 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
1618 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
1619 	case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
1620 	case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
1621 		return true;
1622 	}
1623 	return false;
1624 }
1625 
1626 static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
1627 {
1628 	switch (reg) {
1629 	case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
1630 	case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
1631 	case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
1632 	case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
1633 	case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
1634 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
1635 	case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
1636 	case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1637 	case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1638 	case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1639 	case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1640 	case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1641 	case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
1642 	case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1643 	case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1644 	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
1645 	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1646 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
1647 	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1648 	case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
1649 	case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1650 	case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1651 	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
1652 	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1653 	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1654 	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
1655 	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1656 	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1657 	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
1658 	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1659 	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1660 	case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1661 	case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
1662 	case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1663 	case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
1664 	case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1665 	case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
1666 	case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
1667 	case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
1668 	case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
1669 	case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
1670 	case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
1671 	case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
1672 	case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
1673 	case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
1674 	case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
1675 	case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
1676 	case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
1677 	case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1678 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
1679 	case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
1680 	case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
1681 	case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
1682 		return true;
1683 	}
1684 	return false;
1685 }
1686 
1687 static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
1688 	{ MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
1689 	{ MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
1690 	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
1691 	{ MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 },
1692 };
1693 
1694 struct mlxplat_mlxcpld_regmap_context {
1695 	void __iomem *base;
1696 };
1697 
1698 static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
1699 
1700 static int
1701 mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
1702 {
1703 	struct mlxplat_mlxcpld_regmap_context *ctx = context;
1704 
1705 	*val = ioread8(ctx->base + reg);
1706 	return 0;
1707 }
1708 
1709 static int
1710 mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
1711 {
1712 	struct mlxplat_mlxcpld_regmap_context *ctx = context;
1713 
1714 	iowrite8(val, ctx->base + reg);
1715 	return 0;
1716 }
1717 
1718 static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
1719 	.reg_bits = 8,
1720 	.val_bits = 8,
1721 	.max_register = 255,
1722 	.cache_type = REGCACHE_FLAT,
1723 	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
1724 	.readable_reg = mlxplat_mlxcpld_readable_reg,
1725 	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
1726 	.reg_defaults = mlxplat_mlxcpld_regmap_default,
1727 	.num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default),
1728 	.reg_read = mlxplat_mlxcpld_reg_read,
1729 	.reg_write = mlxplat_mlxcpld_reg_write,
1730 };
1731 
1732 static struct resource mlxplat_mlxcpld_resources[] = {
1733 	[0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
1734 };
1735 
1736 static struct platform_device *mlxplat_dev;
1737 static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
1738 static struct mlxreg_core_platform_data *mlxplat_led;
1739 static struct mlxreg_core_platform_data *mlxplat_regs_io;
1740 static struct mlxreg_core_platform_data *mlxplat_fan;
1741 static struct mlxreg_core_platform_data
1742 	*mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS];
1743 
1744 static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
1745 {
1746 	int i;
1747 
1748 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1749 		mlxplat_mux_data[i].values = mlxplat_default_channels[i];
1750 		mlxplat_mux_data[i].n_values =
1751 				ARRAY_SIZE(mlxplat_default_channels[i]);
1752 	}
1753 	mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
1754 	mlxplat_hotplug->deferred_nr =
1755 		mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
1756 	mlxplat_led = &mlxplat_default_led_data;
1757 	mlxplat_regs_io = &mlxplat_default_regs_io_data;
1758 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
1759 
1760 	return 1;
1761 };
1762 
1763 static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
1764 {
1765 	int i;
1766 
1767 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1768 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
1769 		mlxplat_mux_data[i].n_values =
1770 				ARRAY_SIZE(mlxplat_msn21xx_channels);
1771 	}
1772 	mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
1773 	mlxplat_hotplug->deferred_nr =
1774 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
1775 	mlxplat_led = &mlxplat_msn21xx_led_data;
1776 	mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
1777 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
1778 
1779 	return 1;
1780 };
1781 
1782 static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
1783 {
1784 	int i;
1785 
1786 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1787 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
1788 		mlxplat_mux_data[i].n_values =
1789 				ARRAY_SIZE(mlxplat_msn21xx_channels);
1790 	}
1791 	mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
1792 	mlxplat_hotplug->deferred_nr =
1793 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
1794 	mlxplat_led = &mlxplat_default_led_data;
1795 	mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
1796 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
1797 
1798 	return 1;
1799 };
1800 
1801 static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
1802 {
1803 	int i;
1804 
1805 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1806 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
1807 		mlxplat_mux_data[i].n_values =
1808 				ARRAY_SIZE(mlxplat_msn21xx_channels);
1809 	}
1810 	mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
1811 	mlxplat_hotplug->deferred_nr =
1812 		mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
1813 	mlxplat_led = &mlxplat_msn21xx_led_data;
1814 	mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
1815 	mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
1816 
1817 	return 1;
1818 };
1819 
1820 static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
1821 {
1822 	int i;
1823 
1824 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1825 		mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
1826 		mlxplat_mux_data[i].n_values =
1827 				ARRAY_SIZE(mlxplat_msn21xx_channels);
1828 	}
1829 	mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
1830 	mlxplat_hotplug->deferred_nr =
1831 		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
1832 	mlxplat_led = &mlxplat_default_ng_led_data;
1833 	mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
1834 	mlxplat_fan = &mlxplat_default_fan_data;
1835 	for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
1836 		mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
1837 
1838 	return 1;
1839 };
1840 
1841 static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
1842 	{
1843 		.callback = mlxplat_dmi_msn274x_matched,
1844 		.matches = {
1845 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1846 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN274"),
1847 		},
1848 	},
1849 	{
1850 		.callback = mlxplat_dmi_default_matched,
1851 		.matches = {
1852 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1853 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"),
1854 		},
1855 	},
1856 	{
1857 		.callback = mlxplat_dmi_default_matched,
1858 		.matches = {
1859 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1860 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"),
1861 		},
1862 	},
1863 	{
1864 		.callback = mlxplat_dmi_default_matched,
1865 		.matches = {
1866 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1867 			DMI_MATCH(DMI_PRODUCT_NAME, "MSB"),
1868 		},
1869 	},
1870 	{
1871 		.callback = mlxplat_dmi_default_matched,
1872 		.matches = {
1873 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1874 			DMI_MATCH(DMI_PRODUCT_NAME, "MSX"),
1875 		},
1876 	},
1877 	{
1878 		.callback = mlxplat_dmi_msn21xx_matched,
1879 		.matches = {
1880 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1881 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"),
1882 		},
1883 	},
1884 	{
1885 		.callback = mlxplat_dmi_msn201x_matched,
1886 		.matches = {
1887 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1888 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN201"),
1889 		},
1890 	},
1891 	{
1892 		.callback = mlxplat_dmi_qmb7xx_matched,
1893 		.matches = {
1894 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1895 			DMI_MATCH(DMI_PRODUCT_NAME, "MQM87"),
1896 		},
1897 	},
1898 	{
1899 		.callback = mlxplat_dmi_qmb7xx_matched,
1900 		.matches = {
1901 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1902 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN37"),
1903 		},
1904 	},
1905 	{
1906 		.callback = mlxplat_dmi_qmb7xx_matched,
1907 		.matches = {
1908 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1909 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"),
1910 		},
1911 	},
1912 	{
1913 		.callback = mlxplat_dmi_qmb7xx_matched,
1914 		.matches = {
1915 			DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1916 			DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"),
1917 		},
1918 	},
1919 	{
1920 		.callback = mlxplat_dmi_default_matched,
1921 		.matches = {
1922 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
1923 		},
1924 	},
1925 	{
1926 		.callback = mlxplat_dmi_msn21xx_matched,
1927 		.matches = {
1928 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"),
1929 		},
1930 	},
1931 	{
1932 		.callback = mlxplat_dmi_msn274x_matched,
1933 		.matches = {
1934 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"),
1935 		},
1936 	},
1937 	{
1938 		.callback = mlxplat_dmi_msn201x_matched,
1939 		.matches = {
1940 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"),
1941 		},
1942 	},
1943 	{
1944 		.callback = mlxplat_dmi_qmb7xx_matched,
1945 		.matches = {
1946 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
1947 		},
1948 	},
1949 	{
1950 		.callback = mlxplat_dmi_qmb7xx_matched,
1951 		.matches = {
1952 			DMI_MATCH(DMI_BOARD_NAME, "VMOD0007"),
1953 		},
1954 	},
1955 	{ }
1956 };
1957 
1958 MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
1959 
1960 static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
1961 {
1962 	struct i2c_adapter *search_adap;
1963 	int shift, i;
1964 
1965 	/* Scan adapters from expected id to verify it is free. */
1966 	*nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
1967 	for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
1968 	     MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; i++) {
1969 		search_adap = i2c_get_adapter(i);
1970 		if (search_adap) {
1971 			i2c_put_adapter(search_adap);
1972 			continue;
1973 		}
1974 
1975 		/* Return if expected parent adapter is free. */
1976 		if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR)
1977 			return 0;
1978 		break;
1979 	}
1980 
1981 	/* Return with error if free id for adapter is not found. */
1982 	if (i == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM)
1983 		return -ENODEV;
1984 
1985 	/* Shift adapter ids, since expected parent adapter is not free. */
1986 	*nr = i;
1987 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1988 		shift = *nr - mlxplat_mux_data[i].parent;
1989 		mlxplat_mux_data[i].parent = *nr;
1990 		mlxplat_mux_data[i].base_nr += shift;
1991 		if (shift > 0)
1992 			mlxplat_hotplug->shift_nr = shift;
1993 	}
1994 
1995 	return 0;
1996 }
1997 
1998 static int __init mlxplat_init(void)
1999 {
2000 	struct mlxplat_priv *priv;
2001 	int i, j, nr, err;
2002 
2003 	if (!dmi_check_system(mlxplat_dmi_table))
2004 		return -ENODEV;
2005 
2006 	mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, -1,
2007 					mlxplat_lpc_resources,
2008 					ARRAY_SIZE(mlxplat_lpc_resources));
2009 
2010 	if (IS_ERR(mlxplat_dev))
2011 		return PTR_ERR(mlxplat_dev);
2012 
2013 	priv = devm_kzalloc(&mlxplat_dev->dev, sizeof(struct mlxplat_priv),
2014 			    GFP_KERNEL);
2015 	if (!priv) {
2016 		err = -ENOMEM;
2017 		goto fail_alloc;
2018 	}
2019 	platform_set_drvdata(mlxplat_dev, priv);
2020 
2021 	err = mlxplat_mlxcpld_verify_bus_topology(&nr);
2022 	if (nr < 0)
2023 		goto fail_alloc;
2024 
2025 	nr = (nr == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) ? -1 : nr;
2026 	priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", nr,
2027 							 NULL, 0);
2028 	if (IS_ERR(priv->pdev_i2c)) {
2029 		err = PTR_ERR(priv->pdev_i2c);
2030 		goto fail_alloc;
2031 	}
2032 
2033 	for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
2034 		priv->pdev_mux[i] = platform_device_register_resndata(
2035 						&priv->pdev_i2c->dev,
2036 						"i2c-mux-reg", i, NULL,
2037 						0, &mlxplat_mux_data[i],
2038 						sizeof(mlxplat_mux_data[i]));
2039 		if (IS_ERR(priv->pdev_mux[i])) {
2040 			err = PTR_ERR(priv->pdev_mux[i]);
2041 			goto fail_platform_mux_register;
2042 		}
2043 	}
2044 
2045 	mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
2046 			       mlxplat_lpc_resources[1].start, 1);
2047 	if (!mlxplat_mlxcpld_regmap_ctx.base) {
2048 		err = -ENOMEM;
2049 		goto fail_platform_mux_register;
2050 	}
2051 
2052 	mlxplat_hotplug->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
2053 					&mlxplat_mlxcpld_regmap_ctx,
2054 					&mlxplat_mlxcpld_regmap_config);
2055 	if (IS_ERR(mlxplat_hotplug->regmap)) {
2056 		err = PTR_ERR(mlxplat_hotplug->regmap);
2057 		goto fail_platform_mux_register;
2058 	}
2059 
2060 	priv->pdev_hotplug = platform_device_register_resndata(
2061 				&mlxplat_dev->dev, "mlxreg-hotplug",
2062 				PLATFORM_DEVID_NONE,
2063 				mlxplat_mlxcpld_resources,
2064 				ARRAY_SIZE(mlxplat_mlxcpld_resources),
2065 				mlxplat_hotplug, sizeof(*mlxplat_hotplug));
2066 	if (IS_ERR(priv->pdev_hotplug)) {
2067 		err = PTR_ERR(priv->pdev_hotplug);
2068 		goto fail_platform_mux_register;
2069 	}
2070 
2071 	/* Set default registers. */
2072 	for (j = 0; j <  mlxplat_mlxcpld_regmap_config.num_reg_defaults; j++) {
2073 		err = regmap_write(mlxplat_hotplug->regmap,
2074 				   mlxplat_mlxcpld_regmap_default[j].reg,
2075 				   mlxplat_mlxcpld_regmap_default[j].def);
2076 		if (err)
2077 			goto fail_platform_mux_register;
2078 	}
2079 
2080 	/* Add LED driver. */
2081 	mlxplat_led->regmap = mlxplat_hotplug->regmap;
2082 	priv->pdev_led = platform_device_register_resndata(
2083 				&mlxplat_dev->dev, "leds-mlxreg",
2084 				PLATFORM_DEVID_NONE, NULL, 0,
2085 				mlxplat_led, sizeof(*mlxplat_led));
2086 	if (IS_ERR(priv->pdev_led)) {
2087 		err = PTR_ERR(priv->pdev_led);
2088 		goto fail_platform_hotplug_register;
2089 	}
2090 
2091 	/* Add registers io access driver. */
2092 	if (mlxplat_regs_io) {
2093 		mlxplat_regs_io->regmap = mlxplat_hotplug->regmap;
2094 		priv->pdev_io_regs = platform_device_register_resndata(
2095 					&mlxplat_dev->dev, "mlxreg-io",
2096 					PLATFORM_DEVID_NONE, NULL, 0,
2097 					mlxplat_regs_io,
2098 					sizeof(*mlxplat_regs_io));
2099 		if (IS_ERR(priv->pdev_io_regs)) {
2100 			err = PTR_ERR(priv->pdev_io_regs);
2101 			goto fail_platform_led_register;
2102 		}
2103 	}
2104 
2105 	/* Add FAN driver. */
2106 	if (mlxplat_fan) {
2107 		mlxplat_fan->regmap = mlxplat_hotplug->regmap;
2108 		priv->pdev_fan = platform_device_register_resndata(
2109 					&mlxplat_dev->dev, "mlxreg-fan",
2110 					PLATFORM_DEVID_NONE, NULL, 0,
2111 					mlxplat_fan,
2112 					sizeof(*mlxplat_fan));
2113 		if (IS_ERR(priv->pdev_fan)) {
2114 			err = PTR_ERR(priv->pdev_fan);
2115 			goto fail_platform_io_regs_register;
2116 		}
2117 	}
2118 
2119 	/* Add WD drivers. */
2120 	for (j = 0; j < MLXPLAT_CPLD_WD_MAX_DEVS; j++) {
2121 		if (mlxplat_wd_data[j]) {
2122 			mlxplat_wd_data[j]->regmap = mlxplat_hotplug->regmap;
2123 			priv->pdev_wd[j] = platform_device_register_resndata(
2124 						&mlxplat_dev->dev, "mlx-wdt",
2125 						j, NULL, 0,
2126 						mlxplat_wd_data[j],
2127 						sizeof(*mlxplat_wd_data[j]));
2128 			if (IS_ERR(priv->pdev_wd[j])) {
2129 				err = PTR_ERR(priv->pdev_wd[j]);
2130 				goto fail_platform_wd_register;
2131 			}
2132 		}
2133 	}
2134 
2135 	/* Sync registers with hardware. */
2136 	regcache_mark_dirty(mlxplat_hotplug->regmap);
2137 	err = regcache_sync(mlxplat_hotplug->regmap);
2138 	if (err)
2139 		goto fail_platform_wd_register;
2140 
2141 	return 0;
2142 
2143 fail_platform_wd_register:
2144 	while (--j >= 0)
2145 		platform_device_unregister(priv->pdev_wd[j]);
2146 	if (mlxplat_fan)
2147 		platform_device_unregister(priv->pdev_fan);
2148 fail_platform_io_regs_register:
2149 	if (mlxplat_regs_io)
2150 		platform_device_unregister(priv->pdev_io_regs);
2151 fail_platform_led_register:
2152 	platform_device_unregister(priv->pdev_led);
2153 fail_platform_hotplug_register:
2154 	platform_device_unregister(priv->pdev_hotplug);
2155 fail_platform_mux_register:
2156 	while (--i >= 0)
2157 		platform_device_unregister(priv->pdev_mux[i]);
2158 	platform_device_unregister(priv->pdev_i2c);
2159 fail_alloc:
2160 	platform_device_unregister(mlxplat_dev);
2161 
2162 	return err;
2163 }
2164 module_init(mlxplat_init);
2165 
2166 static void __exit mlxplat_exit(void)
2167 {
2168 	struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
2169 	int i;
2170 
2171 	for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
2172 		platform_device_unregister(priv->pdev_wd[i]);
2173 	if (priv->pdev_fan)
2174 		platform_device_unregister(priv->pdev_fan);
2175 	if (priv->pdev_io_regs)
2176 		platform_device_unregister(priv->pdev_io_regs);
2177 	platform_device_unregister(priv->pdev_led);
2178 	platform_device_unregister(priv->pdev_hotplug);
2179 
2180 	for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
2181 		platform_device_unregister(priv->pdev_mux[i]);
2182 
2183 	platform_device_unregister(priv->pdev_i2c);
2184 	platform_device_unregister(mlxplat_dev);
2185 }
2186 module_exit(mlxplat_exit);
2187 
2188 MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
2189 MODULE_DESCRIPTION("Mellanox platform driver");
2190 MODULE_LICENSE("Dual BSD/GPL");
2191