1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
3 * Mellanox platform driver
5 * Copyright (C) 2016-2018 Mellanox Technologies
6 * Copyright (C) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
9 #include <linux/device.h>
10 #include <linux/dmi.h>
11 #include <linux/i2c.h>
12 #include <linux/i2c-mux.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/platform_data/i2c-mux-reg.h>
17 #include <linux/platform_data/mlxreg.h>
18 #include <linux/regmap.h>
20 #define MLX_PLAT_DEVICE_NAME "mlxplat"
22 /* LPC bus IO offsets */
23 #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
24 #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
25 #define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00
26 #define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01
27 #define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02
28 #define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET 0x03
29 #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d
30 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e
31 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f
32 #define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET 0x20
33 #define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET 0x21
34 #define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22
35 #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23
36 #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24
37 #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION 0x2a
38 #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET 0x30
39 #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
40 #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
41 #define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33
42 #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37
43 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
44 #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
45 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
46 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41
47 #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
48 #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET 0x51
49 #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET 0x52
50 #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET 0x58
51 #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET 0x59
52 #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET 0x5a
53 #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET 0x64
54 #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET 0x65
55 #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET 0x66
56 #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
57 #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
58 #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
59 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET 0xc7
60 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET 0xc8
61 #define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET 0xc9
62 #define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET 0xcb
63 #define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET 0xcd
64 #define MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET 0xce
65 #define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET 0xcf
66 #define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET 0xd1
67 #define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET 0xd2
68 #define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd3
69 #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
70 #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
71 #define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
72 #define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET 0xe6
73 #define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET 0xe7
74 #define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET 0xe8
75 #define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET 0xe9
76 #define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET 0xeb
77 #define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET 0xec
78 #define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET 0xed
79 #define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xee
80 #define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xef
81 #define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xf0
82 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET 0xf5
83 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET 0xf6
84 #define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET 0xf7
85 #define MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET 0xf8
86 #define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
87 #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
88 #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
90 #define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL
91 #define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
92 MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
93 MLXPLAT_CPLD_LPC_PIO_OFFSET)
94 #define MLXPLAT_CPLD_LPC_REG2 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
95 MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \
96 MLXPLAT_CPLD_LPC_PIO_OFFSET)
98 /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
99 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF 0x04
100 #define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF 0x08
101 #define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF 0x08
102 #define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF 0x40
103 #define MLXPLAT_CPLD_AGGR_MASK_DEF (MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
104 MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
105 MLXPLAT_CPLD_AGGR_FAN_MASK_DEF)
106 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG 0x01
107 #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF 0x04
108 #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1
109 #define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0)
110 #define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0)
111 #define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0)
112 #define MLXPLAT_CPLD_ASIC_MASK GENMASK(1, 0)
113 #define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(5, 0)
114 #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4)
115 #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0)
117 /* Default I2C parent bus number */
118 #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
120 /* Maximum number of possible physical buses equipped on system */
121 #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16
123 /* Number of channels in group */
124 #define MLXPLAT_CPLD_GRP_CHNL_NUM 8
126 /* Start channel numbers */
127 #define MLXPLAT_CPLD_CH1 2
128 #define MLXPLAT_CPLD_CH2 10
130 /* Number of LPC attached MUX platform devices */
131 #define MLXPLAT_CPLD_LPC_MUX_DEVS 2
133 /* Hotplug devices adapter numbers */
134 #define MLXPLAT_CPLD_NR_NONE -1
135 #define MLXPLAT_CPLD_PSU_DEFAULT_NR 10
136 #define MLXPLAT_CPLD_PSU_MSNXXXX_NR 4
137 #define MLXPLAT_CPLD_FAN1_DEFAULT_NR 11
138 #define MLXPLAT_CPLD_FAN2_DEFAULT_NR 12
139 #define MLXPLAT_CPLD_FAN3_DEFAULT_NR 13
140 #define MLXPLAT_CPLD_FAN4_DEFAULT_NR 14
142 /* Masks and default values for watchdogs */
143 #define MLXPLAT_CPLD_WD1_CLEAR_MASK GENMASK(7, 1)
144 #define MLXPLAT_CPLD_WD2_CLEAR_MASK (GENMASK(7, 0) & ~BIT(1))
146 #define MLXPLAT_CPLD_WD_TYPE1_TO_MASK GENMASK(7, 4)
147 #define MLXPLAT_CPLD_WD_TYPE2_TO_MASK 0
148 #define MLXPLAT_CPLD_WD_RESET_ACT_MASK GENMASK(7, 1)
149 #define MLXPLAT_CPLD_WD_FAN_ACT_MASK (GENMASK(7, 0) & ~BIT(4))
150 #define MLXPLAT_CPLD_WD_COUNT_ACT_MASK (GENMASK(7, 0) & ~BIT(7))
151 #define MLXPLAT_CPLD_WD_DFLT_TIMEOUT 30
152 #define MLXPLAT_CPLD_WD_MAX_DEVS 2
154 /* mlxplat_priv - platform private data
155 * @pdev_i2c - i2c controller platform device
156 * @pdev_mux - array of mux platform devices
157 * @pdev_hotplug - hotplug platform devices
158 * @pdev_led - led platform devices
159 * @pdev_io_regs - register access platform devices
160 * @pdev_fan - FAN platform devices
161 * @pdev_wd - array of watchdog platform devices
163 struct mlxplat_priv
{
164 struct platform_device
*pdev_i2c
;
165 struct platform_device
*pdev_mux
[MLXPLAT_CPLD_LPC_MUX_DEVS
];
166 struct platform_device
*pdev_hotplug
;
167 struct platform_device
*pdev_led
;
168 struct platform_device
*pdev_io_regs
;
169 struct platform_device
*pdev_fan
;
170 struct platform_device
*pdev_wd
[MLXPLAT_CPLD_WD_MAX_DEVS
];
173 /* Regions for LPC I2C controller and LPC base register space */
174 static const struct resource mlxplat_lpc_resources
[] = {
175 [0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR
,
176 MLXPLAT_CPLD_LPC_IO_RANGE
,
177 "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO
),
178 [1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR
,
179 MLXPLAT_CPLD_LPC_IO_RANGE
,
180 "mlxplat_cpld_lpc_regs",
184 /* Platform default channels */
185 static const int mlxplat_default_channels
[][MLXPLAT_CPLD_GRP_CHNL_NUM
] = {
187 MLXPLAT_CPLD_CH1
, MLXPLAT_CPLD_CH1
+ 1, MLXPLAT_CPLD_CH1
+ 2,
188 MLXPLAT_CPLD_CH1
+ 3, MLXPLAT_CPLD_CH1
+ 4, MLXPLAT_CPLD_CH1
+
189 5, MLXPLAT_CPLD_CH1
+ 6, MLXPLAT_CPLD_CH1
+ 7
192 MLXPLAT_CPLD_CH2
, MLXPLAT_CPLD_CH2
+ 1, MLXPLAT_CPLD_CH2
+ 2,
193 MLXPLAT_CPLD_CH2
+ 3, MLXPLAT_CPLD_CH2
+ 4, MLXPLAT_CPLD_CH2
+
194 5, MLXPLAT_CPLD_CH2
+ 6, MLXPLAT_CPLD_CH2
+ 7
198 /* Platform channels for MSN21xx system family */
199 static const int mlxplat_msn21xx_channels
[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
201 /* Platform mux data */
202 static struct i2c_mux_reg_platform_data mlxplat_mux_data
[] = {
205 .base_nr
= MLXPLAT_CPLD_CH1
,
207 .reg
= (void __iomem
*)MLXPLAT_CPLD_LPC_REG1
,
213 .base_nr
= MLXPLAT_CPLD_CH2
,
215 .reg
= (void __iomem
*)MLXPLAT_CPLD_LPC_REG2
,
222 /* Platform hotplug devices */
223 static struct i2c_board_info mlxplat_mlxcpld_psu
[] = {
225 I2C_BOARD_INFO("24c02", 0x51),
228 I2C_BOARD_INFO("24c02", 0x50),
232 static struct i2c_board_info mlxplat_mlxcpld_ng_psu
[] = {
234 I2C_BOARD_INFO("24c32", 0x51),
237 I2C_BOARD_INFO("24c32", 0x50),
241 static struct i2c_board_info mlxplat_mlxcpld_pwr
[] = {
243 I2C_BOARD_INFO("dps460", 0x59),
246 I2C_BOARD_INFO("dps460", 0x58),
250 static struct i2c_board_info mlxplat_mlxcpld_fan
[] = {
252 I2C_BOARD_INFO("24c32", 0x50),
255 I2C_BOARD_INFO("24c32", 0x50),
258 I2C_BOARD_INFO("24c32", 0x50),
261 I2C_BOARD_INFO("24c32", 0x50),
265 /* Platform hotplug default data */
266 static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data
[] = {
269 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
271 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[0],
272 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
276 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
278 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[1],
279 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
283 static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data
[] = {
286 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
288 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[0],
289 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
293 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
295 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[1],
296 .hpdev
.nr
= MLXPLAT_CPLD_PSU_DEFAULT_NR
,
300 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data
[] = {
303 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
305 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[0],
306 .hpdev
.nr
= MLXPLAT_CPLD_FAN1_DEFAULT_NR
,
310 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
312 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[1],
313 .hpdev
.nr
= MLXPLAT_CPLD_FAN2_DEFAULT_NR
,
317 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
319 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[2],
320 .hpdev
.nr
= MLXPLAT_CPLD_FAN3_DEFAULT_NR
,
324 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
326 .hpdev
.brdinfo
= &mlxplat_mlxcpld_fan
[3],
327 .hpdev
.nr
= MLXPLAT_CPLD_FAN4_DEFAULT_NR
,
331 static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data
[] = {
334 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
335 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
336 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
340 static struct mlxreg_core_item mlxplat_mlxcpld_default_items
[] = {
342 .data
= mlxplat_mlxcpld_default_psu_items_data
,
343 .aggr_mask
= MLXPLAT_CPLD_AGGR_PSU_MASK_DEF
,
344 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
345 .mask
= MLXPLAT_CPLD_PSU_MASK
,
346 .count
= ARRAY_SIZE(mlxplat_mlxcpld_psu
),
351 .data
= mlxplat_mlxcpld_default_pwr_items_data
,
352 .aggr_mask
= MLXPLAT_CPLD_AGGR_PWR_MASK_DEF
,
353 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
354 .mask
= MLXPLAT_CPLD_PWR_MASK
,
355 .count
= ARRAY_SIZE(mlxplat_mlxcpld_pwr
),
360 .data
= mlxplat_mlxcpld_default_fan_items_data
,
361 .aggr_mask
= MLXPLAT_CPLD_AGGR_FAN_MASK_DEF
,
362 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
363 .mask
= MLXPLAT_CPLD_FAN_MASK
,
364 .count
= ARRAY_SIZE(mlxplat_mlxcpld_fan
),
369 .data
= mlxplat_mlxcpld_default_asic_items_data
,
370 .aggr_mask
= MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF
,
371 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
372 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
373 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data
),
380 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data
= {
381 .items
= mlxplat_mlxcpld_default_items
,
382 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_items
),
383 .cell
= MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
,
384 .mask
= MLXPLAT_CPLD_AGGR_MASK_DEF
,
385 .cell_low
= MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
,
386 .mask_low
= MLXPLAT_CPLD_LOW_AGGR_MASK_LOW
,
389 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data
[] = {
392 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
394 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
398 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
400 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
404 /* Platform hotplug MSN21xx system family data */
405 static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items
[] = {
407 .data
= mlxplat_mlxcpld_msn21xx_pwr_items_data
,
408 .aggr_mask
= MLXPLAT_CPLD_AGGR_PWR_MASK_DEF
,
409 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
410 .mask
= MLXPLAT_CPLD_PWR_MASK
,
411 .count
= ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_pwr_items_data
),
416 .data
= mlxplat_mlxcpld_default_asic_items_data
,
417 .aggr_mask
= MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF
,
418 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
419 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
420 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data
),
427 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data
= {
428 .items
= mlxplat_mlxcpld_msn21xx_items
,
429 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items
),
430 .cell
= MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
,
431 .mask
= MLXPLAT_CPLD_AGGR_MASK_DEF
,
432 .cell_low
= MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
,
433 .mask_low
= MLXPLAT_CPLD_LOW_AGGR_MASK_LOW
,
436 /* Platform hotplug msn274x system family data */
437 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data
[] = {
440 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
442 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[0],
443 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
447 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
449 .hpdev
.brdinfo
= &mlxplat_mlxcpld_psu
[1],
450 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
454 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data
[] = {
457 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
459 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[0],
460 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
464 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
466 .hpdev
.brdinfo
= &mlxplat_mlxcpld_pwr
[1],
467 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
471 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data
[] = {
474 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
476 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
480 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
482 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
486 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
488 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
492 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
494 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
498 static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items
[] = {
500 .data
= mlxplat_mlxcpld_msn274x_psu_items_data
,
501 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
502 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
503 .mask
= MLXPLAT_CPLD_PSU_MASK
,
504 .count
= ARRAY_SIZE(mlxplat_mlxcpld_msn274x_psu_items_data
),
509 .data
= mlxplat_mlxcpld_default_ng_pwr_items_data
,
510 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
511 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
512 .mask
= MLXPLAT_CPLD_PWR_MASK
,
513 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data
),
518 .data
= mlxplat_mlxcpld_msn274x_fan_items_data
,
519 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
520 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
521 .mask
= MLXPLAT_CPLD_FAN_MASK
,
522 .count
= ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data
),
527 .data
= mlxplat_mlxcpld_default_asic_items_data
,
528 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
529 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
530 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
531 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data
),
538 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data
= {
539 .items
= mlxplat_mlxcpld_msn274x_items
,
540 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items
),
541 .cell
= MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
,
542 .mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
543 .cell_low
= MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
,
544 .mask_low
= MLXPLAT_CPLD_LOW_AGGR_MASK_LOW
,
547 /* Platform hotplug MSN201x system family data */
548 static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data
[] = {
551 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
553 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
557 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
559 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
563 static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items
[] = {
565 .data
= mlxplat_mlxcpld_msn201x_pwr_items_data
,
566 .aggr_mask
= MLXPLAT_CPLD_AGGR_PWR_MASK_DEF
,
567 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
568 .mask
= MLXPLAT_CPLD_PWR_MASK
,
569 .count
= ARRAY_SIZE(mlxplat_mlxcpld_msn201x_pwr_items_data
),
574 .data
= mlxplat_mlxcpld_default_asic_items_data
,
575 .aggr_mask
= MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF
,
576 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
577 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
578 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data
),
585 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data
= {
586 .items
= mlxplat_mlxcpld_msn201x_items
,
587 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items
),
588 .cell
= MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
,
589 .mask
= MLXPLAT_CPLD_AGGR_MASK_DEF
,
590 .cell_low
= MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
,
591 .mask_low
= MLXPLAT_CPLD_LOW_AGGR_MASK_LOW
,
594 /* Platform hotplug next generation system family data */
595 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data
[] = {
598 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
600 .hpdev
.brdinfo
= &mlxplat_mlxcpld_ng_psu
[0],
601 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
605 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
607 .hpdev
.brdinfo
= &mlxplat_mlxcpld_ng_psu
[1],
608 .hpdev
.nr
= MLXPLAT_CPLD_PSU_MSNXXXX_NR
,
612 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data
[] = {
615 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
617 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
619 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
623 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
625 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
627 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
631 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
633 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
635 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
639 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
641 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
643 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
647 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
649 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
651 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
655 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
657 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
659 .hpdev
.nr
= MLXPLAT_CPLD_NR_NONE
,
663 static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items
[] = {
665 .data
= mlxplat_mlxcpld_default_ng_psu_items_data
,
666 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
667 .reg
= MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
,
668 .mask
= MLXPLAT_CPLD_PSU_MASK
,
669 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data
),
674 .data
= mlxplat_mlxcpld_default_ng_pwr_items_data
,
675 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
676 .reg
= MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
,
677 .mask
= MLXPLAT_CPLD_PWR_MASK
,
678 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data
),
683 .data
= mlxplat_mlxcpld_default_ng_fan_items_data
,
684 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
685 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
,
686 .mask
= MLXPLAT_CPLD_FAN_NG_MASK
,
687 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data
),
692 .data
= mlxplat_mlxcpld_default_asic_items_data
,
693 .aggr_mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
694 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
695 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
696 .count
= ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data
),
703 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data
= {
704 .items
= mlxplat_mlxcpld_default_ng_items
,
705 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items
),
706 .cell
= MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
,
707 .mask
= MLXPLAT_CPLD_AGGR_MASK_NG_DEF
,
708 .cell_low
= MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
,
709 .mask_low
= MLXPLAT_CPLD_LOW_AGGR_MASK_LOW
,
712 /* Platform led default data */
713 static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data
[] = {
715 .label
= "status:green",
716 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
717 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
720 .label
= "status:red",
721 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
722 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
725 .label
= "psu:green",
726 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
727 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
731 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
732 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
735 .label
= "fan1:green",
736 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
737 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
741 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
742 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
745 .label
= "fan2:green",
746 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
747 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
751 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
752 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
755 .label
= "fan3:green",
756 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
757 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
761 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
762 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
765 .label
= "fan4:green",
766 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
767 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
771 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
772 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
776 static struct mlxreg_core_platform_data mlxplat_default_led_data
= {
777 .data
= mlxplat_mlxcpld_default_led_data
,
778 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_led_data
),
781 /* Platform led MSN21xx system family data */
782 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data
[] = {
784 .label
= "status:green",
785 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
786 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
789 .label
= "status:red",
790 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
791 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
794 .label
= "fan:green",
795 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
796 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
800 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
801 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
804 .label
= "psu1:green",
805 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
806 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
810 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
811 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
814 .label
= "psu2:green",
815 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
816 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
820 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
821 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
825 .reg
= MLXPLAT_CPLD_LPC_REG_LED5_OFFSET
,
826 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
830 static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data
= {
831 .data
= mlxplat_mlxcpld_msn21xx_led_data
,
832 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data
),
835 /* Platform led for default data for 200GbE systems */
836 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data
[] = {
838 .label
= "status:green",
839 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
840 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
843 .label
= "status:orange",
844 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
845 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
848 .label
= "psu:green",
849 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
850 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
853 .label
= "psu:orange",
854 .reg
= MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
,
855 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
858 .label
= "fan1:green",
859 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
860 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
861 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
865 .label
= "fan1:orange",
866 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
867 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
868 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
872 .label
= "fan2:green",
873 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
874 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
875 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
879 .label
= "fan2:orange",
880 .reg
= MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
,
881 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
882 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
886 .label
= "fan3:green",
887 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
888 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
889 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
893 .label
= "fan3:orange",
894 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
895 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
896 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
900 .label
= "fan4:green",
901 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
902 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
903 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
907 .label
= "fan4:orange",
908 .reg
= MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
,
909 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
910 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
914 .label
= "fan5:green",
915 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
916 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
917 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
921 .label
= "fan5:orange",
922 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
923 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
924 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
928 .label
= "fan6:green",
929 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
930 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
931 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
935 .label
= "fan6:orange",
936 .reg
= MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
,
937 .mask
= MLXPLAT_CPLD_LED_HI_NIBBLE_MASK
,
938 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
,
943 .reg
= MLXPLAT_CPLD_LPC_REG_LED5_OFFSET
,
944 .mask
= MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
,
948 static struct mlxreg_core_platform_data mlxplat_default_ng_led_data
= {
949 .data
= mlxplat_mlxcpld_default_ng_led_data
,
950 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data
),
953 /* Platform register access default */
954 static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data
[] = {
956 .label
= "cpld1_version",
957 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
,
958 .bit
= GENMASK(7, 0),
962 .label
= "cpld2_version",
963 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
,
964 .bit
= GENMASK(7, 0),
968 .label
= "reset_long_pb",
969 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
970 .mask
= GENMASK(7, 0) & ~BIT(0),
974 .label
= "reset_short_pb",
975 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
976 .mask
= GENMASK(7, 0) & ~BIT(1),
980 .label
= "reset_aux_pwr_or_ref",
981 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
982 .mask
= GENMASK(7, 0) & ~BIT(2),
986 .label
= "reset_main_pwr_fail",
987 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
988 .mask
= GENMASK(7, 0) & ~BIT(3),
992 .label
= "reset_sw_reset",
993 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
994 .mask
= GENMASK(7, 0) & ~BIT(4),
998 .label
= "reset_fw_reset",
999 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1000 .mask
= GENMASK(7, 0) & ~BIT(5),
1004 .label
= "reset_hotswap_or_wd",
1005 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1006 .mask
= GENMASK(7, 0) & ~BIT(6),
1010 .label
= "reset_asic_thermal",
1011 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1012 .mask
= GENMASK(7, 0) & ~BIT(7),
1017 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1018 .mask
= GENMASK(7, 0) & ~BIT(0),
1023 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1024 .mask
= GENMASK(7, 0) & ~BIT(1),
1028 .label
= "pwr_cycle",
1029 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1030 .mask
= GENMASK(7, 0) & ~BIT(2),
1034 .label
= "pwr_down",
1035 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1036 .mask
= GENMASK(7, 0) & ~BIT(3),
1040 .label
= "select_iio",
1041 .reg
= MLXPLAT_CPLD_LPC_REG_GP2_OFFSET
,
1042 .mask
= GENMASK(7, 0) & ~BIT(6),
1046 .label
= "asic_health",
1047 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
1048 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
1054 static struct mlxreg_core_platform_data mlxplat_default_regs_io_data
= {
1055 .data
= mlxplat_mlxcpld_default_regs_io_data
,
1056 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data
),
1059 /* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
1060 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data
[] = {
1062 .label
= "cpld1_version",
1063 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
,
1064 .bit
= GENMASK(7, 0),
1068 .label
= "cpld2_version",
1069 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
,
1070 .bit
= GENMASK(7, 0),
1074 .label
= "reset_long_pb",
1075 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1076 .mask
= GENMASK(7, 0) & ~BIT(0),
1080 .label
= "reset_short_pb",
1081 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1082 .mask
= GENMASK(7, 0) & ~BIT(1),
1086 .label
= "reset_aux_pwr_or_ref",
1087 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1088 .mask
= GENMASK(7, 0) & ~BIT(2),
1092 .label
= "reset_sw_reset",
1093 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1094 .mask
= GENMASK(7, 0) & ~BIT(3),
1098 .label
= "reset_main_pwr_fail",
1099 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1100 .mask
= GENMASK(7, 0) & ~BIT(4),
1104 .label
= "reset_asic_thermal",
1105 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1106 .mask
= GENMASK(7, 0) & ~BIT(5),
1110 .label
= "reset_hotswap_or_halt",
1111 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1112 .mask
= GENMASK(7, 0) & ~BIT(6),
1117 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1118 .mask
= GENMASK(7, 0) & ~BIT(0),
1123 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1124 .mask
= GENMASK(7, 0) & ~BIT(1),
1128 .label
= "pwr_cycle",
1129 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1130 .mask
= GENMASK(7, 0) & ~BIT(2),
1134 .label
= "pwr_down",
1135 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1136 .mask
= GENMASK(7, 0) & ~BIT(3),
1140 .label
= "asic_health",
1141 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
1142 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
1148 static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data
= {
1149 .data
= mlxplat_mlxcpld_msn21xx_regs_io_data
,
1150 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data
),
1153 /* Platform register access for next generation systems families data */
1154 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data
[] = {
1156 .label
= "cpld1_version",
1157 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
,
1158 .bit
= GENMASK(7, 0),
1162 .label
= "cpld2_version",
1163 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
,
1164 .bit
= GENMASK(7, 0),
1168 .label
= "cpld3_version",
1169 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET
,
1170 .bit
= GENMASK(7, 0),
1174 .label
= "cpld4_version",
1175 .reg
= MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET
,
1176 .bit
= GENMASK(7, 0),
1180 .label
= "reset_long_pb",
1181 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1182 .mask
= GENMASK(7, 0) & ~BIT(0),
1186 .label
= "reset_short_pb",
1187 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1188 .mask
= GENMASK(7, 0) & ~BIT(1),
1192 .label
= "reset_aux_pwr_or_ref",
1193 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1194 .mask
= GENMASK(7, 0) & ~BIT(2),
1198 .label
= "reset_from_comex",
1199 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1200 .mask
= GENMASK(7, 0) & ~BIT(4),
1204 .label
= "reset_asic_thermal",
1205 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1206 .mask
= GENMASK(7, 0) & ~BIT(7),
1210 .label
= "reset_comex_pwr_fail",
1211 .reg
= MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET
,
1212 .mask
= GENMASK(7, 0) & ~BIT(3),
1216 .label
= "reset_voltmon_upgrade_fail",
1217 .reg
= MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET
,
1218 .mask
= GENMASK(7, 0) & ~BIT(0),
1222 .label
= "reset_system",
1223 .reg
= MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET
,
1224 .mask
= GENMASK(7, 0) & ~BIT(1),
1229 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1230 .mask
= GENMASK(7, 0) & ~BIT(0),
1235 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1236 .mask
= GENMASK(7, 0) & ~BIT(1),
1240 .label
= "pwr_cycle",
1241 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1242 .mask
= GENMASK(7, 0) & ~BIT(2),
1246 .label
= "pwr_down",
1247 .reg
= MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
,
1248 .mask
= GENMASK(7, 0) & ~BIT(3),
1252 .label
= "jtag_enable",
1253 .reg
= MLXPLAT_CPLD_LPC_REG_GP2_OFFSET
,
1254 .mask
= GENMASK(7, 0) & ~BIT(4),
1258 .label
= "asic_health",
1259 .reg
= MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
,
1260 .mask
= MLXPLAT_CPLD_ASIC_MASK
,
1266 .reg
= MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION
,
1267 .bit
= GENMASK(7, 0),
1272 static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data
= {
1273 .data
= mlxplat_mlxcpld_default_ng_regs_io_data
,
1274 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_ng_regs_io_data
),
1277 /* Platform FAN default */
1278 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data
[] = {
1281 .reg
= MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET
,
1285 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET
,
1286 .mask
= GENMASK(7, 0),
1287 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1292 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET
,
1293 .mask
= GENMASK(7, 0),
1294 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1299 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET
,
1300 .mask
= GENMASK(7, 0),
1301 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1306 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET
,
1307 .mask
= GENMASK(7, 0),
1308 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1313 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET
,
1314 .mask
= GENMASK(7, 0),
1315 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1320 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET
,
1321 .mask
= GENMASK(7, 0),
1322 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1327 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET
,
1328 .mask
= GENMASK(7, 0),
1329 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1334 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET
,
1335 .mask
= GENMASK(7, 0),
1336 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
,
1341 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET
,
1342 .mask
= GENMASK(7, 0),
1343 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET
,
1348 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET
,
1349 .mask
= GENMASK(7, 0),
1350 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET
,
1355 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET
,
1356 .mask
= GENMASK(7, 0),
1357 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET
,
1362 .reg
= MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET
,
1363 .mask
= GENMASK(7, 0),
1364 .capability
= MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET
,
1369 .capability
= MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET
,
1373 static struct mlxreg_core_platform_data mlxplat_default_fan_data
= {
1374 .data
= mlxplat_mlxcpld_default_fan_data
,
1375 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data
),
1378 /* Watchdog type1: hardware implementation version1
1379 * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
1381 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1
[] = {
1384 .reg
= MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET
,
1385 .mask
= MLXPLAT_CPLD_WD_RESET_ACT_MASK
,
1390 .reg
= MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET
,
1391 .mask
= MLXPLAT_CPLD_WD_TYPE1_TO_MASK
,
1392 .health_cntr
= MLXPLAT_CPLD_WD_DFLT_TIMEOUT
,
1396 .reg
= MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET
,
1397 .mask
= MLXPLAT_CPLD_WD1_CLEAR_MASK
,
1402 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1403 .mask
= GENMASK(7, 0) & ~BIT(6),
1408 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1
[] = {
1411 .reg
= MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET
,
1412 .mask
= MLXPLAT_CPLD_WD_FAN_ACT_MASK
,
1417 .reg
= MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET
,
1418 .mask
= MLXPLAT_CPLD_WD_TYPE1_TO_MASK
,
1419 .health_cntr
= MLXPLAT_CPLD_WD_DFLT_TIMEOUT
,
1423 .reg
= MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET
,
1424 .mask
= MLXPLAT_CPLD_WD1_CLEAR_MASK
,
1429 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type1
[] = {
1431 .data
= mlxplat_mlxcpld_wd_main_regs_type1
,
1432 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1
),
1433 .version
= MLX_WDT_TYPE1
,
1434 .identity
= "mlx-wdt-main",
1437 .data
= mlxplat_mlxcpld_wd_aux_regs_type1
,
1438 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1
),
1439 .version
= MLX_WDT_TYPE1
,
1440 .identity
= "mlx-wdt-aux",
1444 /* Watchdog type2: hardware implementation version 2
1445 * (all systems except (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140).
1447 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2
[] = {
1450 .reg
= MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET
,
1451 .mask
= MLXPLAT_CPLD_WD_RESET_ACT_MASK
,
1456 .reg
= MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET
,
1457 .mask
= MLXPLAT_CPLD_WD_TYPE2_TO_MASK
,
1458 .health_cntr
= MLXPLAT_CPLD_WD_DFLT_TIMEOUT
,
1461 .label
= "timeleft",
1462 .reg
= MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET
,
1463 .mask
= MLXPLAT_CPLD_WD_TYPE2_TO_MASK
,
1467 .reg
= MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET
,
1468 .mask
= MLXPLAT_CPLD_WD_RESET_ACT_MASK
,
1473 .reg
= MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
,
1474 .mask
= GENMASK(7, 0) & ~BIT(6),
1479 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2
[] = {
1482 .reg
= MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET
,
1483 .mask
= MLXPLAT_CPLD_WD_FAN_ACT_MASK
,
1488 .reg
= MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET
,
1489 .mask
= MLXPLAT_CPLD_WD_TYPE2_TO_MASK
,
1490 .health_cntr
= MLXPLAT_CPLD_WD_DFLT_TIMEOUT
,
1493 .label
= "timeleft",
1494 .reg
= MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET
,
1495 .mask
= MLXPLAT_CPLD_WD_TYPE2_TO_MASK
,
1499 .reg
= MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET
,
1500 .mask
= MLXPLAT_CPLD_WD_FAN_ACT_MASK
,
1505 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type2
[] = {
1507 .data
= mlxplat_mlxcpld_wd_main_regs_type2
,
1508 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2
),
1509 .version
= MLX_WDT_TYPE2
,
1510 .identity
= "mlx-wdt-main",
1513 .data
= mlxplat_mlxcpld_wd_aux_regs_type2
,
1514 .counter
= ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2
),
1515 .version
= MLX_WDT_TYPE2
,
1516 .identity
= "mlx-wdt-aux",
1520 static bool mlxplat_mlxcpld_writeable_reg(struct device
*dev
, unsigned int reg
)
1523 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
:
1524 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
:
1525 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
:
1526 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
:
1527 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET
:
1528 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
:
1529 case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET
:
1530 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET
:
1531 case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET
:
1532 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET
:
1533 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET
:
1534 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET
:
1535 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET
:
1536 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET
:
1537 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET
:
1538 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET
:
1539 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET
:
1540 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET
:
1541 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET
:
1542 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET
:
1543 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET
:
1544 case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET
:
1545 case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET
:
1546 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET
:
1547 case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET
:
1548 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET
:
1549 case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET
:
1550 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET
:
1551 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET
:
1557 static bool mlxplat_mlxcpld_readable_reg(struct device
*dev
, unsigned int reg
)
1560 case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
:
1561 case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
:
1562 case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET
:
1563 case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET
:
1564 case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
:
1565 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET
:
1566 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET
:
1567 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
:
1568 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
:
1569 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
:
1570 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
:
1571 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET
:
1572 case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION
:
1573 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
:
1574 case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET
:
1575 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET
:
1576 case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET
:
1577 case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
:
1578 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET
:
1579 case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
:
1580 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET
:
1581 case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
:
1582 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET
:
1583 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET
:
1584 case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
:
1585 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET
:
1586 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET
:
1587 case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
:
1588 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET
:
1589 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET
:
1590 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
:
1591 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET
:
1592 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET
:
1593 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET
:
1594 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET
:
1595 case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET
:
1596 case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET
:
1597 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET
:
1598 case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET
:
1599 case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET
:
1600 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET
:
1601 case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET
:
1602 case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET
:
1603 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET
:
1604 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET
:
1605 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET
:
1606 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET
:
1607 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET
:
1608 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET
:
1609 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET
:
1610 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET
:
1611 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET
:
1612 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET
:
1613 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET
:
1614 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET
:
1615 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET
:
1616 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET
:
1617 case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
:
1618 case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET
:
1619 case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
:
1620 case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET
:
1626 static bool mlxplat_mlxcpld_volatile_reg(struct device
*dev
, unsigned int reg
)
1629 case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET
:
1630 case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET
:
1631 case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET
:
1632 case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET
:
1633 case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET
:
1634 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET
:
1635 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET
:
1636 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET
:
1637 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET
:
1638 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET
:
1639 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET
:
1640 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET
:
1641 case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION
:
1642 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET
:
1643 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET
:
1644 case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET
:
1645 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET
:
1646 case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET
:
1647 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET
:
1648 case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET
:
1649 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET
:
1650 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET
:
1651 case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET
:
1652 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET
:
1653 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET
:
1654 case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET
:
1655 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET
:
1656 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET
:
1657 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET
:
1658 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET
:
1659 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET
:
1660 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET
:
1661 case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET
:
1662 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET
:
1663 case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET
:
1664 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET
:
1665 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET
:
1666 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET
:
1667 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET
:
1668 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET
:
1669 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET
:
1670 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET
:
1671 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET
:
1672 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET
:
1673 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET
:
1674 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET
:
1675 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET
:
1676 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET
:
1677 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET
:
1678 case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET
:
1679 case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET
:
1680 case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET
:
1681 case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET
:
1687 static const struct reg_default mlxplat_mlxcpld_regmap_default
[] = {
1688 { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET
, 0x00 },
1689 { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET
, 0x00 },
1690 { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET
, 0x00 },
1691 { MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET
, 0x00 },
1694 struct mlxplat_mlxcpld_regmap_context
{
1698 static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx
;
1701 mlxplat_mlxcpld_reg_read(void *context
, unsigned int reg
, unsigned int *val
)
1703 struct mlxplat_mlxcpld_regmap_context
*ctx
= context
;
1705 *val
= ioread8(ctx
->base
+ reg
);
1710 mlxplat_mlxcpld_reg_write(void *context
, unsigned int reg
, unsigned int val
)
1712 struct mlxplat_mlxcpld_regmap_context
*ctx
= context
;
1714 iowrite8(val
, ctx
->base
+ reg
);
1718 static const struct regmap_config mlxplat_mlxcpld_regmap_config
= {
1721 .max_register
= 255,
1722 .cache_type
= REGCACHE_FLAT
,
1723 .writeable_reg
= mlxplat_mlxcpld_writeable_reg
,
1724 .readable_reg
= mlxplat_mlxcpld_readable_reg
,
1725 .volatile_reg
= mlxplat_mlxcpld_volatile_reg
,
1726 .reg_defaults
= mlxplat_mlxcpld_regmap_default
,
1727 .num_reg_defaults
= ARRAY_SIZE(mlxplat_mlxcpld_regmap_default
),
1728 .reg_read
= mlxplat_mlxcpld_reg_read
,
1729 .reg_write
= mlxplat_mlxcpld_reg_write
,
1732 static struct resource mlxplat_mlxcpld_resources
[] = {
1733 [0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
1736 static struct platform_device
*mlxplat_dev
;
1737 static struct mlxreg_core_hotplug_platform_data
*mlxplat_hotplug
;
1738 static struct mlxreg_core_platform_data
*mlxplat_led
;
1739 static struct mlxreg_core_platform_data
*mlxplat_regs_io
;
1740 static struct mlxreg_core_platform_data
*mlxplat_fan
;
1741 static struct mlxreg_core_platform_data
1742 *mlxplat_wd_data
[MLXPLAT_CPLD_WD_MAX_DEVS
];
1744 static int __init
mlxplat_dmi_default_matched(const struct dmi_system_id
*dmi
)
1748 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1749 mlxplat_mux_data
[i
].values
= mlxplat_default_channels
[i
];
1750 mlxplat_mux_data
[i
].n_values
=
1751 ARRAY_SIZE(mlxplat_default_channels
[i
]);
1753 mlxplat_hotplug
= &mlxplat_mlxcpld_default_data
;
1754 mlxplat_hotplug
->deferred_nr
=
1755 mlxplat_default_channels
[i
- 1][MLXPLAT_CPLD_GRP_CHNL_NUM
- 1];
1756 mlxplat_led
= &mlxplat_default_led_data
;
1757 mlxplat_regs_io
= &mlxplat_default_regs_io_data
;
1758 mlxplat_wd_data
[0] = &mlxplat_mlxcpld_wd_set_type1
[0];
1763 static int __init
mlxplat_dmi_msn21xx_matched(const struct dmi_system_id
*dmi
)
1767 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1768 mlxplat_mux_data
[i
].values
= mlxplat_msn21xx_channels
;
1769 mlxplat_mux_data
[i
].n_values
=
1770 ARRAY_SIZE(mlxplat_msn21xx_channels
);
1772 mlxplat_hotplug
= &mlxplat_mlxcpld_msn21xx_data
;
1773 mlxplat_hotplug
->deferred_nr
=
1774 mlxplat_msn21xx_channels
[MLXPLAT_CPLD_GRP_CHNL_NUM
- 1];
1775 mlxplat_led
= &mlxplat_msn21xx_led_data
;
1776 mlxplat_regs_io
= &mlxplat_msn21xx_regs_io_data
;
1777 mlxplat_wd_data
[0] = &mlxplat_mlxcpld_wd_set_type1
[0];
1782 static int __init
mlxplat_dmi_msn274x_matched(const struct dmi_system_id
*dmi
)
1786 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1787 mlxplat_mux_data
[i
].values
= mlxplat_msn21xx_channels
;
1788 mlxplat_mux_data
[i
].n_values
=
1789 ARRAY_SIZE(mlxplat_msn21xx_channels
);
1791 mlxplat_hotplug
= &mlxplat_mlxcpld_msn274x_data
;
1792 mlxplat_hotplug
->deferred_nr
=
1793 mlxplat_msn21xx_channels
[MLXPLAT_CPLD_GRP_CHNL_NUM
- 1];
1794 mlxplat_led
= &mlxplat_default_led_data
;
1795 mlxplat_regs_io
= &mlxplat_msn21xx_regs_io_data
;
1796 mlxplat_wd_data
[0] = &mlxplat_mlxcpld_wd_set_type1
[0];
1801 static int __init
mlxplat_dmi_msn201x_matched(const struct dmi_system_id
*dmi
)
1805 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1806 mlxplat_mux_data
[i
].values
= mlxplat_msn21xx_channels
;
1807 mlxplat_mux_data
[i
].n_values
=
1808 ARRAY_SIZE(mlxplat_msn21xx_channels
);
1810 mlxplat_hotplug
= &mlxplat_mlxcpld_msn201x_data
;
1811 mlxplat_hotplug
->deferred_nr
=
1812 mlxplat_default_channels
[i
- 1][MLXPLAT_CPLD_GRP_CHNL_NUM
- 1];
1813 mlxplat_led
= &mlxplat_msn21xx_led_data
;
1814 mlxplat_regs_io
= &mlxplat_msn21xx_regs_io_data
;
1815 mlxplat_wd_data
[0] = &mlxplat_mlxcpld_wd_set_type1
[0];
1820 static int __init
mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id
*dmi
)
1824 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1825 mlxplat_mux_data
[i
].values
= mlxplat_msn21xx_channels
;
1826 mlxplat_mux_data
[i
].n_values
=
1827 ARRAY_SIZE(mlxplat_msn21xx_channels
);
1829 mlxplat_hotplug
= &mlxplat_mlxcpld_default_ng_data
;
1830 mlxplat_hotplug
->deferred_nr
=
1831 mlxplat_msn21xx_channels
[MLXPLAT_CPLD_GRP_CHNL_NUM
- 1];
1832 mlxplat_led
= &mlxplat_default_ng_led_data
;
1833 mlxplat_regs_io
= &mlxplat_default_ng_regs_io_data
;
1834 mlxplat_fan
= &mlxplat_default_fan_data
;
1835 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2
); i
++)
1836 mlxplat_wd_data
[i
] = &mlxplat_mlxcpld_wd_set_type2
[i
];
1841 static const struct dmi_system_id mlxplat_dmi_table
[] __initconst
= {
1843 .callback
= mlxplat_dmi_msn274x_matched
,
1845 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1846 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN274"),
1850 .callback
= mlxplat_dmi_default_matched
,
1852 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1853 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN24"),
1857 .callback
= mlxplat_dmi_default_matched
,
1859 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1860 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN27"),
1864 .callback
= mlxplat_dmi_default_matched
,
1866 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1867 DMI_MATCH(DMI_PRODUCT_NAME
, "MSB"),
1871 .callback
= mlxplat_dmi_default_matched
,
1873 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1874 DMI_MATCH(DMI_PRODUCT_NAME
, "MSX"),
1878 .callback
= mlxplat_dmi_msn21xx_matched
,
1880 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1881 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN21"),
1885 .callback
= mlxplat_dmi_msn201x_matched
,
1887 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1888 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN201"),
1892 .callback
= mlxplat_dmi_qmb7xx_matched
,
1894 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1895 DMI_MATCH(DMI_PRODUCT_NAME
, "MQM87"),
1899 .callback
= mlxplat_dmi_qmb7xx_matched
,
1901 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1902 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN37"),
1906 .callback
= mlxplat_dmi_qmb7xx_matched
,
1908 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1909 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN34"),
1913 .callback
= mlxplat_dmi_qmb7xx_matched
,
1915 DMI_MATCH(DMI_BOARD_VENDOR
, "Mellanox Technologies"),
1916 DMI_MATCH(DMI_PRODUCT_NAME
, "MSN38"),
1920 .callback
= mlxplat_dmi_default_matched
,
1922 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0001"),
1926 .callback
= mlxplat_dmi_msn21xx_matched
,
1928 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0002"),
1932 .callback
= mlxplat_dmi_msn274x_matched
,
1934 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0003"),
1938 .callback
= mlxplat_dmi_msn201x_matched
,
1940 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0004"),
1944 .callback
= mlxplat_dmi_qmb7xx_matched
,
1946 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0005"),
1950 .callback
= mlxplat_dmi_qmb7xx_matched
,
1952 DMI_MATCH(DMI_BOARD_NAME
, "VMOD0007"),
1958 MODULE_DEVICE_TABLE(dmi
, mlxplat_dmi_table
);
1960 static int mlxplat_mlxcpld_verify_bus_topology(int *nr
)
1962 struct i2c_adapter
*search_adap
;
1965 /* Scan adapters from expected id to verify it is free. */
1966 *nr
= MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR
;
1967 for (i
= MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR
; i
<
1968 MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM
; i
++) {
1969 search_adap
= i2c_get_adapter(i
);
1971 i2c_put_adapter(search_adap
);
1975 /* Return if expected parent adapter is free. */
1976 if (i
== MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR
)
1981 /* Return with error if free id for adapter is not found. */
1982 if (i
== MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM
)
1985 /* Shift adapter ids, since expected parent adapter is not free. */
1987 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
1988 shift
= *nr
- mlxplat_mux_data
[i
].parent
;
1989 mlxplat_mux_data
[i
].parent
= *nr
;
1990 mlxplat_mux_data
[i
].base_nr
+= shift
;
1992 mlxplat_hotplug
->shift_nr
= shift
;
1998 static int __init
mlxplat_init(void)
2000 struct mlxplat_priv
*priv
;
2003 if (!dmi_check_system(mlxplat_dmi_table
))
2006 mlxplat_dev
= platform_device_register_simple(MLX_PLAT_DEVICE_NAME
, -1,
2007 mlxplat_lpc_resources
,
2008 ARRAY_SIZE(mlxplat_lpc_resources
));
2010 if (IS_ERR(mlxplat_dev
))
2011 return PTR_ERR(mlxplat_dev
);
2013 priv
= devm_kzalloc(&mlxplat_dev
->dev
, sizeof(struct mlxplat_priv
),
2019 platform_set_drvdata(mlxplat_dev
, priv
);
2021 err
= mlxplat_mlxcpld_verify_bus_topology(&nr
);
2025 nr
= (nr
== MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM
) ? -1 : nr
;
2026 priv
->pdev_i2c
= platform_device_register_simple("i2c_mlxcpld", nr
,
2028 if (IS_ERR(priv
->pdev_i2c
)) {
2029 err
= PTR_ERR(priv
->pdev_i2c
);
2033 for (i
= 0; i
< ARRAY_SIZE(mlxplat_mux_data
); i
++) {
2034 priv
->pdev_mux
[i
] = platform_device_register_resndata(
2036 "i2c-mux-reg", i
, NULL
,
2037 0, &mlxplat_mux_data
[i
],
2038 sizeof(mlxplat_mux_data
[i
]));
2039 if (IS_ERR(priv
->pdev_mux
[i
])) {
2040 err
= PTR_ERR(priv
->pdev_mux
[i
]);
2041 goto fail_platform_mux_register
;
2045 mlxplat_mlxcpld_regmap_ctx
.base
= devm_ioport_map(&mlxplat_dev
->dev
,
2046 mlxplat_lpc_resources
[1].start
, 1);
2047 if (!mlxplat_mlxcpld_regmap_ctx
.base
) {
2049 goto fail_platform_mux_register
;
2052 mlxplat_hotplug
->regmap
= devm_regmap_init(&mlxplat_dev
->dev
, NULL
,
2053 &mlxplat_mlxcpld_regmap_ctx
,
2054 &mlxplat_mlxcpld_regmap_config
);
2055 if (IS_ERR(mlxplat_hotplug
->regmap
)) {
2056 err
= PTR_ERR(mlxplat_hotplug
->regmap
);
2057 goto fail_platform_mux_register
;
2060 priv
->pdev_hotplug
= platform_device_register_resndata(
2061 &mlxplat_dev
->dev
, "mlxreg-hotplug",
2062 PLATFORM_DEVID_NONE
,
2063 mlxplat_mlxcpld_resources
,
2064 ARRAY_SIZE(mlxplat_mlxcpld_resources
),
2065 mlxplat_hotplug
, sizeof(*mlxplat_hotplug
));
2066 if (IS_ERR(priv
->pdev_hotplug
)) {
2067 err
= PTR_ERR(priv
->pdev_hotplug
);
2068 goto fail_platform_mux_register
;
2071 /* Set default registers. */
2072 for (j
= 0; j
< mlxplat_mlxcpld_regmap_config
.num_reg_defaults
; j
++) {
2073 err
= regmap_write(mlxplat_hotplug
->regmap
,
2074 mlxplat_mlxcpld_regmap_default
[j
].reg
,
2075 mlxplat_mlxcpld_regmap_default
[j
].def
);
2077 goto fail_platform_mux_register
;
2080 /* Add LED driver. */
2081 mlxplat_led
->regmap
= mlxplat_hotplug
->regmap
;
2082 priv
->pdev_led
= platform_device_register_resndata(
2083 &mlxplat_dev
->dev
, "leds-mlxreg",
2084 PLATFORM_DEVID_NONE
, NULL
, 0,
2085 mlxplat_led
, sizeof(*mlxplat_led
));
2086 if (IS_ERR(priv
->pdev_led
)) {
2087 err
= PTR_ERR(priv
->pdev_led
);
2088 goto fail_platform_hotplug_register
;
2091 /* Add registers io access driver. */
2092 if (mlxplat_regs_io
) {
2093 mlxplat_regs_io
->regmap
= mlxplat_hotplug
->regmap
;
2094 priv
->pdev_io_regs
= platform_device_register_resndata(
2095 &mlxplat_dev
->dev
, "mlxreg-io",
2096 PLATFORM_DEVID_NONE
, NULL
, 0,
2098 sizeof(*mlxplat_regs_io
));
2099 if (IS_ERR(priv
->pdev_io_regs
)) {
2100 err
= PTR_ERR(priv
->pdev_io_regs
);
2101 goto fail_platform_led_register
;
2105 /* Add FAN driver. */
2107 mlxplat_fan
->regmap
= mlxplat_hotplug
->regmap
;
2108 priv
->pdev_fan
= platform_device_register_resndata(
2109 &mlxplat_dev
->dev
, "mlxreg-fan",
2110 PLATFORM_DEVID_NONE
, NULL
, 0,
2112 sizeof(*mlxplat_fan
));
2113 if (IS_ERR(priv
->pdev_fan
)) {
2114 err
= PTR_ERR(priv
->pdev_fan
);
2115 goto fail_platform_io_regs_register
;
2119 /* Add WD drivers. */
2120 for (j
= 0; j
< MLXPLAT_CPLD_WD_MAX_DEVS
; j
++) {
2121 if (mlxplat_wd_data
[j
]) {
2122 mlxplat_wd_data
[j
]->regmap
= mlxplat_hotplug
->regmap
;
2123 priv
->pdev_wd
[j
] = platform_device_register_resndata(
2124 &mlxplat_dev
->dev
, "mlx-wdt",
2127 sizeof(*mlxplat_wd_data
[j
]));
2128 if (IS_ERR(priv
->pdev_wd
[j
])) {
2129 err
= PTR_ERR(priv
->pdev_wd
[j
]);
2130 goto fail_platform_wd_register
;
2135 /* Sync registers with hardware. */
2136 regcache_mark_dirty(mlxplat_hotplug
->regmap
);
2137 err
= regcache_sync(mlxplat_hotplug
->regmap
);
2139 goto fail_platform_wd_register
;
2143 fail_platform_wd_register
:
2145 platform_device_unregister(priv
->pdev_wd
[j
]);
2147 platform_device_unregister(priv
->pdev_fan
);
2148 fail_platform_io_regs_register
:
2149 if (mlxplat_regs_io
)
2150 platform_device_unregister(priv
->pdev_io_regs
);
2151 fail_platform_led_register
:
2152 platform_device_unregister(priv
->pdev_led
);
2153 fail_platform_hotplug_register
:
2154 platform_device_unregister(priv
->pdev_hotplug
);
2155 fail_platform_mux_register
:
2157 platform_device_unregister(priv
->pdev_mux
[i
]);
2158 platform_device_unregister(priv
->pdev_i2c
);
2160 platform_device_unregister(mlxplat_dev
);
2164 module_init(mlxplat_init
);
2166 static void __exit
mlxplat_exit(void)
2168 struct mlxplat_priv
*priv
= platform_get_drvdata(mlxplat_dev
);
2171 for (i
= MLXPLAT_CPLD_WD_MAX_DEVS
- 1; i
>= 0 ; i
--)
2172 platform_device_unregister(priv
->pdev_wd
[i
]);
2174 platform_device_unregister(priv
->pdev_fan
);
2175 if (priv
->pdev_io_regs
)
2176 platform_device_unregister(priv
->pdev_io_regs
);
2177 platform_device_unregister(priv
->pdev_led
);
2178 platform_device_unregister(priv
->pdev_hotplug
);
2180 for (i
= ARRAY_SIZE(mlxplat_mux_data
) - 1; i
>= 0 ; i
--)
2181 platform_device_unregister(priv
->pdev_mux
[i
]);
2183 platform_device_unregister(priv
->pdev_i2c
);
2184 platform_device_unregister(mlxplat_dev
);
2186 module_exit(mlxplat_exit
);
2188 MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
2189 MODULE_DESCRIPTION("Mellanox platform driver");
2190 MODULE_LICENSE("Dual BSD/GPL");