summaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-10-26 21:56:59 +0100
committerMark Brown <broonie@kernel.org>2020-10-26 21:56:59 +0100
commitf88d47190a1f379c5c0a113ed79832f3fff69579 (patch)
treed79c50cdf06e6ee61cb2e01411df102e981fb1be /drivers/regulator
parentregulator: lp872x: make a const array static, makes object smaller (diff)
parentregulator: fixed: provide bindings using power domain (diff)
downloadlinux-f88d47190a1f379c5c0a113ed79832f3fff69579.tar.xz
linux-f88d47190a1f379c5c0a113ed79832f3fff69579.zip
Merge series " [PATCH v2 0/5]" from Dmitry Baryshkov <dmitry.baryshkov@linaro.org>:
On SM8250 MDSS_GDSC (and the rest of display clock controller) is supplied power by MMCX power domain. Handle this link in GDSC code by binding the power domain in dts file. This patchset depends on [1] Changes since v1: - Define fixed-regulator-domain regulator using power domain performance state for enabling/disabling. - Rework to use new fixed regulator type (fixed-regulator-domain) instead of controlling power domain directly from gdsc code. Changes since RFC: - Fix naming of gdsc_supply_on/gdsc_supply_off functions - Fix detaching of solo gdsc's power domain in error handling code - Drop the dts patch, as respective display nodes are still not submitted to the mailing list. [1] https://lore.kernel.org/linux-arm-msm/20200927190653.13876-1-jonathan@marek.ca/
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/fixed.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 3de7709bdcd4..02ad83153e19 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -18,6 +18,8 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h>
#include <linux/gpio/consumer.h>
@@ -34,11 +36,13 @@ struct fixed_voltage_data {
struct regulator_dev *dev;
struct clk *enable_clock;
- unsigned int clk_enable_counter;
+ unsigned int enable_counter;
+ int performance_state;
};
struct fixed_dev_type {
bool has_enable_clock;
+ bool has_performance_state;
};
static int reg_clock_enable(struct regulator_dev *rdev)
@@ -50,7 +54,7 @@ static int reg_clock_enable(struct regulator_dev *rdev)
if (ret)
return ret;
- priv->clk_enable_counter++;
+ priv->enable_counter++;
return ret;
}
@@ -60,16 +64,41 @@ static int reg_clock_disable(struct regulator_dev *rdev)
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
clk_disable_unprepare(priv->enable_clock);
- priv->clk_enable_counter--;
+ priv->enable_counter--;
return 0;
}
-static int reg_clock_is_enabled(struct regulator_dev *rdev)
+static int reg_domain_enable(struct regulator_dev *rdev)
{
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+ struct device *dev = rdev->dev.parent;
+ int ret;
+
+ ret = dev_pm_genpd_set_performance_state(dev, priv->performance_state);
+ if (ret)
+ return ret;
- return priv->clk_enable_counter > 0;
+ priv->enable_counter++;
+
+ return ret;
+}
+
+static int reg_domain_disable(struct regulator_dev *rdev)
+{
+ struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+ struct device *dev = rdev->dev.parent;
+
+ priv->enable_counter--;
+
+ return dev_pm_genpd_set_performance_state(dev, 0);
+}
+
+static int reg_is_enabled(struct regulator_dev *rdev)
+{
+ struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+
+ return priv->enable_counter > 0;
}
@@ -129,7 +158,13 @@ static const struct regulator_ops fixed_voltage_ops = {
static const struct regulator_ops fixed_voltage_clkenabled_ops = {
.enable = reg_clock_enable,
.disable = reg_clock_disable,
- .is_enabled = reg_clock_is_enabled,
+ .is_enabled = reg_is_enabled,
+};
+
+static const struct regulator_ops fixed_voltage_domain_ops = {
+ .enable = reg_domain_enable,
+ .disable = reg_domain_disable,
+ .is_enabled = reg_is_enabled,
};
static int reg_fixed_voltage_probe(struct platform_device *pdev)
@@ -177,6 +212,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
dev_err(dev, "Can't get enable-clock from devicetree\n");
return -ENOENT;
}
+ } else if (drvtype && drvtype->has_performance_state) {
+ drvdata->desc.ops = &fixed_voltage_domain_ops;
+
+ drvdata->performance_state = of_get_required_opp_performance_state(dev->of_node, 0);
+ if (drvdata->performance_state < 0) {
+ dev_err(dev, "Can't get performance state from devicetree\n");
+ return drvdata->performance_state;
+ }
} else {
drvdata->desc.ops = &fixed_voltage_ops;
}
@@ -260,6 +303,10 @@ static const struct fixed_dev_type fixed_clkenable_data = {
.has_enable_clock = true,
};
+static const struct fixed_dev_type fixed_domain_data = {
+ .has_performance_state = true,
+};
+
static const struct of_device_id fixed_of_match[] = {
{
.compatible = "regulator-fixed",
@@ -270,6 +317,10 @@ static const struct of_device_id fixed_of_match[] = {
.data = &fixed_clkenable_data,
},
{
+ .compatible = "regulator-fixed-domain",
+ .data = &fixed_domain_data,
+ },
+ {
},
};
MODULE_DEVICE_TABLE(of, fixed_of_match);