diff options
author | Arnd Bergmann <arnd@arndb.de> | 2017-02-07 11:20:07 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2017-02-07 11:20:07 -0500 |
commit | 28eedd15ec3ea25a2cd9e706e8c00a4b197aca72 (patch) | |
tree | 5436c43c5e271cc47498aeaaf33d56feb1d57ada | |
parent | 57ac490466a5f9f703a9183a8583df1d9660ce0c (diff) | |
parent | b13b2330aab53af4ebaa2859f72f2c802d01abad (diff) |
Merge tag 'samsung-drivers-soc-pm-domains-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into next/drivers
Pull "soc: samsung: pm_domains for v4.11" from Krzysztof Kozłowski:
Improve the PM domains driver for Exynos by displaying a user-friendly name of
power domain. Till now, the name of node from DT was used which mostly is just
"power-domain". We need more than that.
* tag 'samsung-drivers-soc-pm-domains-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux:
soc: samsung: pm_domains: Read domain name from the new label property
soc: samsung: pm_domains: Remove message about failed memory allocation
soc: samsung: pm_domains: Remove unused name field
soc: samsung: pm_domains: Use full names in subdomains registration log
-rw-r--r-- | Documentation/devicetree/bindings/power/pd-samsung.txt | 4 | ||||
-rw-r--r-- | drivers/soc/samsung/pm_domains.c | 24 |
2 files changed, 18 insertions, 10 deletions
diff --git a/Documentation/devicetree/bindings/power/pd-samsung.txt b/Documentation/devicetree/bindings/power/pd-samsung.txt index f5d4b68d2760..7eb9674e9687 100644 --- a/Documentation/devicetree/bindings/power/pd-samsung.txt +++ b/Documentation/devicetree/bindings/power/pd-samsung.txt | |||
@@ -13,6 +13,8 @@ Required Properties: | |||
13 | must be 0. | 13 | must be 0. |
14 | 14 | ||
15 | Optional Properties: | 15 | Optional Properties: |
16 | - label: Human readable string with domain name. Will be visible in userspace | ||
17 | to let user to distinguish between multiple domains in SoC. | ||
16 | - clocks: List of clock handles. The parent clocks of the input clocks to the | 18 | - clocks: List of clock handles. The parent clocks of the input clocks to the |
17 | devices in this power domain are set to oscclk before power gating | 19 | devices in this power domain are set to oscclk before power gating |
18 | and restored back after powering on a domain. This is required for | 20 | and restored back after powering on a domain. This is required for |
@@ -39,6 +41,7 @@ Example: | |||
39 | compatible = "samsung,exynos4210-pd"; | 41 | compatible = "samsung,exynos4210-pd"; |
40 | reg = <0x10023C00 0x10>; | 42 | reg = <0x10023C00 0x10>; |
41 | #power-domain-cells = <0>; | 43 | #power-domain-cells = <0>; |
44 | label = "LCD0"; | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | mfc_pd: power-domain@10044060 { | 47 | mfc_pd: power-domain@10044060 { |
@@ -47,6 +50,7 @@ Example: | |||
47 | clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>; | 50 | clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>; |
48 | clock-names = "oscclk", "clk0"; | 51 | clock-names = "oscclk", "clk0"; |
49 | #power-domain-cells = <0>; | 52 | #power-domain-cells = <0>; |
53 | label = "MFC"; | ||
50 | }; | 54 | }; |
51 | 55 | ||
52 | See Documentation/devicetree/bindings/power/power_domain.txt for description | 56 | See Documentation/devicetree/bindings/power/power_domain.txt for description |
diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 15bad1543409..a6a5d807cc2b 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c | |||
@@ -35,7 +35,6 @@ struct exynos_pm_domain_config { | |||
35 | */ | 35 | */ |
36 | struct exynos_pm_domain { | 36 | struct exynos_pm_domain { |
37 | void __iomem *base; | 37 | void __iomem *base; |
38 | char const *name; | ||
39 | bool is_off; | 38 | bool is_off; |
40 | struct generic_pm_domain pd; | 39 | struct generic_pm_domain pd; |
41 | struct clk *oscclk; | 40 | struct clk *oscclk; |
@@ -70,7 +69,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) | |||
70 | pd->pclk[i] = clk_get_parent(pd->clk[i]); | 69 | pd->pclk[i] = clk_get_parent(pd->clk[i]); |
71 | if (clk_set_parent(pd->clk[i], pd->oscclk)) | 70 | if (clk_set_parent(pd->clk[i], pd->oscclk)) |
72 | pr_err("%s: error setting oscclk as parent to clock %d\n", | 71 | pr_err("%s: error setting oscclk as parent to clock %d\n", |
73 | pd->name, i); | 72 | domain->name, i); |
74 | } | 73 | } |
75 | } | 74 | } |
76 | 75 | ||
@@ -101,7 +100,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) | |||
101 | continue; /* Skip on first power up */ | 100 | continue; /* Skip on first power up */ |
102 | if (clk_set_parent(pd->clk[i], pd->pclk[i])) | 101 | if (clk_set_parent(pd->clk[i], pd->pclk[i])) |
103 | pr_err("%s: error setting parent to clock%d\n", | 102 | pr_err("%s: error setting parent to clock%d\n", |
104 | pd->name, i); | 103 | domain->name, i); |
105 | } | 104 | } |
106 | } | 105 | } |
107 | 106 | ||
@@ -143,6 +142,15 @@ static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { | |||
143 | { }, | 142 | { }, |
144 | }; | 143 | }; |
145 | 144 | ||
145 | static __init const char *exynos_get_domain_name(struct device_node *node) | ||
146 | { | ||
147 | const char *name; | ||
148 | |||
149 | if (of_property_read_string(node, "label", &name) < 0) | ||
150 | name = strrchr(node->full_name, '/') + 1; | ||
151 | return kstrdup_const(name, GFP_KERNEL); | ||
152 | } | ||
153 | |||
146 | static __init int exynos4_pm_init_power_domain(void) | 154 | static __init int exynos4_pm_init_power_domain(void) |
147 | { | 155 | { |
148 | struct device_node *np; | 156 | struct device_node *np; |
@@ -157,20 +165,16 @@ static __init int exynos4_pm_init_power_domain(void) | |||
157 | 165 | ||
158 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); | 166 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); |
159 | if (!pd) { | 167 | if (!pd) { |
160 | pr_err("%s: failed to allocate memory for domain\n", | ||
161 | __func__); | ||
162 | of_node_put(np); | 168 | of_node_put(np); |
163 | return -ENOMEM; | 169 | return -ENOMEM; |
164 | } | 170 | } |
165 | pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1, | 171 | pd->pd.name = exynos_get_domain_name(np); |
166 | GFP_KERNEL); | ||
167 | if (!pd->pd.name) { | 172 | if (!pd->pd.name) { |
168 | kfree(pd); | 173 | kfree(pd); |
169 | of_node_put(np); | 174 | of_node_put(np); |
170 | return -ENOMEM; | 175 | return -ENOMEM; |
171 | } | 176 | } |
172 | 177 | ||
173 | pd->name = pd->pd.name; | ||
174 | pd->base = of_iomap(np, 0); | 178 | pd->base = of_iomap(np, 0); |
175 | if (!pd->base) { | 179 | if (!pd->base) { |
176 | pr_warn("%s: failed to map memory\n", __func__); | 180 | pr_warn("%s: failed to map memory\n", __func__); |
@@ -234,10 +238,10 @@ no_clk: | |||
234 | 238 | ||
235 | if (of_genpd_add_subdomain(&parent, &child)) | 239 | if (of_genpd_add_subdomain(&parent, &child)) |
236 | pr_warn("%s failed to add subdomain: %s\n", | 240 | pr_warn("%s failed to add subdomain: %s\n", |
237 | parent.np->name, child.np->name); | 241 | parent.np->full_name, child.np->full_name); |
238 | else | 242 | else |
239 | pr_info("%s has as child subdomain: %s.\n", | 243 | pr_info("%s has as child subdomain: %s.\n", |
240 | parent.np->name, child.np->name); | 244 | parent.np->full_name, child.np->full_name); |
241 | } | 245 | } |
242 | 246 | ||
243 | return 0; | 247 | return 0; |