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(adap: dev->adapter, info: dev->brdinfo);
421 if (IS_ERR(ptr: 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(ptr: 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(client: 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(client: 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(map: mlxreg_lc->par_regmap, reg: mlxreg_lc->data->reg_pwr, val: &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(map: mlxreg_lc->par_regmap, reg: mlxreg_lc->data->reg_pwr, val: 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(map: mlxreg_lc->par_regmap, reg: mlxreg_lc->data->reg_ena, val: &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(map: mlxreg_lc->par_regmap, reg: mlxreg_lc->data->reg_ena, val: 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, src: mlxreg_lc_aux_pwr_brdinfo,
519 len: 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, src: mlxreg_lc_main_pwr_brdinfo,
524 len: 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(lock: &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, state: 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, action: 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, action: 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, action: 1);
595
596 goto mlxreg_lc_enable_disable_exit;
597 }
598 err = mlxreg_lc_create_static_devices(mlxreg_lc, devs: mlxreg_lc->main_devs,
599 size: 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, action: 1);
606 } else {
607 mlxreg_lc_destroy_static_devices(mlxreg_lc, devs: mlxreg_lc->main_devs,
608 size: mlxreg_lc->main_devs_num);
609 }
610 mlxreg_lc_state_update(mlxreg_lc, state: 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: !!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, action: 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(lock: &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, devs: mlxreg_lc->aux_devs,
657 size: 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(map: mlxreg_lc->par_regmap, reg: mlxreg_lc->data->reg_pwr, val: &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, devs: mlxreg_lc->main_devs,
675 size: 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, state: MLXREG_LC_POWERED, action: 1);
680 }
681
682 /* Verify if line card is synchronized. */
683 err = regmap_read(map: mlxreg_lc->par_regmap, reg: mlxreg_lc->data->reg_sync, val: &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, state: MLXREG_LC_SYNCED, action: 1);
691 if (mlxreg_lc->state & ~MLXREG_LC_POWERED) {
692 err = mlxreg_lc_power_on_off(mlxreg_lc, action: 1);
693 if (err)
694 goto mlxreg_lc_regmap_power_on_off_fail;
695 }
696 }
697
698 mlxreg_lc_state_update_locked(mlxreg_lc, state: MLXREG_LC_INITIALIZED, action: 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, devs: mlxreg_lc->main_devs,
706 size: mlxreg_lc->main_devs_num);
707mlxreg_lc_create_static_devices_failed:
708 mlxreg_lc_destroy_static_devices(mlxreg_lc, devs: mlxreg_lc->aux_devs, size: 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(map: regmap, MLXREG_LC_REG_CONFIG_OFFSET, val: &lsb);
723 err = (!err) ? regmap_read(map: regmap, MLXREG_LC_REG_CONFIG_OFFSET, val: &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(parent: dev, name: "i2c-mux-mlxcpld", id: data->hpdev.nr,
746 NULL, num: 0, data: mlxreg_lc->mux_data,
747 size: sizeof(*mlxreg_lc->mux_data));
748 if (IS_ERR(ptr: 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(ptr: 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(parent: dev, name: "mlxreg-io", id: data->hpdev.nr, NULL, num: 0,
759 data: mlxreg_lc->io_data, size: sizeof(*mlxreg_lc->io_data));
760 if (IS_ERR(ptr: 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(ptr: 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(parent: dev, name: "leds-mlxreg", id: data->hpdev.nr, NULL, num: 0,
774 data: mlxreg_lc->led_data,
775 size: sizeof(*mlxreg_lc->led_data));
776 if (IS_ERR(ptr: 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(ptr: 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(dev: &pdev->dev);
819 if (!data)
820 return -EINVAL;
821
822 mlxreg_lc = devm_kzalloc(dev: &pdev->dev, size: 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(nr: 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(adap: data->hpdev.adapter,
841 info: data->hpdev.brdinfo);
842 if (IS_ERR(ptr: 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(ptr: 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(ptr: 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(ptr: 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(map: regmap, reg: mlxreg_lc_regmap_default[i].reg,
861 val: 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(map: regmap);
872 err = regcache_sync(map: 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, data: 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(client: data->hpdev.client);
897 data->hpdev.client = NULL;
898i2c_new_device_fail:
899 i2c_put_adapter(adap: 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(dev: &pdev->dev);
913 struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
914
915 mlxreg_lc_state_update_locked(mlxreg_lc, state: MLXREG_LC_INITIALIZED, action: 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, devs: mlxreg_lc->main_devs,
932 size: mlxreg_lc->main_devs_num);
933 /* Destroy static I2C device feeding by auxiliary power. */
934 mlxreg_lc_destroy_static_devices(mlxreg_lc, devs: mlxreg_lc->aux_devs, size: 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(client: data->hpdev.client);
939 data->hpdev.client = NULL;
940 i2c_put_adapter(adap: 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

source code of linux/drivers/platform/mellanox/mlxreg-lc.c