diff options
author | Rajendra Nayak <rnayak@codeaurora.org> | 2015-12-01 19:12:11 +0300 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2016-02-12 03:24:00 +0300 |
commit | c2c7f0a47493ae23f9a76fabdbdd4f25e1de0925 (patch) | |
tree | 504a0b0db5ca155532ddd9445ec7be343c8bee40 /drivers/clk/qcom/gdsc.c | |
parent | 7e0810c9485ce696df3813574bca44139f6eb0c8 (diff) | |
download | linux-c2c7f0a47493ae23f9a76fabdbdd4f25e1de0925.tar.xz |
clk: qcom: gdsc: Add support for hierarchical power domains
Some qcom SoCs' can have hierarchical power domains. Let the gdsc structs
specify the parents (if any) and the driver add genpd subdomains for them.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/qcom/gdsc.c')
-rw-r--r-- | drivers/clk/qcom/gdsc.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index da9fad8b642b..bfab75bd272c 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -201,11 +201,14 @@ static int gdsc_init(struct gdsc *sc) return 0; } -int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, +int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, struct regmap *regmap) { int i, ret; struct genpd_onecell_data *data; + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + size_t num = desc->num; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -228,10 +231,30 @@ int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, data->domains[i] = &scs[i]->pd; } + /* Add subdomains */ + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + } + return of_genpd_add_provider_onecell(dev->of_node, data); } -void gdsc_unregister(struct device *dev) +void gdsc_unregister(struct gdsc_desc *desc) { + int i; + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + size_t num = desc->num; + + /* Remove subdomains */ + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); + } of_genpd_del_provider(dev->of_node); } |