xref: /linux/drivers/platform/mellanox/mlxreg-lc.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Nvidia line card driver
4  *
5  * Copyright (C) 2020 Nvidia Technologies Ltd.
6  */
7 
8 #include <linux/device.h>
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <linux/platform_data/mlxcpld.h>
12 #include <linux/platform_data/mlxreg.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 
16 /* I2C bus IO offsets */
17 #define MLXREG_LC_REG_CPLD1_VER_OFFSET		0x2500
18 #define MLXREG_LC_REG_FPGA1_VER_OFFSET		0x2501
19 #define MLXREG_LC_REG_CPLD1_PN_OFFSET		0x2504
20 #define MLXREG_LC_REG_FPGA1_PN_OFFSET		0x2506
21 #define MLXREG_LC_REG_RESET_CAUSE_OFFSET	0x251d
22 #define MLXREG_LC_REG_LED1_OFFSET		0x2520
23 #define MLXREG_LC_REG_GP0_OFFSET		0x252e
24 #define MLXREG_LC_REG_FIELD_UPGRADE		0x2534
25 #define MLXREG_LC_CHANNEL_I2C_REG		0x25dc
26 #define MLXREG_LC_REG_CPLD1_MVER_OFFSET		0x25de
27 #define MLXREG_LC_REG_FPGA1_MVER_OFFSET		0x25df
28 #define MLXREG_LC_REG_MAX_POWER_OFFSET		0x25f1
29 #define MLXREG_LC_REG_CONFIG_OFFSET		0x25fb
30 #define MLXREG_LC_REG_MAX			0x3fff
31 
32 /**
33  * enum mlxreg_lc_type - line cards types
34  *
35  * @MLXREG_LC_SN4800_C16: 100GbE line card with 16 QSFP28 ports;
36  */
37 enum mlxreg_lc_type {
38 	MLXREG_LC_SN4800_C16 = 0x0000,
39 };
40 
41 /**
42  * enum mlxreg_lc_state - line cards state
43  *
44  * @MLXREG_LC_INITIALIZED: line card is initialized;
45  * @MLXREG_LC_POWERED: line card is powered;
46  * @MLXREG_LC_SYNCED: line card is synchronized between hardware and firmware;
47  */
48 enum mlxreg_lc_state {
49 	MLXREG_LC_INITIALIZED = BIT(0),
50 	MLXREG_LC_POWERED = BIT(1),
51 	MLXREG_LC_SYNCED = BIT(2),
52 };
53 
54 #define MLXREG_LC_CONFIGURED	(MLXREG_LC_INITIALIZED | MLXREG_LC_POWERED | MLXREG_LC_SYNCED)
55 
56 /* mlxreg_lc - device private data
57  * @dev: platform device;
58  * @lock: line card lock;
59  * @par_regmap: parent device regmap handle;
60  * @data: pltaform core data;
61  * @io_data: register access platform data;
62  * @led_data: LED platform data ;
63  * @mux_data: MUX platform data;
64  * @led: LED device;
65  * @io_regs: register access device;
66  * @mux_brdinfo: mux configuration;
67  * @mux: mux devices;
68  * @aux_devs: I2C devices feeding by auxiliary power;
69  * @aux_devs_num: number of I2C devices feeding by auxiliary power;
70  * @main_devs: I2C devices feeding by main power;
71  * @main_devs_num: number of I2C devices feeding by main power;
72  * @state: line card state;
73  */
74 struct mlxreg_lc {
75 	struct device *dev;
76 	struct mutex lock; /* line card access lock */
77 	void *par_regmap;
78 	struct mlxreg_core_data *data;
79 	struct mlxreg_core_platform_data *io_data;
80 	struct mlxreg_core_platform_data *led_data;
81 	struct mlxcpld_mux_plat_data *mux_data;
82 	struct platform_device *led;
83 	struct platform_device *io_regs;
84 	struct i2c_board_info *mux_brdinfo;
85 	struct platform_device *mux;
86 	struct mlxreg_hotplug_device *aux_devs;
87 	int aux_devs_num;
88 	struct mlxreg_hotplug_device *main_devs;
89 	int main_devs_num;
90 	enum mlxreg_lc_state state;
91 };
92 
mlxreg_lc_writeable_reg(struct device * dev,unsigned int reg)93 static bool mlxreg_lc_writeable_reg(struct device *dev, unsigned int reg)
94 {
95 	switch (reg) {
96 	case MLXREG_LC_REG_LED1_OFFSET:
97 	case MLXREG_LC_REG_GP0_OFFSET:
98 	case MLXREG_LC_REG_FIELD_UPGRADE:
99 	case MLXREG_LC_CHANNEL_I2C_REG:
100 		return true;
101 	}
102 	return false;
103 }
104 
mlxreg_lc_readable_reg(struct device * dev,unsigned int reg)105 static bool mlxreg_lc_readable_reg(struct device *dev, unsigned int reg)
106 {
107 	switch (reg) {
108 	case MLXREG_LC_REG_CPLD1_VER_OFFSET:
109 	case MLXREG_LC_REG_FPGA1_VER_OFFSET:
110 	case MLXREG_LC_REG_CPLD1_PN_OFFSET:
111 	case MLXREG_LC_REG_FPGA1_PN_OFFSET:
112 	case MLXREG_LC_REG_RESET_CAUSE_OFFSET:
113 	case MLXREG_LC_REG_LED1_OFFSET:
114 	case MLXREG_LC_REG_GP0_OFFSET:
115 	case MLXREG_LC_REG_FIELD_UPGRADE:
116 	case MLXREG_LC_CHANNEL_I2C_REG:
117 	case MLXREG_LC_REG_CPLD1_MVER_OFFSET:
118 	case MLXREG_LC_REG_FPGA1_MVER_OFFSET:
119 	case MLXREG_LC_REG_MAX_POWER_OFFSET:
120 	case MLXREG_LC_REG_CONFIG_OFFSET:
121 		return true;
122 	}
123 	return false;
124 }
125 
mlxreg_lc_volatile_reg(struct device * dev,unsigned int reg)126 static bool mlxreg_lc_volatile_reg(struct device *dev, unsigned int reg)
127 {
128 	switch (reg) {
129 	case MLXREG_LC_REG_CPLD1_VER_OFFSET:
130 	case MLXREG_LC_REG_FPGA1_VER_OFFSET:
131 	case MLXREG_LC_REG_CPLD1_PN_OFFSET:
132 	case MLXREG_LC_REG_FPGA1_PN_OFFSET:
133 	case MLXREG_LC_REG_RESET_CAUSE_OFFSET:
134 	case MLXREG_LC_REG_LED1_OFFSET:
135 	case MLXREG_LC_REG_GP0_OFFSET:
136 	case MLXREG_LC_REG_FIELD_UPGRADE:
137 	case MLXREG_LC_CHANNEL_I2C_REG:
138 	case MLXREG_LC_REG_CPLD1_MVER_OFFSET:
139 	case MLXREG_LC_REG_FPGA1_MVER_OFFSET:
140 	case MLXREG_LC_REG_MAX_POWER_OFFSET:
141 	case MLXREG_LC_REG_CONFIG_OFFSET:
142 		return true;
143 	}
144 	return false;
145 }
146 
147 static const struct reg_default mlxreg_lc_regmap_default[] = {
148 	{ MLXREG_LC_CHANNEL_I2C_REG, 0x00 },
149 };
150 
151 /* Configuration for the register map of a device with 2 bytes address space. */
152 static const struct regmap_config mlxreg_lc_regmap_conf = {
153 	.reg_bits = 16,
154 	.val_bits = 8,
155 	.max_register = MLXREG_LC_REG_MAX,
156 	.cache_type = REGCACHE_FLAT,
157 	.writeable_reg = mlxreg_lc_writeable_reg,
158 	.readable_reg = mlxreg_lc_readable_reg,
159 	.volatile_reg = mlxreg_lc_volatile_reg,
160 	.reg_defaults = mlxreg_lc_regmap_default,
161 	.num_reg_defaults = ARRAY_SIZE(mlxreg_lc_regmap_default),
162 };
163 
164 /* Default channels vector.
165  * It contains only the channels, which physically connected to the devices,
166  * empty channels are skipped.
167  */
168 static int mlxreg_lc_chan[] = {
169 	0x04, 0x05, 0x06, 0x07, 0x08, 0x10, 0x20, 0x21, 0x22, 0x23, 0x40, 0x41,
170 	0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
171 	0x4e, 0x4f
172 };
173 
174 /* Defaul mux configuration. */
175 static struct mlxcpld_mux_plat_data mlxreg_lc_mux_data[] = {
176 	{
177 		.chan_ids = mlxreg_lc_chan,
178 		.num_adaps = ARRAY_SIZE(mlxreg_lc_chan),
179 		.sel_reg_addr = MLXREG_LC_CHANNEL_I2C_REG,
180 		.reg_size = 2,
181 	},
182 };
183 
184 /* Defaul mux board info. */
185 static struct i2c_board_info mlxreg_lc_mux_brdinfo = {
186 	I2C_BOARD_INFO("i2c-mux-mlxcpld", 0x32),
187 };
188 
189 /* Line card default auxiliary power static devices. */
190 static struct i2c_board_info mlxreg_lc_aux_pwr_devices[] = {
191 	{
192 		I2C_BOARD_INFO("24c32", 0x51),
193 	},
194 	{
195 		I2C_BOARD_INFO("24c32", 0x51),
196 	},
197 };
198 
199 /* Line card default auxiliary power board info. */
200 static struct mlxreg_hotplug_device mlxreg_lc_aux_pwr_brdinfo[] = {
201 	{
202 		.brdinfo = &mlxreg_lc_aux_pwr_devices[0],
203 		.nr = 3,
204 	},
205 	{
206 		.brdinfo = &mlxreg_lc_aux_pwr_devices[1],
207 		.nr = 4,
208 	},
209 };
210 
211 /* Line card default main power static devices. */
212 static struct i2c_board_info mlxreg_lc_main_pwr_devices[] = {
213 	{
214 		I2C_BOARD_INFO("mp2975", 0x62),
215 	},
216 	{
217 		I2C_BOARD_INFO("mp2975", 0x64),
218 	},
219 	{
220 		I2C_BOARD_INFO("max11603", 0x6d),
221 	},
222 	{
223 		I2C_BOARD_INFO("lm25066", 0x15),
224 	},
225 };
226 
227 /* Line card default main power board info. */
228 static struct mlxreg_hotplug_device mlxreg_lc_main_pwr_brdinfo[] = {
229 	{
230 		.brdinfo = &mlxreg_lc_main_pwr_devices[0],
231 		.nr = 0,
232 	},
233 	{
234 		.brdinfo = &mlxreg_lc_main_pwr_devices[1],
235 		.nr = 0,
236 	},
237 	{
238 		.brdinfo = &mlxreg_lc_main_pwr_devices[2],
239 		.nr = 1,
240 	},
241 	{
242 		.brdinfo = &mlxreg_lc_main_pwr_devices[3],
243 		.nr = 2,
244 	},
245 };
246 
247 /* LED default data. */
248 static struct mlxreg_core_data mlxreg_lc_led_data[] = {
249 	{
250 		.label = "status:green",
251 		.reg = MLXREG_LC_REG_LED1_OFFSET,
252 		.mask = GENMASK(7, 4),
253 	},
254 	{
255 		.label = "status:orange",
256 		.reg = MLXREG_LC_REG_LED1_OFFSET,
257 		.mask = GENMASK(7, 4),
258 	},
259 };
260 
261 static struct mlxreg_core_platform_data mlxreg_lc_led = {
262 	.identity = "pci",
263 	.data = mlxreg_lc_led_data,
264 	.counter = ARRAY_SIZE(mlxreg_lc_led_data),
265 };
266 
267 /* Default register access data. */
268 static struct mlxreg_core_data mlxreg_lc_io_data[] = {
269 	{
270 		.label = "cpld1_version",
271 		.reg = MLXREG_LC_REG_CPLD1_VER_OFFSET,
272 		.bit = GENMASK(7, 0),
273 		.mode = 0444,
274 	},
275 	{
276 		.label = "fpga1_version",
277 		.reg = MLXREG_LC_REG_FPGA1_VER_OFFSET,
278 		.bit = GENMASK(7, 0),
279 		.mode = 0444,
280 	},
281 	{
282 		.label = "cpld1_pn",
283 		.reg = MLXREG_LC_REG_CPLD1_PN_OFFSET,
284 		.bit = GENMASK(15, 0),
285 		.mode = 0444,
286 		.regnum = 2,
287 	},
288 	{
289 		.label = "fpga1_pn",
290 		.reg = MLXREG_LC_REG_FPGA1_PN_OFFSET,
291 		.bit = GENMASK(15, 0),
292 		.mode = 0444,
293 		.regnum = 2,
294 	},
295 	{
296 		.label = "cpld1_version_min",
297 		.reg = MLXREG_LC_REG_CPLD1_MVER_OFFSET,
298 		.bit = GENMASK(7, 0),
299 		.mode = 0444,
300 	},
301 	{
302 		.label = "fpga1_version_min",
303 		.reg = MLXREG_LC_REG_FPGA1_MVER_OFFSET,
304 		.bit = GENMASK(7, 0),
305 		.mode = 0444,
306 	},
307 	{
308 		.label = "reset_fpga_not_done",
309 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
310 		.mask = GENMASK(7, 0) & ~BIT(1),
311 		.mode = 0444,
312 	},
313 	{
314 		.label = "reset_aux_pwr_or_ref",
315 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
316 		.mask = GENMASK(7, 0) & ~BIT(2),
317 		.mode = 0444,
318 	},
319 	{
320 		.label = "reset_dc_dc_pwr_fail",
321 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
322 		.mask = GENMASK(7, 0) & ~BIT(3),
323 		.mode = 0444,
324 	},
325 	{
326 		.label = "reset_from_chassis",
327 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
328 		.mask = GENMASK(7, 0) & ~BIT(4),
329 		.mode = 0444,
330 	},
331 	{
332 		.label = "reset_pwr_off_from_chassis",
333 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
334 		.mask = GENMASK(7, 0) & ~BIT(5),
335 		.mode = 0444,
336 	},
337 	{
338 		.label = "reset_line_card",
339 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
340 		.mask = GENMASK(7, 0) & ~BIT(6),
341 		.mode = 0444,
342 	},
343 	{
344 		.label = "reset_line_card_pwr_en",
345 		.reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
346 		.mask = GENMASK(7, 0) & ~BIT(7),
347 		.mode = 0444,
348 	},
349 	{
350 		.label = "cpld_upgrade_en",
351 		.reg = MLXREG_LC_REG_FIELD_UPGRADE,
352 		.mask = GENMASK(7, 0) & ~BIT(0),
353 		.mode = 0644,
354 		.secured = 1,
355 	},
356 	{
357 		.label = "fpga_upgrade_en",
358 		.reg = MLXREG_LC_REG_FIELD_UPGRADE,
359 		.mask = GENMASK(7, 0) & ~BIT(1),
360 		.mode = 0644,
361 		.secured = 1,
362 	},
363 	{
364 		.label = "qsfp_pwr_en",
365 		.reg = MLXREG_LC_REG_GP0_OFFSET,
366 		.mask = GENMASK(7, 0) & ~BIT(0),
367 		.mode = 0644,
368 	},
369 	{
370 		.label = "vpd_wp",
371 		.reg = MLXREG_LC_REG_GP0_OFFSET,
372 		.mask = GENMASK(7, 0) & ~BIT(3),
373 		.mode = 0644,
374 		.secured = 1,
375 	},
376 	{
377 		.label = "agb_spi_burn_en",
378 		.reg = MLXREG_LC_REG_GP0_OFFSET,
379 		.mask = GENMASK(7, 0) & ~BIT(5),
380 		.mode = 0644,
381 		.secured = 1,
382 	},
383 	{
384 		.label = "fpga_spi_burn_en",
385 		.reg = MLXREG_LC_REG_GP0_OFFSET,
386 		.mask = GENMASK(7, 0) & ~BIT(6),
387 		.mode = 0644,
388 		.secured = 1,
389 	},
390 	{
391 		.label = "max_power",
392 		.reg = MLXREG_LC_REG_MAX_POWER_OFFSET,
393 		.bit = GENMASK(15, 0),
394 		.mode = 0444,
395 		.regnum = 2,
396 	},
397 	{
398 		.label = "config",
399 		.reg = MLXREG_LC_REG_CONFIG_OFFSET,
400 		.bit = GENMASK(15, 0),
401 		.mode = 0444,
402 		.regnum = 2,
403 	},
404 };
405 
406 static struct mlxreg_core_platform_data mlxreg_lc_regs_io = {
407 	.data = mlxreg_lc_io_data,
408 	.counter = ARRAY_SIZE(mlxreg_lc_io_data),
409 };
410 
411 static int
mlxreg_lc_create_static_devices(struct mlxreg_lc * mlxreg_lc,struct mlxreg_hotplug_device * devs,int size)412 mlxreg_lc_create_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotplug_device *devs,
413 				int size)
414 {
415 	struct mlxreg_hotplug_device *dev = devs;
416 	int i, ret;
417 
418 	/* Create static I2C device feeding by auxiliary or main power. */
419 	for (i = 0; i < size; i++, dev++) {
420 		dev->client = i2c_new_client_device(dev->adapter, dev->brdinfo);
421 		if (IS_ERR(dev->client)) {
422 			dev_err(mlxreg_lc->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
423 				dev->brdinfo->type, dev->nr, dev->brdinfo->addr);
424 
425 			dev->adapter = NULL;
426 			ret = PTR_ERR(dev->client);
427 			goto fail_create_static_devices;
428 		}
429 	}
430 
431 	return 0;
432 
433 fail_create_static_devices:
434 	while (--i >= 0) {
435 		dev = devs + i;
436 		i2c_unregister_device(dev->client);
437 		dev->client = NULL;
438 	}
439 	return ret;
440 }
441 
442 static void
mlxreg_lc_destroy_static_devices(struct mlxreg_lc * mlxreg_lc,struct mlxreg_hotplug_device * devs,int size)443 mlxreg_lc_destroy_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotplug_device *devs,
444 				 int size)
445 {
446 	struct mlxreg_hotplug_device *dev = devs;
447 	int i;
448 
449 	/* Destroy static I2C device feeding by auxiliary or main power. */
450 	for (i = 0; i < size; i++, dev++) {
451 		if (dev->client) {
452 			i2c_unregister_device(dev->client);
453 			dev->client = NULL;
454 		}
455 	}
456 }
457 
mlxreg_lc_power_on_off(struct mlxreg_lc * mlxreg_lc,u8 action)458 static int mlxreg_lc_power_on_off(struct mlxreg_lc *mlxreg_lc, u8 action)
459 {
460 	u32 regval;
461 	int err;
462 
463 	err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, &regval);
464 	if (err)
465 		goto regmap_read_fail;
466 
467 	if (action)
468 		regval |= BIT(mlxreg_lc->data->slot - 1);
469 	else
470 		regval &= ~BIT(mlxreg_lc->data->slot - 1);
471 
472 	err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, regval);
473 
474 regmap_read_fail:
475 	return err;
476 }
477 
mlxreg_lc_enable_disable(struct mlxreg_lc * mlxreg_lc,bool action)478 static int mlxreg_lc_enable_disable(struct mlxreg_lc *mlxreg_lc, bool action)
479 {
480 	u32 regval;
481 	int err;
482 
483 	/*
484 	 * Hardware holds the line card after powering on in the disabled state. Holding line card
485 	 * in disabled state protects access to the line components, like FPGA and gearboxes.
486 	 * Line card should be enabled in order to get it in operational state. Line card could be
487 	 * disabled for moving it to non-operational state. Enabling line card does not affect the
488 	 * line card which is already has been enabled. Disabling does not affect the disabled line
489 	 * card.
490 	 */
491 	err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, &regval);
492 	if (err)
493 		goto regmap_read_fail;
494 
495 	if (action)
496 		regval |= BIT(mlxreg_lc->data->slot - 1);
497 	else
498 		regval &= ~BIT(mlxreg_lc->data->slot - 1);
499 
500 	err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, regval);
501 
502 regmap_read_fail:
503 	return err;
504 }
505 
506 static int
mlxreg_lc_sn4800_c16_config_init(struct mlxreg_lc * mlxreg_lc,void * regmap,struct mlxreg_core_data * data)507 mlxreg_lc_sn4800_c16_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
508 				 struct mlxreg_core_data *data)
509 {
510 	struct device *dev = &data->hpdev.client->dev;
511 
512 	/* Set line card configuration according to the type. */
513 	mlxreg_lc->mux_data = mlxreg_lc_mux_data;
514 	mlxreg_lc->io_data = &mlxreg_lc_regs_io;
515 	mlxreg_lc->led_data = &mlxreg_lc_led;
516 	mlxreg_lc->mux_brdinfo = &mlxreg_lc_mux_brdinfo;
517 
518 	mlxreg_lc->aux_devs = devm_kmemdup(dev, mlxreg_lc_aux_pwr_brdinfo,
519 					   sizeof(mlxreg_lc_aux_pwr_brdinfo), GFP_KERNEL);
520 	if (!mlxreg_lc->aux_devs)
521 		return -ENOMEM;
522 	mlxreg_lc->aux_devs_num = ARRAY_SIZE(mlxreg_lc_aux_pwr_brdinfo);
523 	mlxreg_lc->main_devs = devm_kmemdup(dev, mlxreg_lc_main_pwr_brdinfo,
524 					    sizeof(mlxreg_lc_main_pwr_brdinfo), GFP_KERNEL);
525 	if (!mlxreg_lc->main_devs)
526 		return -ENOMEM;
527 	mlxreg_lc->main_devs_num = ARRAY_SIZE(mlxreg_lc_main_pwr_brdinfo);
528 
529 	return 0;
530 }
531 
532 static void
mlxreg_lc_state_update(struct mlxreg_lc * mlxreg_lc,enum mlxreg_lc_state state,u8 action)533 mlxreg_lc_state_update(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action)
534 {
535 	if (action)
536 		mlxreg_lc->state |= state;
537 	else
538 		mlxreg_lc->state &= ~state;
539 }
540 
541 static void
mlxreg_lc_state_update_locked(struct mlxreg_lc * mlxreg_lc,enum mlxreg_lc_state state,u8 action)542 mlxreg_lc_state_update_locked(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action)
543 {
544 	mutex_lock(&mlxreg_lc->lock);
545 
546 	if (action)
547 		mlxreg_lc->state |= state;
548 	else
549 		mlxreg_lc->state &= ~state;
550 
551 	mutex_unlock(&mlxreg_lc->lock);
552 }
553 
554 /*
555  * Callback is to be called from mlxreg-hotplug driver to notify about line card about received
556  * event.
557  */
mlxreg_lc_event_handler(void * handle,enum mlxreg_hotplug_kind kind,u8 action)558 static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind, u8 action)
559 {
560 	struct mlxreg_lc *mlxreg_lc = handle;
561 	int err = 0;
562 
563 	dev_info(mlxreg_lc->dev, "linecard#%d state %d event kind %d action %d\n",
564 		 mlxreg_lc->data->slot, mlxreg_lc->state, kind, action);
565 
566 	mutex_lock(&mlxreg_lc->lock);
567 	if (!(mlxreg_lc->state & MLXREG_LC_INITIALIZED))
568 		goto mlxreg_lc_non_initialzed_exit;
569 
570 	switch (kind) {
571 	case MLXREG_HOTPLUG_LC_SYNCED:
572 		/*
573 		 * Synchronization event - hardware and firmware are synchronized. Power on/off
574 		 * line card - to allow/disallow main power source.
575 		 */
576 		mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_SYNCED, action);
577 		/* Power line card if it is not powered yet. */
578 		if (!(mlxreg_lc->state & MLXREG_LC_POWERED) && action) {
579 			err = mlxreg_lc_power_on_off(mlxreg_lc, 1);
580 			if (err)
581 				goto mlxreg_lc_power_on_off_fail;
582 		}
583 		/* In case line card is configured - enable it. */
584 		if (mlxreg_lc->state & MLXREG_LC_CONFIGURED && action)
585 			err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
586 		break;
587 	case MLXREG_HOTPLUG_LC_POWERED:
588 		/* Power event - attach or de-attach line card device feeding by the main power. */
589 		if (action) {
590 			/* Do not create devices, if line card is already powered. */
591 			if (mlxreg_lc->state & MLXREG_LC_POWERED) {
592 				/* In case line card is configured - enable it. */
593 				if (mlxreg_lc->state & MLXREG_LC_CONFIGURED)
594 					err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
595 
596 				goto mlxreg_lc_enable_disable_exit;
597 			}
598 			err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
599 							      mlxreg_lc->main_devs_num);
600 			if (err)
601 				goto mlxreg_lc_create_static_devices_fail;
602 
603 			/* In case line card is already in ready state - enable it. */
604 			if (mlxreg_lc->state & MLXREG_LC_CONFIGURED)
605 				err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
606 		} else {
607 			mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
608 							 mlxreg_lc->main_devs_num);
609 		}
610 		mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_POWERED, action);
611 		break;
612 	case MLXREG_HOTPLUG_LC_READY:
613 		/*
614 		 * Ready event – enable line card by releasing it from reset or disable it by put
615 		 * to reset state.
616 		 */
617 		err = mlxreg_lc_enable_disable(mlxreg_lc, !!action);
618 		break;
619 	case MLXREG_HOTPLUG_LC_THERMAL:
620 		/* Thermal shutdown event – power off line card. */
621 		if (action)
622 			err = mlxreg_lc_power_on_off(mlxreg_lc, 0);
623 		break;
624 	default:
625 		break;
626 	}
627 
628 mlxreg_lc_enable_disable_exit:
629 mlxreg_lc_power_on_off_fail:
630 mlxreg_lc_create_static_devices_fail:
631 mlxreg_lc_non_initialzed_exit:
632 	mutex_unlock(&mlxreg_lc->lock);
633 
634 	return err;
635 }
636 
637 /*
638  * Callback is to be called from i2c-mux-mlxcpld driver to indicate that all adapter devices has
639  * been created.
640  */
mlxreg_lc_completion_notify(void * handle,struct i2c_adapter * parent,struct i2c_adapter * adapters[])641 static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent,
642 				       struct i2c_adapter *adapters[])
643 {
644 	struct mlxreg_hotplug_device *main_dev, *aux_dev;
645 	struct mlxreg_lc *mlxreg_lc = handle;
646 	u32 regval;
647 	int i, err;
648 
649 	/* Update I2C devices feeding by auxiliary power. */
650 	aux_dev = mlxreg_lc->aux_devs;
651 	for (i = 0; i < mlxreg_lc->aux_devs_num; i++, aux_dev++) {
652 		aux_dev->adapter = adapters[aux_dev->nr];
653 		aux_dev->nr = adapters[aux_dev->nr]->nr;
654 	}
655 
656 	err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->aux_devs,
657 					      mlxreg_lc->aux_devs_num);
658 	if (err)
659 		return err;
660 
661 	/* Update I2C devices feeding by main power. */
662 	main_dev = mlxreg_lc->main_devs;
663 	for (i = 0; i < mlxreg_lc->main_devs_num; i++, main_dev++) {
664 		main_dev->adapter = adapters[main_dev->nr];
665 		main_dev->nr = adapters[main_dev->nr]->nr;
666 	}
667 
668 	/* Verify if line card is powered. */
669 	err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, &regval);
670 	if (err)
671 		goto mlxreg_lc_regmap_read_power_fail;
672 
673 	if (regval & mlxreg_lc->data->mask) {
674 		err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
675 						      mlxreg_lc->main_devs_num);
676 		if (err)
677 			goto mlxreg_lc_create_static_devices_failed;
678 
679 		mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_POWERED, 1);
680 	}
681 
682 	/* Verify if line card is synchronized. */
683 	err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_sync, &regval);
684 	if (err)
685 		goto mlxreg_lc_regmap_read_sync_fail;
686 
687 	/* Power on line card if necessary. */
688 	if (regval & mlxreg_lc->data->mask) {
689 		mlxreg_lc->state |= MLXREG_LC_SYNCED;
690 		mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_SYNCED, 1);
691 		if (mlxreg_lc->state & ~MLXREG_LC_POWERED) {
692 			err = mlxreg_lc_power_on_off(mlxreg_lc, 1);
693 			if (err)
694 				goto mlxreg_lc_regmap_power_on_off_fail;
695 		}
696 	}
697 
698 	mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_INITIALIZED, 1);
699 
700 	return 0;
701 
702 mlxreg_lc_regmap_power_on_off_fail:
703 mlxreg_lc_regmap_read_sync_fail:
704 	if (mlxreg_lc->state & MLXREG_LC_POWERED)
705 		mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
706 						 mlxreg_lc->main_devs_num);
707 mlxreg_lc_create_static_devices_failed:
708 	mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
709 mlxreg_lc_regmap_read_power_fail:
710 	return err;
711 }
712 
713 static int
mlxreg_lc_config_init(struct mlxreg_lc * mlxreg_lc,void * regmap,struct mlxreg_core_data * data)714 mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
715 		      struct mlxreg_core_data *data)
716 {
717 	struct device *dev = &data->hpdev.client->dev;
718 	int lsb, err;
719 	u32 regval;
720 
721 	/* Validate line card type. */
722 	err = regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, &lsb);
723 	err = (!err) ? regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, &regval) : err;
724 	if (err)
725 		return err;
726 	regval = (regval & GENMASK(7, 0)) << 8 | (lsb & GENMASK(7, 0));
727 	switch (regval) {
728 	case MLXREG_LC_SN4800_C16:
729 		err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data);
730 		if (err) {
731 			dev_err(dev, "Failed to config client %s at bus %d at addr 0x%02x\n",
732 				data->hpdev.brdinfo->type, data->hpdev.nr,
733 				data->hpdev.brdinfo->addr);
734 			return err;
735 		}
736 		break;
737 	default:
738 		return -ENODEV;
739 	}
740 
741 	/* Create mux infrastructure. */
742 	mlxreg_lc->mux_data->handle = mlxreg_lc;
743 	mlxreg_lc->mux_data->completion_notify = mlxreg_lc_completion_notify;
744 	mlxreg_lc->mux_brdinfo->platform_data = mlxreg_lc->mux_data;
745 	mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr,
746 							   NULL, 0, mlxreg_lc->mux_data,
747 							   sizeof(*mlxreg_lc->mux_data));
748 	if (IS_ERR(mlxreg_lc->mux)) {
749 		dev_err(dev, "Failed to create mux infra for client %s at bus %d at addr 0x%02x\n",
750 			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
751 		return PTR_ERR(mlxreg_lc->mux);
752 	}
753 
754 	/* Register IO access driver. */
755 	if (mlxreg_lc->io_data) {
756 		mlxreg_lc->io_data->regmap = regmap;
757 		mlxreg_lc->io_regs =
758 		platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0,
759 						  mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data));
760 		if (IS_ERR(mlxreg_lc->io_regs)) {
761 			dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
762 				data->hpdev.brdinfo->type, data->hpdev.nr,
763 				data->hpdev.brdinfo->addr);
764 			err = PTR_ERR(mlxreg_lc->io_regs);
765 			goto fail_register_io;
766 		}
767 	}
768 
769 	/* Register LED driver. */
770 	if (mlxreg_lc->led_data) {
771 		mlxreg_lc->led_data->regmap = regmap;
772 		mlxreg_lc->led =
773 		platform_device_register_resndata(dev, "leds-mlxreg", data->hpdev.nr, NULL, 0,
774 						  mlxreg_lc->led_data,
775 						  sizeof(*mlxreg_lc->led_data));
776 		if (IS_ERR(mlxreg_lc->led)) {
777 			dev_err(dev, "Failed to create LED objects for client %s at bus %d at addr 0x%02x\n",
778 				data->hpdev.brdinfo->type, data->hpdev.nr,
779 				data->hpdev.brdinfo->addr);
780 			err = PTR_ERR(mlxreg_lc->led);
781 			goto fail_register_led;
782 		}
783 	}
784 
785 	return 0;
786 
787 fail_register_led:
788 	if (mlxreg_lc->io_regs)
789 		platform_device_unregister(mlxreg_lc->io_regs);
790 fail_register_io:
791 	if (mlxreg_lc->mux)
792 		platform_device_unregister(mlxreg_lc->mux);
793 
794 	return err;
795 }
796 
mlxreg_lc_config_exit(struct mlxreg_lc * mlxreg_lc)797 static void mlxreg_lc_config_exit(struct mlxreg_lc *mlxreg_lc)
798 {
799 	/* Unregister LED driver. */
800 	if (mlxreg_lc->led)
801 		platform_device_unregister(mlxreg_lc->led);
802 	/* Unregister IO access driver. */
803 	if (mlxreg_lc->io_regs)
804 		platform_device_unregister(mlxreg_lc->io_regs);
805 	/* Remove mux infrastructure. */
806 	if (mlxreg_lc->mux)
807 		platform_device_unregister(mlxreg_lc->mux);
808 }
809 
mlxreg_lc_probe(struct platform_device * pdev)810 static int mlxreg_lc_probe(struct platform_device *pdev)
811 {
812 	struct mlxreg_core_hotplug_platform_data *par_pdata;
813 	struct mlxreg_core_data *data;
814 	struct mlxreg_lc *mlxreg_lc;
815 	void *regmap;
816 	int i, err;
817 
818 	data = dev_get_platdata(&pdev->dev);
819 	if (!data)
820 		return -EINVAL;
821 
822 	mlxreg_lc = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_lc), GFP_KERNEL);
823 	if (!mlxreg_lc)
824 		return -ENOMEM;
825 
826 	mutex_init(&mlxreg_lc->lock);
827 	/* Set event notification callback. */
828 	data->notifier->user_handler = mlxreg_lc_event_handler;
829 	data->notifier->handle = mlxreg_lc;
830 
831 	data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
832 	if (!data->hpdev.adapter) {
833 		dev_err(&pdev->dev, "Failed to get adapter for bus %d\n",
834 			data->hpdev.nr);
835 		err = -EFAULT;
836 		goto i2c_get_adapter_fail;
837 	}
838 
839 	/* Create device at the top of line card I2C tree.*/
840 	data->hpdev.client = i2c_new_client_device(data->hpdev.adapter,
841 						   data->hpdev.brdinfo);
842 	if (IS_ERR(data->hpdev.client)) {
843 		dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
844 			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
845 		err = PTR_ERR(data->hpdev.client);
846 		goto i2c_new_device_fail;
847 	}
848 
849 	regmap = devm_regmap_init_i2c(data->hpdev.client,
850 				      &mlxreg_lc_regmap_conf);
851 	if (IS_ERR(regmap)) {
852 		dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
853 			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
854 		err = PTR_ERR(regmap);
855 		goto devm_regmap_init_i2c_fail;
856 	}
857 
858 	/* Set default registers. */
859 	for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) {
860 		err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg,
861 				   mlxreg_lc_regmap_default[i].def);
862 		if (err) {
863 			dev_err(&pdev->dev, "Failed to set default regmap %d for client %s at bus %d at addr 0x%02x\n",
864 				i, data->hpdev.brdinfo->type, data->hpdev.nr,
865 				data->hpdev.brdinfo->addr);
866 			goto regmap_write_fail;
867 		}
868 	}
869 
870 	/* Sync registers with hardware. */
871 	regcache_mark_dirty(regmap);
872 	err = regcache_sync(regmap);
873 	if (err) {
874 		dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
875 			data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
876 		goto regcache_sync_fail;
877 	}
878 
879 	par_pdata = data->hpdev.brdinfo->platform_data;
880 	mlxreg_lc->par_regmap = par_pdata->regmap;
881 	mlxreg_lc->data = data;
882 	mlxreg_lc->dev = &pdev->dev;
883 	platform_set_drvdata(pdev, mlxreg_lc);
884 
885 	/* Configure line card. */
886 	err = mlxreg_lc_config_init(mlxreg_lc, regmap, data);
887 	if (err)
888 		goto mlxreg_lc_config_init_fail;
889 
890 	return 0;
891 
892 mlxreg_lc_config_init_fail:
893 regcache_sync_fail:
894 regmap_write_fail:
895 devm_regmap_init_i2c_fail:
896 	i2c_unregister_device(data->hpdev.client);
897 	data->hpdev.client = NULL;
898 i2c_new_device_fail:
899 	i2c_put_adapter(data->hpdev.adapter);
900 	data->hpdev.adapter = NULL;
901 i2c_get_adapter_fail:
902 	/* Clear event notification callback and handle. */
903 	if (data->notifier) {
904 		data->notifier->user_handler = NULL;
905 		data->notifier->handle = NULL;
906 	}
907 	return err;
908 }
909 
mlxreg_lc_remove(struct platform_device * pdev)910 static void mlxreg_lc_remove(struct platform_device *pdev)
911 {
912 	struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
913 	struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
914 
915 	mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_INITIALIZED, 0);
916 
917 	/*
918 	 * Probing and removing are invoked by hotplug events raised upon line card insertion and
919 	 * removing. If probing procedure fails all data is cleared. However, hotplug event still
920 	 * will be raised on line card removing and activate removing procedure. In this case there
921 	 * is nothing to remove.
922 	 */
923 	if (!data->notifier || !data->notifier->handle)
924 		return;
925 
926 	/* Clear event notification callback and handle. */
927 	data->notifier->user_handler = NULL;
928 	data->notifier->handle = NULL;
929 
930 	/* Destroy static I2C device feeding by main power. */
931 	mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
932 					 mlxreg_lc->main_devs_num);
933 	/* Destroy static I2C device feeding by auxiliary power. */
934 	mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
935 	/* Unregister underlying drivers. */
936 	mlxreg_lc_config_exit(mlxreg_lc);
937 	if (data->hpdev.client) {
938 		i2c_unregister_device(data->hpdev.client);
939 		data->hpdev.client = NULL;
940 		i2c_put_adapter(data->hpdev.adapter);
941 		data->hpdev.adapter = NULL;
942 	}
943 }
944 
945 static struct platform_driver mlxreg_lc_driver = {
946 	.probe = mlxreg_lc_probe,
947 	.remove_new = mlxreg_lc_remove,
948 	.driver = {
949 		.name = "mlxreg-lc",
950 	},
951 };
952 
953 module_platform_driver(mlxreg_lc_driver);
954 
955 MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>");
956 MODULE_DESCRIPTION("Nvidia line card platform driver");
957 MODULE_LICENSE("Dual BSD/GPL");
958 MODULE_ALIAS("platform:mlxreg-lc");
959