2 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
3 * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
34 #include <linux/device.h>
35 #include <linux/dmi.h>
36 #include <linux/i2c.h>
37 #include <linux/i2c-mux.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>
45 #define MLX_PLAT_DEVICE_NAME "mlxplat"
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
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)
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)
123 /* Default I2C parent bus number */
124 #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
126 /* Maximum number of possible physical buses equipped on system */
127 #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16
129 /* Number of channels in group */
130 #define MLXPLAT_CPLD_GRP_CHNL_NUM 8
132 /* Start channel numbers */
133 #define MLXPLAT_CPLD_CH1 2
134 #define MLXPLAT_CPLD_CH2 10
136 /* Number of LPC attached MUX platform devices */
137 #define MLXPLAT_CPLD_LPC_MUX_DEVS 2
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
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
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
;
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",
176 /* Platform default channels */
177 static const int mlxplat_default_channels
[][MLXPLAT_CPLD_GRP_CHNL_NUM
] = {
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
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
190 /* Platform channels for MSN21xx system family */
191 static const int mlxplat_msn21xx_channels
[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
193 /* Platform mux data */
194 static struct i2c_mux_reg_platform_data mlxplat_mux_data
[] = {
197 .base_nr
= MLXPLAT_CPLD_CH1
,
199 .reg
= (void __iomem
*)MLXPLAT_CPLD_LPC_REG1
,
205 .base_nr
= MLXPLAT_CPLD_CH2
,
207 .reg
= (void __iomem
*)MLXPLAT_CPLD_LPC_REG2
,
214 /* Platform hotplug devices */
215 static struct i2c_board_info mlxplat_mlxcpld_psu
[] = {
217 I2C_BOARD_INFO("24c02", 0x51),
220 I2C_BOARD_INFO("24c02", 0x50),
224 static struct i2c_board_info mlxplat_mlxcpld_ng_psu
[] = {
226 I2C_BOARD_INFO("24c32", 0x51),
229 I2C_BOARD_INFO("24c32", 0x50),
233 static struct i2c_board_info mlxplat_mlxcpld_pwr
[] = {
235 I2C_BOARD_INFO("dps460", 0x59),
238 I2C_BOARD_INFO("dps460", 0x58),
242 static struct i2c_board_info mlxplat_mlxcpld_fan
[] = {
244 I2C_BOARD_INFO("24c32", 0x50),
247 I2C_BOARD_INFO("24c32", 0x50),
250 I2C_BOARD_INFO("24c32", 0x50),
253 I2C_BOARD_INFO("24c32", 0x50),
257 /* Platform hotplug default data */
258 static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data
[] = {
261 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
263 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[0],
264 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
268 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
270 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[1],
271 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
275 static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data
[] = {
278 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
280 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[0],
281 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
285 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
287 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[1],
288 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
292 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data
[] = {
295 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
297 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[0],
298 .hpdev
.nr
= MLXPLAT_CPLD_FAN1_DEFAULT_NR
,
302 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
304 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[1],
305 .hpdev
.nr
= MLXPLAT_CPLD_FAN2_DEFAULT_NR
,
309 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
311 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[2],
312 .hpdev
.nr
= MLXPLAT_CPLD_FAN3_DEFAULT_NR
,
316 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
318 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[3],
319 .hpdev
.nr
= MLXPLAT_CPLD_FAN4_DEFAULT_NR
,
323 static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data
[] = {
326 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
327 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
328 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
332 static struct mlxreg_core_item mlxplat_mlxcpld_default_items
[] = {
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
),
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
),
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
),
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
),
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
,
381 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data
[] = {
384 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
386 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
390 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
392 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
396 /* Platform hotplug MSN21xx system family data */
397 static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items
[] = {
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
),
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
),
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
,
428 /* Platform hotplug msn274x system family data */
429 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data
[] = {
432 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
434 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[0],
435 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
439 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
441 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[1],
442 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
446 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data
[] = {
449 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
451 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[0],
452 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
456 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
458 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[1],
459 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
463 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data
[] = {
466 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
468 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
472 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
474 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
478 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
480 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
484 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
486 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
490 static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items
[] = {
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
),
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
),
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
),
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
),
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
,
539 /* Platform hotplug MSN201x system family data */
540 static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data
[] = {
543 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
545 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
549 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
551 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
555 static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items
[] = {
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
),
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
),
577 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data
= {
578 .items
= mlxplat_mlxcpld_msn21xx_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
,
586 /* Platform hotplug next generation system family data */
587 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data
[] = {
590 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
592 .hpdev
.brdinfo
= &mlxplat_mlxcpld_ng_psu
[0],
593 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
597 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
599 .hpdev
.brdinfo
= &mlxplat_mlxcpld_ng_psu
[1],
600 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
604 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data
[] = {
607 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
609 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
613 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
615 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
619 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
621 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
625 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
627 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
631 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
633 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
637 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
639 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
643 static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items
[] = {
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
),
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
),
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
),
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
),
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
,
692 /* Platform led default data */
693 static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data
[] = {
695 .label
= "status:green",
696 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
697 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
700 .label
= "status:red",
701 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
702 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
705 .label
= "psu:green",
706 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
707 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
711 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
712 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
715 .label
= "fan1:green",
716 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
717 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
721 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
722 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
725 .label
= "fan2:green",
726 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
727 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
731 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
732 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
735 .label
= "fan3:green",
736 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
737 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
741 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
742 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
745 .label
= "fan4:green",
746 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
747 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
751 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
752 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
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
),
761 /* Platform led MSN21xx system family data */
762 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data
[] = {
764 .label
= "status:green",
765 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
766 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
769 .label
= "status:red",
770 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
771 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
774 .label
= "fan:green",
775 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
776 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
780 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
781 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
784 .label
= "psu1:green",
785 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
786 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
790 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
791 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
794 .label
= "psu2:green",
795 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
796 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
800 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
801 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
805 .reg
= MLXPLAT_CPLD_LPC_REG_LED5_OFFSET
,
806 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
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
),
815 /* Platform led for default data for 200GbE systems */
816 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data
[] = {
818 .label
= "status:green",
819 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
820 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
823 .label
= "status:orange",
824 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
825 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
828 .label
= "psu:green",
829 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
830 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
833 .label
= "psu:orange",
834 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
835 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
838 .label
= "fan1:green",
839 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
840 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
843 .label
= "fan1:orange",
844 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
845 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
848 .label
= "fan2:green",
849 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
850 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
853 .label
= "fan2:orange",
854 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
855 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
858 .label
= "fan3:green",
859 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
860 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
863 .label
= "fan3:orange",
864 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
865 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
868 .label
= "fan4:green",
869 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
870 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
873 .label
= "fan4:orange",
874 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
875 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
878 .label
= "fan5:green",
879 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
880 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
883 .label
= "fan5:orange",
884 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
885 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
888 .label
= "fan6:green",
889 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
890 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
893 .label
= "fan6:orange",
894 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
895 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
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
),
904 /* Platform register access default */
905 static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data
[] = {
907 .label
= "cpld1_version",
908 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
,
909 .bit
= GENMASK(7, 0),
913 .label
= "cpld2_version",
914 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
,
915 .bit
= GENMASK(7, 0),
919 .label
= "reset_long_pb",
920 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
921 .mask
= GENMASK(7, 0) & ~BIT(0),
925 .label
= "reset_short_pb",
926 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
927 .mask
= GENMASK(7, 0) & ~BIT(1),
931 .label
= "reset_aux_pwr_or_ref",
932 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
933 .mask
= GENMASK(7, 0) & ~BIT(2),
937 .label
= "reset_main_pwr_fail",
938 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
939 .mask
= GENMASK(7, 0) & ~BIT(3),
943 .label
= "reset_sw_reset",
944 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
945 .mask
= GENMASK(7, 0) & ~BIT(4),
949 .label
= "reset_fw_reset",
950 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
951 .mask
= GENMASK(7, 0) & ~BIT(5),
955 .label
= "reset_hotswap_or_wd",
956 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
957 .mask
= GENMASK(7, 0) & ~BIT(6),
961 .label
= "reset_asic_thermal",
962 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
963 .mask
= GENMASK(7, 0) & ~BIT(7),
968 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
969 .mask
= GENMASK(7, 0) & ~BIT(0),
974 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
975 .mask
= GENMASK(7, 0) & ~BIT(1),
979 .label
= "pwr_cycle",
980 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
981 .mask
= GENMASK(7, 0) & ~BIT(2),
986 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
987 .mask
= GENMASK(7, 0) & ~BIT(3),
991 .label
= "select_iio",
992 .reg
= MLXPLAT_CPLD_LPC_REG_GP2_OFFSET
,
993 .mask
= GENMASK(7, 0) & ~BIT(6),
997 .label
= "asic_health",
998 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
999 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
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
),
1010 /* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
1011 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data
[] = {
1013 .label
= "cpld1_version",
1014 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
,
1015 .bit
= GENMASK(7, 0),
1019 .label
= "cpld2_version",
1020 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
,
1021 .bit
= GENMASK(7, 0),
1025 .label
= "reset_long_pb",
1026 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1027 .mask
= GENMASK(7, 0) & ~BIT(0),
1031 .label
= "reset_short_pb",
1032 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1033 .mask
= GENMASK(7, 0) & ~BIT(1),
1037 .label
= "reset_aux_pwr_or_ref",
1038 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1039 .mask
= GENMASK(7, 0) & ~BIT(2),
1043 .label
= "reset_sw_reset",
1044 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1045 .mask
= GENMASK(7, 0) & ~BIT(3),
1049 .label
= "reset_main_pwr_fail",
1050 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1051 .mask
= GENMASK(7, 0) & ~BIT(4),
1055 .label
= "reset_asic_thermal",
1056 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1057 .mask
= GENMASK(7, 0) & ~BIT(5),
1061 .label
= "reset_hotswap_or_halt",
1062 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1063 .mask
= GENMASK(7, 0) & ~BIT(6),
1068 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1069 .mask
= GENMASK(7, 0) & ~BIT(0),
1074 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1075 .mask
= GENMASK(7, 0) & ~BIT(1),
1079 .label
= "pwr_cycle",
1080 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1081 .mask
= GENMASK(7, 0) & ~BIT(2),
1085 .label
= "pwr_down",
1086 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1087 .mask
= GENMASK(7, 0) & ~BIT(3),
1091 .label
= "asic_health",
1092 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
1093 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
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
),
1104 /* Platform FAN default */
1105 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data
[] = {
1108 .reg
= MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET
,
1112 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET
,
1113 .mask
= GENMASK(7, 0),
1117 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET
,
1118 .mask
= GENMASK(7, 0),
1122 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET
,
1123 .mask
= GENMASK(7, 0),
1127 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET
,
1128 .mask
= GENMASK(7, 0),
1132 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET
,
1133 .mask
= GENMASK(7, 0),
1137 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET
,
1138 .mask
= GENMASK(7, 0),
1142 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET
,
1143 .mask
= GENMASK(7, 0),
1147 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET
,
1148 .mask
= GENMASK(7, 0),
1152 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET
,
1153 .mask
= GENMASK(7, 0),
1157 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET
,
1158 .mask
= GENMASK(7, 0),
1162 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET
,
1163 .mask
= GENMASK(7, 0),
1167 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET
,
1168 .mask
= GENMASK(7, 0),
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
),
1177 static bool mlxplat_mlxcpld_writeable_reg(struct device
*dev
, unsigned int 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
:
1206 static bool mlxplat_mlxcpld_readable_reg(struct device
*dev
, unsigned int 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
:
1256 static bool mlxplat_mlxcpld_volatile_reg(struct device
*dev
, unsigned int 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
:
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 },
1310 struct mlxplat_mlxcpld_regmap_context
{
1314 static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx
;
1317 mlxplat_mlxcpld_reg_read(void *context
, unsigned int reg
, unsigned int *val
)
1319 struct mlxplat_mlxcpld_regmap_context
*ctx
= context
;
1321 *val
= ioread8(ctx
->base
+ reg
);
1326 mlxplat_mlxcpld_reg_write(void *context
, unsigned int reg
, unsigned int val
)
1328 struct mlxplat_mlxcpld_regmap_context
*ctx
= context
;
1330 iowrite8(val
, ctx
->base
+ reg
);
1334 static const struct regmap_config mlxplat_mlxcpld_regmap_config
= {
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
,
1348 static struct resource mlxplat_mlxcpld_resources
[] = {
1349 [0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
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
;
1358 static int __init
mlxplat_dmi_default_matched(const struct dmi_system_id
*dmi
)
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
]);
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
;
1376 static int __init
mlxplat_dmi_msn21xx_matched(const struct dmi_system_id
*dmi
)
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
);
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
;
1394 static int __init
mlxplat_dmi_msn274x_matched(const struct dmi_system_id
*dmi
)
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
);
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
;
1412 static int __init
mlxplat_dmi_msn201x_matched(const struct dmi_system_id
*dmi
)
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
);
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
;
1430 static int __init
mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id
*dmi
)
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
);
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
;
1448 static const struct dmi_system_id mlxplat_dmi_table
[] __initconst
= {
1450 .callback
= mlxplat_dmi_msn274x_matched
,
1452 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1453 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN274"),
1457 .callback
= mlxplat_dmi_default_matched
,
1459 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1460 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN24"),
1464 .callback
= mlxplat_dmi_default_matched
,
1466 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1467 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN27"),
1471 .callback
= mlxplat_dmi_default_matched
,
1473 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1474 DMI_MATCH(DMI_PRODUCT_NAME
, "MSB"),
1478 .callback
= mlxplat_dmi_default_matched
,
1480 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1481 DMI_MATCH(DMI_PRODUCT_NAME
, "MSX"),
1485 .callback
= mlxplat_dmi_msn21xx_matched
,
1487 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1488 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN21"),
1492 .callback
= mlxplat_dmi_msn201x_matched
,
1494 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1495 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN201"),
1499 .callback
= mlxplat_dmi_qmb7xx_matched
,
1501 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1502 DMI_MATCH(DMI_PRODUCT_NAME
, "QMB7"),
1506 .callback
= mlxplat_dmi_qmb7xx_matched
,
1508 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1509 DMI_MATCH(DMI_PRODUCT_NAME
, "SN37"),
1513 .callback
= mlxplat_dmi_qmb7xx_matched
,
1515 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1516 DMI_MATCH(DMI_PRODUCT_NAME
, "SN34"),
1520 .callback
= mlxplat_dmi_default_matched
,
1522 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0001"),
1526 .callback
= mlxplat_dmi_msn21xx_matched
,
1528 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0002"),
1532 .callback
= mlxplat_dmi_msn274x_matched
,
1534 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0003"),
1538 .callback
= mlxplat_dmi_msn201x_matched
,
1540 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0004"),
1544 .callback
= mlxplat_dmi_qmb7xx_matched
,
1546 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0005"),
1552 MODULE_DEVICE_TABLE(dmi
, mlxplat_dmi_table
);
1554 static int mlxplat_mlxcpld_verify_bus_topology(int *nr
)
1556 struct i2c_adapter
*search_adap
;
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
);
1565 i2c_put_adapter(search_adap
);
1569 /* Return if expected parent adapter is free. */
1570 if (i
== MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR
)
1575 /* Return with error if free id for adapter is not found. */
1576 if (i
== MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM
)
1579 /* Shift adapter ids, since expected parent adapter is not free. */
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
;
1586 mlxplat_hotplug
->shift_nr
= shift
;
1592 static int __init
mlxplat_init(void)
1594 struct mlxplat_priv
*priv
;
1597 if (!dmi_check_system(mlxplat_dmi_table
))
1600 mlxplat_dev
= platform_device_register_simple(MLX_PLAT_DEVICE_NAME
, -1,
1601 mlxplat_lpc_resources
,
1602 ARRAY_SIZE(mlxplat_lpc_resources
));
1604 if (IS_ERR(mlxplat_dev
))
1605 return PTR_ERR(mlxplat_dev
);
1607 priv
= devm_kzalloc(&mlxplat_dev
->dev
, sizeof(struct mlxplat_priv
),
1613 platform_set_drvdata(mlxplat_dev
, priv
);
1615 err
= mlxplat_mlxcpld_verify_bus_topology(&nr
);
1619 nr
= (nr
== MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM
) ? -1 : nr
;
1620 priv
->pdev_i2c
= platform_device_register_simple("i2c_mlxcpld", nr
,
1622 if (IS_ERR(priv
->pdev_i2c
)) {
1623 err
= PTR_ERR(priv
->pdev_i2c
);
1627 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1628 priv
->pdev_mux
[i
] = platform_device_register_resndata(
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
;
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
) {
1643 goto fail_platform_mux_register
;
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
;
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
;
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
);
1671 goto fail_platform_mux_register
;
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
;
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,
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
;
1699 /* Add FAN driver. */
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,
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
;
1713 /* Sync registers with hardware. */
1714 regcache_mark_dirty(mlxplat_hotplug
->regmap
);
1715 err
= regcache_sync(mlxplat_hotplug
->regmap
);
1717 goto fail_platform_fan_register
;
1721 fail_platform_fan_register
:
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
:
1733 platform_device_unregister(priv
->pdev_mux
[i
]);
1734 platform_device_unregister(priv
->pdev_i2c
);
1736 platform_device_unregister(mlxplat_dev
);
1740 module_init(mlxplat_init
);
1742 static void __exit
mlxplat_exit(void)
1744 struct mlxplat_priv
*priv
= platform_get_drvdata(mlxplat_dev
);
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
);
1754 for (i
= ARRAY_SIZE(mlxplat_mux_data
) - 1; i
>= 0 ; i
--)
1755 platform_device_unregister(priv
->pdev_mux
[i
]);
1757 platform_device_unregister(priv
->pdev_i2c
);
1758 platform_device_unregister(mlxplat_dev
);
1760 module_exit(mlxplat_exit
);
1762 MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
1763 MODULE_DESCRIPTION("Mellanox platform driver");
1764 MODULE_LICENSE("Dual BSD/GPL");