summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-05-19 13:12:37 +0200
committerSeung-Woo Kim <sw0312.kim@samsung.com>2016-12-14 13:50:45 +0900
commit88750ef5c951b4aa292f9e20d44ace35ec9c68bf (patch)
tree46778cf003bb9706bc3cac32eab6e05651f26b48
parent15f8386c66d725c5b0700371c38790e220caa9d8 (diff)
soc: exynos: pm_domains: restore old way of getting dt clocks
This restores support for asb clocks, which got lost during core rewrite. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Change-Id: Idc37a9814bd4825863960dc0e59486e07ddf9139
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433.dtsi3
-rw-r--r--drivers/soc/samsung/pm_domains.c75
2 files changed, 41 insertions, 37 deletions
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 34d4b1ee52bc..69fefd39b7c9 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -605,6 +605,9 @@
<&cmu_disp CLK_MOUT_PHYCLK_MIPIDPHY1_RXCLKESC0_USER>,
<&cmu_disp CLK_MOUT_PHYCLK_MIPIDPHY1_BITCLKDIV8_USER>,
<&xxti>;
+ clock-names = "clk0", "clk1", "clk2", "clk3", "clk4", "clk5",
+ "clk6", "clk7", "clk8", "clk9", "clk10", "clk11",
+ "clk12", "clk13", "oscclk";
};
pd_cam1: cam1-power-domain@105c40a0 {
diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c
index 0313d3eab207..a2e1022a19e4 100644
--- a/drivers/soc/samsung/pm_domains.c
+++ b/drivers/soc/samsung/pm_domains.c
@@ -23,6 +23,8 @@
#include <linux/sched.h>
#include <linux/soc/samsung/pm_domain.h>
+#define MAX_CLK_PER_DOMAIN 16
+
struct exynos_pm_domain_config {
/* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
u32 local_pwr_cfg;
@@ -36,13 +38,11 @@ struct exynos_pm_domain {
void __iomem *base;
char const *name;
bool is_off;
- int nr_reparent_clks;
struct atomic_notifier_head nh;
struct clk *oscclk;
- struct clk **clk;
- struct clk **pclk;
- int nr_asb_clks;
- struct clk **asb_clk;
+ struct clk *clk[MAX_CLK_PER_DOMAIN];
+ struct clk *pclk[MAX_CLK_PER_DOMAIN];
+ struct clk *asb_clk[MAX_CLK_PER_DOMAIN];
u32 local_pwr_cfg;
};
@@ -107,7 +107,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
exynos_pd_notify_pre(pd, power_on);
- for (i = 0; i < pd->nr_asb_clks; i++) {
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->asb_clk[i]))
break;
clk_prepare_enable(pd->asb_clk[i]);
@@ -115,7 +115,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
/* Set oscclk before powering off a domain*/
if (!power_on) {
- for (i = 0; i < pd->nr_reparent_clks; i++) {
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
pd->pclk[i] = clk_get_parent(pd->clk[i]);
@@ -144,7 +144,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
/* Restore clocks after powering on a domain*/
if (power_on) {
- for (i = 0; i < pd->nr_reparent_clks; i++) {
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
if (IS_ERR(pd->pclk[i]))
@@ -155,7 +155,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
}
}
- for (i = 0; i < pd->nr_asb_clks; i++) {
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->asb_clk[i]))
break;
clk_disable_unprepare(pd->asb_clk[i]);
@@ -199,7 +199,6 @@ static __init int exynos4_pm_init_power_domain(void)
{
struct device_node *np;
const struct of_device_id *match;
- int nr_clks;
for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) {
const struct exynos_pm_domain_config *pm_domain_cfg;
@@ -228,35 +227,37 @@ static __init int exynos4_pm_init_power_domain(void)
ATOMIC_INIT_NOTIFIER_HEAD(&pd->nh);
- nr_clks = of_count_phandle_with_args(np, "clocks","#clock-cells");
- if (nr_clks > 1) {
- /* oscclk is the last phandle */
- pd->oscclk = of_clk_get(np, --nr_clks);
-
- if (IS_ERR(pd->oscclk)) {
- pr_err("Could not get oscclk for %s domain\n", pd->pd.name);
- kfree(pd);
- continue;
- }
-
- pd->clk = kcalloc(sizeof(struct clk *),
- nr_clks, GFP_KERNEL);
- pd->pclk = kcalloc(sizeof(struct clk *),
- nr_clks, GFP_KERNEL);
- for (i = 0; i < nr_clks; i++) {
- pd->clk[i] = of_clk_get(np, i);
- if (IS_ERR(pd->clk[i]))
- break;
- /*
- * Skip setting parent on first power up.
- * The parent at this time may not be useful at all.
- */
- pd->pclk[i] = ERR_PTR(-EINVAL);
- }
-
- pd->nr_reparent_clks = nr_clks;
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ char clk_name[8];
+
+ snprintf(clk_name, sizeof(clk_name), "asb%d", i);
+ pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
+ if (IS_ERR(pd->asb_clk[i]))
+ break;
+ }
+
+ pd->oscclk = of_clk_get_by_name(np, "oscclk");
+ if (IS_ERR(pd->oscclk))
+ goto no_clk;
+
+ for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
+ char clk_name[8];
+
+ snprintf(clk_name, sizeof(clk_name), "clk%d", i);
+ pd->clk[i] = of_clk_get_by_name(np, clk_name);
+ if (IS_ERR(pd->clk[i]))
+ break;
+ /*
+ * Skip setting parent on first power up.
+ * The parent at this time may not be useful at all.
+ */
+ pd->pclk[i] = ERR_PTR(-EINVAL);
}
+ if (IS_ERR(pd->clk[0]))
+ clk_put(pd->oscclk);
+
+no_clk:
on = __raw_readl(pd->base + 0x4) & pd->local_pwr_cfg;
pm_genpd_init(&pd->pd, NULL, !on);