Re: [PATCH v4 08/11] ARM: EXYNOS: Refactored code for using PMU address via DT

2014-06-17 Thread Tomasz Figa
Hi Pankaj,

[Dropped yg1004.j...@samsung.com from CC, as apparently his mailbox is
temporarily locked, at least from the point of view of my mail server.]

Please see my comments inline.

On 10.05.2014 08:56, Pankaj Dubey wrote:
 Under arm/mach-exynos many files are using PMU register offsets.
 Since we have added support for accessing PMU base address via DT,
 now we can remove PMU mapping from exynosX_iodesc. Let's convert
 all these access using either of iomapped address or regmap handle.
 This will help us in removing static mapping of PMU base address
 as well as help in reducing dependency over machine header files.
 Thus helping for migration of PMU implementation from machine to
 driver folder which can be reused for ARM64 bsed SoC.

[snip]

 diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
 index 3b1d245..59eb1f1 100644
 --- a/arch/arm/mach-exynos/exynos.c
 +++ b/arch/arm/mach-exynos/exynos.c

[snip]

 @@ -156,7 +147,7 @@ static void exynos_restart(enum reboot_mode mode, const 
 char *cmd)
  {
   struct device_node *np;
   u32 val = 0x1;
 - void __iomem *addr = EXYNOS_SWRESET;
 + void __iomem *addr = NULL;

This will probably change into addr = exynos_pmu_base + EXYNOS_SWRESET.

  
   if (of_machine_is_compatible(samsung,exynos5440)) {
   u32 status;
 @@ -169,9 +160,9 @@ static void exynos_restart(enum reboot_mode mode, const 
 char *cmd)
   val = __raw_readl(addr);
  
   val = (val  0x) | (status  0x);
 - }
 -
 - __raw_writel(val, addr);
 + __raw_writel(val, addr);
 + } else
 + regmap_write(exynos_pmu_regmap, EXYNOS_SWRESET, val);
  }
  
  static struct platform_device exynos_cpuidle = {
 diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
 index 73b0b5c..0243ef3 100644
 --- a/arch/arm/mach-exynos/hotplug.c
 +++ b/arch/arm/mach-exynos/hotplug.c
 @@ -13,6 +13,7 @@
  #include linux/errno.h
  #include linux/smp.h
  #include linux/io.h
 +#include linux/regmap.h
  
  #include asm/cacheflush.h
  #include asm/cp15.h
 @@ -91,11 +92,12 @@ static inline void cpu_leave_lowpower(void)
  
  static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
  {
 + struct regmap *pmu_regmap = get_exynos_pmuregmap();
   for (;;) {
  
   /* make cpu1 to be turned off at next WFI command */
   if (cpu == 1)
 - __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION);
 + regmap_write(pmu_regmap, S5P_ARM_CORE1_CONFIGURATION, 
 0);

This change should disappear.

[snip]

 diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
 index 1f63596..33eb364 100644
 --- a/arch/arm/mach-exynos/platsmp.c
 +++ b/arch/arm/mach-exynos/platsmp.c

[snip]

 +static void __iomem *pmu_base_addr(void)
 +{
 + struct device_node *np = NULL;
 + if (!pmu_base) {
 + np = of_find_matching_node(NULL, exynos_dt_pmu_match);
 +
 + if (!np)
 + panic(%s, failed to find PMU node\n, __func__);
 +
 + pmu_base = of_iomap(np, 0);
 +
 + if (!pmu_base)
 + panic(%s: failed to map registers\n, __func__);
 + }
 + return pmu_base;
 +}

As we discussed before, PMU mapping for arch code should be handled in
the same way as SYSRAM.

  static DEFINE_SPINLOCK(boot_lock);
  
  static void exynos_secondary_init(unsigned int cpu)
 @@ -132,14 +158,14 @@ static int exynos_boot_secondary(unsigned int cpu, 
 struct task_struct *idle)
*/
   write_pen_release(phys_cpu);
  
 - if (!(__raw_readl(S5P_ARM_CORE1_STATUS)  S5P_CORE_LOCAL_PWR_EN)) {
 + if (!(__raw_readl(pmu_base + S5P_ARM_CORE1_STATUS)
 +  S5P_CORE_LOCAL_PWR_EN)) {

Creating a variable to save register value to would probably make the
code more readable.

   __raw_writel(S5P_CORE_LOCAL_PWR_EN,
 -  S5P_ARM_CORE1_CONFIGURATION);
 -
 + pmu_base + S5P_ARM_CORE1_CONFIGURATION);
   timeout = 10;
  
   /* wait max 10 ms until cpu1 is on */
 - while ((__raw_readl(S5P_ARM_CORE1_STATUS)
 + while ((__raw_readl(pmu_base + S5P_ARM_CORE1_STATUS)
S5P_CORE_LOCAL_PWR_EN) != S5P_CORE_LOCAL_PWR_EN) {

Ditto.

   if (timeout-- == 0)
   break;
 @@ -238,6 +264,8 @@ static void __init exynos_smp_prepare_cpus(unsigned int 
 max_cpus)
  {
   int i;
  
 + pmu_base = pmu_base_addr();
 +
   if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
   scu_enable(scu_base_addr());
  
 diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
 index f445c49..ee427d7 100644
 --- a/arch/arm/mach-exynos/pm.c
 +++ b/arch/arm/mach-exynos/pm.c
 @@ -21,6 +21,7 @@
  #include linux/irqchip/arm-gic.h
  #include linux/err.h
  #include linux/clk.h
 +#include 

[PATCH v4 08/11] ARM: EXYNOS: Refactored code for using PMU address via DT

2014-05-10 Thread Pankaj Dubey
Under arm/mach-exynos many files are using PMU register offsets.
Since we have added support for accessing PMU base address via DT,
now we can remove PMU mapping from exynosX_iodesc. Let's convert
all these access using either of iomapped address or regmap handle.
This will help us in removing static mapping of PMU base address
as well as help in reducing dependency over machine header files.
Thus helping for migration of PMU implementation from machine to
driver folder which can be reused for ARM64 bsed SoC.

Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com
---
 arch/arm/mach-exynos/common.h|4 +-
 arch/arm/mach-exynos/exynos.c|   19 +-
 arch/arm/mach-exynos/hotplug.c   |4 +-
 arch/arm/mach-exynos/include/mach/map.h  |3 -
 arch/arm/mach-exynos/platsmp.c   |   38 +-
 arch/arm/mach-exynos/pm.c|   77 ++--
 arch/arm/mach-exynos/pmu.c   |   40 +-
 arch/arm/mach-exynos/regs-pmu.h  |  506 +-
 arch/arm/plat-samsung/include/plat/map-s5p.h |1 -
 9 files changed, 362 insertions(+), 330 deletions(-)

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index d533e2d..58b2b5d 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -39,7 +39,7 @@ extern void exynos_cpu_die(unsigned int cpu);
 
 /* PMU(Power Management Unit) support */
 
-#define PMU_TABLE_END  NULL
+#define PMU_TABLE_END  (-1U)
 
 enum sys_powerdown {
SYS_AFTR,
@@ -50,7 +50,7 @@ enum sys_powerdown {
 
 extern unsigned long l2x0_regs_phys;
 struct exynos_pmu_conf {
-   void __iomem *reg;
+   unsigned int offset;
unsigned int val[NUM_SYS_POWERDOWN];
 };
 
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 3b1d245..59eb1f1 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -20,6 +20,7 @@
 #include linux/platform_device.h
 #include linux/pm_domain.h
 #include linux/mfd/syscon.h
+#include linux/regmap.h
 
 #include asm/cacheflush.h
 #include asm/hardware/cache-l2x0.h
@@ -66,11 +67,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
.length = SZ_4K,
.type   = MT_DEVICE,
}, {
-   .virtual= (unsigned long)S5P_VA_PMU,
-   .pfn= __phys_to_pfn(EXYNOS4_PA_PMU),
-   .length = SZ_64K,
-   .type   = MT_DEVICE,
-   }, {
.virtual= (unsigned long)S5P_VA_COMBINER_BASE,
.pfn= __phys_to_pfn(EXYNOS4_PA_COMBINER),
.length = SZ_4K,
@@ -144,11 +140,6 @@ static struct map_desc exynos5_iodesc[] __initdata = {
.pfn= __phys_to_pfn(EXYNOS5_PA_CMU),
.length = 144 * SZ_1K,
.type   = MT_DEVICE,
-   }, {
-   .virtual= (unsigned long)S5P_VA_PMU,
-   .pfn= __phys_to_pfn(EXYNOS5_PA_PMU),
-   .length = SZ_64K,
-   .type   = MT_DEVICE,
},
 };
 
@@ -156,7 +147,7 @@ static void exynos_restart(enum reboot_mode mode, const 
char *cmd)
 {
struct device_node *np;
u32 val = 0x1;
-   void __iomem *addr = EXYNOS_SWRESET;
+   void __iomem *addr = NULL;
 
if (of_machine_is_compatible(samsung,exynos5440)) {
u32 status;
@@ -169,9 +160,9 @@ static void exynos_restart(enum reboot_mode mode, const 
char *cmd)
val = __raw_readl(addr);
 
val = (val  0x) | (status  0x);
-   }
-
-   __raw_writel(val, addr);
+   __raw_writel(val, addr);
+   } else
+   regmap_write(exynos_pmu_regmap, EXYNOS_SWRESET, val);
 }
 
 static struct platform_device exynos_cpuidle = {
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index 73b0b5c..0243ef3 100644
--- a/arch/arm/mach-exynos/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
@@ -13,6 +13,7 @@
 #include linux/errno.h
 #include linux/smp.h
 #include linux/io.h
+#include linux/regmap.h
 
 #include asm/cacheflush.h
 #include asm/cp15.h
@@ -91,11 +92,12 @@ static inline void cpu_leave_lowpower(void)
 
 static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 {
+   struct regmap *pmu_regmap = get_exynos_pmuregmap();
for (;;) {
 
/* make cpu1 to be turned off at next WFI command */
if (cpu == 1)
-   __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION);
+   regmap_write(pmu_regmap, S5P_ARM_CORE1_CONFIGURATION, 
0);
 
/*
 * here's the WFI
diff --git a/arch/arm/mach-exynos/include/mach/map.h 
b/arch/arm/mach-exynos/include/mach/map.h
index 548269a..34eee6e 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++