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

Merge branch 'topic/tps6586x' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into regulator-hotplug

Conflicts:
drivers/regulator/tps6586x-regulator.c

+165 -94
-1
drivers/mfd/Kconfig
··· 201 201 depends on I2C=y && GENERIC_HARDIRQS 202 202 select MFD_CORE 203 203 select REGMAP_I2C 204 - depends on REGULATOR 205 204 help 206 205 If you say yes here you get support for the TPS6586X series of 207 206 Power Management chips.
+8 -68
drivers/mfd/tps6586x.c
··· 24 24 #include <linux/err.h> 25 25 #include <linux/i2c.h> 26 26 #include <linux/regmap.h> 27 - #include <linux/regulator/of_regulator.h> 28 - #include <linux/regulator/machine.h> 29 27 30 28 #include <linux/mfd/core.h> 31 29 #include <linux/mfd/tps6586x.h> ··· 95 97 static struct mfd_cell tps6586x_cell[] = { 96 98 { 97 99 .name = "tps6586x-gpio", 100 + }, 101 + { 102 + .name = "tps6586x-pmic", 98 103 }, 99 104 { 100 105 .name = "tps6586x-rtc", ··· 351 350 } 352 351 353 352 #ifdef CONFIG_OF 354 - static struct of_regulator_match tps6586x_matches[] = { 355 - { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS }, 356 - { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, 357 - { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, 358 - { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, 359 - { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, 360 - { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, 361 - { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, 362 - { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, 363 - { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, 364 - { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, 365 - { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, 366 - { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, 367 - { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, 368 - { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, 369 - { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, 370 - }; 371 - 372 353 static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) 373 354 { 374 - const unsigned int num = ARRAY_SIZE(tps6586x_matches); 375 355 struct device_node *np = client->dev.of_node; 376 356 struct tps6586x_platform_data *pdata; 377 - struct tps6586x_subdev_info *devs; 378 - struct device_node *regs; 379 - const char *sys_rail_name = NULL; 380 - unsigned int count; 381 - unsigned int i, j; 382 - int err; 383 - 384 - regs = of_find_node_by_name(np, "regulators"); 385 - if (!regs) 386 - return NULL; 387 - 388 - err = of_regulator_match(&client->dev, regs, tps6586x_matches, num); 389 - if (err < 0) { 390 - of_node_put(regs); 391 - return NULL; 392 - } 393 - 394 - of_node_put(regs); 395 - count = err; 396 - 397 - devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL); 398 - if (!devs) 399 - return NULL; 400 - 401 - for (i = 0, j = 0; i < num && j < count; i++) { 402 - struct regulator_init_data *reg_idata; 403 - 404 - if (!tps6586x_matches[i].init_data) 405 - continue; 406 - 407 - reg_idata = tps6586x_matches[i].init_data; 408 - devs[j].name = "tps6586x-regulator"; 409 - devs[j].platform_data = tps6586x_matches[i].init_data; 410 - devs[j].id = (int)tps6586x_matches[i].driver_data; 411 - if (devs[j].id == TPS6586X_ID_SYS) 412 - sys_rail_name = reg_idata->constraints.name; 413 - 414 - if ((devs[j].id == TPS6586X_ID_LDO_5) || 415 - (devs[j].id == TPS6586X_ID_LDO_RTC)) 416 - reg_idata->supply_regulator = sys_rail_name; 417 - 418 - devs[j].of_node = tps6586x_matches[i].of_node; 419 - j++; 420 - } 421 357 422 358 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 423 - if (!pdata) 359 + if (!pdata) { 360 + dev_err(&client->dev, "Memory allocation failed\n"); 424 361 return NULL; 362 + } 425 363 426 - pdata->num_subdevs = count; 427 - pdata->subdevs = devs; 364 + pdata->num_subdevs = 0; 365 + pdata->subdevs = NULL; 428 366 pdata->gpio_base = -1; 429 367 pdata->irq_base = -1; 430 368 pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
+154 -25
drivers/regulator/tps6586x-regulator.c
··· 17 17 #include <linux/module.h> 18 18 #include <linux/init.h> 19 19 #include <linux/err.h> 20 + #include <linux/of.h> 20 21 #include <linux/slab.h> 21 22 #include <linux/platform_device.h> 22 23 #include <linux/regulator/driver.h> 23 24 #include <linux/regulator/machine.h> 25 + #include <linux/regulator/of_regulator.h> 24 26 #include <linux/mfd/tps6586x.h> 25 27 26 28 /* supply control and voltage setting */ ··· 257 255 1 << ri->enable_bit[1]); 258 256 } 259 257 260 - static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev) 258 + static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev, 259 + int id, struct regulator_init_data *p) 261 260 { 262 261 struct device *parent = pdev->dev.parent; 263 - struct regulator_init_data *p = pdev->dev.platform_data; 264 262 struct tps6586x_settings *setting = p->driver_data; 265 263 uint8_t reg; 266 264 ··· 271 269 return 0; 272 270 273 271 /* only SM0 and SM1 can have the slew rate settings */ 274 - switch (pdev->id) { 272 + switch (id) { 275 273 case TPS6586X_ID_SM_0: 276 274 reg = TPS6586X_SM0SL; 277 275 break; ··· 300 298 return NULL; 301 299 } 302 300 301 + #ifdef CONFIG_OF 302 + static struct of_regulator_match tps6586x_matches[] = { 303 + { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS }, 304 + { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, 305 + { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, 306 + { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, 307 + { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, 308 + { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, 309 + { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, 310 + { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, 311 + { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, 312 + { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, 313 + { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, 314 + { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, 315 + { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, 316 + { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, 317 + { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, 318 + }; 319 + 320 + static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( 321 + struct platform_device *pdev, 322 + struct of_regulator_match **tps6586x_reg_matches) 323 + { 324 + const unsigned int num = ARRAY_SIZE(tps6586x_matches); 325 + struct device_node *np = pdev->dev.parent->of_node; 326 + struct device_node *regs; 327 + const char *sys_rail = NULL; 328 + unsigned int i; 329 + struct tps6586x_platform_data *pdata; 330 + int err; 331 + 332 + regs = of_find_node_by_name(np, "regulators"); 333 + if (!regs) { 334 + dev_err(&pdev->dev, "regulator node not found\n"); 335 + return NULL; 336 + } 337 + 338 + err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num); 339 + if (err < 0) { 340 + dev_err(&pdev->dev, "Regulator match failed, e %d\n", err); 341 + of_node_put(regs); 342 + return NULL; 343 + } 344 + 345 + of_node_put(regs); 346 + 347 + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 348 + if (!pdata) { 349 + dev_err(&pdev->dev, "Memory alloction failed\n"); 350 + return NULL; 351 + } 352 + 353 + for (i = 0; i < num; i++) { 354 + int id; 355 + if (!tps6586x_matches[i].init_data) 356 + continue; 357 + 358 + pdata->reg_init_data[i] = tps6586x_matches[i].init_data; 359 + id = (int)tps6586x_matches[i].driver_data; 360 + if (id == TPS6586X_ID_SYS) 361 + sys_rail = pdata->reg_init_data[i]->constraints.name; 362 + 363 + if ((id == TPS6586X_ID_LDO_5) || (id == TPS6586X_ID_LDO_RTC)) 364 + pdata->reg_init_data[i]->supply_regulator = sys_rail; 365 + } 366 + *tps6586x_reg_matches = tps6586x_matches; 367 + return pdata; 368 + } 369 + #else 370 + static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( 371 + struct platform_device *pdev, 372 + struct of_regulator_match **tps6586x_reg_matches) 373 + { 374 + *tps6586x_reg_matches = NULL; 375 + return NULL; 376 + } 377 + #endif 378 + 303 379 static int tps6586x_regulator_probe(struct platform_device *pdev) 304 380 { 305 381 struct tps6586x_regulator *ri = NULL; 306 382 struct regulator_config config = { }; 307 - struct regulator_dev *rdev; 308 - int id = pdev->id; 383 + struct regulator_dev **rdev; 384 + struct regulator_init_data *reg_data; 385 + struct tps6586x_platform_data *pdata; 386 + struct of_regulator_match *tps6586x_reg_matches = NULL; 387 + int id; 309 388 int err; 310 389 311 390 dev_dbg(&pdev->dev, "Probing regulator %d\n", id); 312 391 313 - ri = find_regulator_info(id); 314 - if (ri == NULL) { 315 - dev_err(&pdev->dev, "invalid regulator ID specified\n"); 316 - return -EINVAL; 392 + pdata = dev_get_platdata(pdev->dev.parent); 393 + if ((!pdata) && (pdev->dev.parent->of_node)) 394 + pdata = tps6586x_parse_regulator_dt(pdev, 395 + &tps6586x_reg_matches); 396 + 397 + if (!pdata) { 398 + dev_err(&pdev->dev, "Platform data not available, exiting\n"); 399 + return -ENODEV; 317 400 } 318 401 319 - err = tps6586x_regulator_preinit(pdev->dev.parent, ri); 320 - if (err) 321 - return err; 402 + rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR * 403 + sizeof(*rdev), GFP_KERNEL); 404 + if (!rdev) { 405 + dev_err(&pdev->dev, "Mmemory alloc failed\n"); 406 + return -ENOMEM; 407 + } 322 408 323 - config.dev = pdev->dev.parent; 324 - config.of_node = pdev->dev.of_node; 325 - config.init_data = pdev->dev.platform_data; 326 - config.driver_data = ri; 409 + for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) { 410 + reg_data = pdata->reg_init_data[id]; 327 411 328 - rdev = regulator_register(&ri->desc, &config); 329 - if (IS_ERR(rdev)) { 330 - dev_err(&pdev->dev, "failed to register regulator %s\n", 331 - ri->desc.name); 332 - return PTR_ERR(rdev); 412 + ri = find_regulator_info(id); 413 + if (!ri) { 414 + dev_err(&pdev->dev, "invalid regulator ID specified\n"); 415 + err = -EINVAL; 416 + goto fail; 417 + } 418 + 419 + err = tps6586x_regulator_preinit(pdev->dev.parent, ri); 420 + if (err) { 421 + dev_err(&pdev->dev, 422 + "regulator %d preinit failed, e %d\n", id, err); 423 + goto fail; 424 + } 425 + 426 + config.dev = pdev->dev.parent; 427 + config.init_data = reg_data; 428 + config.driver_data = ri; 429 + 430 + if (tps6586x_reg_matches) 431 + config.of_node = tps6586x_reg_matches[id].of_node; 432 + 433 + rdev[id] = regulator_register(&ri->desc, &config); 434 + if (IS_ERR(rdev[id])) { 435 + dev_err(&pdev->dev, "failed to register regulator %s\n", 436 + ri->desc.name); 437 + err = PTR_ERR(rdev[id]); 438 + goto fail; 439 + } 440 + 441 + if (reg_data) { 442 + err = tps6586x_regulator_set_slew_rate(pdev, id, 443 + reg_data); 444 + if (err < 0) { 445 + dev_err(&pdev->dev, 446 + "Slew rate config failed, e %d\n", err); 447 + regulator_unregister(rdev[id]); 448 + goto fail; 449 + } 450 + } 333 451 } 334 452 335 453 platform_set_drvdata(pdev, rdev); 454 + return 0; 336 455 337 - return tps6586x_regulator_set_slew_rate(pdev); 456 + fail: 457 + while (--id >= 0) 458 + regulator_unregister(rdev[id]); 459 + return err; 338 460 } 339 461 340 462 static int __devexit tps6586x_regulator_remove(struct platform_device *pdev) 341 463 { 342 - struct regulator_dev *rdev = platform_get_drvdata(pdev); 464 + struct regulator_dev **rdev = platform_get_drvdata(pdev); 465 + int id = TPS6586X_ID_MAX_REGULATOR; 343 466 344 - regulator_unregister(rdev); 467 + while (--id >= 0) 468 + regulator_unregister(rdev[id]); 469 + 345 470 return 0; 346 471 } 347 472 348 473 static struct platform_driver tps6586x_regulator_driver = { 349 474 .driver = { 350 - .name = "tps6586x-regulator", 475 + .name = "tps6586x-pmic", 351 476 .owner = THIS_MODULE, 352 477 }, 353 478 .probe = tps6586x_regulator_probe,
+3
include/linux/mfd/tps6586x.h
··· 29 29 TPS6586X_ID_LDO_8, 30 30 TPS6586X_ID_LDO_9, 31 31 TPS6586X_ID_LDO_RTC, 32 + TPS6586X_ID_MAX_REGULATOR, 32 33 }; 33 34 34 35 enum { ··· 80 79 int gpio_base; 81 80 int irq_base; 82 81 bool pm_off; 82 + 83 + struct regulator_init_data *reg_init_data[TPS6586X_ID_MAX_REGULATOR]; 83 84 }; 84 85 85 86 /*