1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Nvidia Data Processor Unit platform driver 4 * 5 * Copyright (C) 2025 Nvidia Technologies Ltd. 6 */ 7 8 #include <linux/device.h> 9 #include <linux/dev_printk.h> 10 #include <linux/i2c.h> 11 #include <linux/module.h> 12 #include <linux/platform_data/mlxcpld.h> 13 #include <linux/platform_data/mlxreg.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 17 /* I2C bus IO offsets */ 18 #define MLXREG_DPU_REG_FPGA1_VER_OFFSET 0x2400 19 #define MLXREG_DPU_REG_FPGA1_PN_OFFSET 0x2404 20 #define MLXREG_DPU_REG_FPGA1_PN1_OFFSET 0x2405 21 #define MLXREG_DPU_REG_PG_OFFSET 0x2414 22 #define MLXREG_DPU_REG_PG_EVENT_OFFSET 0x2415 23 #define MLXREG_DPU_REG_PG_MASK_OFFSET 0x2416 24 #define MLXREG_DPU_REG_RESET_GP1_OFFSET 0x2417 25 #define MLXREG_DPU_REG_RST_CAUSE1_OFFSET 0x241e 26 #define MLXREG_DPU_REG_GP0_RO_OFFSET 0x242b 27 #define MLXREG_DPU_REG_GP0_OFFSET 0x242e 28 #define MLXREG_DPU_REG_GP1_OFFSET 0x242c 29 #define MLXREG_DPU_REG_GP4_OFFSET 0x2438 30 #define MLXREG_DPU_REG_AGGRCO_OFFSET 0x2442 31 #define MLXREG_DPU_REG_AGGRCO_MASK_OFFSET 0x2443 32 #define MLXREG_DPU_REG_HEALTH_OFFSET 0x244d 33 #define MLXREG_DPU_REG_HEALTH_EVENT_OFFSET 0x244e 34 #define MLXREG_DPU_REG_HEALTH_MASK_OFFSET 0x244f 35 #define MLXREG_DPU_REG_FPGA1_MVER_OFFSET 0x24de 36 #define MLXREG_DPU_REG_CONFIG3_OFFSET 0x24fd 37 #define MLXREG_DPU_REG_MAX 0x3fff 38 39 /* Power Good event masks. */ 40 #define MLXREG_DPU_PG_VDDIO_MASK BIT(0) 41 #define MLXREG_DPU_PG_VDD_CPU_MASK BIT(1) 42 #define MLXREG_DPU_PG_VDD_MASK BIT(2) 43 #define MLXREG_DPU_PG_1V8_MASK BIT(3) 44 #define MLXREG_DPU_PG_COMPARATOR_MASK BIT(4) 45 #define MLXREG_DPU_PG_VDDQ_MASK BIT(5) 46 #define MLXREG_DPU_PG_HVDD_MASK BIT(6) 47 #define MLXREG_DPU_PG_DVDD_MASK BIT(7) 48 #define MLXREG_DPU_PG_MASK (MLXREG_DPU_PG_DVDD_MASK | \ 49 MLXREG_DPU_PG_HVDD_MASK | \ 50 MLXREG_DPU_PG_VDDQ_MASK | \ 51 MLXREG_DPU_PG_COMPARATOR_MASK | \ 52 MLXREG_DPU_PG_1V8_MASK | \ 53 MLXREG_DPU_PG_VDD_CPU_MASK | \ 54 MLXREG_DPU_PG_VDD_MASK | \ 55 MLXREG_DPU_PG_VDDIO_MASK) 56 57 /* Health event masks. */ 58 #define MLXREG_DPU_HLTH_THERMAL_TRIP_MASK BIT(0) 59 #define MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK BIT(1) 60 #define MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK BIT(2) 61 #define MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK BIT(3) 62 #define MLXREG_DPU_HLTH_VDDQ_ALERT_MASK BIT(4) 63 #define MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK BIT(5) 64 #define MLXREG_DPU_HEALTH_MASK (MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK | \ 65 MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK | \ 66 MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK | \ 67 MLXREG_DPU_HLTH_VDDQ_ALERT_MASK | \ 68 MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK | \ 69 MLXREG_DPU_HLTH_THERMAL_TRIP_MASK) 70 71 /* Hotplug aggregation masks. */ 72 #define MLXREG_DPU_HEALTH_AGGR_MASK BIT(0) 73 #define MLXREG_DPU_PG_AGGR_MASK BIT(1) 74 #define MLXREG_DPU_AGGR_MASK (MLXREG_DPU_HEALTH_AGGR_MASK | \ 75 MLXREG_DPU_PG_AGGR_MASK) 76 77 /* Voltage regulator firmware update status mask. */ 78 #define MLXREG_DPU_VOLTREG_UPD_MASK GENMASK(5, 4) 79 80 #define MLXREG_DPU_NR_NONE (-1) 81 82 /* 83 * enum mlxreg_dpu_type - Data Processor Unit types 84 * 85 * @MLXREG_DPU_BF3: DPU equipped with BF3 SoC; 86 */ 87 enum mlxreg_dpu_type { 88 MLXREG_DPU_BF3 = 0x0050, 89 }; 90 91 /* Default register access data. */ 92 static struct mlxreg_core_data mlxreg_dpu_io_data[] = { 93 { 94 .label = "fpga1_version", 95 .reg = MLXREG_DPU_REG_FPGA1_VER_OFFSET, 96 .bit = GENMASK(7, 0), 97 .mode = 0444, 98 }, 99 { 100 .label = "fpga1_pn", 101 .reg = MLXREG_DPU_REG_FPGA1_PN_OFFSET, 102 .bit = GENMASK(15, 0), 103 .mode = 0444, 104 .regnum = 2, 105 }, 106 { 107 .label = "fpga1_version_min", 108 .reg = MLXREG_DPU_REG_FPGA1_MVER_OFFSET, 109 .bit = GENMASK(7, 0), 110 .mode = 0444, 111 }, 112 { 113 .label = "perst_rst", 114 .reg = MLXREG_DPU_REG_RESET_GP1_OFFSET, 115 .mask = GENMASK(7, 0) & ~BIT(0), 116 .mode = 0644, 117 }, 118 { 119 .label = "usbphy_rst", 120 .reg = MLXREG_DPU_REG_RESET_GP1_OFFSET, 121 .mask = GENMASK(7, 0) & ~BIT(1), 122 .mode = 0644, 123 }, 124 { 125 .label = "phy_rst", 126 .reg = MLXREG_DPU_REG_RESET_GP1_OFFSET, 127 .mask = GENMASK(7, 0) & ~BIT(2), 128 .mode = 0644, 129 }, 130 { 131 .label = "tpm_rst", 132 .reg = MLXREG_DPU_REG_RESET_GP1_OFFSET, 133 .mask = GENMASK(7, 0) & ~BIT(6), 134 .mode = 0644, 135 }, 136 { 137 .label = "reset_from_main_board", 138 .reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET, 139 .mask = GENMASK(7, 0) & ~BIT(1), 140 .mode = 0444, 141 }, 142 { 143 .label = "reset_aux_pwr_or_reload", 144 .reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET, 145 .mask = GENMASK(7, 0) & ~BIT(2), 146 .mode = 0444, 147 }, 148 { 149 .label = "reset_comex_pwr_fail", 150 .reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET, 151 .mask = GENMASK(7, 0) & ~BIT(3), 152 .mode = 0444, 153 }, 154 { 155 .label = "reset_dpu_thermal", 156 .reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET, 157 .mask = GENMASK(7, 0) & ~BIT(6), 158 .mode = 0444, 159 }, 160 { 161 .label = "reset_pwr_off", 162 .reg = MLXREG_DPU_REG_RST_CAUSE1_OFFSET, 163 .mask = GENMASK(7, 0) & ~BIT(7), 164 .mode = 0444, 165 }, 166 { 167 .label = "dpu_id", 168 .reg = MLXREG_DPU_REG_GP0_RO_OFFSET, 169 .bit = GENMASK(3, 0), 170 .mode = 0444, 171 }, 172 { 173 .label = "voltreg_update_status", 174 .reg = MLXREG_DPU_REG_GP0_RO_OFFSET, 175 .mask = MLXREG_DPU_VOLTREG_UPD_MASK, 176 .bit = 5, 177 .mode = 0444, 178 }, 179 { 180 .label = "boot_progress", 181 .reg = MLXREG_DPU_REG_GP1_OFFSET, 182 .mask = GENMASK(3, 0), 183 .mode = 0444, 184 }, 185 { 186 .label = "ufm_upgrade", 187 .reg = MLXREG_DPU_REG_GP4_OFFSET, 188 .mask = GENMASK(7, 0) & ~BIT(1), 189 .mode = 0644, 190 }, 191 }; 192 193 static struct mlxreg_core_platform_data mlxreg_dpu_default_regs_io_data = { 194 .data = mlxreg_dpu_io_data, 195 .counter = ARRAY_SIZE(mlxreg_dpu_io_data), 196 }; 197 198 /* Default hotplug data. */ 199 static struct mlxreg_core_data mlxreg_dpu_power_events_items_data[] = { 200 { 201 .label = "pg_vddio", 202 .reg = MLXREG_DPU_REG_PG_OFFSET, 203 .mask = MLXREG_DPU_PG_VDDIO_MASK, 204 .hpdev.nr = MLXREG_DPU_NR_NONE, 205 }, 206 { 207 .label = "pg_vdd_cpu", 208 .reg = MLXREG_DPU_REG_PG_OFFSET, 209 .mask = MLXREG_DPU_PG_VDD_CPU_MASK, 210 .hpdev.nr = MLXREG_DPU_NR_NONE, 211 }, 212 { 213 .label = "pg_vdd", 214 .reg = MLXREG_DPU_REG_PG_OFFSET, 215 .mask = MLXREG_DPU_PG_VDD_MASK, 216 .hpdev.nr = MLXREG_DPU_NR_NONE, 217 }, 218 { 219 .label = "pg_1v8", 220 .reg = MLXREG_DPU_REG_PG_OFFSET, 221 .mask = MLXREG_DPU_PG_1V8_MASK, 222 .hpdev.nr = MLXREG_DPU_NR_NONE, 223 }, 224 { 225 .label = "pg_comparator", 226 .reg = MLXREG_DPU_REG_PG_OFFSET, 227 .mask = MLXREG_DPU_PG_COMPARATOR_MASK, 228 .hpdev.nr = MLXREG_DPU_NR_NONE, 229 }, 230 { 231 .label = "pg_vddq", 232 .reg = MLXREG_DPU_REG_PG_OFFSET, 233 .mask = MLXREG_DPU_PG_VDDQ_MASK, 234 .hpdev.nr = MLXREG_DPU_NR_NONE, 235 }, 236 { 237 .label = "pg_hvdd", 238 .reg = MLXREG_DPU_REG_PG_OFFSET, 239 .mask = MLXREG_DPU_PG_HVDD_MASK, 240 .hpdev.nr = MLXREG_DPU_NR_NONE, 241 }, 242 { 243 .label = "pg_dvdd", 244 .reg = MLXREG_DPU_REG_PG_OFFSET, 245 .mask = MLXREG_DPU_PG_DVDD_MASK, 246 .hpdev.nr = MLXREG_DPU_NR_NONE, 247 }, 248 }; 249 250 static struct mlxreg_core_data mlxreg_dpu_health_events_items_data[] = { 251 { 252 .label = "thermal_trip", 253 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 254 .mask = MLXREG_DPU_HLTH_THERMAL_TRIP_MASK, 255 .hpdev.nr = MLXREG_DPU_NR_NONE, 256 }, 257 { 258 .label = "ufm_upgrade_done", 259 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 260 .mask = MLXREG_DPU_HLTH_UFM_UPGRADE_DONE_MASK, 261 .hpdev.nr = MLXREG_DPU_NR_NONE, 262 }, 263 { 264 .label = "vddq_hot_alert", 265 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 266 .mask = MLXREG_DPU_HLTH_VDDQ_HOT_ALERT_MASK, 267 .hpdev.nr = MLXREG_DPU_NR_NONE, 268 }, 269 { 270 .label = "vdd_cpu_hot_alert", 271 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 272 .mask = MLXREG_DPU_HLTH_VDD_CPU_HOT_ALERT_MASK, 273 .hpdev.nr = MLXREG_DPU_NR_NONE, 274 }, 275 { 276 .label = "vddq_alert", 277 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 278 .mask = MLXREG_DPU_HLTH_VDDQ_ALERT_MASK, 279 .hpdev.nr = MLXREG_DPU_NR_NONE, 280 }, 281 { 282 .label = "vdd_cpu_alert", 283 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 284 .mask = MLXREG_DPU_HLTH_VDD_CPU_ALERT_MASK, 285 .hpdev.nr = MLXREG_DPU_NR_NONE, 286 }, 287 }; 288 289 static struct mlxreg_core_item mlxreg_dpu_hotplug_items[] = { 290 { 291 .data = mlxreg_dpu_power_events_items_data, 292 .aggr_mask = MLXREG_DPU_PG_AGGR_MASK, 293 .reg = MLXREG_DPU_REG_PG_OFFSET, 294 .mask = MLXREG_DPU_PG_MASK, 295 .count = ARRAY_SIZE(mlxreg_dpu_power_events_items_data), 296 .health = false, 297 .inversed = 0, 298 }, 299 { 300 .data = mlxreg_dpu_health_events_items_data, 301 .aggr_mask = MLXREG_DPU_HEALTH_AGGR_MASK, 302 .reg = MLXREG_DPU_REG_HEALTH_OFFSET, 303 .mask = MLXREG_DPU_HEALTH_MASK, 304 .count = ARRAY_SIZE(mlxreg_dpu_health_events_items_data), 305 .health = false, 306 .inversed = 0, 307 }, 308 }; 309 310 static 311 struct mlxreg_core_hotplug_platform_data mlxreg_dpu_default_hotplug_data = { 312 .items = mlxreg_dpu_hotplug_items, 313 .count = ARRAY_SIZE(mlxreg_dpu_hotplug_items), 314 .cell = MLXREG_DPU_REG_AGGRCO_OFFSET, 315 .mask = MLXREG_DPU_AGGR_MASK, 316 }; 317 318 /** 319 * struct mlxreg_dpu - device private data 320 * @dev: platform device 321 * @data: platform core data 322 * @io_data: register access platform data 323 * @io_regs: register access device 324 * @hotplug_data: hotplug platform data 325 * @hotplug: hotplug device 326 */ 327 struct mlxreg_dpu { 328 struct device *dev; 329 struct mlxreg_core_data *data; 330 struct mlxreg_core_platform_data *io_data; 331 struct platform_device *io_regs; 332 struct mlxreg_core_hotplug_platform_data *hotplug_data; 333 struct platform_device *hotplug; 334 }; 335 336 static bool mlxreg_dpu_writeable_reg(struct device *dev, unsigned int reg) 337 { 338 switch (reg) { 339 case MLXREG_DPU_REG_PG_EVENT_OFFSET: 340 case MLXREG_DPU_REG_PG_MASK_OFFSET: 341 case MLXREG_DPU_REG_RESET_GP1_OFFSET: 342 case MLXREG_DPU_REG_GP0_OFFSET: 343 case MLXREG_DPU_REG_GP1_OFFSET: 344 case MLXREG_DPU_REG_GP4_OFFSET: 345 case MLXREG_DPU_REG_AGGRCO_OFFSET: 346 case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET: 347 case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET: 348 case MLXREG_DPU_REG_HEALTH_MASK_OFFSET: 349 return true; 350 } 351 return false; 352 } 353 354 static bool mlxreg_dpu_readable_reg(struct device *dev, unsigned int reg) 355 { 356 switch (reg) { 357 case MLXREG_DPU_REG_FPGA1_VER_OFFSET: 358 case MLXREG_DPU_REG_FPGA1_PN_OFFSET: 359 case MLXREG_DPU_REG_FPGA1_PN1_OFFSET: 360 case MLXREG_DPU_REG_PG_OFFSET: 361 case MLXREG_DPU_REG_PG_EVENT_OFFSET: 362 case MLXREG_DPU_REG_PG_MASK_OFFSET: 363 case MLXREG_DPU_REG_RESET_GP1_OFFSET: 364 case MLXREG_DPU_REG_RST_CAUSE1_OFFSET: 365 case MLXREG_DPU_REG_GP0_RO_OFFSET: 366 case MLXREG_DPU_REG_GP0_OFFSET: 367 case MLXREG_DPU_REG_GP1_OFFSET: 368 case MLXREG_DPU_REG_GP4_OFFSET: 369 case MLXREG_DPU_REG_AGGRCO_OFFSET: 370 case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET: 371 case MLXREG_DPU_REG_HEALTH_OFFSET: 372 case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET: 373 case MLXREG_DPU_REG_HEALTH_MASK_OFFSET: 374 case MLXREG_DPU_REG_FPGA1_MVER_OFFSET: 375 case MLXREG_DPU_REG_CONFIG3_OFFSET: 376 return true; 377 } 378 return false; 379 } 380 381 static bool mlxreg_dpu_volatile_reg(struct device *dev, unsigned int reg) 382 { 383 switch (reg) { 384 case MLXREG_DPU_REG_FPGA1_VER_OFFSET: 385 case MLXREG_DPU_REG_FPGA1_PN_OFFSET: 386 case MLXREG_DPU_REG_FPGA1_PN1_OFFSET: 387 case MLXREG_DPU_REG_PG_OFFSET: 388 case MLXREG_DPU_REG_PG_EVENT_OFFSET: 389 case MLXREG_DPU_REG_PG_MASK_OFFSET: 390 case MLXREG_DPU_REG_RESET_GP1_OFFSET: 391 case MLXREG_DPU_REG_RST_CAUSE1_OFFSET: 392 case MLXREG_DPU_REG_GP0_RO_OFFSET: 393 case MLXREG_DPU_REG_GP0_OFFSET: 394 case MLXREG_DPU_REG_GP1_OFFSET: 395 case MLXREG_DPU_REG_GP4_OFFSET: 396 case MLXREG_DPU_REG_AGGRCO_OFFSET: 397 case MLXREG_DPU_REG_AGGRCO_MASK_OFFSET: 398 case MLXREG_DPU_REG_HEALTH_OFFSET: 399 case MLXREG_DPU_REG_HEALTH_EVENT_OFFSET: 400 case MLXREG_DPU_REG_HEALTH_MASK_OFFSET: 401 case MLXREG_DPU_REG_FPGA1_MVER_OFFSET: 402 case MLXREG_DPU_REG_CONFIG3_OFFSET: 403 return true; 404 } 405 return false; 406 } 407 408 /* Configuration for the register map of a device with 2 bytes address space. */ 409 static const struct regmap_config mlxreg_dpu_regmap_conf = { 410 .reg_bits = 16, 411 .val_bits = 8, 412 .max_register = MLXREG_DPU_REG_MAX, 413 .cache_type = REGCACHE_FLAT, 414 .writeable_reg = mlxreg_dpu_writeable_reg, 415 .readable_reg = mlxreg_dpu_readable_reg, 416 .volatile_reg = mlxreg_dpu_volatile_reg, 417 }; 418 419 static int 420 mlxreg_dpu_copy_hotplug_data(struct device *dev, struct mlxreg_dpu *mlxreg_dpu, 421 const struct mlxreg_core_hotplug_platform_data *hotplug_data) 422 { 423 struct mlxreg_core_item *item; 424 int i; 425 426 mlxreg_dpu->hotplug_data = devm_kmemdup(dev, hotplug_data, 427 sizeof(*mlxreg_dpu->hotplug_data), GFP_KERNEL); 428 if (!mlxreg_dpu->hotplug_data) 429 return -ENOMEM; 430 431 mlxreg_dpu->hotplug_data->items = devm_kmemdup(dev, hotplug_data->items, 432 mlxreg_dpu->hotplug_data->count * 433 sizeof(*mlxreg_dpu->hotplug_data->items), 434 GFP_KERNEL); 435 if (!mlxreg_dpu->hotplug_data->items) 436 return -ENOMEM; 437 438 item = mlxreg_dpu->hotplug_data->items; 439 for (i = 0; i < hotplug_data->count; i++, item++) { 440 item->data = devm_kmemdup(dev, hotplug_data->items[i].data, 441 hotplug_data->items[i].count * sizeof(*item->data), 442 GFP_KERNEL); 443 if (!item->data) 444 return -ENOMEM; 445 } 446 447 return 0; 448 } 449 450 static int mlxreg_dpu_config_init(struct mlxreg_dpu *mlxreg_dpu, void *regmap, 451 struct mlxreg_core_data *data, int irq) 452 { 453 struct device *dev = &data->hpdev.client->dev; 454 u32 regval; 455 int err; 456 457 /* Validate DPU type. */ 458 err = regmap_read(regmap, MLXREG_DPU_REG_CONFIG3_OFFSET, ®val); 459 if (err) 460 return err; 461 462 switch (regval) { 463 case MLXREG_DPU_BF3: 464 /* Copy platform specific hotplug data. */ 465 err = mlxreg_dpu_copy_hotplug_data(dev, mlxreg_dpu, 466 &mlxreg_dpu_default_hotplug_data); 467 if (err) 468 return err; 469 470 mlxreg_dpu->io_data = &mlxreg_dpu_default_regs_io_data; 471 472 break; 473 default: 474 return -ENODEV; 475 } 476 477 /* Register IO access driver. */ 478 if (mlxreg_dpu->io_data) { 479 mlxreg_dpu->io_data->regmap = regmap; 480 mlxreg_dpu->io_regs = 481 platform_device_register_resndata(dev, "mlxreg-io", 482 data->slot, NULL, 0, 483 mlxreg_dpu->io_data, 484 sizeof(*mlxreg_dpu->io_data)); 485 if (IS_ERR(mlxreg_dpu->io_regs)) { 486 dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n", 487 data->hpdev.brdinfo->type, data->hpdev.nr, 488 data->hpdev.brdinfo->addr); 489 return PTR_ERR(mlxreg_dpu->io_regs); 490 } 491 } 492 493 /* Register hotplug driver. */ 494 if (mlxreg_dpu->hotplug_data && irq) { 495 mlxreg_dpu->hotplug_data->regmap = regmap; 496 mlxreg_dpu->hotplug_data->irq = irq; 497 mlxreg_dpu->hotplug = 498 platform_device_register_resndata(dev, "mlxreg-hotplug", 499 data->slot, NULL, 0, 500 mlxreg_dpu->hotplug_data, 501 sizeof(*mlxreg_dpu->hotplug_data)); 502 if (IS_ERR(mlxreg_dpu->hotplug)) { 503 err = PTR_ERR(mlxreg_dpu->hotplug); 504 goto fail_register_hotplug; 505 } 506 } 507 508 return 0; 509 510 fail_register_hotplug: 511 platform_device_unregister(mlxreg_dpu->io_regs); 512 513 return err; 514 } 515 516 static void mlxreg_dpu_config_exit(struct mlxreg_dpu *mlxreg_dpu) 517 { 518 platform_device_unregister(mlxreg_dpu->hotplug); 519 platform_device_unregister(mlxreg_dpu->io_regs); 520 } 521 522 static int mlxreg_dpu_probe(struct platform_device *pdev) 523 { 524 struct mlxreg_core_data *data; 525 struct mlxreg_dpu *mlxreg_dpu; 526 void *regmap; 527 int err; 528 529 data = dev_get_platdata(&pdev->dev); 530 if (!data || !data->hpdev.brdinfo) 531 return -EINVAL; 532 533 data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr); 534 if (!data->hpdev.adapter) 535 return -EPROBE_DEFER; 536 537 mlxreg_dpu = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_dpu), GFP_KERNEL); 538 if (!mlxreg_dpu) { 539 err = -ENOMEM; 540 goto alloc_fail; 541 } 542 543 /* Create device at the top of DPU I2C tree. */ 544 data->hpdev.client = i2c_new_client_device(data->hpdev.adapter, 545 data->hpdev.brdinfo); 546 if (IS_ERR(data->hpdev.client)) { 547 dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n", 548 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); 549 err = PTR_ERR(data->hpdev.client); 550 goto i2c_new_device_fail; 551 } 552 553 regmap = devm_regmap_init_i2c(data->hpdev.client, &mlxreg_dpu_regmap_conf); 554 if (IS_ERR(regmap)) { 555 dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n", 556 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); 557 err = PTR_ERR(regmap); 558 goto devm_regmap_init_i2c_fail; 559 } 560 561 /* Sync registers with hardware. */ 562 regcache_mark_dirty(regmap); 563 err = regcache_sync(regmap); 564 if (err) { 565 dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n", 566 data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); 567 goto regcache_sync_fail; 568 } 569 570 mlxreg_dpu->data = data; 571 mlxreg_dpu->dev = &pdev->dev; 572 platform_set_drvdata(pdev, mlxreg_dpu); 573 574 err = mlxreg_dpu_config_init(mlxreg_dpu, regmap, data, data->hpdev.brdinfo->irq); 575 if (err) 576 goto mlxreg_dpu_config_init_fail; 577 578 return err; 579 580 mlxreg_dpu_config_init_fail: 581 regcache_sync_fail: 582 devm_regmap_init_i2c_fail: 583 i2c_unregister_device(data->hpdev.client); 584 i2c_new_device_fail: 585 alloc_fail: 586 i2c_put_adapter(data->hpdev.adapter); 587 return err; 588 } 589 590 static void mlxreg_dpu_remove(struct platform_device *pdev) 591 { 592 struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev); 593 struct mlxreg_dpu *mlxreg_dpu = platform_get_drvdata(pdev); 594 595 mlxreg_dpu_config_exit(mlxreg_dpu); 596 i2c_unregister_device(data->hpdev.client); 597 i2c_put_adapter(data->hpdev.adapter); 598 } 599 600 static struct platform_driver mlxreg_dpu_driver = { 601 .probe = mlxreg_dpu_probe, 602 .remove = mlxreg_dpu_remove, 603 .driver = { 604 .name = "mlxreg-dpu", 605 }, 606 }; 607 608 module_platform_driver(mlxreg_dpu_driver); 609 610 MODULE_AUTHOR("Vadim Pasternak <vadimp@nvidia.com>"); 611 MODULE_DESCRIPTION("Nvidia Data Processor Unit platform driver"); 612 MODULE_LICENSE("Dual BSD/GPL"); 613 MODULE_ALIAS("platform:mlxreg-dpu"); 614