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