From 0ffff5a60fdd7455c83855ee788a8aae9a79aab4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 14 Aug 2012 12:41:50 +0000 Subject: [PATCH] regulator: twl: make twl_info tables const I currently carry the series to make of_device_id->data const in the arm-soc tree, which fixes a number of issues, but leaves one new compiler warning about the twl-regulator driver: drivers/regulator/twl-regulator.c: In function 'twlreg_probe': drivers/regulator/twl-regulator.c:1130:8: warning: assignment discards 'const' qualifier from pointer target type [enabled by default] drivers/regulator/twl-regulator.c:1139:9: warning: assignment discards 'const' qualifier from pointer target type [enabled by default] The warning indicates that the driver takes a static table with initialization data for each regulator, modifies the data in place and passes a pointer to that structure to the regulator_register function. This is probably ok because a system contains only one instance of each regulator, but it's still bad style because any driver should be written to support multiple instances of the same hardware. This patch changes the code to dynamically allocate the memory we pass to the regulator core so the table can be constant. Signed-off-by: Arnd Bergmann Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 38 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 5ce841087447..a8365229ea6d 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -863,7 +863,7 @@ static struct regulator_ops twlsmps_ops = { 0x0, TWL6030, twl6030fixed_ops) #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ -static struct twlreg_info TWL4030_INFO_##label = { \ +static const struct twlreg_info TWL4030_INFO_##label = { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ @@ -881,7 +881,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \ } #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ -static struct twlreg_info TWL4030_INFO_##label = { \ +static const struct twlreg_info TWL4030_INFO_##label = { \ .base = offset, \ .id = num, \ .remap = remap_conf, \ @@ -896,7 +896,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \ } #define TWL6030_ADJUSTABLE_SMPS(label) \ -static struct twlreg_info TWL6030_INFO_##label = { \ +static const struct twlreg_info TWL6030_INFO_##label = { \ .desc = { \ .name = #label, \ .id = TWL6030_REG_##label, \ @@ -907,7 +907,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \ } #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ -static struct twlreg_info TWL6030_INFO_##label = { \ +static const struct twlreg_info TWL6030_INFO_##label = { \ .base = offset, \ .min_mV = min_mVolts, \ .max_mV = max_mVolts, \ @@ -922,7 +922,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \ } #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ -static struct twlreg_info TWL6025_INFO_##label = { \ +static const struct twlreg_info TWL6025_INFO_##label = { \ .base = offset, \ .min_mV = min_mVolts, \ .max_mV = max_mVolts, \ @@ -938,7 +938,7 @@ static struct twlreg_info TWL6025_INFO_##label = { \ #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ family, operations) \ -static struct twlreg_info TWLFIXED_INFO_##label = { \ +static const struct twlreg_info TWLFIXED_INFO_##label = { \ .base = offset, \ .id = num, \ .min_mV = mVolts, \ @@ -968,7 +968,7 @@ static struct twlreg_info TWLRES_INFO_##label = { \ } #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ -static struct twlreg_info TWLSMPS_INFO_##label = { \ +static const struct twlreg_info TWLSMPS_INFO_##label = { \ .base = offset, \ .min_mV = 600, \ .max_mV = 2100, \ @@ -1125,6 +1125,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) { int i, id; struct twlreg_info *info; + const struct twlreg_info *template; struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; @@ -1134,17 +1135,17 @@ static int __devinit twlreg_probe(struct platform_device *pdev) match = of_match_device(twl_of_match, &pdev->dev); if (match) { - info = match->data; - id = info->desc.id; + template = match->data; + id = template->desc.id; initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); drvdata = NULL; } else { id = pdev->id; initdata = pdev->dev.platform_data; - for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { - info = twl_of_match[i].data; - if (info && info->desc.id == id) + for (i = 0, template = NULL; i < ARRAY_SIZE(twl_of_match); i++) { + template = twl_of_match[i].data; + if (template && template->desc.id == id) break; } if (i == ARRAY_SIZE(twl_of_match)) @@ -1155,12 +1156,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev) return -EINVAL; } - if (!info) + if (!template) return -ENODEV; if (!initdata) return -EINVAL; + info = kmemdup(template, sizeof (*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + if (drvdata) { /* copy the driver data into regulator data */ info->features = drvdata->features; @@ -1221,6 +1226,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); + kfree(info); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); @@ -1242,7 +1248,11 @@ static int __devinit twlreg_probe(struct platform_device *pdev) static int __devexit twlreg_remove(struct platform_device *pdev) { - regulator_unregister(platform_get_drvdata(pdev)); + struct regulator_dev *rdev = platform_get_drvdata(pdev); + struct twlreg_info *info = rdev->reg_data; + + regulator_unregister(rdev); + kfree(info); return 0; } -- 2.39.5