diff options
-rw-r--r-- | drivers/regulator/tps65090-regulator.c | 86 | ||||
-rw-r--r-- | include/linux/mfd/tps65090.h | 2 | ||||
-rw-r--r-- | include/linux/regulator/tps65090-regulator.h | 2 |
3 files changed, 68 insertions, 22 deletions
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index e18679c51fea..ebefbf5ea377 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -142,47 +142,89 @@ static inline struct tps65090_regulator_info *find_regulator_info(int id) static int __devinit tps65090_regulator_probe(struct platform_device *pdev) { struct tps65090_regulator_info *rinfo = NULL; - struct tps65090_regulator *ri = NULL; + struct tps65090_regulator *ri; + struct tps65090_regulator *pmic; struct regulator_dev *rdev; struct tps65090_regulator_platform_data *tps_pdata; - int id = pdev->id; + struct tps65090_platform_data *tps65090_pdata; + int id; + int num; + int ret; - dev_dbg(&pdev->dev, "Probing regulator %d\n", id); + dev_dbg(&pdev->dev, "Probing regulator\n"); - rinfo = find_regulator_info(id); - if (rinfo == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); + tps65090_pdata = dev_get_platdata(pdev->dev.parent); + if (!tps65090_pdata || !tps65090_pdata->num_reg_pdata) { + dev_err(&pdev->dev, "Proper platform data missing\n"); return -EINVAL; } - tps_pdata = pdev->dev.platform_data; - ri = devm_kzalloc(&pdev->dev, sizeof(*ri), GFP_KERNEL); - if (!ri) { - dev_err(&pdev->dev, "mem alloc for ri failed\n"); + pmic = devm_kzalloc(&pdev->dev, + tps65090_pdata->num_reg_pdata * sizeof(*pmic), + GFP_KERNEL); + if (!pmic) { + dev_err(&pdev->dev, "mem alloc for pmic failed\n"); return -ENOMEM; } - ri->dev = &pdev->dev; - ri->rinfo = rinfo; - - rdev = regulator_register(&ri->rinfo->desc, &pdev->dev, + for (num = 0; num < tps65090_pdata->num_reg_pdata; ++num) { + tps_pdata = tps65090_pdata->reg_pdata[num]; + if (!tps_pdata || !tps_pdata->reg_init_data) { + dev_err(&pdev->dev, + "Null platform data for regultor %d\n", num); + ret = -EINVAL; + goto scrub; + } + + id = tps_pdata->id; + rinfo = find_regulator_info(id); + if (!rinfo) { + dev_err(&pdev->dev, + "invalid regulator ID %d specified\n", id); + ret = -EINVAL; + goto scrub; + } + + ri = &pmic[num]; + ri->dev = &pdev->dev; + ri->rinfo = rinfo; + rdev = regulator_register(&ri->rinfo->desc, &pdev->dev, tps_pdata->reg_init_data, ri); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", ri->rinfo->desc.name); - return PTR_ERR(rdev); + ret = PTR_ERR(rdev); + goto scrub; + } + ri->rdev = rdev; } - ri->rdev = rdev; - platform_set_drvdata(pdev, ri); + platform_set_drvdata(pdev, pmic); return 0; + +scrub: + while (--num >= 0) { + ri = &pmic[num]; + regulator_unregister(ri->rdev); + } + return ret; } static int __devexit tps65090_regulator_remove(struct platform_device *pdev) { - struct tps65090_regulator *ri = platform_get_drvdata(pdev); - - regulator_unregister(ri->rdev); + struct tps65090_regulator *pmic = platform_get_drvdata(pdev); + struct tps65090_platform_data *tps65090_pdata; + struct tps65090_regulator *ri; + int num; + + tps65090_pdata = dev_get_platdata(pdev->dev.parent); + if (!tps65090_pdata || !tps65090_pdata->num_reg_pdata) + return 0; + + for (num = 0; num < tps65090_pdata->num_reg_pdata; ++num) { + ri = &pmic[num]; + regulator_unregister(ri->rdev); + } return 0; } diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index 38e31c55adbb..df4cf8164aec 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -32,6 +32,8 @@ struct tps65090_platform_data { int irq_base; int num_subdevs; struct tps65090_subdev_info *subdevs; + struct tps65090_regulator_platform_data **reg_pdata; + int num_reg_pdata; }; /* diff --git a/include/linux/regulator/tps65090-regulator.h b/include/linux/regulator/tps65090-regulator.h index e352a93a7bc7..2b7d0a18f836 100644 --- a/include/linux/regulator/tps65090-regulator.h +++ b/include/linux/regulator/tps65090-regulator.h @@ -40,10 +40,12 @@ enum { * struct tps65090_regulator_platform_data * * @reg_init_data: The regulator init data. + * @id: Regulator ID. * @slew_rate_uV_per_us: Slew rate microvolt per microsec. */ struct tps65090_regulator_platform_data { + int id; struct regulator_init_data *reg_init_data; }; |