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