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 */
37enum 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 */
48enum 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 */
74struct 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
93static 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
105static 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
126static 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
147static 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. */
152static 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 */
168static 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. */
175static 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. */
185static 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. */
190static 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. */
200static 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. */
212static 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. */
228static 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. */
248static 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
261static 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. */
268static 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
406static 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
411static int
412mlxreg_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
433fail_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
442static void
443mlxreg_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
458static 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
474regmap_read_fail:
475	return err;
476}
477
478static 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
502regmap_read_fail:
503	return err;
504}
505
506static int
507mlxreg_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
532static void
533mlxreg_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
541static void
542mlxreg_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 */
558static 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
628mlxreg_lc_enable_disable_exit:
629mlxreg_lc_power_on_off_fail:
630mlxreg_lc_create_static_devices_fail:
631mlxreg_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 */
641static 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
702mlxreg_lc_regmap_power_on_off_fail:
703mlxreg_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);
707mlxreg_lc_create_static_devices_failed:
708	mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
709mlxreg_lc_regmap_read_power_fail:
710	return err;
711}
712
713static int
714mlxreg_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
787fail_register_led:
788	if (mlxreg_lc->io_regs)
789		platform_device_unregister(mlxreg_lc->io_regs);
790fail_register_io:
791	if (mlxreg_lc->mux)
792		platform_device_unregister(mlxreg_lc->mux);
793
794	return err;
795}
796
797static 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
810static 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
892mlxreg_lc_config_init_fail:
893regcache_sync_fail:
894regmap_write_fail:
895devm_regmap_init_i2c_fail:
896	i2c_unregister_device(data->hpdev.client);
897	data->hpdev.client = NULL;
898i2c_new_device_fail:
899	i2c_put_adapter(data->hpdev.adapter);
900	data->hpdev.adapter = NULL;
901i2c_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
910static 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
945static 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
953module_platform_driver(mlxreg_lc_driver);
954
955MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>");
956MODULE_DESCRIPTION("Nvidia line card platform driver");
957MODULE_LICENSE("Dual BSD/GPL");
958MODULE_ALIAS("platform:mlxreg-lc");
959