diff mbox

[RFC,06/10] ARM: s3c64xx: pm: Add device tree based power domain instantiation

Message ID 1389469372-17199-7-git-send-email-tomasz.figa@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomasz Figa Jan. 11, 2014, 7:42 p.m. UTC
This patch adds support for registering power domains of S3C64xx SoCs
and binding devices to them using device tree.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c                      | 71 +++++++++++++++++++++----
 include/dt-bindings/arm/s3c64xx-power-domains.h | 26 +++++++++
 2 files changed, 88 insertions(+), 9 deletions(-)
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

Comments

Mark Brown Jan. 12, 2014, 7:29 p.m. UTC | #1
On Sat, Jan 11, 2014 at 08:42:48PM +0100, Tomasz Figa wrote:

> This patch adds support for registering power domains of S3C64xx SoCs
> and binding devices to them using device tree.

> +#ifdef CONFIG_OF
> +static struct of_device_id s3c64xx_pd_matches[] = {
> +	{ .compatible = "samsung,s3c6400-clock", },
> +	{ .compatible = "samsung,s3c6410-clock", },
> +	{ },
>  };

Looks like a rebasing issue?  Otherwise this looks nice.
Tomasz Figa Jan. 12, 2014, 7:34 p.m. UTC | #2
On 12.01.2014 20:29, Mark Brown wrote:
> On Sat, Jan 11, 2014 at 08:42:48PM +0100, Tomasz Figa wrote:
>
>> This patch adds support for registering power domains of S3C64xx SoCs
>> and binding devices to them using device tree.
>
>> +#ifdef CONFIG_OF
>> +static struct of_device_id s3c64xx_pd_matches[] = {
>> +	{ .compatible = "samsung,s3c6400-clock", },
>> +	{ .compatible = "samsung,s3c6410-clock", },
>> +	{ },
>>   };
>
> Looks like a rebasing issue?  Otherwise this looks nice.

Hmm, what's the problem here? Maybe I'm just blind, but I fail to see 
anything wrong (except that the array should be const...).

Thanks for reviewing this.

Best regards,
Tomasz
Mark Brown Jan. 13, 2014, 11:09 a.m. UTC | #3
On Sun, Jan 12, 2014 at 08:34:10PM +0100, Tomasz Figa wrote:
> On 12.01.2014 20:29, Mark Brown wrote:
> >On Sat, Jan 11, 2014 at 08:42:48PM +0100, Tomasz Figa wrote:

> >>This patch adds support for registering power domains of S3C64xx SoCs
> >>and binding devices to them using device tree.

> >>+#ifdef CONFIG_OF
> >>+static struct of_device_id s3c64xx_pd_matches[] = {
> >>+	{ .compatible = "samsung,s3c6400-clock", },
> >>+	{ .compatible = "samsung,s3c6410-clock", },
> >>+	{ },
> >>  };

> >Looks like a rebasing issue?  Otherwise this looks nice.

> Hmm, what's the problem here? Maybe I'm just blind, but I fail to
> see anything wrong (except that the array should be const...).

> Thanks for reviewing this.

I wasn't expecting to see references to clocks come up in power domain
code.
Tomasz Figa Jan. 13, 2014, 12:13 p.m. UTC | #4
On 13.01.2014 12:09, Mark Brown wrote:
> On Sun, Jan 12, 2014 at 08:34:10PM +0100, Tomasz Figa wrote:
>> On 12.01.2014 20:29, Mark Brown wrote:
>>> On Sat, Jan 11, 2014 at 08:42:48PM +0100, Tomasz Figa wrote:
>
>>>> This patch adds support for registering power domains of S3C64xx SoCs
>>>> and binding devices to them using device tree.
>
>>>> +#ifdef CONFIG_OF
>>>> +static struct of_device_id s3c64xx_pd_matches[] = {
>>>> +	{ .compatible = "samsung,s3c6400-clock", },
>>>> +	{ .compatible = "samsung,s3c6410-clock", },
>>>> +	{ },
>>>>   };
>
>>> Looks like a rebasing issue?  Otherwise this looks nice.
>
>> Hmm, what's the problem here? Maybe I'm just blind, but I fail to
>> see anything wrong (except that the array should be const...).
>
>> Thanks for reviewing this.
>
> I wasn't expecting to see references to clocks come up in power domain
> code.
>

