Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mfd: rohm-bd96801: Add chip info

Prepare for adding support for BD96802 which is very similar to BD96801.
Separate chip specific data into own structure which can be picked based
on the type of the IC.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/826f9aa28795a2aa70ea41a3688ff9a83ec25a98.1744090658.git.mazziesaccount@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Matti Vaittinen and committed by
Lee Jones
7289d96b 82c21896

+64 -26
+64 -26
drivers/mfd/rohm-bd96801.c
··· 40 40 #include <linux/mfd/rohm-bd96801.h> 41 41 #include <linux/mfd/rohm-generic.h> 42 42 43 - static const struct resource regulator_errb_irqs[] = { 43 + struct bd968xx { 44 + const struct resource *errb_irqs; 45 + const struct resource *intb_irqs; 46 + int num_errb_irqs; 47 + int num_intb_irqs; 48 + const struct regmap_irq_chip *errb_irq_chip; 49 + const struct regmap_irq_chip *intb_irq_chip; 50 + const struct regmap_config *regmap_config; 51 + struct mfd_cell *cells; 52 + int num_cells; 53 + int unlock_reg; 54 + int unlock_val; 55 + }; 56 + 57 + static const struct resource bd96801_reg_errb_irqs[] = { 44 58 DEFINE_RES_IRQ_NAMED(BD96801_OTP_ERR_STAT, "bd96801-otp-err"), 45 59 DEFINE_RES_IRQ_NAMED(BD96801_DBIST_ERR_STAT, "bd96801-dbist-err"), 46 60 DEFINE_RES_IRQ_NAMED(BD96801_EEP_ERR_STAT, "bd96801-eep-err"), ··· 112 98 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_SHDN_ERR_STAT, "bd96801-ldo7-shdn-err"), 113 99 }; 114 100 115 - static const struct resource regulator_intb_irqs[] = { 101 + static const struct resource bd96801_reg_intb_irqs[] = { 116 102 DEFINE_RES_IRQ_NAMED(BD96801_TW_STAT, "bd96801-core-thermal"), 117 103 118 104 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPH_STAT, "bd96801-buck1-overcurr-h"), ··· 359 345 .cache_type = REGCACHE_MAPLE, 360 346 }; 361 347 348 + static const struct bd968xx bd96801_data = { 349 + .errb_irqs = bd96801_reg_errb_irqs, 350 + .intb_irqs = bd96801_reg_intb_irqs, 351 + .num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs), 352 + .num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs), 353 + .errb_irq_chip = &bd96801_irq_chip_errb, 354 + .intb_irq_chip = &bd96801_irq_chip_intb, 355 + .regmap_config = &bd96801_regmap_config, 356 + .cells = bd96801_cells, 357 + .num_cells = ARRAY_SIZE(bd96801_cells), 358 + .unlock_reg = BD96801_LOCK_REG, 359 + .unlock_val = BD96801_UNLOCK, 360 + }; 361 + 362 362 static int bd96801_i2c_probe(struct i2c_client *i2c) 363 363 { 364 364 struct regmap_irq_chip_data *intb_irq_data, *errb_irq_data; 365 365 struct irq_domain *intb_domain, *errb_domain; 366 + const struct bd968xx *ddata; 366 367 const struct fwnode_handle *fwnode; 367 368 struct resource *regulator_res; 368 369 struct resource wdg_irq; 369 370 struct regmap *regmap; 370 - int intb_irq, errb_irq, num_intb, num_errb = 0; 371 + int intb_irq, errb_irq, num_errb = 0; 371 372 int num_regu_irqs, wdg_irq_no; 373 + unsigned int chip_type; 372 374 int i, ret; 375 + 376 + chip_type = (unsigned int)(uintptr_t)device_get_match_data(&i2c->dev); 377 + switch (chip_type) { 378 + case ROHM_CHIP_TYPE_BD96801: 379 + ddata = &bd96801_data; 380 + break; 381 + default: 382 + dev_err(&i2c->dev, "Unknown IC\n"); 383 + return -EINVAL; 384 + } 373 385 374 386 fwnode = dev_fwnode(&i2c->dev); 375 387 if (!fwnode) ··· 405 365 if (intb_irq < 0) 406 366 return dev_err_probe(&i2c->dev, intb_irq, "INTB IRQ not configured\n"); 407 367 408 - num_intb = ARRAY_SIZE(regulator_intb_irqs); 409 - 410 368 /* ERRB may be omitted if processor is powered by the PMIC */ 411 369 errb_irq = fwnode_irq_get_byname(fwnode, "errb"); 412 - if (errb_irq < 0) 413 - errb_irq = 0; 370 + if (errb_irq == -EPROBE_DEFER) 371 + return errb_irq; 414 372 415 - if (errb_irq) 416 - num_errb = ARRAY_SIZE(regulator_errb_irqs); 373 + if (errb_irq > 0) 374 + num_errb = ddata->num_errb_irqs; 417 375 418 - num_regu_irqs = num_intb + num_errb; 376 + num_regu_irqs = ddata->num_intb_irqs + num_errb; 419 377 420 378 regulator_res = devm_kcalloc(&i2c->dev, num_regu_irqs, 421 379 sizeof(*regulator_res), GFP_KERNEL); 422 380 if (!regulator_res) 423 381 return -ENOMEM; 424 382 425 - regmap = devm_regmap_init_i2c(i2c, &bd96801_regmap_config); 383 + regmap = devm_regmap_init_i2c(i2c, ddata->regmap_config); 426 384 if (IS_ERR(regmap)) 427 385 return dev_err_probe(&i2c->dev, PTR_ERR(regmap), 428 386 "Regmap initialization failed\n"); 429 387 430 - ret = regmap_write(regmap, BD96801_LOCK_REG, BD96801_UNLOCK); 388 + ret = regmap_write(regmap, ddata->unlock_reg, ddata->unlock_val); 431 389 if (ret) 432 390 return dev_err_probe(&i2c->dev, ret, "Failed to unlock PMIC\n"); 433 391 434 392 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, intb_irq, 435 - IRQF_ONESHOT, 0, &bd96801_irq_chip_intb, 393 + IRQF_ONESHOT, 0, ddata->intb_irq_chip, 436 394 &intb_irq_data); 437 395 if (ret) 438 396 return dev_err_probe(&i2c->dev, ret, "Failed to add INTB IRQ chip\n"); ··· 442 404 * has two domains so we do IRQ mapping here and provide the 443 405 * already mapped IRQ numbers to sub-devices. 444 406 */ 445 - for (i = 0; i < num_intb; i++) { 407 + for (i = 0; i < ddata->num_intb_irqs; i++) { 446 408 struct resource *res = &regulator_res[i]; 447 409 448 - *res = regulator_intb_irqs[i]; 410 + *res = ddata->intb_irqs[i]; 449 411 res->start = res->end = irq_create_mapping(intb_domain, 450 412 res->start); 451 413 } 452 414 453 415 wdg_irq_no = irq_create_mapping(intb_domain, BD96801_WDT_ERR_STAT); 454 416 wdg_irq = DEFINE_RES_IRQ_NAMED(wdg_irq_no, "bd96801-wdg"); 455 - bd96801_cells[WDG_CELL].resources = &wdg_irq; 456 - bd96801_cells[WDG_CELL].num_resources = 1; 417 + 418 + ddata->cells[WDG_CELL].resources = &wdg_irq; 419 + ddata->cells[WDG_CELL].num_resources = 1; 457 420 458 421 if (!num_errb) 459 422 goto skip_errb; 460 423 461 424 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, errb_irq, IRQF_ONESHOT, 462 - 0, &bd96801_irq_chip_errb, &errb_irq_data); 425 + 0, ddata->errb_irq_chip, &errb_irq_data); 463 426 if (ret) 464 427 return dev_err_probe(&i2c->dev, ret, 465 428 "Failed to add ERRB IRQ chip\n"); ··· 468 429 errb_domain = regmap_irq_get_domain(errb_irq_data); 469 430 470 431 for (i = 0; i < num_errb; i++) { 471 - struct resource *res = &regulator_res[num_intb + i]; 432 + struct resource *res = &regulator_res[ddata->num_intb_irqs + i]; 472 433 473 - *res = regulator_errb_irqs[i]; 434 + *res = ddata->errb_irqs[i]; 474 435 res->start = res->end = irq_create_mapping(errb_domain, res->start); 475 436 } 476 437 477 438 skip_errb: 478 - bd96801_cells[REGULATOR_CELL].resources = regulator_res; 479 - bd96801_cells[REGULATOR_CELL].num_resources = num_regu_irqs; 480 - 481 - ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, bd96801_cells, 482 - ARRAY_SIZE(bd96801_cells), NULL, 0, NULL); 439 + ddata->cells[REGULATOR_CELL].resources = regulator_res; 440 + ddata->cells[REGULATOR_CELL].num_resources = num_regu_irqs; 441 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, ddata->cells, 442 + ddata->num_cells, NULL, 0, NULL); 483 443 if (ret) 484 444 dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n"); 485 445 ··· 486 448 } 487 449 488 450 static const struct of_device_id bd96801_of_match[] = { 489 - { .compatible = "rohm,bd96801", }, 451 + { .compatible = "rohm,bd96801", .data = (void *)ROHM_CHIP_TYPE_BD96801 }, 490 452 { } 491 453 }; 492 454 MODULE_DEVICE_TABLE(of, bd96801_of_match);