0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/i2c.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_data/mlxcpld.h>
0012 #include <linux/platform_data/mlxreg.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regmap.h>
0015
0016
0017 #define MLXREG_LC_REG_CPLD1_VER_OFFSET 0x2500
0018 #define MLXREG_LC_REG_FPGA1_VER_OFFSET 0x2501
0019 #define MLXREG_LC_REG_CPLD1_PN_OFFSET 0x2504
0020 #define MLXREG_LC_REG_FPGA1_PN_OFFSET 0x2506
0021 #define MLXREG_LC_REG_RESET_CAUSE_OFFSET 0x251d
0022 #define MLXREG_LC_REG_LED1_OFFSET 0x2520
0023 #define MLXREG_LC_REG_GP0_OFFSET 0x252e
0024 #define MLXREG_LC_REG_FIELD_UPGRADE 0x2534
0025 #define MLXREG_LC_CHANNEL_I2C_REG 0x25dc
0026 #define MLXREG_LC_REG_CPLD1_MVER_OFFSET 0x25de
0027 #define MLXREG_LC_REG_FPGA1_MVER_OFFSET 0x25df
0028 #define MLXREG_LC_REG_MAX_POWER_OFFSET 0x25f1
0029 #define MLXREG_LC_REG_CONFIG_OFFSET 0x25fb
0030 #define MLXREG_LC_REG_MAX 0x3fff
0031
0032
0033
0034
0035
0036
0037 enum mlxreg_lc_type {
0038 MLXREG_LC_SN4800_C16 = 0x0000,
0039 };
0040
0041
0042
0043
0044
0045
0046
0047
0048 enum mlxreg_lc_state {
0049 MLXREG_LC_INITIALIZED = BIT(0),
0050 MLXREG_LC_POWERED = BIT(1),
0051 MLXREG_LC_SYNCED = BIT(2),
0052 };
0053
0054 #define MLXREG_LC_CONFIGURED (MLXREG_LC_INITIALIZED | MLXREG_LC_POWERED | MLXREG_LC_SYNCED)
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 struct mlxreg_lc {
0075 struct device *dev;
0076 struct mutex lock;
0077 void *par_regmap;
0078 struct mlxreg_core_data *data;
0079 struct mlxreg_core_platform_data *io_data;
0080 struct mlxreg_core_platform_data *led_data;
0081 struct mlxcpld_mux_plat_data *mux_data;
0082 struct platform_device *led;
0083 struct platform_device *io_regs;
0084 struct i2c_board_info *mux_brdinfo;
0085 struct platform_device *mux;
0086 struct mlxreg_hotplug_device *aux_devs;
0087 int aux_devs_num;
0088 struct mlxreg_hotplug_device *main_devs;
0089 int main_devs_num;
0090 enum mlxreg_lc_state state;
0091 };
0092
0093 static bool mlxreg_lc_writeable_reg(struct device *dev, unsigned int reg)
0094 {
0095 switch (reg) {
0096 case MLXREG_LC_REG_LED1_OFFSET:
0097 case MLXREG_LC_REG_GP0_OFFSET:
0098 case MLXREG_LC_REG_FIELD_UPGRADE:
0099 case MLXREG_LC_CHANNEL_I2C_REG:
0100 return true;
0101 }
0102 return false;
0103 }
0104
0105 static bool mlxreg_lc_readable_reg(struct device *dev, unsigned int reg)
0106 {
0107 switch (reg) {
0108 case MLXREG_LC_REG_CPLD1_VER_OFFSET:
0109 case MLXREG_LC_REG_FPGA1_VER_OFFSET:
0110 case MLXREG_LC_REG_CPLD1_PN_OFFSET:
0111 case MLXREG_LC_REG_FPGA1_PN_OFFSET:
0112 case MLXREG_LC_REG_RESET_CAUSE_OFFSET:
0113 case MLXREG_LC_REG_LED1_OFFSET:
0114 case MLXREG_LC_REG_GP0_OFFSET:
0115 case MLXREG_LC_REG_FIELD_UPGRADE:
0116 case MLXREG_LC_CHANNEL_I2C_REG:
0117 case MLXREG_LC_REG_CPLD1_MVER_OFFSET:
0118 case MLXREG_LC_REG_FPGA1_MVER_OFFSET:
0119 case MLXREG_LC_REG_MAX_POWER_OFFSET:
0120 case MLXREG_LC_REG_CONFIG_OFFSET:
0121 return true;
0122 }
0123 return false;
0124 }
0125
0126 static bool mlxreg_lc_volatile_reg(struct device *dev, unsigned int reg)
0127 {
0128 switch (reg) {
0129 case MLXREG_LC_REG_CPLD1_VER_OFFSET:
0130 case MLXREG_LC_REG_FPGA1_VER_OFFSET:
0131 case MLXREG_LC_REG_CPLD1_PN_OFFSET:
0132 case MLXREG_LC_REG_FPGA1_PN_OFFSET:
0133 case MLXREG_LC_REG_RESET_CAUSE_OFFSET:
0134 case MLXREG_LC_REG_LED1_OFFSET:
0135 case MLXREG_LC_REG_GP0_OFFSET:
0136 case MLXREG_LC_REG_FIELD_UPGRADE:
0137 case MLXREG_LC_CHANNEL_I2C_REG:
0138 case MLXREG_LC_REG_CPLD1_MVER_OFFSET:
0139 case MLXREG_LC_REG_FPGA1_MVER_OFFSET:
0140 case MLXREG_LC_REG_MAX_POWER_OFFSET:
0141 case MLXREG_LC_REG_CONFIG_OFFSET:
0142 return true;
0143 }
0144 return false;
0145 }
0146
0147 static const struct reg_default mlxreg_lc_regmap_default[] = {
0148 { MLXREG_LC_CHANNEL_I2C_REG, 0x00 },
0149 };
0150
0151
0152 static const struct regmap_config mlxreg_lc_regmap_conf = {
0153 .reg_bits = 16,
0154 .val_bits = 8,
0155 .max_register = MLXREG_LC_REG_MAX,
0156 .cache_type = REGCACHE_FLAT,
0157 .writeable_reg = mlxreg_lc_writeable_reg,
0158 .readable_reg = mlxreg_lc_readable_reg,
0159 .volatile_reg = mlxreg_lc_volatile_reg,
0160 .reg_defaults = mlxreg_lc_regmap_default,
0161 .num_reg_defaults = ARRAY_SIZE(mlxreg_lc_regmap_default),
0162 };
0163
0164
0165
0166
0167
0168 static int mlxreg_lc_chan[] = {
0169 0x04, 0x05, 0x06, 0x07, 0x08, 0x10, 0x20, 0x21, 0x22, 0x23, 0x40, 0x41,
0170 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
0171 0x4e, 0x4f
0172 };
0173
0174
0175 static struct mlxcpld_mux_plat_data mlxreg_lc_mux_data[] = {
0176 {
0177 .chan_ids = mlxreg_lc_chan,
0178 .num_adaps = ARRAY_SIZE(mlxreg_lc_chan),
0179 .sel_reg_addr = MLXREG_LC_CHANNEL_I2C_REG,
0180 .reg_size = 2,
0181 },
0182 };
0183
0184
0185 static struct i2c_board_info mlxreg_lc_mux_brdinfo = {
0186 I2C_BOARD_INFO("i2c-mux-mlxcpld", 0x32),
0187 };
0188
0189
0190 static struct i2c_board_info mlxreg_lc_aux_pwr_devices[] = {
0191 {
0192 I2C_BOARD_INFO("24c32", 0x51),
0193 },
0194 {
0195 I2C_BOARD_INFO("24c32", 0x51),
0196 },
0197 };
0198
0199
0200 static struct mlxreg_hotplug_device mlxreg_lc_aux_pwr_brdinfo[] = {
0201 {
0202 .brdinfo = &mlxreg_lc_aux_pwr_devices[0],
0203 .nr = 3,
0204 },
0205 {
0206 .brdinfo = &mlxreg_lc_aux_pwr_devices[1],
0207 .nr = 4,
0208 },
0209 };
0210
0211
0212 static struct i2c_board_info mlxreg_lc_main_pwr_devices[] = {
0213 {
0214 I2C_BOARD_INFO("mp2975", 0x62),
0215 },
0216 {
0217 I2C_BOARD_INFO("mp2975", 0x64),
0218 },
0219 {
0220 I2C_BOARD_INFO("max11603", 0x6d),
0221 },
0222 {
0223 I2C_BOARD_INFO("lm25066", 0x15),
0224 },
0225 };
0226
0227
0228 static struct mlxreg_hotplug_device mlxreg_lc_main_pwr_brdinfo[] = {
0229 {
0230 .brdinfo = &mlxreg_lc_main_pwr_devices[0],
0231 .nr = 0,
0232 },
0233 {
0234 .brdinfo = &mlxreg_lc_main_pwr_devices[1],
0235 .nr = 0,
0236 },
0237 {
0238 .brdinfo = &mlxreg_lc_main_pwr_devices[2],
0239 .nr = 1,
0240 },
0241 {
0242 .brdinfo = &mlxreg_lc_main_pwr_devices[3],
0243 .nr = 2,
0244 },
0245 };
0246
0247
0248 static struct mlxreg_core_data mlxreg_lc_led_data[] = {
0249 {
0250 .label = "status:green",
0251 .reg = MLXREG_LC_REG_LED1_OFFSET,
0252 .mask = GENMASK(7, 4),
0253 },
0254 {
0255 .label = "status:orange",
0256 .reg = MLXREG_LC_REG_LED1_OFFSET,
0257 .mask = GENMASK(7, 4),
0258 },
0259 };
0260
0261 static struct mlxreg_core_platform_data mlxreg_lc_led = {
0262 .identity = "pci",
0263 .data = mlxreg_lc_led_data,
0264 .counter = ARRAY_SIZE(mlxreg_lc_led_data),
0265 };
0266
0267
0268 static struct mlxreg_core_data mlxreg_lc_io_data[] = {
0269 {
0270 .label = "cpld1_version",
0271 .reg = MLXREG_LC_REG_CPLD1_VER_OFFSET,
0272 .bit = GENMASK(7, 0),
0273 .mode = 0444,
0274 },
0275 {
0276 .label = "fpga1_version",
0277 .reg = MLXREG_LC_REG_FPGA1_VER_OFFSET,
0278 .bit = GENMASK(7, 0),
0279 .mode = 0444,
0280 },
0281 {
0282 .label = "cpld1_pn",
0283 .reg = MLXREG_LC_REG_CPLD1_PN_OFFSET,
0284 .bit = GENMASK(15, 0),
0285 .mode = 0444,
0286 .regnum = 2,
0287 },
0288 {
0289 .label = "fpga1_pn",
0290 .reg = MLXREG_LC_REG_FPGA1_PN_OFFSET,
0291 .bit = GENMASK(15, 0),
0292 .mode = 0444,
0293 .regnum = 2,
0294 },
0295 {
0296 .label = "cpld1_version_min",
0297 .reg = MLXREG_LC_REG_CPLD1_MVER_OFFSET,
0298 .bit = GENMASK(7, 0),
0299 .mode = 0444,
0300 },
0301 {
0302 .label = "fpga1_version_min",
0303 .reg = MLXREG_LC_REG_FPGA1_MVER_OFFSET,
0304 .bit = GENMASK(7, 0),
0305 .mode = 0444,
0306 },
0307 {
0308 .label = "reset_fpga_not_done",
0309 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0310 .mask = GENMASK(7, 0) & ~BIT(1),
0311 .mode = 0444,
0312 },
0313 {
0314 .label = "reset_aux_pwr_or_ref",
0315 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0316 .mask = GENMASK(7, 0) & ~BIT(2),
0317 .mode = 0444,
0318 },
0319 {
0320 .label = "reset_dc_dc_pwr_fail",
0321 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0322 .mask = GENMASK(7, 0) & ~BIT(3),
0323 .mode = 0444,
0324 },
0325 {
0326 .label = "reset_from_chassis",
0327 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0328 .mask = GENMASK(7, 0) & ~BIT(4),
0329 .mode = 0444,
0330 },
0331 {
0332 .label = "reset_pwr_off_from_chassis",
0333 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0334 .mask = GENMASK(7, 0) & ~BIT(5),
0335 .mode = 0444,
0336 },
0337 {
0338 .label = "reset_line_card",
0339 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0340 .mask = GENMASK(7, 0) & ~BIT(6),
0341 .mode = 0444,
0342 },
0343 {
0344 .label = "reset_line_card_pwr_en",
0345 .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
0346 .mask = GENMASK(7, 0) & ~BIT(7),
0347 .mode = 0444,
0348 },
0349 {
0350 .label = "cpld_upgrade_en",
0351 .reg = MLXREG_LC_REG_FIELD_UPGRADE,
0352 .mask = GENMASK(7, 0) & ~BIT(0),
0353 .mode = 0644,
0354 .secured = 1,
0355 },
0356 {
0357 .label = "fpga_upgrade_en",
0358 .reg = MLXREG_LC_REG_FIELD_UPGRADE,
0359 .mask = GENMASK(7, 0) & ~BIT(1),
0360 .mode = 0644,
0361 .secured = 1,
0362 },
0363 {
0364 .label = "qsfp_pwr_en",
0365 .reg = MLXREG_LC_REG_GP0_OFFSET,
0366 .mask = GENMASK(7, 0) & ~BIT(0),
0367 .mode = 0644,
0368 },
0369 {
0370 .label = "vpd_wp",
0371 .reg = MLXREG_LC_REG_GP0_OFFSET,
0372 .mask = GENMASK(7, 0) & ~BIT(3),
0373 .mode = 0644,
0374 .secured = 1,
0375 },
0376 {
0377 .label = "agb_spi_burn_en",
0378 .reg = MLXREG_LC_REG_GP0_OFFSET,
0379 .mask = GENMASK(7, 0) & ~BIT(5),
0380 .mode = 0644,
0381 .secured = 1,
0382 },
0383 {
0384 .label = "fpga_spi_burn_en",
0385 .reg = MLXREG_LC_REG_GP0_OFFSET,
0386 .mask = GENMASK(7, 0) & ~BIT(6),
0387 .mode = 0644,
0388 .secured = 1,
0389 },
0390 {
0391 .label = "max_power",
0392 .reg = MLXREG_LC_REG_MAX_POWER_OFFSET,
0393 .bit = GENMASK(15, 0),
0394 .mode = 0444,
0395 .regnum = 2,
0396 },
0397 {
0398 .label = "config",
0399 .reg = MLXREG_LC_REG_CONFIG_OFFSET,
0400 .bit = GENMASK(15, 0),
0401 .mode = 0444,
0402 .regnum = 2,
0403 },
0404 };
0405
0406 static struct mlxreg_core_platform_data mlxreg_lc_regs_io = {
0407 .data = mlxreg_lc_io_data,
0408 .counter = ARRAY_SIZE(mlxreg_lc_io_data),
0409 };
0410
0411 static int
0412 mlxreg_lc_create_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotplug_device *devs,
0413 int size)
0414 {
0415 struct mlxreg_hotplug_device *dev = devs;
0416 int i, ret;
0417
0418
0419 for (i = 0; i < size; i++, dev++) {
0420 dev->client = i2c_new_client_device(dev->adapter, dev->brdinfo);
0421 if (IS_ERR(dev->client)) {
0422 dev_err(mlxreg_lc->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
0423 dev->brdinfo->type, dev->nr, dev->brdinfo->addr);
0424
0425 dev->adapter = NULL;
0426 ret = PTR_ERR(dev->client);
0427 goto fail_create_static_devices;
0428 }
0429 }
0430
0431 return 0;
0432
0433 fail_create_static_devices:
0434 while (--i >= 0) {
0435 dev = devs + i;
0436 i2c_unregister_device(dev->client);
0437 dev->client = NULL;
0438 }
0439 return ret;
0440 }
0441
0442 static void
0443 mlxreg_lc_destroy_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotplug_device *devs,
0444 int size)
0445 {
0446 struct mlxreg_hotplug_device *dev = devs;
0447 int i;
0448
0449
0450 for (i = 0; i < size; i++, dev++) {
0451 if (dev->client) {
0452 i2c_unregister_device(dev->client);
0453 dev->client = NULL;
0454 }
0455 }
0456 }
0457
0458 static int mlxreg_lc_power_on_off(struct mlxreg_lc *mlxreg_lc, u8 action)
0459 {
0460 u32 regval;
0461 int err;
0462
0463 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, ®val);
0464 if (err)
0465 goto regmap_read_fail;
0466
0467 if (action)
0468 regval |= BIT(mlxreg_lc->data->slot - 1);
0469 else
0470 regval &= ~BIT(mlxreg_lc->data->slot - 1);
0471
0472 err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, regval);
0473
0474 regmap_read_fail:
0475 return err;
0476 }
0477
0478 static int mlxreg_lc_enable_disable(struct mlxreg_lc *mlxreg_lc, bool action)
0479 {
0480 u32 regval;
0481 int err;
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, ®val);
0492 if (err)
0493 goto regmap_read_fail;
0494
0495 if (action)
0496 regval |= BIT(mlxreg_lc->data->slot - 1);
0497 else
0498 regval &= ~BIT(mlxreg_lc->data->slot - 1);
0499
0500 err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, regval);
0501
0502 regmap_read_fail:
0503 return err;
0504 }
0505
0506 static int
0507 mlxreg_lc_sn4800_c16_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
0508 struct mlxreg_core_data *data)
0509 {
0510 struct device *dev = &data->hpdev.client->dev;
0511
0512
0513 mlxreg_lc->mux_data = mlxreg_lc_mux_data;
0514 mlxreg_lc->io_data = &mlxreg_lc_regs_io;
0515 mlxreg_lc->led_data = &mlxreg_lc_led;
0516 mlxreg_lc->mux_brdinfo = &mlxreg_lc_mux_brdinfo;
0517
0518 mlxreg_lc->aux_devs = devm_kmemdup(dev, mlxreg_lc_aux_pwr_brdinfo,
0519 sizeof(mlxreg_lc_aux_pwr_brdinfo), GFP_KERNEL);
0520 if (!mlxreg_lc->aux_devs)
0521 return -ENOMEM;
0522 mlxreg_lc->aux_devs_num = ARRAY_SIZE(mlxreg_lc_aux_pwr_brdinfo);
0523 mlxreg_lc->main_devs = devm_kmemdup(dev, mlxreg_lc_main_pwr_brdinfo,
0524 sizeof(mlxreg_lc_main_pwr_brdinfo), GFP_KERNEL);
0525 if (!mlxreg_lc->main_devs)
0526 return -ENOMEM;
0527 mlxreg_lc->main_devs_num = ARRAY_SIZE(mlxreg_lc_main_pwr_brdinfo);
0528
0529 return 0;
0530 }
0531
0532 static void
0533 mlxreg_lc_state_update(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action)
0534 {
0535 if (action)
0536 mlxreg_lc->state |= state;
0537 else
0538 mlxreg_lc->state &= ~state;
0539 }
0540
0541 static void
0542 mlxreg_lc_state_update_locked(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action)
0543 {
0544 mutex_lock(&mlxreg_lc->lock);
0545
0546 if (action)
0547 mlxreg_lc->state |= state;
0548 else
0549 mlxreg_lc->state &= ~state;
0550
0551 mutex_unlock(&mlxreg_lc->lock);
0552 }
0553
0554
0555
0556
0557
0558 static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind, u8 action)
0559 {
0560 struct mlxreg_lc *mlxreg_lc = handle;
0561 int err = 0;
0562
0563 dev_info(mlxreg_lc->dev, "linecard#%d state %d event kind %d action %d\n",
0564 mlxreg_lc->data->slot, mlxreg_lc->state, kind, action);
0565
0566 mutex_lock(&mlxreg_lc->lock);
0567 if (!(mlxreg_lc->state & MLXREG_LC_INITIALIZED)) {
0568 mutex_unlock(&mlxreg_lc->lock);
0569 return 0;
0570 }
0571
0572 switch (kind) {
0573 case MLXREG_HOTPLUG_LC_SYNCED:
0574
0575
0576
0577
0578 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_SYNCED, action);
0579
0580 if (!(mlxreg_lc->state & MLXREG_LC_POWERED) && action) {
0581 err = mlxreg_lc_power_on_off(mlxreg_lc, 1);
0582 if (err)
0583 goto mlxreg_lc_power_on_off_fail;
0584 }
0585
0586 if (mlxreg_lc->state & MLXREG_LC_CONFIGURED && action)
0587 err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
0588 break;
0589 case MLXREG_HOTPLUG_LC_POWERED:
0590
0591 if (action) {
0592
0593 if (mlxreg_lc->state & MLXREG_LC_POWERED) {
0594
0595 if (mlxreg_lc->state & MLXREG_LC_CONFIGURED)
0596 err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
0597 mutex_unlock(&mlxreg_lc->lock);
0598 return err;
0599 }
0600 err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
0601 mlxreg_lc->main_devs_num);
0602 if (err)
0603 goto mlxreg_lc_create_static_devices_fail;
0604
0605
0606 if (mlxreg_lc->state & MLXREG_LC_CONFIGURED)
0607 err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
0608 } else {
0609 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
0610 mlxreg_lc->main_devs_num);
0611 }
0612 mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_POWERED, action);
0613 break;
0614 case MLXREG_HOTPLUG_LC_READY:
0615
0616
0617
0618
0619 err = mlxreg_lc_enable_disable(mlxreg_lc, !!action);
0620 break;
0621 case MLXREG_HOTPLUG_LC_THERMAL:
0622
0623 if (action)
0624 err = mlxreg_lc_power_on_off(mlxreg_lc, 0);
0625 break;
0626 default:
0627 break;
0628 }
0629
0630 mlxreg_lc_power_on_off_fail:
0631 mlxreg_lc_create_static_devices_fail:
0632 mutex_unlock(&mlxreg_lc->lock);
0633
0634 return err;
0635 }
0636
0637
0638
0639
0640
0641 static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent,
0642 struct i2c_adapter *adapters[])
0643 {
0644 struct mlxreg_hotplug_device *main_dev, *aux_dev;
0645 struct mlxreg_lc *mlxreg_lc = handle;
0646 u32 regval;
0647 int i, err;
0648
0649
0650 aux_dev = mlxreg_lc->aux_devs;
0651 for (i = 0; i < mlxreg_lc->aux_devs_num; i++, aux_dev++) {
0652 aux_dev->adapter = adapters[aux_dev->nr];
0653 aux_dev->nr = adapters[aux_dev->nr]->nr;
0654 }
0655
0656 err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->aux_devs,
0657 mlxreg_lc->aux_devs_num);
0658 if (err)
0659 return err;
0660
0661
0662 main_dev = mlxreg_lc->main_devs;
0663 for (i = 0; i < mlxreg_lc->main_devs_num; i++, main_dev++) {
0664 main_dev->adapter = adapters[main_dev->nr];
0665 main_dev->nr = adapters[main_dev->nr]->nr;
0666 }
0667
0668
0669 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, ®val);
0670 if (err)
0671 goto mlxreg_lc_regmap_read_power_fail;
0672
0673 if (regval & mlxreg_lc->data->mask) {
0674 err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
0675 mlxreg_lc->main_devs_num);
0676 if (err)
0677 goto mlxreg_lc_create_static_devices_failed;
0678
0679 mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_POWERED, 1);
0680 }
0681
0682
0683 err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_sync, ®val);
0684 if (err)
0685 goto mlxreg_lc_regmap_read_sync_fail;
0686
0687
0688 if (regval & mlxreg_lc->data->mask) {
0689 mlxreg_lc->state |= MLXREG_LC_SYNCED;
0690 mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_SYNCED, 1);
0691 if (mlxreg_lc->state & ~MLXREG_LC_POWERED) {
0692 err = mlxreg_lc_power_on_off(mlxreg_lc, 1);
0693 if (err)
0694 goto mlxreg_lc_regmap_power_on_off_fail;
0695 }
0696 }
0697
0698 mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_INITIALIZED, 1);
0699
0700 return 0;
0701
0702 mlxreg_lc_regmap_power_on_off_fail:
0703 mlxreg_lc_regmap_read_sync_fail:
0704 if (mlxreg_lc->state & MLXREG_LC_POWERED)
0705 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
0706 mlxreg_lc->main_devs_num);
0707 mlxreg_lc_create_static_devices_failed:
0708 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
0709 mlxreg_lc_regmap_read_power_fail:
0710 return err;
0711 }
0712
0713 static int
0714 mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
0715 struct mlxreg_core_data *data)
0716 {
0717 struct device *dev = &data->hpdev.client->dev;
0718 int lsb, err;
0719 u32 regval;
0720
0721
0722 err = regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, &lsb);
0723 err = (!err) ? regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, ®val) : err;
0724 if (err)
0725 return err;
0726 regval = (regval & GENMASK(7, 0)) << 8 | (lsb & GENMASK(7, 0));
0727 switch (regval) {
0728 case MLXREG_LC_SN4800_C16:
0729 err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data);
0730 if (err) {
0731 dev_err(dev, "Failed to config client %s at bus %d at addr 0x%02x\n",
0732 data->hpdev.brdinfo->type, data->hpdev.nr,
0733 data->hpdev.brdinfo->addr);
0734 return err;
0735 }
0736 break;
0737 default:
0738 return -ENODEV;
0739 }
0740
0741
0742 mlxreg_lc->mux_data->handle = mlxreg_lc;
0743 mlxreg_lc->mux_data->completion_notify = mlxreg_lc_completion_notify;
0744 mlxreg_lc->mux_brdinfo->platform_data = mlxreg_lc->mux_data;
0745 mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr,
0746 NULL, 0, mlxreg_lc->mux_data,
0747 sizeof(*mlxreg_lc->mux_data));
0748 if (IS_ERR(mlxreg_lc->mux)) {
0749 dev_err(dev, "Failed to create mux infra for client %s at bus %d at addr 0x%02x\n",
0750 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
0751 return PTR_ERR(mlxreg_lc->mux);
0752 }
0753
0754
0755 if (mlxreg_lc->io_data) {
0756 mlxreg_lc->io_data->regmap = regmap;
0757 mlxreg_lc->io_regs =
0758 platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0,
0759 mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data));
0760 if (IS_ERR(mlxreg_lc->io_regs)) {
0761 dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
0762 data->hpdev.brdinfo->type, data->hpdev.nr,
0763 data->hpdev.brdinfo->addr);
0764 err = PTR_ERR(mlxreg_lc->io_regs);
0765 goto fail_register_io;
0766 }
0767 }
0768
0769
0770 if (mlxreg_lc->led_data) {
0771 mlxreg_lc->led_data->regmap = regmap;
0772 mlxreg_lc->led =
0773 platform_device_register_resndata(dev, "leds-mlxreg", data->hpdev.nr, NULL, 0,
0774 mlxreg_lc->led_data,
0775 sizeof(*mlxreg_lc->led_data));
0776 if (IS_ERR(mlxreg_lc->led)) {
0777 dev_err(dev, "Failed to create LED objects for client %s at bus %d at addr 0x%02x\n",
0778 data->hpdev.brdinfo->type, data->hpdev.nr,
0779 data->hpdev.brdinfo->addr);
0780 err = PTR_ERR(mlxreg_lc->led);
0781 goto fail_register_led;
0782 }
0783 }
0784
0785 return 0;
0786
0787 fail_register_led:
0788 if (mlxreg_lc->io_regs)
0789 platform_device_unregister(mlxreg_lc->io_regs);
0790 fail_register_io:
0791 if (mlxreg_lc->mux)
0792 platform_device_unregister(mlxreg_lc->mux);
0793
0794 return err;
0795 }
0796
0797 static void mlxreg_lc_config_exit(struct mlxreg_lc *mlxreg_lc)
0798 {
0799
0800 if (mlxreg_lc->led)
0801 platform_device_unregister(mlxreg_lc->led);
0802
0803 if (mlxreg_lc->io_regs)
0804 platform_device_unregister(mlxreg_lc->io_regs);
0805
0806 if (mlxreg_lc->mux)
0807 platform_device_unregister(mlxreg_lc->mux);
0808 }
0809
0810 static int mlxreg_lc_probe(struct platform_device *pdev)
0811 {
0812 struct mlxreg_core_hotplug_platform_data *par_pdata;
0813 struct mlxreg_core_data *data;
0814 struct mlxreg_lc *mlxreg_lc;
0815 void *regmap;
0816 int i, err;
0817
0818 data = dev_get_platdata(&pdev->dev);
0819 if (!data)
0820 return -EINVAL;
0821
0822 mlxreg_lc = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_lc), GFP_KERNEL);
0823 if (!mlxreg_lc)
0824 return -ENOMEM;
0825
0826 mutex_init(&mlxreg_lc->lock);
0827
0828 data->notifier->user_handler = mlxreg_lc_event_handler;
0829 data->notifier->handle = mlxreg_lc;
0830
0831 data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
0832 if (!data->hpdev.adapter) {
0833 dev_err(&pdev->dev, "Failed to get adapter for bus %d\n",
0834 data->hpdev.nr);
0835 err = -EFAULT;
0836 goto i2c_get_adapter_fail;
0837 }
0838
0839
0840 data->hpdev.client = i2c_new_client_device(data->hpdev.adapter,
0841 data->hpdev.brdinfo);
0842 if (IS_ERR(data->hpdev.client)) {
0843 dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
0844 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
0845 err = PTR_ERR(data->hpdev.client);
0846 goto i2c_new_device_fail;
0847 }
0848
0849 regmap = devm_regmap_init_i2c(data->hpdev.client,
0850 &mlxreg_lc_regmap_conf);
0851 if (IS_ERR(regmap)) {
0852 dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
0853 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
0854 err = PTR_ERR(regmap);
0855 goto devm_regmap_init_i2c_fail;
0856 }
0857
0858
0859 for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) {
0860 err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg,
0861 mlxreg_lc_regmap_default[i].def);
0862 if (err) {
0863 dev_err(&pdev->dev, "Failed to set default regmap %d for client %s at bus %d at addr 0x%02x\n",
0864 i, data->hpdev.brdinfo->type, data->hpdev.nr,
0865 data->hpdev.brdinfo->addr);
0866 goto regmap_write_fail;
0867 }
0868 }
0869
0870
0871 regcache_mark_dirty(regmap);
0872 err = regcache_sync(regmap);
0873 if (err) {
0874 dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
0875 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
0876 goto regcache_sync_fail;
0877 }
0878
0879 par_pdata = data->hpdev.brdinfo->platform_data;
0880 mlxreg_lc->par_regmap = par_pdata->regmap;
0881 mlxreg_lc->data = data;
0882 mlxreg_lc->dev = &pdev->dev;
0883 platform_set_drvdata(pdev, mlxreg_lc);
0884
0885
0886 err = mlxreg_lc_config_init(mlxreg_lc, regmap, data);
0887 if (err)
0888 goto mlxreg_lc_config_init_fail;
0889
0890 return 0;
0891
0892 mlxreg_lc_config_init_fail:
0893 regcache_sync_fail:
0894 regmap_write_fail:
0895 devm_regmap_init_i2c_fail:
0896 i2c_unregister_device(data->hpdev.client);
0897 data->hpdev.client = NULL;
0898 i2c_new_device_fail:
0899 i2c_put_adapter(data->hpdev.adapter);
0900 data->hpdev.adapter = NULL;
0901 i2c_get_adapter_fail:
0902
0903 if (data->notifier) {
0904 data->notifier->user_handler = NULL;
0905 data->notifier->handle = NULL;
0906 }
0907 return err;
0908 }
0909
0910 static int mlxreg_lc_remove(struct platform_device *pdev)
0911 {
0912 struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
0913 struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
0914
0915 mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_INITIALIZED, 0);
0916
0917
0918
0919
0920
0921
0922
0923 if (!data->notifier || !data->notifier->handle)
0924 return 0;
0925
0926
0927 data->notifier->user_handler = NULL;
0928 data->notifier->handle = NULL;
0929
0930
0931 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
0932 mlxreg_lc->main_devs_num);
0933
0934 mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
0935
0936 mlxreg_lc_config_exit(mlxreg_lc);
0937 if (data->hpdev.client) {
0938 i2c_unregister_device(data->hpdev.client);
0939 data->hpdev.client = NULL;
0940 i2c_put_adapter(data->hpdev.adapter);
0941 data->hpdev.adapter = NULL;
0942 }
0943
0944 return 0;
0945 }
0946
0947 static struct platform_driver mlxreg_lc_driver = {
0948 .probe = mlxreg_lc_probe,
0949 .remove = mlxreg_lc_remove,
0950 .driver = {
0951 .name = "mlxreg-lc",
0952 },
0953 };
0954
0955 module_platform_driver(mlxreg_lc_driver);
0956
0957 MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>");
0958 MODULE_DESCRIPTION("Nvidia line card platform driver");
0959 MODULE_LICENSE("Dual BSD/GPL");
0960 MODULE_ALIAS("platform:mlxreg-lc");