From 0f6ce809a518d736232de5f496b957733b1b4724 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:18 +0200 Subject: [PATCH 01/24] regulator: max1586: Constify regulator_ops Static struct regulator_ops is not modified so can be made const for code safeness. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/max1586.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 2c1228d5796a..6779c2b53674 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -126,14 +126,14 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back * the set up value. */ -static struct regulator_ops max1586_v3_ops = { +static const struct regulator_ops max1586_v3_ops = { .get_voltage_sel = max1586_v3_get_voltage_sel, .set_voltage_sel = max1586_v3_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; -static struct regulator_ops max1586_v6_ops = { +static const struct regulator_ops max1586_v6_ops = { .get_voltage_sel = max1586_v6_get_voltage_sel, .set_voltage_sel = max1586_v6_set_voltage_sel, .list_voltage = regulator_list_voltage_table, From a08904fdb8b5be2334f3873cbeea4bc004528d02 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:19 +0200 Subject: [PATCH 02/24] regulator: max77693: Constify regulator_ops Static struct regulator_ops is not modified so can be made const for code safeness. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/max77693-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max77693-regulator.c b/drivers/regulator/max77693-regulator.c index cfbb9512e486..2e7c55058c2b 100644 --- a/drivers/regulator/max77693-regulator.c +++ b/drivers/regulator/max77693-regulator.c @@ -150,7 +150,7 @@ static struct regulator_ops max77693_safeout_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static struct regulator_ops max77693_charger_ops = { +static const struct regulator_ops max77693_charger_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, From 8c2cd4697bfe524639ad3212f8f152c322941889 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:20 +0200 Subject: [PATCH 03/24] regulator: max8660: Constify regulator_ops Static struct regulator_ops (except max8660_dcdc_ops) are not modified so can be made const for code safeness. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/max8660.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index b87f62dd484e..a6183425f27d 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -194,7 +194,7 @@ static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev, return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0); } -static struct regulator_ops max8660_ldo5_ops = { +static const struct regulator_ops max8660_ldo5_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .set_voltage_sel = max8660_ldo5_set_voltage_sel, @@ -252,7 +252,7 @@ static int max8660_ldo67_set_voltage_sel(struct regulator_dev *rdev, selector << 4); } -static struct regulator_ops max8660_ldo67_ops = { +static const struct regulator_ops max8660_ldo67_ops = { .is_enabled = max8660_ldo67_is_enabled, .enable = max8660_ldo67_enable, .disable = max8660_ldo67_disable, From f465bf9b05303154a86fdd74a571733b0f37af7c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:21 +0200 Subject: [PATCH 04/24] regulator: s2mpa01: Constify regulator_ops Static struct regulator_ops is not modified so can be made const for code safeness. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/s2mpa01.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 92f88753bfed..dc2105c619a6 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -212,7 +212,7 @@ ramp_disable: 1 << enable_shift, 0); } -static struct regulator_ops s2mpa01_ldo_ops = { +static const struct regulator_ops s2mpa01_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -223,7 +223,7 @@ static struct regulator_ops s2mpa01_ldo_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops s2mpa01_buck_ops = { +static const struct regulator_ops s2mpa01_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, From 71b4540f61e9cc5597e2a0c0236781efd40af4c6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:22 +0200 Subject: [PATCH 05/24] regulator: s2mps11: Constify regulator_ops Static struct regulator_ops is not modified so can be made const for code safeness. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/s2mps11.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d838e77dd947..7726b874e539 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -238,7 +238,7 @@ ramp_disable: 1 << enable_shift, 0); } -static struct regulator_ops s2mps11_ldo_ops = { +static const struct regulator_ops s2mps11_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -249,7 +249,7 @@ static struct regulator_ops s2mps11_ldo_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops s2mps11_buck_ops = { +static const struct regulator_ops s2mps11_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -392,7 +392,7 @@ static const struct regulator_desc s2mps11_regulators[] = { regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV), }; -static struct regulator_ops s2mps14_reg_ops; +static const struct regulator_ops s2mps14_reg_ops; #define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \ .name = "LDO"#num, \ @@ -599,7 +599,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) rdev->desc->enable_mask, state); } -static struct regulator_ops s2mps14_reg_ops = { +static const struct regulator_ops s2mps14_reg_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -681,7 +681,7 @@ static const struct regulator_desc s2mps14_regulators[] = { S2MPS14_BUCK1235_START_SEL), }; -static struct regulator_ops s2mps15_reg_ldo_ops = { +static const struct regulator_ops s2mps15_reg_ldo_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .is_enabled = regulator_is_enabled_regmap, @@ -691,7 +691,7 @@ static struct regulator_ops s2mps15_reg_ldo_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static struct regulator_ops s2mps15_reg_buck_ops = { +static const struct regulator_ops s2mps15_reg_buck_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .is_enabled = regulator_is_enabled_regmap, @@ -886,7 +886,7 @@ static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) ramp_val << ramp_shift); } -static struct regulator_ops s2mpu02_ldo_ops = { +static const struct regulator_ops s2mpu02_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -898,7 +898,7 @@ static struct regulator_ops s2mpu02_ldo_ops = { .set_suspend_disable = s2mps14_regulator_set_suspend_disable, }; -static struct regulator_ops s2mpu02_buck_ops = { +static const struct regulator_ops s2mpu02_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, From 8a05eb190238d44a101a7db9addddbe74be0968e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:23 +0200 Subject: [PATCH 06/24] regulator: s5m8767: Constify regulator_ops Static struct regulator_ops is not modified so can be made const for code safeness. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 27343e1c43ef..383cd7533721 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -357,7 +357,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, return 0; } -static struct regulator_ops s5m8767_ops = { +static const struct regulator_ops s5m8767_ops = { .list_voltage = regulator_list_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, @@ -367,7 +367,7 @@ static struct regulator_ops s5m8767_ops = { .set_voltage_time_sel = s5m8767_set_voltage_time_sel, }; -static struct regulator_ops s5m8767_buck78_ops = { +static const struct regulator_ops s5m8767_buck78_ops = { .list_voltage = regulator_list_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, From 5339c34f3906b34ddcd8c9614232ae1302d30c7b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 11 Mar 2017 21:01:24 +0200 Subject: [PATCH 07/24] regulator: s2mpa01: Fix inconsistent indenting Broken indenting makes code more difficult to read and brings confusion. Fix warning reported by Smatch: s2mpa01.c:362 s2mpa01_pmic_probe() warn: inconsistent indenting Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Signed-off-by: Mark Brown --- drivers/regulator/s2mpa01.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index dc2105c619a6..8ac50bc9d5ff 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -357,11 +357,11 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev) if (iodev->dev->of_node) { reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); - if (!reg_np) { - dev_err(&pdev->dev, - "could not find regulators sub-node\n"); - return -EINVAL; - } + if (!reg_np) { + dev_err(&pdev->dev, + "could not find regulators sub-node\n"); + return -EINVAL; + } of_regulator_match(&pdev->dev, reg_np, rdata, S2MPA01_REGULATOR_MAX); From 2543ef3173889373fc07df61520e1bb42a99c85e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 28 Mar 2017 15:14:37 +0100 Subject: [PATCH 08/24] regulator: arizona-micsupp: Avoid potential memory leak reading init_data The device argument passed to of_get_regulator_init_data is used to do some devres memory allocation. Currently the driver passes the MFD device pointer to this function, this could result in the init_data allocation being leaked if the regulator is unbound but the MFD isn't. Correct this issue by correctly passing the local platform device. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/regulator/arizona-micsupp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index fcb98dbda837..0ed14e41de11 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -197,7 +197,8 @@ static const struct regulator_init_data arizona_micsupp_ext_default = { .num_consumer_supplies = 1, }; -static int arizona_micsupp_of_get_pdata(struct arizona *arizona, +static int arizona_micsupp_of_get_pdata(struct device *dev, + struct arizona *arizona, struct regulator_config *config, const struct regulator_desc *desc) { @@ -211,7 +212,7 @@ static int arizona_micsupp_of_get_pdata(struct arizona *arizona, if (np) { config->of_node = np; - init_data = of_get_regulator_init_data(arizona->dev, np, desc); + init_data = of_get_regulator_init_data(dev, np, desc); if (init_data) { init_data->consumer_supplies = &micsupp->supply; @@ -266,8 +267,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev) if (IS_ENABLED(CONFIG_OF)) { if (!dev_get_platdata(arizona->dev)) { - ret = arizona_micsupp_of_get_pdata(arizona, &config, - desc); + ret = arizona_micsupp_of_get_pdata(&pdev->dev, arizona, + &config, desc); if (ret < 0) return ret; } From 0feb837a42c95fee901e03f76a1266db85ceb6ec Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 28 Mar 2017 15:14:38 +0100 Subject: [PATCH 09/24] regulator: arizona-ldo1: Avoid potential memory leak reading init_data The device argument passed to of_get_regulator_init_data is used to do some devres memory allocation. Currently the driver passes the MFD device pointer to this function, this could result in the init_data allocation being leaked if the regulator is unbound but the MFD isn't. Correct this issue by correctly passing the local platform device. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/regulator/arizona-ldo1.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 302b57cb89c6..cf558168664d 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -186,7 +186,8 @@ static const struct regulator_init_data arizona_ldo1_wm5110 = { .num_consumer_supplies = 1, }; -static int arizona_ldo1_of_get_pdata(struct arizona *arizona, +static int arizona_ldo1_of_get_pdata(struct device *dev, + struct arizona *arizona, struct regulator_config *config, const struct regulator_desc *desc) { @@ -212,8 +213,7 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona, if (init_node) { config->of_node = init_node; - init_data = of_get_regulator_init_data(arizona->dev, init_node, - desc); + init_data = of_get_regulator_init_data(dev, init_node, desc); if (init_data) { init_data->consumer_supplies = &ldo1->supply; @@ -283,7 +283,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev) if (IS_ENABLED(CONFIG_OF)) { if (!dev_get_platdata(arizona->dev)) { - ret = arizona_ldo1_of_get_pdata(arizona, &config, desc); + ret = arizona_ldo1_of_get_pdata(&pdev->dev, arizona, + &config, desc); if (ret < 0) return ret; } From cdf4275e957c6bad3756e98942341667f1d7de7d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 28 Mar 2017 15:14:39 +0100 Subject: [PATCH 10/24] MAINTAINERS: Add missing regulator regex for Wolfson Arizona parts The maintainers entry for the Wolfson parts seems to be missing an entry that covers the Arizona regulator drivers, correct this by adding one. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9bf5aa617cf2..ef0c801aff45 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13119,6 +13119,7 @@ F: drivers/mfd/cs47l24* F: drivers/power/supply/wm83*.c F: drivers/rtc/rtc-wm83*.c F: drivers/regulator/wm8*.c +F: drivers/regulator/arizona* F: drivers/video/backlight/wm83*_bl.c F: drivers/watchdog/wm83*_wdt.c F: include/linux/mfd/arizona/ From 7f51cf2ea7186e3f217e616a5522f1156678356f Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 12 Apr 2017 09:58:42 +0800 Subject: [PATCH 11/24] regulator: anatop: check return value of of_get_regulator_init_data Should check the return value of of_get_regulator_init_data before using it. Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 3a6d0290c54c..aa93f462ac6e 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -200,6 +200,9 @@ static int anatop_regulator_probe(struct platform_device *pdev) rdesc->owner = THIS_MODULE; initdata = of_get_regulator_init_data(dev, np, rdesc); + if (!initdata) + return -ENOMEM; + initdata->supply_regulator = "vin"; sreg->initdata = initdata; From 5062e04711dbc4f67b24ffd926cc67060267792d Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 12 Apr 2017 09:58:44 +0800 Subject: [PATCH 12/24] regulator: anatop: use of_property_read_string to read the name sreg->name is a string, so use a more proper api to read back the string instead of of_get_property. Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index aa93f462ac6e..58141cbdf257 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -193,7 +193,8 @@ static int anatop_regulator_probe(struct platform_device *pdev) sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); if (!sreg) return -ENOMEM; - sreg->name = of_get_property(np, "regulator-name", NULL); + + of_property_read_string(np, "regulator-name", &sreg->name); rdesc = &sreg->rdesc; rdesc->name = sreg->name; rdesc->type = REGULATOR_VOLTAGE; From aeb1404d68df62b0a1d277a4138dbd92a4330304 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 12 Apr 2017 09:58:45 +0800 Subject: [PATCH 13/24] regulator: anatop: remove unneeded name field of struct anatop_regulator sreg->name is only used as an intermediate assign of rdesc->name, plus another strcmp. Since we already have rdesc->name, no need it anymore. Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 58141cbdf257..c6ce9745ffc8 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -39,7 +39,6 @@ #define LDO_FET_FULL_ON 0x1f struct anatop_regulator { - const char *name; u32 control_reg; struct regmap *anatop; int vol_bit_shift; @@ -194,12 +193,12 @@ static int anatop_regulator_probe(struct platform_device *pdev) if (!sreg) return -ENOMEM; - of_property_read_string(np, "regulator-name", &sreg->name); rdesc = &sreg->rdesc; - rdesc->name = sreg->name; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; + of_property_read_string(np, "regulator-name", &rdesc->name); + initdata = of_get_regulator_init_data(dev, np, rdesc); if (!initdata) return -ENOMEM; @@ -297,7 +296,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) * a sane default until imx6-cpufreq was probed and changes the * voltage to the correct value. In this case we set 1.25V. */ - if (!sreg->sel && !strcmp(sreg->name, "vddpu")) + if (!sreg->sel && !strcmp(rdesc->name, "vddpu")) sreg->sel = 22; if (!sreg->bypass && !sreg->sel) { From 9bf944548169f6153c3d3778cf983cb5db251a0e Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 12 Apr 2017 09:58:47 +0800 Subject: [PATCH 14/24] regulator: anatop: set default voltage selector for pcie Set the initial voltage selector for vddpcie in case it's disabled by default. This fixes the below warning: 20c8000.anatop:regulator-vddpcie: Failed to read a valid default voltage selector. anatop_regulator: probe of 20c8000.anatop:regulator-vddpcie failed with error -22 Cc: Liam Girdwood Cc: Mark Brown Cc: Shawn Guo Cc: Sascha Hauer Cc: Robin Gong Cc: Richard Zhu Signed-off-by: Richard Zhu Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index c6ce9745ffc8..fa27c9de6744 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -299,6 +299,11 @@ static int anatop_regulator_probe(struct platform_device *pdev) if (!sreg->sel && !strcmp(rdesc->name, "vddpu")) sreg->sel = 22; + /* set the default voltage of the pcie phy to be 1.100v */ + if (!sreg->sel && rdesc->name && + !strcmp(rdesc->name, "vddpcie")) + sreg->sel = 0x10; + if (!sreg->bypass && !sreg->sel) { dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n"); return -EINVAL; From 4af5924c02818ca170bb6902dbb883687b969aeb Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 14 Apr 2017 22:32:43 +0800 Subject: [PATCH 15/24] regulator: anatop: make sure regulator name is properly defined For anatop regulator we must have a name accordingly. Make sure the name is properly checked before using it to avoid a possible kernel NULL point crash. Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index fa27c9de6744..606f3fa6de62 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -198,6 +198,10 @@ static int anatop_regulator_probe(struct platform_device *pdev) rdesc->owner = THIS_MODULE; of_property_read_string(np, "regulator-name", &rdesc->name); + if (!rdesc->name) { + dev_err(dev, "failed to get a regulator-name\n"); + return -EINVAL; + } initdata = of_get_regulator_init_data(dev, np, rdesc); if (!initdata) @@ -300,8 +304,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) sreg->sel = 22; /* set the default voltage of the pcie phy to be 1.100v */ - if (!sreg->sel && rdesc->name && - !strcmp(rdesc->name, "vddpcie")) + if (!sreg->sel && !strcmp(rdesc->name, "vddpcie")) sreg->sel = 0x10; if (!sreg->bypass && !sreg->sel) { From 0e69c2eceb7c71327086c6f48db42a0ba2378cbb Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 21 Apr 2017 10:53:52 +0800 Subject: [PATCH 16/24] regulator: anatop: make regulator name property required We actually can't allow the missing of the regualor name, thus update the binding doc to make regulator-name property to be required. Acked-by: Rob Herring Signed-off-by: Dong Aisheng Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/anatop-regulator.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt index 37c4ea076f88..312060658a53 100644 --- a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt @@ -2,6 +2,7 @@ Anatop Voltage regulators Required properties: - compatible: Must be "fsl,anatop-regulator" +- regulator-name: A string used as a descriptive name for regulator outputs - anatop-reg-offset: Anatop MFD register offset - anatop-vol-bit-shift: Bit shift for the register - anatop-vol-bit-width: Number of bits used in the register From 7e6425968bf742b9772aa5bae1250158c9312e31 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:48 +0100 Subject: [PATCH 17/24] regulator: arizona: Split KConfig options for LDO1 and MICSUPP regulators The CS47L24 Arizona codec and most Madera codecs do not have a LDO1 regulator. Split the LDO1 and MICSUPP regulators into separate KConfig options so the LDO1 is only built into the kernel if needed. Signed-off-by: Richard Fitzgerald Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 14 +++++++++++--- drivers/regulator/Makefile | 3 ++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index be06eb29c681..c026b09c479c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -125,12 +125,20 @@ config REGULATOR_AB8500 This driver supports the regulators found on the ST-Ericsson mixed signal AB8500 PMIC -config REGULATOR_ARIZONA - tristate "Wolfson Arizona class devices" +config REGULATOR_ARIZONA_LDO1 + tristate "Wolfson Arizona class devices LDO1" depends on MFD_ARIZONA depends on SND_SOC help - Support for the regulators found on Wolfson Arizona class + Support for the LDO1 regulators found on Wolfson Arizona class + devices. + +config REGULATOR_ARIZONA_MICSUPP + tristate "Wolfson Arizona class devices MICSUPP" + depends on MFD_ARIZONA + depends on SND_SOC + help + Support for the MICSUPP regulators found on Wolfson Arizona class devices. config REGULATOR_AS3711 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ef7725e2592a..313a7ca97b4d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -19,7 +19,8 @@ obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o -obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o +obj-$(CONFIG_REGULATOR_ARIZONA_LDO1) += arizona-ldo1.o +obj-$(CONFIG_REGULATOR_ARIZONA_MICSUPP) += arizona-micsupp.o obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o From 22161f3eb65dc29434325736c4d780908fe3bf6a Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:49 +0100 Subject: [PATCH 18/24] regulator: arizona-micsupp: Move pdata into a separate structure In preparation for sharing this driver with Madera, move the pdata for the micsupp regulator out of struct arizona_pdata into a dedicated pdata struct for this driver. As a result the code in arizona_micsupp_of_get_pdata() can be made independent of struct arizona. This patch also updates the definition of struct arizona_pdata and the use of this pdata in mach-crag6410-module.c Signed-off-by: Richard Fitzgerald Acked-by: Lee Jones Signed-off-by: Mark Brown --- MAINTAINERS | 1 + drivers/regulator/arizona-micsupp.c | 21 +++++++++++---------- include/linux/mfd/arizona/pdata.h | 3 ++- include/linux/regulator/arizona-micsupp.h | 21 +++++++++++++++++++++ 4 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 include/linux/regulator/arizona-micsupp.h diff --git a/MAINTAINERS b/MAINTAINERS index c35e0cea7831..6ed8ef18e7b6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13623,6 +13623,7 @@ F: include/linux/mfd/arizona/ F: include/linux/mfd/wm831x/ F: include/linux/mfd/wm8350/ F: include/linux/mfd/wm8400* +F: include/linux/regulator/arizona* F: include/linux/wm97xx.h F: include/sound/wm????.h F: sound/soc/codecs/arizona.? diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 5e38861e71d8..5f8b5a713311 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -30,6 +30,8 @@ #include #include +#include + struct arizona_micsupp { struct regulator_dev *regulator; struct arizona *arizona; @@ -199,28 +201,26 @@ static const struct regulator_init_data arizona_micsupp_ext_default = { .num_consumer_supplies = 1, }; -static int arizona_micsupp_of_get_pdata(struct device *dev, - struct arizona *arizona, +static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata, struct regulator_config *config, const struct regulator_desc *desc) { - struct arizona_pdata *pdata = &arizona->pdata; struct arizona_micsupp *micsupp = config->driver_data; struct device_node *np; struct regulator_init_data *init_data; - np = of_get_child_by_name(arizona->dev->of_node, "micvdd"); + np = of_get_child_by_name(config->dev->of_node, "micvdd"); if (np) { config->of_node = np; - init_data = of_get_regulator_init_data(dev, np, desc); + init_data = of_get_regulator_init_data(config->dev, np, desc); if (init_data) { init_data->consumer_supplies = &micsupp->supply; init_data->num_consumer_supplies = 1; - pdata->micvdd = init_data; + pdata->init_data = init_data; } } @@ -232,6 +232,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev) struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); const struct regulator_desc *desc; struct regulator_config config = { }; + struct arizona_micsupp_pdata *pdata = &arizona->pdata.micvdd; struct arizona_micsupp *micsupp; int ret; @@ -269,15 +270,15 @@ static int arizona_micsupp_probe(struct platform_device *pdev) if (IS_ENABLED(CONFIG_OF)) { if (!dev_get_platdata(arizona->dev)) { - ret = arizona_micsupp_of_get_pdata(&pdev->dev, arizona, - &config, desc); + ret = arizona_micsupp_of_get_pdata(pdata, &config, + desc); if (ret < 0) return ret; } } - if (arizona->pdata.micvdd) - config.init_data = arizona->pdata.micvdd; + if (pdata->init_data) + config.init_data = pdata->init_data; else config.init_data = &micsupp->init_data; diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 64faeeff698c..43e875f9850c 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -12,6 +12,7 @@ #define _ARIZONA_PDATA_H #include +#include #define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */ #define ARIZONA_GPN_DIR_SHIFT 15 /* GPN_DIR */ @@ -79,7 +80,7 @@ struct arizona_pdata { int ldoena; /** GPIO controlling LODENA, if any */ /** Regulator configuration for MICVDD */ - struct regulator_init_data *micvdd; + struct arizona_micsupp_pdata micvdd; /** Regulator configuration for LDO1 */ struct regulator_init_data *ldo1; diff --git a/include/linux/regulator/arizona-micsupp.h b/include/linux/regulator/arizona-micsupp.h new file mode 100644 index 000000000000..616842619c00 --- /dev/null +++ b/include/linux/regulator/arizona-micsupp.h @@ -0,0 +1,21 @@ +/* + * Platform data for Arizona micsupp regulator + * + * Copyright 2017 Cirrus Logic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ARIZONA_MICSUPP_H +#define ARIZONA_MICSUPP_H + +struct regulator_init_data; + +struct arizona_micsupp_pdata { + /** Regulator configuration for micsupp */ + const struct regulator_init_data *init_data; +}; + +#endif From e165983e5102c953d68bd935048e95567564e438 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:50 +0100 Subject: [PATCH 19/24] regulator: arizona-micsupp: Make arizona_micsupp independent of struct arizona In preparation for supporting Madera codecs, remove the dependency on struct arizona in the regulator callbacks and struct arizona_micsupp. Signed-off-by: Richard Fitzgerald Signed-off-by: Mark Brown --- drivers/regulator/arizona-micsupp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 5f8b5a713311..db4fecf228b7 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -34,7 +34,10 @@ struct arizona_micsupp { struct regulator_dev *regulator; - struct arizona *arizona; + struct regmap *regmap; + struct snd_soc_dapm_context **dapm; + unsigned int enable_reg; + struct device *dev; struct regulator_consumer_supply supply; struct regulator_init_data init_data; @@ -46,21 +49,22 @@ static void arizona_micsupp_check_cp(struct work_struct *work) { struct arizona_micsupp *micsupp = container_of(work, struct arizona_micsupp, check_cp_work); - struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm; - struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); - struct arizona *arizona = micsupp->arizona; - struct regmap *regmap = arizona->regmap; - unsigned int reg; + struct snd_soc_dapm_context *dapm = *micsupp->dapm; + struct snd_soc_component *component; + unsigned int val; int ret; - ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, ®); + ret = regmap_read(micsupp->regmap, micsupp->enable_reg, &val); if (ret != 0) { - dev_err(arizona->dev, "Failed to read CP state: %d\n", ret); + dev_err(micsupp->dev, + "Failed to read CP state: %d\n", ret); return; } if (dapm) { - if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) == + component = snd_soc_dapm_to_component(dapm); + + if ((val & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) == ARIZONA_CPMIC_ENA) snd_soc_component_force_enable_pin(component, "MICSUPP"); @@ -240,7 +244,9 @@ static int arizona_micsupp_probe(struct platform_device *pdev) if (!micsupp) return -ENOMEM; - micsupp->arizona = arizona; + micsupp->regmap = arizona->regmap; + micsupp->dapm = &arizona->dapm; + micsupp->dev = arizona->dev; INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); /* @@ -263,6 +269,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev) micsupp->init_data.consumer_supplies = &micsupp->supply; micsupp->supply.supply = "MICVDD"; micsupp->supply.dev_name = dev_name(arizona->dev); + micsupp->enable_reg = desc->enable_reg; config.dev = arizona->dev; config.driver_data = micsupp; From 7d8d14b51921cbfe082a796e55c22d0c1dd8fc26 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:51 +0100 Subject: [PATCH 20/24] regulator: arizona-micsupp: Factor out generic initialization In preparation for sharing this driver with Madera codecs, factor out the parts of initialization that aren't dependent on struct arizona. Signed-off-by: Richard Fitzgerald Signed-off-by: Mark Brown --- drivers/regulator/arizona-micsupp.c | 104 +++++++++++++++------------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index db4fecf228b7..120de94caf02 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -231,14 +231,66 @@ static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata, return 0; } +static int arizona_micsupp_common_init(struct platform_device *pdev, + struct arizona_micsupp *micsupp, + const struct regulator_desc *desc, + struct arizona_micsupp_pdata *pdata) +{ + struct regulator_config config = { }; + int ret; + + INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); + + micsupp->init_data.consumer_supplies = &micsupp->supply; + micsupp->supply.supply = "MICVDD"; + micsupp->supply.dev_name = dev_name(micsupp->dev); + micsupp->enable_reg = desc->enable_reg; + + config.dev = micsupp->dev; + config.driver_data = micsupp; + config.regmap = micsupp->regmap; + + if (IS_ENABLED(CONFIG_OF)) { + if (!dev_get_platdata(micsupp->dev)) { + ret = arizona_micsupp_of_get_pdata(pdata, &config, + desc); + if (ret < 0) + return ret; + } + } + + if (pdata->init_data) + config.init_data = pdata->init_data; + else + config.init_data = &micsupp->init_data; + + /* Default to regulated mode */ + regmap_update_bits(micsupp->regmap, micsupp->enable_reg, + ARIZONA_CPMIC_BYPASS, 0); + + micsupp->regulator = devm_regulator_register(&pdev->dev, + desc, + &config); + + of_node_put(config.of_node); + + if (IS_ERR(micsupp->regulator)) { + ret = PTR_ERR(micsupp->regulator); + dev_err(micsupp->dev, "Failed to register mic supply: %d\n", + ret); + return ret; + } + + platform_set_drvdata(pdev, micsupp); + + return 0; +} + static int arizona_micsupp_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); const struct regulator_desc *desc; - struct regulator_config config = { }; - struct arizona_micsupp_pdata *pdata = &arizona->pdata.micvdd; struct arizona_micsupp *micsupp; - int ret; micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); if (!micsupp) @@ -247,7 +299,6 @@ static int arizona_micsupp_probe(struct platform_device *pdev) micsupp->regmap = arizona->regmap; micsupp->dapm = &arizona->dapm; micsupp->dev = arizona->dev; - INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); /* * Since the chip usually supplies itself we provide some @@ -266,49 +317,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev) break; } - micsupp->init_data.consumer_supplies = &micsupp->supply; - micsupp->supply.supply = "MICVDD"; - micsupp->supply.dev_name = dev_name(arizona->dev); - micsupp->enable_reg = desc->enable_reg; - - config.dev = arizona->dev; - config.driver_data = micsupp; - config.regmap = arizona->regmap; - - if (IS_ENABLED(CONFIG_OF)) { - if (!dev_get_platdata(arizona->dev)) { - ret = arizona_micsupp_of_get_pdata(pdata, &config, - desc); - if (ret < 0) - return ret; - } - } - - if (pdata->init_data) - config.init_data = pdata->init_data; - else - config.init_data = &micsupp->init_data; - - /* Default to regulated mode until the API supports bypass */ - regmap_update_bits(arizona->regmap, ARIZONA_MIC_CHARGE_PUMP_1, - ARIZONA_CPMIC_BYPASS, 0); - - micsupp->regulator = devm_regulator_register(&pdev->dev, - desc, - &config); - - of_node_put(config.of_node); - - if (IS_ERR(micsupp->regulator)) { - ret = PTR_ERR(micsupp->regulator); - dev_err(arizona->dev, "Failed to register mic supply: %d\n", - ret); - return ret; - } - - platform_set_drvdata(pdev, micsupp); - - return 0; + return arizona_micsupp_common_init(pdev, micsupp, desc, + &arizona->pdata.micvdd); } static struct platform_driver arizona_micsupp_driver = { From aaa84e6a0399df374634c42590e644a698fcc3ff Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:52 +0100 Subject: [PATCH 21/24] regulator: arizona-ldo1: Move pdata into a separate structure In preparation for sharing this driver with Madera, move the pdata for the LDO1 regulator out of struct arizona_pdata into a dedicated pdata struct for this driver. As a result the code in arizona_ldo1_of_get_pdata() can be made independent of struct arizona. This patch also updates the definition of struct arizona_pdata and the use of this pdata in mach-crag6410-module.c Signed-off-by: Richard Fitzgerald Acked-by: Krzysztof Kozlowski Acked-by: Lee Jones Signed-off-by: Mark Brown --- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 8 +++- drivers/regulator/arizona-ldo1.c | 39 +++++++++++--------- include/linux/mfd/arizona/pdata.h | 4 +- include/linux/regulator/arizona-ldo1.h | 24 ++++++++++++ 4 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 include/linux/regulator/arizona-ldo1.h diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index ccc3ab8d58e7..ea5f2169c850 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -209,7 +209,9 @@ static const struct i2c_board_info wm1277_devs[] = { }; static struct arizona_pdata wm5102_reva_pdata = { - .ldoena = S3C64XX_GPN(7), + .ldo1 = { + .ldoena = S3C64XX_GPN(7), + }, .gpio_base = CODEC_GPIO_BASE, .irq_flags = IRQF_TRIGGER_HIGH, .micd_pol_gpio = CODEC_GPIO_BASE + 4, @@ -239,7 +241,9 @@ static struct spi_board_info wm5102_reva_spi_devs[] = { }; static struct arizona_pdata wm5102_pdata = { - .ldoena = S3C64XX_GPN(7), + .ldo1 = { + .ldoena = S3C64XX_GPN(7), + }, .gpio_base = CODEC_GPIO_BASE, .irq_flags = IRQF_TRIGGER_HIGH, .micd_pol_gpio = CODEC_GPIO_BASE + 2, diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index b726fa17f7b2..f5bc75ab85fa 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -25,6 +25,8 @@ #include #include +#include + #include #include #include @@ -186,20 +188,19 @@ static const struct regulator_init_data arizona_ldo1_wm5110 = { .num_consumer_supplies = 1, }; -static int arizona_ldo1_of_get_pdata(struct device *dev, - struct arizona *arizona, +static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata, struct regulator_config *config, - const struct regulator_desc *desc) + const struct regulator_desc *desc, + bool *external_dcvdd) { - struct arizona_pdata *pdata = &arizona->pdata; struct arizona_ldo1 *ldo1 = config->driver_data; - struct device_node *np = arizona->dev->of_node; + struct device_node *np = config->dev->of_node; struct device_node *init_node, *dcvdd_node; struct regulator_init_data *init_data; pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0); if (pdata->ldoena < 0) { - dev_warn(arizona->dev, + dev_warn(config->dev, "LDOENA GPIO property missing/malformed: %d\n", pdata->ldoena); pdata->ldoena = 0; @@ -213,19 +214,19 @@ static int arizona_ldo1_of_get_pdata(struct device *dev, if (init_node) { config->of_node = init_node; - init_data = of_get_regulator_init_data(dev, init_node, desc); - + init_data = of_get_regulator_init_data(config->dev, init_node, + desc); if (init_data) { init_data->consumer_supplies = &ldo1->supply; init_data->num_consumer_supplies = 1; if (dcvdd_node && dcvdd_node != init_node) - arizona->external_dcvdd = true; + *external_dcvdd = true; - pdata->ldo1 = init_data; + pdata->init_data = init_data; } } else if (dcvdd_node) { - arizona->external_dcvdd = true; + *external_dcvdd = true; } of_node_put(dcvdd_node); @@ -239,10 +240,9 @@ static int arizona_ldo1_probe(struct platform_device *pdev) const struct regulator_desc *desc; struct regulator_config config = { }; struct arizona_ldo1 *ldo1; + bool external_dcvdd = false; int ret; - arizona->external_dcvdd = false; - ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); if (!ldo1) return -ENOMEM; @@ -283,17 +283,18 @@ static int arizona_ldo1_probe(struct platform_device *pdev) if (IS_ENABLED(CONFIG_OF)) { if (!dev_get_platdata(arizona->dev)) { - ret = arizona_ldo1_of_get_pdata(&pdev->dev, arizona, - &config, desc); + ret = arizona_ldo1_of_get_pdata(&arizona->pdata.ldo1, + &config, desc, + &external_dcvdd); if (ret < 0) return ret; } } - config.ena_gpio = arizona->pdata.ldoena; + config.ena_gpio = arizona->pdata.ldo1.ldoena; - if (arizona->pdata.ldo1) - config.init_data = arizona->pdata.ldo1; + if (arizona->pdata.ldo1.init_data) + config.init_data = arizona->pdata.ldo1.init_data; else config.init_data = &ldo1->init_data; @@ -303,6 +304,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev) */ if (config.init_data->num_consumer_supplies == 0) arizona->external_dcvdd = true; + else + arizona->external_dcvdd = external_dcvdd; ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 43e875f9850c..bfeecf179895 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -12,6 +12,7 @@ #define _ARIZONA_PDATA_H #include +#include #include #define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */ @@ -77,13 +78,12 @@ struct arizona_micd_range { struct arizona_pdata { int reset; /** GPIO controlling /RESET, if any */ - int ldoena; /** GPIO controlling LODENA, if any */ /** Regulator configuration for MICVDD */ struct arizona_micsupp_pdata micvdd; /** Regulator configuration for LDO1 */ - struct regulator_init_data *ldo1; + struct arizona_ldo1_pdata ldo1; /** If a direct 32kHz clock is provided on an MCLK specify it here */ int clk32k_src; diff --git a/include/linux/regulator/arizona-ldo1.h b/include/linux/regulator/arizona-ldo1.h new file mode 100644 index 000000000000..c685f1277c63 --- /dev/null +++ b/include/linux/regulator/arizona-ldo1.h @@ -0,0 +1,24 @@ +/* + * Platform data for Arizona LDO1 regulator + * + * Copyright 2017 Cirrus Logic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ARIZONA_LDO1_H +#define ARIZONA_LDO1_H + +struct regulator_init_data; + +struct arizona_ldo1_pdata { + /** GPIO controlling LDOENA, if any */ + int ldoena; + + /** Regulator configuration for LDO1 */ + const struct regulator_init_data *init_data; +}; + +#endif From 80a55f41aef4ee808f53f1a356491d7eaeefdd3c Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:53 +0100 Subject: [PATCH 22/24] regulator: arizona-ldo1: Make arizona_ldo1 independent of struct arizona In preparation for supporting Madera codecs, remove the dependency on struct arizona in the regulator callbacks and struct arizona_ldo1. Signed-off-by: Richard Fitzgerald Signed-off-by: Mark Brown --- drivers/regulator/arizona-ldo1.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index f5bc75ab85fa..678f81fda22a 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -33,7 +33,7 @@ struct arizona_ldo1 { struct regulator_dev *regulator; - struct arizona *arizona; + struct regmap *regmap; struct regulator_consumer_supply supply; struct regulator_init_data init_data; @@ -67,7 +67,7 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) { struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); - struct regmap *regmap = ldo->arizona->regmap; + struct regmap *regmap = ldo->regmap; unsigned int val; int ret; @@ -93,7 +93,7 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) { struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); - struct regmap *regmap = ldo->arizona->regmap; + struct regmap *regmap = ldo->regmap; unsigned int val; int ret; @@ -247,7 +247,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) if (!ldo1) return -ENOMEM; - ldo1->arizona = arizona; + ldo1->regmap = arizona->regmap; /* * Since the chip usually supplies itself we provide some From af367afafb5ba7ae26defd35e4ba42cfe157ef72 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 18 Apr 2017 11:43:54 +0100 Subject: [PATCH 23/24] regulator: arizona-ldo1: Factor out generic initialization In preparation for sharing this driver with Madera codecs, factor out the parts of initialization that aren't dependent on struct arizona. Signed-off-by: Richard Fitzgerald Signed-off-by: Mark Brown --- drivers/regulator/arizona-ldo1.c | 116 ++++++++++++++++++------------- 1 file changed, 67 insertions(+), 49 deletions(-) diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 678f81fda22a..96fddfff5dc4 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -234,13 +234,72 @@ static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata, return 0; } +static int arizona_ldo1_common_init(struct platform_device *pdev, + struct arizona_ldo1 *ldo1, + const struct regulator_desc *desc, + struct arizona_ldo1_pdata *pdata, + bool *external_dcvdd) +{ + struct device *parent_dev = pdev->dev.parent; + struct regulator_config config = { }; + int ret; + + *external_dcvdd = false; + + ldo1->supply.supply = "DCVDD"; + ldo1->init_data.consumer_supplies = &ldo1->supply; + ldo1->supply.dev_name = dev_name(parent_dev); + + config.dev = parent_dev; + config.driver_data = ldo1; + config.regmap = ldo1->regmap; + + if (IS_ENABLED(CONFIG_OF)) { + if (!dev_get_platdata(parent_dev)) { + ret = arizona_ldo1_of_get_pdata(pdata, + &config, desc, + external_dcvdd); + if (ret < 0) + return ret; + } + } + + config.ena_gpio = pdata->ldoena; + + if (pdata->init_data) + config.init_data = pdata->init_data; + else + config.init_data = &ldo1->init_data; + + /* + * LDO1 can only be used to supply DCVDD so if it has no + * consumers then DCVDD is supplied externally. + */ + if (config.init_data->num_consumer_supplies == 0) + *external_dcvdd = true; + + ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); + + of_node_put(config.of_node); + + if (IS_ERR(ldo1->regulator)) { + ret = PTR_ERR(ldo1->regulator); + dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n", + ret); + return ret; + } + + platform_set_drvdata(pdev, ldo1); + + return 0; +} + static int arizona_ldo1_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); - const struct regulator_desc *desc; - struct regulator_config config = { }; struct arizona_ldo1 *ldo1; - bool external_dcvdd = false; + const struct regulator_desc *desc; + bool external_dcvdd; int ret; ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); @@ -273,54 +332,13 @@ static int arizona_ldo1_probe(struct platform_device *pdev) break; } - ldo1->init_data.consumer_supplies = &ldo1->supply; - ldo1->supply.supply = "DCVDD"; - ldo1->supply.dev_name = dev_name(arizona->dev); - - config.dev = arizona->dev; - config.driver_data = ldo1; - config.regmap = arizona->regmap; - - if (IS_ENABLED(CONFIG_OF)) { - if (!dev_get_platdata(arizona->dev)) { - ret = arizona_ldo1_of_get_pdata(&arizona->pdata.ldo1, - &config, desc, - &external_dcvdd); - if (ret < 0) - return ret; - } - } - - config.ena_gpio = arizona->pdata.ldo1.ldoena; - - if (arizona->pdata.ldo1.init_data) - config.init_data = arizona->pdata.ldo1.init_data; - else - config.init_data = &ldo1->init_data; - - /* - * LDO1 can only be used to supply DCVDD so if it has no - * consumers then DCVDD is supplied externally. - */ - if (config.init_data->num_consumer_supplies == 0) - arizona->external_dcvdd = true; - else + ret = arizona_ldo1_common_init(pdev, ldo1, desc, + &arizona->pdata.ldo1, + &external_dcvdd); + if (ret == 0) arizona->external_dcvdd = external_dcvdd; - ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); - - of_node_put(config.of_node); - - if (IS_ERR(ldo1->regulator)) { - ret = PTR_ERR(ldo1->regulator); - dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", - ret); - return ret; - } - - platform_set_drvdata(pdev, ldo1); - - return 0; + return ret; } static struct platform_driver arizona_ldo1_driver = { From e85c5a153fe237f261838fc9638c28f19e0f27c1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 24 Apr 2017 17:21:30 +0200 Subject: [PATCH 24/24] regulator: Add ROHM BD9571MWV-M PMIC regulator driver Add driver for the regulator block in the ROHM BD9571MWV-W MFD PMIC. This block supports three voltage monitors, VD18, VD25, VD33 for the 1V8, 2V5, 3V3 voltage rails and a single voltage regulator for the DVFS rail. Signed-off-by: Marek Vasut Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 11 ++ drivers/regulator/Makefile | 1 + drivers/regulator/bd9571mwv-regulator.c | 178 ++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 drivers/regulator/bd9571mwv-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index be06eb29c681..a27b97c5695b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -163,6 +163,17 @@ config REGULATOR_BCM590XX BCM590xx PMUs. This will enable support for the software controllable LDO/Switching regulators. +config REGULATOR_BD9571MWV + tristate "ROHM BD9571MWV Regulators" + depends on MFD_BD9571MWV + help + This driver provides support for the voltage regulators on the + ROHM BD9571MWV PMIC. This will enable support for the software + controllable regulator and voltage sampling units. + + This driver can also be built as a module. If so, the module + will be called bd9571mwv-regulator. + config REGULATOR_CPCAP tristate "Motorola CPCAP regulator" depends on MFD_CPCAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ef7725e2592a..439b9b21f2fe 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o +obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c new file mode 100644 index 000000000000..8ba206fec31e --- /dev/null +++ b/drivers/regulator/bd9571mwv-regulator.c @@ -0,0 +1,178 @@ +/* + * ROHM BD9571MWV-M regulator driver + * + * Copyright (C) 2017 Marek Vasut + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + * + * Based on the TPS65086 driver + * + * NOTE: VD09 is missing + */ + +#include +#include +#include +#include + +#include + +enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS }; + +#define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\ + { \ + .name = _name, \ + .of_match = of_match_ptr(_of), \ + .regulators_node = "regulators", \ + .id = _id, \ + .ops = &_ops, \ + .n_voltages = _nv, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = _vr, \ + .vsel_mask = _vm, \ + .min_uV = _min, \ + .uV_step = _step, \ + .linear_min_sel = _lmin, \ + } + +int bd9571mwv_avs_get_moni_state(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, BD9571MWV_AVS_SET_MONI, &val); + if (ret != 0) + return ret; + + return val & BD9571MWV_AVS_SET_MONI_MASK; +} + +int bd9571mwv_avs_set_voltage_sel_regmap(struct regulator_dev *rdev, + unsigned int sel) +{ + int ret; + + ret = bd9571mwv_avs_get_moni_state(rdev); + if (ret < 0) + return ret; + + return regmap_write_bits(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), + rdev->desc->vsel_mask, sel); +} + +int bd9571mwv_avs_get_voltage_sel_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = bd9571mwv_avs_get_moni_state(rdev); + if (ret < 0) + return ret; + + ret = regmap_read(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), &val); + if (ret != 0) + return ret; + + val &= rdev->desc->vsel_mask; + val >>= ffs(rdev->desc->vsel_mask) - 1; + + return val; +} + +int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev, + unsigned int sel) +{ + return regmap_write_bits(rdev->regmap, BD9571MWV_DVFS_SETVID, + rdev->desc->vsel_mask, sel); +} + +/* Operations permitted on AVS voltage regulator */ +static struct regulator_ops avs_ops = { + .set_voltage_sel = bd9571mwv_avs_set_voltage_sel_regmap, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = bd9571mwv_avs_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +/* Operations permitted on voltage regulators */ +static struct regulator_ops reg_ops = { + .set_voltage_sel = bd9571mwv_reg_set_voltage_sel_regmap, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +/* Operations permitted on voltage monitors */ +static struct regulator_ops vid_ops = { + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +static struct regulator_desc regulators[] = { + BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f, + 0x80, 600000, 10000, 0x3c), + BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf, + 16, 1625000, 25000, 0), + BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf, + 16, 2150000, 50000, 0), + BD9571MWV_REG("VD33", "vd33", VD33, vid_ops, BD9571MWV_VD33_VID, 0xf, + 11, 2800000, 100000, 0), + BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops, + BD9571MWV_DVFS_MONIVDAC, 0x7f, + 0x80, 600000, 10000, 0x3c), +}; + +static int bd9571mwv_regulator_probe(struct platform_device *pdev) +{ + struct bd9571mwv *bd = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; + + platform_set_drvdata(pdev, bd); + + config.dev = &pdev->dev; + config.dev->of_node = bd->dev->of_node; + config.driver_data = bd; + config.regmap = bd->regmap; + + for (i = 0; i < ARRAY_SIZE(regulators); i++) { + rdev = devm_regulator_register(&pdev->dev, ®ulators[i], + &config); + if (IS_ERR(rdev)) { + dev_err(bd->dev, "failed to register %s regulator\n", + pdev->name); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct platform_device_id bd9571mwv_regulator_id_table[] = { + { "bd9571mwv-regulator", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table); + +static struct platform_driver bd9571mwv_regulator_driver = { + .driver = { + .name = "bd9571mwv-regulator", + }, + .probe = bd9571mwv_regulator_probe, + .id_table = bd9571mwv_regulator_id_table, +}; +module_platform_driver(bd9571mwv_regulator_driver); + +MODULE_AUTHOR("Marek Vasut "); +MODULE_DESCRIPTION("BD9571MWV Regulator driver"); +MODULE_LICENSE("GPL v2");