Power domain control registers are part of the system controller block, 
which uses the "samsung,s3c64*-clock" compatible string. I know this is 
a bit unfortunate, but all registers of this IP block are mapped at the 
same page and some clock registers are at the other end of this area 
than others, so there is even no good way to split them into separate 
mappings.

Best regards,
Tomasz
Mark Brown Jan. 13, 2014, 12:17 p.m. UTC | #5
On Mon, Jan 13, 2014 at 01:13:52PM +0100, Tomasz Figa wrote:

> Power domain control registers are part of the system controller
> block, which uses the "samsung,s3c64*-clock" compatible string. I
> know this is a bit unfortunate, but all registers of this IP block
> are mapped at the same page and some clock registers are at the
> other end of this area than others, so there is even no good way to
> split them into separate mappings.

I see - probably would've been neater to give it a different name but
too late now.
diff mbox

Patch

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 717d9be..673baaf 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -17,8 +17,11 @@ 
 #include <linux/serial_core.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 #include <linux/pm_domain.h>
 
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
+
 #include <mach/map.h>
 #include <mach/irqs.h>
 
@@ -164,17 +167,63 @@  static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
-	&s3c64xx_pm_irom,
-	&s3c64xx_pm_etm,
-	&s3c64xx_pm_g,
-	&s3c64xx_pm_v,
-	&s3c64xx_pm_i,
-	&s3c64xx_pm_p,
-	&s3c64xx_pm_s,
-	&s3c64xx_pm_f,
+static struct s3c64xx_pm_domain *s3c64xx_pm_domains[NR_DOMAINS] = {
+	[DOMAIN_V] = &s3c64xx_pm_v,
+	[DOMAIN_G] = &s3c64xx_pm_g,
+	[DOMAIN_I] = &s3c64xx_pm_i,
+	[DOMAIN_P] = &s3c64xx_pm_p,
+	[DOMAIN_F] = &s3c64xx_pm_f,
+	[DOMAIN_S] = &s3c64xx_pm_s,
+	[DOMAIN_ETM] = &s3c64xx_pm_etm,
+	[DOMAIN_IROM] = &s3c64xx_pm_irom,
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id s3c64xx_pd_matches[] = {
+	{ .compatible = "samsung,s3c6400-clock", },
+	{ .compatible = "samsung,s3c6410-clock", },
+	{ },
 };
 
+static struct genpd_onecell_data pd_data;
+
+static int s3c64xx_pm_parse_domains(void)
+{
+	struct device_node *np;
+	int i;
+
+	np = of_find_matching_node(NULL, s3c64xx_pd_matches);
+	if (!np)
+		return -ENODEV;
+
+	pd_data.domains = kcalloc(ARRAY_SIZE(s3c64xx_pm_domains),
+				  sizeof(*pd_data.domains), GFP_KERNEL);
+	if (!pd_data.domains)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); ++i) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+		int on;
+
+		on = __raw_readl(S3C64XX_NORMAL_CFG) & pd->ena;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, !on);
+		pd_data.domains[i] = &pd->pd;
+
+		pr_debug("%s: registered domain %s\n", __func__, pd->pd.name);
+	}
+
+	pd_data.domain_num = ARRAY_SIZE(s3c64xx_pm_domains);
+	of_genpd_add_provider(np, of_genpd_xlate_onecell, &pd_data);
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
 void s3c_pm_debug_smdkled(u32 set, u32 clear)
 {
@@ -311,6 +360,10 @@  int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
+#ifdef CONFIG_OF
+	if (of_have_populated_dt())
+		return s3c64xx_pm_parse_domains();
+#endif
 
 	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
 		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
diff --git a/include/dt-bindings/arm/s3c64xx-power-domains.h b/include/dt-bindings/arm/s3c64xx-power-domains.h
new file mode 100644
index 0000000..ce39bef
--- /dev/null
+++ b/include/dt-bindings/arm/s3c64xx-power-domains.h
@@ -0,0 +1,26 @@ 
+/*
+ * Copyright (c) 2014 Tomasz Figa <tomasz.figa at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants for Samsung S3C64xx power domains.
+*/
+
+#ifndef _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+#define _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+
+#define DOMAIN_V		0
+#define DOMAIN_G		1
+#define DOMAIN_I		2
+#define DOMAIN_P		3
+#define DOMAIN_F		4
+#define DOMAIN_S		5
+#define DOMAIN_ETM		6
+#define DOMAIN_IROM		7
+
+/* Total number of clocks. */
+#define NR_DOMAINS		(DOMAIN_IROM + 1)
+
+#endif /* _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H */