diff options
-rw-r--r-- | drivers/regulator/core.c | 15 | ||||
-rw-r--r-- | drivers/regulator/fixed.c | 6 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 3 | ||||
-rw-r--r-- | include/linux/regulator/fixed.h | 1 |
4 files changed, 25 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index fa2f87b504d5..00161bd9cf0f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -32,6 +32,7 @@ #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/module.h> +#include <linux/clk.h> #define CREATE_TRACE_POINTS #include <trace/events/regulator.h> @@ -2123,6 +2124,11 @@ static int _regulator_do_enable(struct regulator_dev *rdev) ret = rdev->desc->ops->enable(rdev); if (ret < 0) return ret; + } else if (rdev->ena_clk) { + ret = clk_prepare_enable(rdev->ena_clk); + if (ret) + return ret; + rdev->ena_clk_state++; } else { return -EINVAL; } @@ -2230,6 +2236,9 @@ static int _regulator_do_disable(struct regulator_dev *rdev) ret = rdev->desc->ops->disable(rdev); if (ret != 0) return ret; + } else if (rdev->ena_clk) { + clk_disable_unprepare(rdev->ena_clk); + rdev->ena_clk_state--; } /* cares about last_off_jiffy only if off_on_delay is required by @@ -2443,6 +2452,9 @@ static int _regulator_is_enabled(struct regulator_dev *rdev) if (rdev->ena_pin) return rdev->ena_gpio_state; + if (rdev->ena_clk) + return (rdev->ena_clk_state > 0) ? 1 : 0; + /* If we don't know then assume that the regulator is always on */ if (!rdev->desc->ops->is_enabled) return 1; @@ -4008,6 +4020,9 @@ regulator_register(const struct regulator_desc *regulator_desc, } } + if (cfg->ena_clk) + rdev->ena_clk = cfg->ena_clk; + /* register with sysfs */ rdev->dev.class = ®ulator_class; rdev->dev.parent = dev; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 136a9a3c7e30..23eebdceeb17 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -31,6 +31,7 @@ #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> #include <linux/pinctrl/consumer.h> +#include <linux/clk.h> struct fixed_voltage_data { struct regulator_desc desc; @@ -93,6 +94,10 @@ of_get_fixed_voltage_config(struct device *dev, if (of_find_property(np, "vin-supply", NULL)) config->input_supply = "vin"; + config->ena_clk = devm_clk_get(dev, NULL); + if (IS_ERR(config->ena_clk)) + config->ena_clk = NULL; + return config; } @@ -177,6 +182,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) cfg.init_data = config->init_data; cfg.driver_data = drvdata; cfg.of_node = pdev->dev.of_node; + cfg.ena_clk = config->ena_clk; drvdata->dev = devm_regulator_register(&pdev->dev, &drvdata->desc, &cfg); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 3c3786df044c..da6da0507cda 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -376,6 +376,7 @@ struct regulator_config { void *driver_data; struct device_node *of_node; struct regmap *regmap; + struct clk *ena_clk; bool ena_gpio_initialized; int ena_gpio; @@ -424,6 +425,8 @@ struct regulator_dev { struct regulator_enable_gpio *ena_pin; unsigned int ena_gpio_state:1; + struct clk *ena_clk; + unsigned int ena_clk_state; unsigned int is_switch:1; diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h index ba4ac009d832..a5859c1d2c01 100644 --- a/include/linux/regulator/fixed.h +++ b/include/linux/regulator/fixed.h @@ -56,6 +56,7 @@ struct fixed_voltage_config { unsigned enable_high:1; unsigned enabled_at_boot:1; struct regulator_init_data *init_data; + struct clk *ena_clk; }; struct regulator_consumer_supply; |