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