mlxreg-lc.c (24492B)
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 mutex_lock(&mlxreg_lc->lock); 464 465 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, ®val); 466 if (err) 467 goto regmap_read_fail; 468 469 if (action) 470 regval |= BIT(mlxreg_lc->data->slot - 1); 471 else 472 regval &= ~BIT(mlxreg_lc->data->slot - 1); 473 474 err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, regval); 475 476regmap_read_fail: 477 mutex_unlock(&mlxreg_lc->lock); 478 return err; 479} 480 481static int mlxreg_lc_enable_disable(struct mlxreg_lc *mlxreg_lc, bool action) 482{ 483 u32 regval; 484 int err; 485 486 /* 487 * Hardware holds the line card after powering on in the disabled state. Holding line card 488 * in disabled state protects access to the line components, like FPGA and gearboxes. 489 * Line card should be enabled in order to get it in operational state. Line card could be 490 * disabled for moving it to non-operational state. Enabling line card does not affect the 491 * line card which is already has been enabled. Disabling does not affect the disabled line 492 * card. 493 */ 494 mutex_lock(&mlxreg_lc->lock); 495 496 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, ®val); 497 if (err) 498 goto regmap_read_fail; 499 500 if (action) 501 regval |= BIT(mlxreg_lc->data->slot - 1); 502 else 503 regval &= ~BIT(mlxreg_lc->data->slot - 1); 504 505 err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, regval); 506 507regmap_read_fail: 508 mutex_unlock(&mlxreg_lc->lock); 509 return err; 510} 511 512static int 513mlxreg_lc_sn4800_c16_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap, 514 struct mlxreg_core_data *data) 515{ 516 struct device *dev = &data->hpdev.client->dev; 517 518 /* Set line card configuration according to the type. */ 519 mlxreg_lc->mux_data = mlxreg_lc_mux_data; 520 mlxreg_lc->io_data = &mlxreg_lc_regs_io; 521 mlxreg_lc->led_data = &mlxreg_lc_led; 522 mlxreg_lc->mux_brdinfo = &mlxreg_lc_mux_brdinfo; 523 524 mlxreg_lc->aux_devs = devm_kmemdup(dev, mlxreg_lc_aux_pwr_brdinfo, 525 sizeof(mlxreg_lc_aux_pwr_brdinfo), GFP_KERNEL); 526 if (!mlxreg_lc->aux_devs) 527 return -ENOMEM; 528 mlxreg_lc->aux_devs_num = ARRAY_SIZE(mlxreg_lc_aux_pwr_brdinfo); 529 mlxreg_lc->main_devs = devm_kmemdup(dev, mlxreg_lc_main_pwr_brdinfo, 530 sizeof(mlxreg_lc_main_pwr_brdinfo), GFP_KERNEL); 531 if (!mlxreg_lc->main_devs) 532 return -ENOMEM; 533 mlxreg_lc->main_devs_num = ARRAY_SIZE(mlxreg_lc_main_pwr_brdinfo); 534 535 return 0; 536} 537 538static void 539mlxreg_lc_state_update(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action) 540{ 541 mutex_lock(&mlxreg_lc->lock); 542 543 if (action) 544 mlxreg_lc->state |= state; 545 else 546 mlxreg_lc->state &= ~state; 547 548 mutex_unlock(&mlxreg_lc->lock); 549} 550 551/* 552 * Callback is to be called from mlxreg-hotplug driver to notify about line card about received 553 * event. 554 */ 555static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind, u8 action) 556{ 557 struct mlxreg_lc *mlxreg_lc = handle; 558 int err = 0; 559 560 dev_info(mlxreg_lc->dev, "linecard#%d state %d event kind %d action %d\n", 561 mlxreg_lc->data->slot, mlxreg_lc->state, kind, action); 562 563 if (!(mlxreg_lc->state & MLXREG_LC_INITIALIZED)) 564 return 0; 565 566 switch (kind) { 567 case MLXREG_HOTPLUG_LC_SYNCED: 568 /* 569 * Synchronization event - hardware and firmware are synchronized. Power on/off 570 * line card - to allow/disallow main power source. 571 */ 572 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_SYNCED, action); 573 /* Power line card if it is not powered yet. */ 574 if (!(mlxreg_lc->state & MLXREG_LC_POWERED) && action) { 575 err = mlxreg_lc_power_on_off(mlxreg_lc, 1); 576 if (err) 577 return err; 578 } 579 /* In case line card is configured - enable it. */ 580 if (mlxreg_lc->state & MLXREG_LC_CONFIGURED && action) 581 err = mlxreg_lc_enable_disable(mlxreg_lc, 1); 582 break; 583 case MLXREG_HOTPLUG_LC_POWERED: 584 /* Power event - attach or de-attach line card device feeding by the main power. */ 585 if (action) { 586 /* Do not create devices, if line card is already powered. */ 587 if (mlxreg_lc->state & MLXREG_LC_POWERED) { 588 /* In case line card is configured - enable it. */ 589 if (mlxreg_lc->state & MLXREG_LC_CONFIGURED) 590 err = mlxreg_lc_enable_disable(mlxreg_lc, 1); 591 return err; 592 } 593 err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs, 594 mlxreg_lc->main_devs_num); 595 if (err) 596 return err; 597 598 /* In case line card is already in ready state - enable it. */ 599 if (mlxreg_lc->state & MLXREG_LC_CONFIGURED) 600 err = mlxreg_lc_enable_disable(mlxreg_lc, 1); 601 } else { 602 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs, 603 mlxreg_lc->main_devs_num); 604 } 605 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_POWERED, action); 606 break; 607 case MLXREG_HOTPLUG_LC_READY: 608 /* 609 * Ready event – enable line card by releasing it from reset or disable it by put 610 * to reset state. 611 */ 612 err = mlxreg_lc_enable_disable(mlxreg_lc, !!action); 613 break; 614 case MLXREG_HOTPLUG_LC_THERMAL: 615 /* Thermal shutdown event – power off line card. */ 616 if (action) 617 err = mlxreg_lc_power_on_off(mlxreg_lc, 0); 618 break; 619 default: 620 break; 621 } 622 623 return err; 624} 625 626/* 627 * Callback is to be called from i2c-mux-mlxcpld driver to indicate that all adapter devices has 628 * been created. 629 */ 630static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent, 631 struct i2c_adapter *adapters[]) 632{ 633 struct mlxreg_hotplug_device *main_dev, *aux_dev; 634 struct mlxreg_lc *mlxreg_lc = handle; 635 u32 regval; 636 int i, err; 637 638 /* Update I2C devices feeding by auxiliary power. */ 639 aux_dev = mlxreg_lc->aux_devs; 640 for (i = 0; i < mlxreg_lc->aux_devs_num; i++, aux_dev++) { 641 aux_dev->adapter = adapters[aux_dev->nr]; 642 aux_dev->nr = adapters[aux_dev->nr]->nr; 643 } 644 645 err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, 646 mlxreg_lc->aux_devs_num); 647 if (err) 648 return err; 649 650 /* Update I2C devices feeding by main power. */ 651 main_dev = mlxreg_lc->main_devs; 652 for (i = 0; i < mlxreg_lc->main_devs_num; i++, main_dev++) { 653 main_dev->adapter = adapters[main_dev->nr]; 654 main_dev->nr = adapters[main_dev->nr]->nr; 655 } 656 657 /* Verify if line card is powered. */ 658 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, ®val); 659 if (err) 660 goto mlxreg_lc_regmap_read_power_fail; 661 662 if (regval & mlxreg_lc->data->mask) { 663 err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs, 664 mlxreg_lc->main_devs_num); 665 if (err) 666 goto mlxreg_lc_create_static_devices_failed; 667 668 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_POWERED, 1); 669 } 670 671 /* Verify if line card is synchronized. */ 672 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_sync, ®val); 673 if (err) 674 goto mlxreg_lc_regmap_read_sync_fail; 675 676 /* Power on line card if necessary. */ 677 if (regval & mlxreg_lc->data->mask) { 678 mlxreg_lc->state |= MLXREG_LC_SYNCED; 679 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_SYNCED, 1); 680 if (mlxreg_lc->state & ~MLXREG_LC_POWERED) { 681 err = mlxreg_lc_power_on_off(mlxreg_lc, 1); 682 if (err) 683 goto mlxreg_lc_regmap_power_on_off_fail; 684 } 685 } 686 687 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_INITIALIZED, 1); 688 689 return 0; 690 691mlxreg_lc_regmap_power_on_off_fail: 692mlxreg_lc_regmap_read_sync_fail: 693 if (mlxreg_lc->state & MLXREG_LC_POWERED) 694 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs, 695 mlxreg_lc->main_devs_num); 696mlxreg_lc_create_static_devices_failed: 697 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num); 698mlxreg_lc_regmap_read_power_fail: 699 return err; 700} 701 702static int 703mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap, 704 struct mlxreg_core_data *data) 705{ 706 struct device *dev = &data->hpdev.client->dev; 707 int lsb, err; 708 u32 regval; 709 710 /* Validate line card type. */ 711 err = regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, &lsb); 712 err = (!err) ? regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, ®val) : err; 713 if (err) 714 return err; 715 regval = (regval & GENMASK(7, 0)) << 8 | (lsb & GENMASK(7, 0)); 716 switch (regval) { 717 case MLXREG_LC_SN4800_C16: 718 err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data); 719 if (err) 720 return err; 721 break; 722 default: 723 return -ENODEV; 724 } 725 726 /* Create mux infrastructure. */ 727 mlxreg_lc->mux_data->handle = mlxreg_lc; 728 mlxreg_lc->mux_data->completion_notify = mlxreg_lc_completion_notify; 729 mlxreg_lc->mux_brdinfo->platform_data = mlxreg_lc->mux_data; 730 mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr, 731 NULL, 0, mlxreg_lc->mux_data, 732 sizeof(*mlxreg_lc->mux_data)); 733 if (IS_ERR(mlxreg_lc->mux)) 734 return PTR_ERR(mlxreg_lc->mux); 735 736 /* Register IO access driver. */ 737 if (mlxreg_lc->io_data) { 738 mlxreg_lc->io_data->regmap = regmap; 739 mlxreg_lc->io_regs = 740 platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0, 741 mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data)); 742 if (IS_ERR(mlxreg_lc->io_regs)) { 743 err = PTR_ERR(mlxreg_lc->io_regs); 744 goto fail_register_io; 745 } 746 } 747 748 /* Register LED driver. */ 749 if (mlxreg_lc->led_data) { 750 mlxreg_lc->led_data->regmap = regmap; 751 mlxreg_lc->led = 752 platform_device_register_resndata(dev, "leds-mlxreg", data->hpdev.nr, NULL, 0, 753 mlxreg_lc->led_data, 754 sizeof(*mlxreg_lc->led_data)); 755 if (IS_ERR(mlxreg_lc->led)) { 756 err = PTR_ERR(mlxreg_lc->led); 757 goto fail_register_led; 758 } 759 } 760 761 return 0; 762 763fail_register_led: 764 if (mlxreg_lc->io_regs) 765 platform_device_unregister(mlxreg_lc->io_regs); 766fail_register_io: 767 if (mlxreg_lc->mux) 768 platform_device_unregister(mlxreg_lc->mux); 769 770 return err; 771} 772 773static void mlxreg_lc_config_exit(struct mlxreg_lc *mlxreg_lc) 774{ 775 /* Unregister LED driver. */ 776 if (mlxreg_lc->led) 777 platform_device_unregister(mlxreg_lc->led); 778 /* Unregister IO access driver. */ 779 if (mlxreg_lc->io_regs) 780 platform_device_unregister(mlxreg_lc->io_regs); 781 /* Remove mux infrastructure. */ 782 if (mlxreg_lc->mux) 783 platform_device_unregister(mlxreg_lc->mux); 784} 785 786static int mlxreg_lc_probe(struct platform_device *pdev) 787{ 788 struct mlxreg_core_hotplug_platform_data *par_pdata; 789 struct mlxreg_core_data *data; 790 struct mlxreg_lc *mlxreg_lc; 791 void *regmap; 792 int i, err; 793 794 data = dev_get_platdata(&pdev->dev); 795 if (!data) 796 return -EINVAL; 797 798 mlxreg_lc = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_lc), GFP_KERNEL); 799 if (!mlxreg_lc) 800 return -ENOMEM; 801 802 mutex_init(&mlxreg_lc->lock); 803 /* Set event notification callback. */ 804 if (data->notifier) { 805 data->notifier->user_handler = mlxreg_lc_event_handler; 806 data->notifier->handle = mlxreg_lc; 807 } 808 data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr); 809 if (!data->hpdev.adapter) { 810 dev_err(&pdev->dev, "Failed to get adapter for bus %d\n", 811 data->hpdev.nr); 812 return -EFAULT; 813 } 814 815 /* Create device at the top of line card I2C tree.*/ 816 data->hpdev.client = i2c_new_client_device(data->hpdev.adapter, 817 data->hpdev.brdinfo); 818 if (IS_ERR(data->hpdev.client)) { 819 dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n", 820 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); 821 822 i2c_put_adapter(data->hpdev.adapter); 823 data->hpdev.adapter = NULL; 824 return PTR_ERR(data->hpdev.client); 825 } 826 827 regmap = devm_regmap_init_i2c(data->hpdev.client, 828 &mlxreg_lc_regmap_conf); 829 if (IS_ERR(regmap)) { 830 err = PTR_ERR(regmap); 831 goto mlxreg_lc_probe_fail; 832 } 833 834 /* Set default registers. */ 835 for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) { 836 err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg, 837 mlxreg_lc_regmap_default[i].def); 838 if (err) 839 goto mlxreg_lc_probe_fail; 840 } 841 842 /* Sync registers with hardware. */ 843 regcache_mark_dirty(regmap); 844 err = regcache_sync(regmap); 845 if (err) 846 goto mlxreg_lc_probe_fail; 847 848 par_pdata = data->hpdev.brdinfo->platform_data; 849 mlxreg_lc->par_regmap = par_pdata->regmap; 850 mlxreg_lc->data = data; 851 mlxreg_lc->dev = &pdev->dev; 852 platform_set_drvdata(pdev, mlxreg_lc); 853 854 /* Configure line card. */ 855 err = mlxreg_lc_config_init(mlxreg_lc, regmap, data); 856 if (err) 857 goto mlxreg_lc_probe_fail; 858 859 return err; 860 861mlxreg_lc_probe_fail: 862 i2c_put_adapter(data->hpdev.adapter); 863 return err; 864} 865 866static int mlxreg_lc_remove(struct platform_device *pdev) 867{ 868 struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev); 869 struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev); 870 871 /* Clear event notification callback. */ 872 if (data->notifier) { 873 data->notifier->user_handler = NULL; 874 data->notifier->handle = NULL; 875 } 876 877 /* Destroy static I2C device feeding by main power. */ 878 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs, 879 mlxreg_lc->main_devs_num); 880 /* Destroy static I2C device feeding by auxiliary power. */ 881 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num); 882 /* Unregister underlying drivers. */ 883 mlxreg_lc_config_exit(mlxreg_lc); 884 if (data->hpdev.client) { 885 i2c_unregister_device(data->hpdev.client); 886 data->hpdev.client = NULL; 887 i2c_put_adapter(data->hpdev.adapter); 888 data->hpdev.adapter = NULL; 889 } 890 891 return 0; 892} 893 894static struct platform_driver mlxreg_lc_driver = { 895 .probe = mlxreg_lc_probe, 896 .remove = mlxreg_lc_remove, 897 .driver = { 898 .name = "mlxreg-lc", 899 }, 900}; 901 902module_platform_driver(mlxreg_lc_driver); 903 904MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>"); 905MODULE_DESCRIPTION("Nvidia line card platform driver"); 906MODULE_LICENSE("Dual BSD/GPL"); 907MODULE_ALIAS("platform:mlxreg-lc");