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