drm/panfrost: Move gpu_{write, read}() macros to panfrost_regs.h
[linux/fpc-iii.git] / drivers / platform / x86 / mlx-platform.c
blobcee039f574994133b02e2e24400f73e134931968
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*
3 * Mellanox platform driver
5 * Copyright (C) 2016-2018 Mellanox Technologies
6 * Copyright (C) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
7 */
9 #include <linux/device.h>
10 #include <linux/dmi.h>
11 #include <linux/i2c.h>
12 #include <linux/i2c-mux.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/platform_data/i2c-mux-reg.h>
17 #include <linux/platform_data/mlxreg.h>
18 #include <linux/regmap.h>
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",
181 IORESOURCE_IO),
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[] = {
204 .parent = 1,
205 .base_nr = MLXPLAT_CPLD_CH1,
206 .write_only = 1,
207 .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
208 .reg_size = 1,
209 .idle_in_use = 1,
212 .parent = 1,
213 .base_nr = MLXPLAT_CPLD_CH2,
214 .write_only = 1,
215 .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
216 .reg_size = 1,
217 .idle_in_use = 1,
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[] = {
268 .label = "psu1",
269 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
270 .mask = BIT(0),
271 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
272 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
275 .label = "psu2",
276 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
277 .mask = BIT(1),
278 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
279 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
283 static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
285 .label = "pwr1",
286 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
287 .mask = BIT(0),
288 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
289 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
292 .label = "pwr2",
293 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
294 .mask = BIT(1),
295 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
296 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
300 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
302 .label = "fan1",
303 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
304 .mask = BIT(0),
305 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
306 .hpdev.nr = MLXPLAT_CPLD_FAN1_DEFAULT_NR,
309 .label = "fan2",
310 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
311 .mask = BIT(1),
312 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
313 .hpdev.nr = MLXPLAT_CPLD_FAN2_DEFAULT_NR,
316 .label = "fan3",
317 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
318 .mask = BIT(2),
319 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
320 .hpdev.nr = MLXPLAT_CPLD_FAN3_DEFAULT_NR,
323 .label = "fan4",
324 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
325 .mask = BIT(3),
326 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
327 .hpdev.nr = MLXPLAT_CPLD_FAN4_DEFAULT_NR,
331 static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = {
333 .label = "asic1",
334 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
335 .mask = MLXPLAT_CPLD_ASIC_MASK,
336 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
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),
347 .inversed = 1,
348 .health = false,
351 .data = mlxplat_mlxcpld_default_pwr_items_data,
352 .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
353 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
354 .mask = MLXPLAT_CPLD_PWR_MASK,
355 .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
356 .inversed = 0,
357 .health = false,
360 .data = mlxplat_mlxcpld_default_fan_items_data,
361 .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
362 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
363 .mask = MLXPLAT_CPLD_FAN_MASK,
364 .count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
365 .inversed = 1,
366 .health = false,
369 .data = mlxplat_mlxcpld_default_asic_items_data,
370 .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
371 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
372 .mask = MLXPLAT_CPLD_ASIC_MASK,
373 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
374 .inversed = 0,
375 .health = true,
379 static
380 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
381 .items = mlxplat_mlxcpld_default_items,
382 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
383 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
384 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
385 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
386 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
389 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = {
391 .label = "pwr1",
392 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
393 .mask = BIT(0),
394 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
397 .label = "pwr2",
398 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
399 .mask = BIT(1),
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),
412 .inversed = 0,
413 .health = false,
416 .data = mlxplat_mlxcpld_default_asic_items_data,
417 .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
418 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
419 .mask = MLXPLAT_CPLD_ASIC_MASK,
420 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
421 .inversed = 0,
422 .health = true,
426 static
427 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
428 .items = mlxplat_mlxcpld_msn21xx_items,
429 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
430 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
431 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
432 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
433 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
436 /* Platform hotplug msn274x system family data */
437 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data[] = {
439 .label = "psu1",
440 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
441 .mask = BIT(0),
442 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
443 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
446 .label = "psu2",
447 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
448 .mask = BIT(1),
449 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
450 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
454 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data[] = {
456 .label = "pwr1",
457 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
458 .mask = BIT(0),
459 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
460 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
463 .label = "pwr2",
464 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
465 .mask = BIT(1),
466 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
467 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
471 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data[] = {
473 .label = "fan1",
474 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
475 .mask = BIT(0),
476 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
479 .label = "fan2",
480 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
481 .mask = BIT(1),
482 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
485 .label = "fan3",
486 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
487 .mask = BIT(2),
488 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
491 .label = "fan4",
492 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
493 .mask = BIT(3),
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),
505 .inversed = 1,
506 .health = false,
509 .data = mlxplat_mlxcpld_default_ng_pwr_items_data,
510 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
511 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
512 .mask = MLXPLAT_CPLD_PWR_MASK,
513 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
514 .inversed = 0,
515 .health = false,
518 .data = mlxplat_mlxcpld_msn274x_fan_items_data,
519 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
520 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
521 .mask = MLXPLAT_CPLD_FAN_MASK,
522 .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data),
523 .inversed = 1,
524 .health = false,
527 .data = mlxplat_mlxcpld_default_asic_items_data,
528 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
529 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
530 .mask = MLXPLAT_CPLD_ASIC_MASK,
531 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
532 .inversed = 0,
533 .health = true,
537 static
538 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = {
539 .items = mlxplat_mlxcpld_msn274x_items,
540 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
541 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
542 .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
543 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
544 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
547 /* Platform hotplug MSN201x system family data */
548 static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data[] = {
550 .label = "pwr1",
551 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
552 .mask = BIT(0),
553 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
556 .label = "pwr2",
557 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
558 .mask = BIT(1),
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),
570 .inversed = 0,
571 .health = false,
574 .data = mlxplat_mlxcpld_default_asic_items_data,
575 .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
576 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
577 .mask = MLXPLAT_CPLD_ASIC_MASK,
578 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
579 .inversed = 0,
580 .health = true,
584 static
585 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
586 .items = mlxplat_mlxcpld_msn201x_items,
587 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
588 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
589 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
590 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
591 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
594 /* Platform hotplug next generation system family data */
595 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data[] = {
597 .label = "psu1",
598 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
599 .mask = BIT(0),
600 .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[0],
601 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
604 .label = "psu2",
605 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
606 .mask = BIT(1),
607 .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[1],
608 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
612 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = {
614 .label = "fan1",
615 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
616 .mask = BIT(0),
617 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
618 .bit = BIT(0),
619 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
622 .label = "fan2",
623 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
624 .mask = BIT(1),
625 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
626 .bit = BIT(1),
627 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
630 .label = "fan3",
631 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
632 .mask = BIT(2),
633 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
634 .bit = BIT(2),
635 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
638 .label = "fan4",
639 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
640 .mask = BIT(3),
641 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
642 .bit = BIT(3),
643 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
646 .label = "fan5",
647 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
648 .mask = BIT(4),
649 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
650 .bit = BIT(4),
651 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
654 .label = "fan6",
655 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
656 .mask = BIT(5),
657 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
658 .bit = BIT(5),
659 .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
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),
670 .inversed = 1,
671 .health = false,
674 .data = mlxplat_mlxcpld_default_ng_pwr_items_data,
675 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
676 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
677 .mask = MLXPLAT_CPLD_PWR_MASK,
678 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
679 .inversed = 0,
680 .health = false,
683 .data = mlxplat_mlxcpld_default_ng_fan_items_data,
684 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
685 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
686 .mask = MLXPLAT_CPLD_FAN_NG_MASK,
687 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
688 .inversed = 1,
689 .health = false,
692 .data = mlxplat_mlxcpld_default_asic_items_data,
693 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
694 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
695 .mask = MLXPLAT_CPLD_ASIC_MASK,
696 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
697 .inversed = 0,
698 .health = true,
702 static
703 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
704 .items = mlxplat_mlxcpld_default_ng_items,
705 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
706 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
707 .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
708 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
709 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
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,
730 .label = "psu:red",
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,
740 .label = "fan1:red",
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,
750 .label = "fan2:red",
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,
760 .label = "fan3:red",
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,
770 .label = "fan4:red",
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,
799 .label = "fan:red",
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,
809 .label = "psu1:red",
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,
819 .label = "psu2:red",
820 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
821 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
824 .label = "uid:blue",
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,
862 .bit = BIT(0),
865 .label = "fan1:orange",
866 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
867 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
868 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
869 .bit = BIT(0),
872 .label = "fan2:green",
873 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
874 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
875 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
876 .bit = BIT(1),
879 .label = "fan2:orange",
880 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
881 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
882 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
883 .bit = BIT(1),
886 .label = "fan3:green",
887 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
888 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
889 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
890 .bit = BIT(2),
893 .label = "fan3:orange",
894 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
895 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
896 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
897 .bit = BIT(2),
900 .label = "fan4:green",
901 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
902 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
903 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
904 .bit = BIT(3),
907 .label = "fan4:orange",
908 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
909 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
910 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
911 .bit = BIT(3),
914 .label = "fan5:green",
915 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
916 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
917 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
918 .bit = BIT(4),
921 .label = "fan5:orange",
922 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
923 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
924 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
925 .bit = BIT(4),
928 .label = "fan6:green",
929 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
930 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
931 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
932 .bit = BIT(5),
935 .label = "fan6:orange",
936 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
937 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
938 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
939 .bit = BIT(5),
942 .label = "uid:blue",
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),
959 .mode = 0444,
962 .label = "cpld2_version",
963 .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
964 .bit = GENMASK(7, 0),
965 .mode = 0444,
968 .label = "reset_long_pb",
969 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
970 .mask = GENMASK(7, 0) & ~BIT(0),
971 .mode = 0444,
974 .label = "reset_short_pb",
975 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
976 .mask = GENMASK(7, 0) & ~BIT(1),
977 .mode = 0444,
980 .label = "reset_aux_pwr_or_ref",
981 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
982 .mask = GENMASK(7, 0) & ~BIT(2),
983 .mode = 0444,
986 .label = "reset_main_pwr_fail",
987 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
988 .mask = GENMASK(7, 0) & ~BIT(3),
989 .mode = 0444,
992 .label = "reset_sw_reset",
993 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
994 .mask = GENMASK(7, 0) & ~BIT(4),
995 .mode = 0444,
998 .label = "reset_fw_reset",
999 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1000 .mask = GENMASK(7, 0) & ~BIT(5),
1001 .mode = 0444,
1004 .label = "reset_hotswap_or_wd",
1005 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1006 .mask = GENMASK(7, 0) & ~BIT(6),
1007 .mode = 0444,
1010 .label = "reset_asic_thermal",
1011 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1012 .mask = GENMASK(7, 0) & ~BIT(7),
1013 .mode = 0444,
1016 .label = "psu1_on",
1017 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1018 .mask = GENMASK(7, 0) & ~BIT(0),
1019 .mode = 0200,
1022 .label = "psu2_on",
1023 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1024 .mask = GENMASK(7, 0) & ~BIT(1),
1025 .mode = 0200,
1028 .label = "pwr_cycle",
1029 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1030 .mask = GENMASK(7, 0) & ~BIT(2),
1031 .mode = 0200,
1034 .label = "pwr_down",
1035 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1036 .mask = GENMASK(7, 0) & ~BIT(3),
1037 .mode = 0200,
1040 .label = "select_iio",
1041 .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1042 .mask = GENMASK(7, 0) & ~BIT(6),
1043 .mode = 0644,
1046 .label = "asic_health",
1047 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1048 .mask = MLXPLAT_CPLD_ASIC_MASK,
1049 .bit = 1,
1050 .mode = 0444,
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),
1065 .mode = 0444,
1068 .label = "cpld2_version",
1069 .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1070 .bit = GENMASK(7, 0),
1071 .mode = 0444,
1074 .label = "reset_long_pb",
1075 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1076 .mask = GENMASK(7, 0) & ~BIT(0),
1077 .mode = 0444,
1080 .label = "reset_short_pb",
1081 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1082 .mask = GENMASK(7, 0) & ~BIT(1),
1083 .mode = 0444,
1086 .label = "reset_aux_pwr_or_ref",
1087 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1088 .mask = GENMASK(7, 0) & ~BIT(2),
1089 .mode = 0444,
1092 .label = "reset_sw_reset",
1093 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1094 .mask = GENMASK(7, 0) & ~BIT(3),
1095 .mode = 0444,
1098 .label = "reset_main_pwr_fail",
1099 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1100 .mask = GENMASK(7, 0) & ~BIT(4),
1101 .mode = 0444,
1104 .label = "reset_asic_thermal",
1105 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1106 .mask = GENMASK(7, 0) & ~BIT(5),
1107 .mode = 0444,
1110 .label = "reset_hotswap_or_halt",
1111 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1112 .mask = GENMASK(7, 0) & ~BIT(6),
1113 .mode = 0444,
1116 .label = "psu1_on",
1117 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1118 .mask = GENMASK(7, 0) & ~BIT(0),
1119 .mode = 0200,
1122 .label = "psu2_on",
1123 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1124 .mask = GENMASK(7, 0) & ~BIT(1),
1125 .mode = 0200,
1128 .label = "pwr_cycle",
1129 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1130 .mask = GENMASK(7, 0) & ~BIT(2),
1131 .mode = 0200,
1134 .label = "pwr_down",
1135 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1136 .mask = GENMASK(7, 0) & ~BIT(3),
1137 .mode = 0200,
1140 .label = "asic_health",
1141 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1142 .mask = MLXPLAT_CPLD_ASIC_MASK,
1143 .bit = 1,
1144 .mode = 0444,
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),
1159 .mode = 0444,
1162 .label = "cpld2_version",
1163 .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
1164 .bit = GENMASK(7, 0),
1165 .mode = 0444,
1168 .label = "cpld3_version",
1169 .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
1170 .bit = GENMASK(7, 0),
1171 .mode = 0444,
1174 .label = "cpld4_version",
1175 .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
1176 .bit = GENMASK(7, 0),
1177 .mode = 0444,
1180 .label = "reset_long_pb",
1181 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1182 .mask = GENMASK(7, 0) & ~BIT(0),
1183 .mode = 0444,
1186 .label = "reset_short_pb",
1187 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1188 .mask = GENMASK(7, 0) & ~BIT(1),
1189 .mode = 0444,
1192 .label = "reset_aux_pwr_or_ref",
1193 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1194 .mask = GENMASK(7, 0) & ~BIT(2),
1195 .mode = 0444,
1198 .label = "reset_from_comex",
1199 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1200 .mask = GENMASK(7, 0) & ~BIT(4),
1201 .mode = 0444,
1204 .label = "reset_asic_thermal",
1205 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1206 .mask = GENMASK(7, 0) & ~BIT(7),
1207 .mode = 0444,
1210 .label = "reset_comex_pwr_fail",
1211 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
1212 .mask = GENMASK(7, 0) & ~BIT(3),
1213 .mode = 0444,
1216 .label = "reset_voltmon_upgrade_fail",
1217 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1218 .mask = GENMASK(7, 0) & ~BIT(0),
1219 .mode = 0444,
1222 .label = "reset_system",
1223 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
1224 .mask = GENMASK(7, 0) & ~BIT(1),
1225 .mode = 0444,
1228 .label = "psu1_on",
1229 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1230 .mask = GENMASK(7, 0) & ~BIT(0),
1231 .mode = 0200,
1234 .label = "psu2_on",
1235 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1236 .mask = GENMASK(7, 0) & ~BIT(1),
1237 .mode = 0200,
1240 .label = "pwr_cycle",
1241 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1242 .mask = GENMASK(7, 0) & ~BIT(2),
1243 .mode = 0200,
1246 .label = "pwr_down",
1247 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
1248 .mask = GENMASK(7, 0) & ~BIT(3),
1249 .mode = 0200,
1252 .label = "jtag_enable",
1253 .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
1254 .mask = GENMASK(7, 0) & ~BIT(4),
1255 .mode = 0644,
1258 .label = "asic_health",
1259 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
1260 .mask = MLXPLAT_CPLD_ASIC_MASK,
1261 .bit = 1,
1262 .mode = 0444,
1265 .label = "fan_dir",
1266 .reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
1267 .bit = GENMASK(7, 0),
1268 .mode = 0444,
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[] = {
1280 .label = "pwm1",
1281 .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
1284 .label = "tacho1",
1285 .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
1286 .mask = GENMASK(7, 0),
1287 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1288 .bit = BIT(0),
1291 .label = "tacho2",
1292 .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
1293 .mask = GENMASK(7, 0),
1294 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1295 .bit = BIT(1),
1298 .label = "tacho3",
1299 .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
1300 .mask = GENMASK(7, 0),
1301 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1302 .bit = BIT(2),
1305 .label = "tacho4",
1306 .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
1307 .mask = GENMASK(7, 0),
1308 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1309 .bit = BIT(3),
1312 .label = "tacho5",
1313 .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
1314 .mask = GENMASK(7, 0),
1315 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1316 .bit = BIT(4),
1319 .label = "tacho6",
1320 .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
1321 .mask = GENMASK(7, 0),
1322 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1323 .bit = BIT(5),
1326 .label = "tacho7",
1327 .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
1328 .mask = GENMASK(7, 0),
1329 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1330 .bit = BIT(6),
1333 .label = "tacho8",
1334 .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
1335 .mask = GENMASK(7, 0),
1336 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
1337 .bit = BIT(7),
1340 .label = "tacho9",
1341 .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
1342 .mask = GENMASK(7, 0),
1343 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1344 .bit = BIT(0),
1347 .label = "tacho10",
1348 .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
1349 .mask = GENMASK(7, 0),
1350 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1351 .bit = BIT(1),
1354 .label = "tacho11",
1355 .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
1356 .mask = GENMASK(7, 0),
1357 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1358 .bit = BIT(2),
1361 .label = "tacho12",
1362 .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
1363 .mask = GENMASK(7, 0),
1364 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
1365 .bit = BIT(3),
1368 .label = "conf",
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[] = {
1383 .label = "action",
1384 .reg = MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET,
1385 .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1386 .bit = 0,
1389 .label = "timeout",
1390 .reg = MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET,
1391 .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
1392 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1395 .label = "ping",
1396 .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
1397 .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
1398 .bit = 0,
1401 .label = "reset",
1402 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1403 .mask = GENMASK(7, 0) & ~BIT(6),
1404 .bit = 6,
1408 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1[] = {
1410 .label = "action",
1411 .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1412 .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1413 .bit = 4,
1416 .label = "timeout",
1417 .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
1418 .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
1419 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1422 .label = "ping",
1423 .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
1424 .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
1425 .bit = 1,
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[] = {
1449 .label = "action",
1450 .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1451 .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1452 .bit = 0,
1455 .label = "timeout",
1456 .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
1457 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1458 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1461 .label = "timeleft",
1462 .reg = MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET,
1463 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1466 .label = "ping",
1467 .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
1468 .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
1469 .bit = 0,
1472 .label = "reset",
1473 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
1474 .mask = GENMASK(7, 0) & ~BIT(6),
1475 .bit = 6,
1479 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2[] = {
1481 .label = "action",
1482 .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
1483 .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1484 .bit = 4,
1487 .label = "timeout",
1488 .reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
1489 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1490 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
1493 .label = "timeleft",
1494 .reg = MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET,
1495 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
1498 .label = "ping",
1499 .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
1500 .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
1501 .bit = 4,
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)
1522 switch (reg) {
1523 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1524 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1525 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1526 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1527 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1528 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1529 case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
1530 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1531 case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
1532 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1533 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1534 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1535 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1536 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1537 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1538 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1539 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1540 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1541 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1542 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
1543 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
1544 case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
1545 case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
1546 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1547 case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
1548 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1549 case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
1550 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1551 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1552 return true;
1554 return false;
1557 static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
1559 switch (reg) {
1560 case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
1561 case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
1562 case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
1563 case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
1564 case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
1565 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
1566 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
1567 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1568 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1569 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1570 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1571 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1572 case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
1573 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1574 case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
1575 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1576 case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
1577 case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
1578 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1579 case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
1580 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1581 case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
1582 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1583 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1584 case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
1585 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1586 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1587 case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
1588 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1589 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1590 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
1591 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1592 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1593 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
1594 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
1595 case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
1596 case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
1597 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1598 case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
1599 case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
1600 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1601 case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
1602 case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
1603 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1604 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
1605 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
1606 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
1607 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
1608 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
1609 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
1610 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
1611 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
1612 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
1613 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
1614 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
1615 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
1616 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1617 case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
1618 case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
1619 case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
1620 case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
1621 return true;
1623 return false;
1626 static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
1628 switch (reg) {
1629 case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
1630 case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
1631 case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
1632 case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
1633 case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
1634 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
1635 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
1636 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
1637 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
1638 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
1639 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
1640 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
1641 case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
1642 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
1643 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
1644 case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
1645 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
1646 case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
1647 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
1648 case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
1649 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
1650 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
1651 case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
1652 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
1653 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
1654 case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
1655 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
1656 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
1657 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
1658 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1659 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1660 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
1661 case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
1662 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
1663 case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
1664 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1665 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
1666 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
1667 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
1668 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
1669 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
1670 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
1671 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
1672 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
1673 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
1674 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
1675 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
1676 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
1677 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1678 case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
1679 case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
1680 case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
1681 case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
1682 return true;
1684 return false;
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 {
1695 void __iomem *base;
1698 static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
1700 static int
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);
1706 return 0;
1709 static int
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);
1715 return 0;
1718 static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
1719 .reg_bits = 8,
1720 .val_bits = 8,
1721 .max_register = 255,
1722 .cache_type = REGCACHE_FLAT,
1723 .writeable_reg = mlxplat_mlxcpld_writeable_reg,
1724 .readable_reg = mlxplat_mlxcpld_readable_reg,
1725 .volatile_reg = mlxplat_mlxcpld_volatile_reg,
1726 .reg_defaults = mlxplat_mlxcpld_regmap_default,
1727 .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default),
1728 .reg_read = mlxplat_mlxcpld_reg_read,
1729 .reg_write = mlxplat_mlxcpld_reg_write,
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)
1746 int i;
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];
1760 return 1;
1763 static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
1765 int i;
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];
1779 return 1;
1782 static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
1784 int i;
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];
1798 return 1;
1801 static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
1803 int i;
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];
1817 return 1;
1820 static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
1822 int i;
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];
1838 return 1;
1841 static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
1843 .callback = mlxplat_dmi_msn274x_matched,
1844 .matches = {
1845 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1846 DMI_MATCH(DMI_PRODUCT_NAME, "MSN274"),
1850 .callback = mlxplat_dmi_default_matched,
1851 .matches = {
1852 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1853 DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"),
1857 .callback = mlxplat_dmi_default_matched,
1858 .matches = {
1859 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1860 DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"),
1864 .callback = mlxplat_dmi_default_matched,
1865 .matches = {
1866 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1867 DMI_MATCH(DMI_PRODUCT_NAME, "MSB"),
1871 .callback = mlxplat_dmi_default_matched,
1872 .matches = {
1873 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1874 DMI_MATCH(DMI_PRODUCT_NAME, "MSX"),
1878 .callback = mlxplat_dmi_msn21xx_matched,
1879 .matches = {
1880 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1881 DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"),
1885 .callback = mlxplat_dmi_msn201x_matched,
1886 .matches = {
1887 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1888 DMI_MATCH(DMI_PRODUCT_NAME, "MSN201"),
1892 .callback = mlxplat_dmi_qmb7xx_matched,
1893 .matches = {
1894 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1895 DMI_MATCH(DMI_PRODUCT_NAME, "MQM87"),
1899 .callback = mlxplat_dmi_qmb7xx_matched,
1900 .matches = {
1901 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1902 DMI_MATCH(DMI_PRODUCT_NAME, "MSN37"),
1906 .callback = mlxplat_dmi_qmb7xx_matched,
1907 .matches = {
1908 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1909 DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"),
1913 .callback = mlxplat_dmi_qmb7xx_matched,
1914 .matches = {
1915 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
1916 DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"),
1920 .callback = mlxplat_dmi_default_matched,
1921 .matches = {
1922 DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
1926 .callback = mlxplat_dmi_msn21xx_matched,
1927 .matches = {
1928 DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"),
1932 .callback = mlxplat_dmi_msn274x_matched,
1933 .matches = {
1934 DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"),
1938 .callback = mlxplat_dmi_msn201x_matched,
1939 .matches = {
1940 DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"),
1944 .callback = mlxplat_dmi_qmb7xx_matched,
1945 .matches = {
1946 DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
1950 .callback = mlxplat_dmi_qmb7xx_matched,
1951 .matches = {
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;
1963 int shift, i;
1965 /* Scan adapters from expected id to verify it is free. */
1966 *nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
1967 for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
1968 MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; i++) {
1969 search_adap = i2c_get_adapter(i);
1970 if (search_adap) {
1971 i2c_put_adapter(search_adap);
1972 continue;
1975 /* Return if expected parent adapter is free. */
1976 if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR)
1977 return 0;
1978 break;
1981 /* Return with error if free id for adapter is not found. */
1982 if (i == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM)
1983 return -ENODEV;
1985 /* Shift adapter ids, since expected parent adapter is not free. */
1986 *nr = i;
1987 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
1988 shift = *nr - mlxplat_mux_data[i].parent;
1989 mlxplat_mux_data[i].parent = *nr;
1990 mlxplat_mux_data[i].base_nr += shift;
1991 if (shift > 0)
1992 mlxplat_hotplug->shift_nr = shift;
1995 return 0;
1998 static int __init mlxplat_init(void)
2000 struct mlxplat_priv *priv;
2001 int i, j, nr, err;
2003 if (!dmi_check_system(mlxplat_dmi_table))
2004 return -ENODEV;
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),
2014 GFP_KERNEL);
2015 if (!priv) {
2016 err = -ENOMEM;
2017 goto fail_alloc;
2019 platform_set_drvdata(mlxplat_dev, priv);
2021 err = mlxplat_mlxcpld_verify_bus_topology(&nr);
2022 if (nr < 0)
2023 goto fail_alloc;
2025 nr = (nr == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) ? -1 : nr;
2026 priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", nr,
2027 NULL, 0);
2028 if (IS_ERR(priv->pdev_i2c)) {
2029 err = PTR_ERR(priv->pdev_i2c);
2030 goto fail_alloc;
2033 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
2034 priv->pdev_mux[i] = platform_device_register_resndata(
2035 &mlxplat_dev->dev,
2036 "i2c-mux-reg", i, NULL,
2037 0, &mlxplat_mux_data[i],
2038 sizeof(mlxplat_mux_data[i]));
2039 if (IS_ERR(priv->pdev_mux[i])) {
2040 err = PTR_ERR(priv->pdev_mux[i]);
2041 goto fail_platform_mux_register;
2045 mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
2046 mlxplat_lpc_resources[1].start, 1);
2047 if (!mlxplat_mlxcpld_regmap_ctx.base) {
2048 err = -ENOMEM;
2049 goto fail_platform_mux_register;
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);
2076 if (err)
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,
2097 mlxplat_regs_io,
2098 sizeof(*mlxplat_regs_io));
2099 if (IS_ERR(priv->pdev_io_regs)) {
2100 err = PTR_ERR(priv->pdev_io_regs);
2101 goto fail_platform_led_register;
2105 /* Add FAN driver. */
2106 if (mlxplat_fan) {
2107 mlxplat_fan->regmap = mlxplat_hotplug->regmap;
2108 priv->pdev_fan = platform_device_register_resndata(
2109 &mlxplat_dev->dev, "mlxreg-fan",
2110 PLATFORM_DEVID_NONE, NULL, 0,
2111 mlxplat_fan,
2112 sizeof(*mlxplat_fan));
2113 if (IS_ERR(priv->pdev_fan)) {
2114 err = PTR_ERR(priv->pdev_fan);
2115 goto fail_platform_io_regs_register;
2119 /* Add WD drivers. */
2120 for (j = 0; j < MLXPLAT_CPLD_WD_MAX_DEVS; j++) {
2121 if (mlxplat_wd_data[j]) {
2122 mlxplat_wd_data[j]->regmap = mlxplat_hotplug->regmap;
2123 priv->pdev_wd[j] = platform_device_register_resndata(
2124 &mlxplat_dev->dev, "mlx-wdt",
2125 j, NULL, 0,
2126 mlxplat_wd_data[j],
2127 sizeof(*mlxplat_wd_data[j]));
2128 if (IS_ERR(priv->pdev_wd[j])) {
2129 err = PTR_ERR(priv->pdev_wd[j]);
2130 goto fail_platform_wd_register;
2135 /* Sync registers with hardware. */
2136 regcache_mark_dirty(mlxplat_hotplug->regmap);
2137 err = regcache_sync(mlxplat_hotplug->regmap);
2138 if (err)
2139 goto fail_platform_wd_register;
2141 return 0;
2143 fail_platform_wd_register:
2144 while (--j >= 0)
2145 platform_device_unregister(priv->pdev_wd[j]);
2146 if (mlxplat_fan)
2147 platform_device_unregister(priv->pdev_fan);
2148 fail_platform_io_regs_register:
2149 if (mlxplat_regs_io)
2150 platform_device_unregister(priv->pdev_io_regs);
2151 fail_platform_led_register:
2152 platform_device_unregister(priv->pdev_led);
2153 fail_platform_hotplug_register:
2154 platform_device_unregister(priv->pdev_hotplug);
2155 fail_platform_mux_register:
2156 while (--i >= 0)
2157 platform_device_unregister(priv->pdev_mux[i]);
2158 platform_device_unregister(priv->pdev_i2c);
2159 fail_alloc:
2160 platform_device_unregister(mlxplat_dev);
2162 return err;
2164 module_init(mlxplat_init);
2166 static void __exit mlxplat_exit(void)
2168 struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
2169 int i;
2171 for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
2172 platform_device_unregister(priv->pdev_wd[i]);
2173 if (priv->pdev_fan)
2174 platform_device_unregister(priv->pdev_fan);
2175 if (priv->pdev_io_regs)
2176 platform_device_unregister(priv->pdev_io_regs);
2177 platform_device_unregister(priv->pdev_led);
2178 platform_device_unregister(priv->pdev_hotplug);
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");