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