From: Rajendra Nayak <rnayak@codeaurora.org>
To: sboyd@codeaurora.org, mturquette@baylibre.com
Cc: linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
stanimir.varbanov@linaro.org, vivek.gautam@codeaurora.org,
Rajendra Nayak <rnayak@codeaurora.org>
Subject: [PATCH v2 3/5] clk: qcom: gdsc: Add support to control associated clks
Date: Thu, 20 Jul 2017 10:18:17 +0530 [thread overview]
Message-ID: <1500526099-9935-4-git-send-email-rnayak@codeaurora.org> (raw)
In-Reply-To: <1500526099-9935-1-git-send-email-rnayak@codeaurora.org>
The devices within a gdsc power domain, quite often have additional
clocks to be turned on/off along with the power domain itself.
Add support for this by specifying a list of clk_hw pointers
per gdsc which would be the clocks turned on/off along with the
powerdomain on/off callbacks.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
drivers/clk/qcom/gdsc.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++--
drivers/clk/qcom/gdsc.h | 8 +++++++
2 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index a4f3580..7e7c051 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -12,6 +12,8 @@
*/
#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/jiffies.h>
@@ -21,6 +23,7 @@
#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
+#include "common.h"
#include "gdsc.h"
#define PWR_ON_MASK BIT(31)
@@ -166,6 +169,29 @@ static inline void gdsc_assert_clamp_io(struct gdsc *sc)
GMEM_CLAMP_IO_MASK, 1);
}
+static inline int gdsc_clk_enable(struct gdsc *sc)
+{
+ int i, ret;
+
+ for (i = 0; i < sc->clk_count; i++) {
+ ret = clk_prepare_enable(sc->clks[i]);
+ if (ret) {
+ for (i--; i >= 0; i--)
+ clk_disable_unprepare(sc->clks[i]);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static inline void gdsc_clk_disable(struct gdsc *sc)
+{
+ int i;
+
+ for (i = 0; i < sc->clk_count; i++)
+ clk_disable_unprepare(sc->clks[i]);
+}
+
static int gdsc_enable(struct generic_pm_domain *domain)
{
struct gdsc *sc = domain_to_gdsc(domain);
@@ -193,6 +219,10 @@ static int gdsc_enable(struct generic_pm_domain *domain)
*/
udelay(1);
+ ret = gdsc_clk_enable(sc);
+ if (ret)
+ return ret;
+
/* Turn on HW trigger mode if supported */
if (sc->flags & HW_CTRL) {
ret = gdsc_hwctrl(sc, true);
@@ -241,6 +271,8 @@ static int gdsc_disable(struct generic_pm_domain *domain)
return ret;
}
+ gdsc_clk_disable(sc);
+
if (sc->pwrsts & PWRSTS_OFF)
gdsc_clear_mem_on(sc);
@@ -254,7 +286,27 @@ static int gdsc_disable(struct generic_pm_domain *domain)
return 0;
}
-static int gdsc_init(struct gdsc *sc)
+static inline int gdsc_clk_get(struct device *dev, struct gdsc *sc)
+{
+ if (sc->clk_count) {
+ int i;
+
+ sc->clks = devm_kcalloc(dev, sc->clk_count, sizeof(*sc->clks),
+ GFP_KERNEL);
+ if (!sc->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < sc->clk_count; i++) {
+ sc->clks[i] = devm_clk_hw_get_clk(dev, sc->clk_hws[i],
+ NULL);
+ if (IS_ERR(sc->clks[i]))
+ return PTR_ERR(sc->clks[i]);
+ }
+ }
+ return 0;
+}
+
+static int gdsc_init(struct device *dev, struct gdsc *sc)
{
u32 mask, val;
int on, ret;
@@ -284,6 +336,10 @@ static int gdsc_init(struct gdsc *sc)
if (on < 0)
return on;
+ ret = gdsc_clk_get(dev, sc);
+ if (ret)
+ return ret;
+
/*
* Votable GDSCs can be ON due to Vote from other masters.
* If a Votable GDSC is ON, make sure we have a Vote.
@@ -327,7 +383,7 @@ int gdsc_register(struct gdsc_desc *desc,
continue;
scs[i]->regmap = regmap;
scs[i]->rcdev = rcdev;
- ret = gdsc_init(scs[i]);
+ ret = gdsc_init(dev, scs[i]);
if (ret)
return ret;
data->domains[i] = &scs[i]->pd;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 3964834..a7fd51b 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,8 @@
#include <linux/err.h>
#include <linux/pm_domain.h>
+struct clk;
+struct clk_hw;
struct regmap;
struct reset_controller_dev;
@@ -32,6 +34,9 @@
* @resets: ids of resets associated with this gdsc
* @reset_count: number of @resets
* @rcdev: reset controller
+ * @clk_count: number of gdsc clocks
+ * @clks: clk pointers for gdsc clocks
+ * @clk_hws: clk_hw pointers for gdsc clocks
*/
struct gdsc {
struct generic_pm_domain pd;
@@ -56,6 +61,9 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;
+ unsigned int clk_count;
+ struct clk **clks;
+ struct clk_hw *clk_hws[];
};
struct gdsc_desc {
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
WARNING: multiple messages have this Message-ID (diff)
From: rnayak@codeaurora.org (Rajendra Nayak)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 3/5] clk: qcom: gdsc: Add support to control associated clks
Date: Thu, 20 Jul 2017 10:18:17 +0530 [thread overview]
Message-ID: <1500526099-9935-4-git-send-email-rnayak@codeaurora.org> (raw)
In-Reply-To: <1500526099-9935-1-git-send-email-rnayak@codeaurora.org>
The devices within a gdsc power domain, quite often have additional
clocks to be turned on/off along with the power domain itself.
Add support for this by specifying a list of clk_hw pointers
per gdsc which would be the clocks turned on/off along with the
powerdomain on/off callbacks.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
drivers/clk/qcom/gdsc.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++--
drivers/clk/qcom/gdsc.h | 8 +++++++
2 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index a4f3580..7e7c051 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -12,6 +12,8 @@
*/
#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/jiffies.h>
@@ -21,6 +23,7 @@
#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
+#include "common.h"
#include "gdsc.h"
#define PWR_ON_MASK BIT(31)
@@ -166,6 +169,29 @@ static inline void gdsc_assert_clamp_io(struct gdsc *sc)
GMEM_CLAMP_IO_MASK, 1);
}
+static inline int gdsc_clk_enable(struct gdsc *sc)
+{
+ int i, ret;
+
+ for (i = 0; i < sc->clk_count; i++) {
+ ret = clk_prepare_enable(sc->clks[i]);
+ if (ret) {
+ for (i--; i >= 0; i--)
+ clk_disable_unprepare(sc->clks[i]);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static inline void gdsc_clk_disable(struct gdsc *sc)
+{
+ int i;
+
+ for (i = 0; i < sc->clk_count; i++)
+ clk_disable_unprepare(sc->clks[i]);
+}
+
static int gdsc_enable(struct generic_pm_domain *domain)
{
struct gdsc *sc = domain_to_gdsc(domain);
@@ -193,6 +219,10 @@ static int gdsc_enable(struct generic_pm_domain *domain)
*/
udelay(1);
+ ret = gdsc_clk_enable(sc);
+ if (ret)
+ return ret;
+
/* Turn on HW trigger mode if supported */
if (sc->flags & HW_CTRL) {
ret = gdsc_hwctrl(sc, true);
@@ -241,6 +271,8 @@ static int gdsc_disable(struct generic_pm_domain *domain)
return ret;
}
+ gdsc_clk_disable(sc);
+
if (sc->pwrsts & PWRSTS_OFF)
gdsc_clear_mem_on(sc);
@@ -254,7 +286,27 @@ static int gdsc_disable(struct generic_pm_domain *domain)
return 0;
}
-static int gdsc_init(struct gdsc *sc)
+static inline int gdsc_clk_get(struct device *dev, struct gdsc *sc)
+{
+ if (sc->clk_count) {
+ int i;
+
+ sc->clks = devm_kcalloc(dev, sc->clk_count, sizeof(*sc->clks),
+ GFP_KERNEL);
+ if (!sc->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < sc->clk_count; i++) {
+ sc->clks[i] = devm_clk_hw_get_clk(dev, sc->clk_hws[i],
+ NULL);
+ if (IS_ERR(sc->clks[i]))
+ return PTR_ERR(sc->clks[i]);
+ }
+ }
+ return 0;
+}
+
+static int gdsc_init(struct device *dev, struct gdsc *sc)
{
u32 mask, val;
int on, ret;
@@ -284,6 +336,10 @@ static int gdsc_init(struct gdsc *sc)
if (on < 0)
return on;
+ ret = gdsc_clk_get(dev, sc);
+ if (ret)
+ return ret;
+
/*
* Votable GDSCs can be ON due to Vote from other masters.
* If a Votable GDSC is ON, make sure we have a Vote.
@@ -327,7 +383,7 @@ int gdsc_register(struct gdsc_desc *desc,
continue;
scs[i]->regmap = regmap;
scs[i]->rcdev = rcdev;
- ret = gdsc_init(scs[i]);
+ ret = gdsc_init(dev, scs[i]);
if (ret)
return ret;
data->domains[i] = &scs[i]->pd;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 3964834..a7fd51b 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,8 @@
#include <linux/err.h>
#include <linux/pm_domain.h>
+struct clk;
+struct clk_hw;
struct regmap;
struct reset_controller_dev;
@@ -32,6 +34,9 @@
* @resets: ids of resets associated with this gdsc
* @reset_count: number of @resets
* @rcdev: reset controller
+ * @clk_count: number of gdsc clocks
+ * @clks: clk pointers for gdsc clocks
+ * @clk_hws: clk_hw pointers for gdsc clocks
*/
struct gdsc {
struct generic_pm_domain pd;
@@ -56,6 +61,9 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;
+ unsigned int clk_count;
+ struct clk **clks;
+ struct clk_hw *clk_hws[];
};
struct gdsc_desc {
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
next prev parent reply other threads:[~2017-07-20 4:48 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-20 4:48 [PATCH v2 0/5] clk: qcom: gdsc: Add support for clk control Rajendra Nayak
2017-07-20 4:48 ` Rajendra Nayak
2017-07-20 4:48 ` [PATCH v2 1/5] arm64: qcom: Select PM_GENERIC_DOMAINS Rajendra Nayak
2017-07-20 4:48 ` Rajendra Nayak
2017-07-28 16:42 ` Stephen Boyd
2017-07-28 16:42 ` Stephen Boyd
2017-08-08 1:28 ` Andy Gross
2017-08-08 1:28 ` Andy Gross
2017-07-20 4:48 ` [PATCH v2 2/5] clk: Add clk_hw_get_clk() helper API to be used by clk providers Rajendra Nayak
2017-07-20 4:48 ` Rajendra Nayak
2017-07-27 22:47 ` Stephen Boyd
2017-07-27 22:47 ` Stephen Boyd
2017-07-28 7:56 ` Rajendra Nayak
2017-07-28 7:56 ` Rajendra Nayak
2017-07-20 4:48 ` Rajendra Nayak [this message]
2017-07-20 4:48 ` [PATCH v2 3/5] clk: qcom: gdsc: Add support to control associated clks Rajendra Nayak
2017-07-21 8:29 ` Stanimir Varbanov
2017-07-21 8:29 ` Stanimir Varbanov
2017-07-27 23:02 ` Stephen Boyd
2017-07-27 23:02 ` Stephen Boyd
2017-07-28 8:05 ` Rajendra Nayak
2017-07-28 8:05 ` Rajendra Nayak
2017-07-28 16:37 ` Stephen Boyd
2017-07-28 16:37 ` Stephen Boyd
2017-07-31 8:25 ` Rajendra Nayak
2017-07-31 8:25 ` Rajendra Nayak
2017-08-02 4:39 ` Rajendra Nayak
2017-08-02 4:39 ` Rajendra Nayak
2017-07-20 4:48 ` [PATCH v2 4/5] clk: qcom: gcc-msm8996: Mark gcc_mmss_noc_cfg_ahb_clk as a critical clock Rajendra Nayak
2017-07-20 4:48 ` Rajendra Nayak
2017-07-27 22:51 ` Stephen Boyd
2017-07-27 22:51 ` Stephen Boyd
2017-07-28 7:58 ` Rajendra Nayak
2017-07-28 7:58 ` Rajendra Nayak
2017-07-28 16:40 ` Stephen Boyd
2017-07-28 16:40 ` Stephen Boyd
2017-07-28 17:02 ` Stephen Boyd
2017-07-28 17:02 ` Stephen Boyd
2017-07-20 4:48 ` [PATCH v2 5/5] clk: qcom: mmcc-8996: Associate all mmagic clks with mmagic gdscs Rajendra Nayak
2017-07-20 4:48 ` Rajendra Nayak
2017-07-26 14:47 ` [PATCH v2 0/5] clk: qcom: gdsc: Add support for clk control Vivek Gautam
2017-07-26 14:47 ` Vivek Gautam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1500526099-9935-4-git-send-email-rnayak@codeaurora.org \
--to=rnayak@codeaurora.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=sboyd@codeaurora.org \
--cc=stanimir.varbanov@linaro.org \
--cc=vivek.gautam@codeaurora.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.