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