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