summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-08-02 19:46:17 +0530
committerSimone Willett <swillett@nvidia.com>2012-08-03 14:02:06 -0700
commitc29f0ba149c9ca26e541df2cce9ef08a3ab18630 (patch)
treeb82fb119f46e51ea1f8eac1dd57a93f0325fb9ff
parent5e7698f9b861a2e24f579eb2b5ab264badd22ad0 (diff)
regulator: tps65090: fix multiple regulator registration issue
The regulator of tps65090 is registered as mfd sub device and hence all regulator should be register in one call of tps65090 regulator probe. Fixing this by providing the list of regulator platform data and registering the regulators in single probe call. Change-Id: I06600d0bf4dfd62238bed77713ee8abf2afe2371 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/120838
-rw-r--r--drivers/regulator/tps65090-regulator.c86
-rw-r--r--include/linux/mfd/tps65090.h2
-rw-r--r--include/linux/regulator/tps65090-regulator.h2
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;
};