All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] ARM: at91: pm: cleanup
@ 2017-03-28 11:19 ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Hi,

This is v2 of the at91 PM cleanup.

The main goal is to use a struct to pass arguments between the C and the
assembly part. This is required to add further functionalities (coming in a
later series).

A bit of refactorization also allows to remove a some initialization in
at91sam9.c

Changes in v2:
 - rebased on top of v4.11-rc4 because of a dependency on a fix
 - added a patch to correct a typo
 - due to an errata on sama5d4, I've left out the following patches for now:
   ARM: at91: pm: use struct members directly
   ARM: at91: pm: use C functions for standby
   ARM: at91: pm: Allow PM even if SRAM allocation failed
   I'll get back to those later.
 - in preparation of the sama5d4 workaround, renamed standby to idle as the
   standby functions are actually used for cpuidle but not standby


Alexandre Belloni (11):
  ARM: at91: pm: Cleanup headers
  ARM: at91: pm: Move at91_ramc_read/write to pm.c
  ARM: at91: pm: Move global variables into at91_pm_data
  ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S
  ARM: at91: pm: Simplify at91rm9200_standby
  ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1
    memories.
  ARM: at91: pm: Tie the memory controller type to the ramc id
  ARM: at91: pm: Tie the USB clock mask to the pmc
  ARM: at91: pm: Merge all at91sam9*_pm_init
  ARM: at91: pm: Remove at91_pm_set_standby
  ARM: at91: pm: correct typo

 arch/arm/mach-at91/Makefile          |  33 ++++++
 arch/arm/mach-at91/at91sam9.c        |  45 +-------
 arch/arm/mach-at91/generic.h         |   8 +-
 arch/arm/mach-at91/pm.c              | 199 +++++++++++++++++------------------
 arch/arm/mach-at91/pm.h              |  24 ++---
 arch/arm/mach-at91/pm_data-offsets.c |  13 +++
 arch/arm/mach-at91/pm_suspend.S      |  31 +++---
 7 files changed, 172 insertions(+), 181 deletions(-)
 create mode 100644 arch/arm/mach-at91/pm_data-offsets.c

-- 
2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 00/11] ARM: at91: pm: cleanup
@ 2017-03-28 11:19 ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This is v2 of the at91 PM cleanup.

The main goal is to use a struct to pass arguments between the C and the
assembly part. This is required to add further functionalities (coming in a
later series).

A bit of refactorization also allows to remove a some initialization in
at91sam9.c

Changes in v2:
 - rebased on top of v4.11-rc4 because of a dependency on a fix
 - added a patch to correct a typo
 - due to an errata on sama5d4, I've left out the following patches for now:
   ARM: at91: pm: use struct members directly
   ARM: at91: pm: use C functions for standby
   ARM: at91: pm: Allow PM even if SRAM allocation failed
   I'll get back to those later.
 - in preparation of the sama5d4 workaround, renamed standby to idle as the
   standby functions are actually used for cpuidle but not standby


Alexandre Belloni (11):
  ARM: at91: pm: Cleanup headers
  ARM: at91: pm: Move at91_ramc_read/write to pm.c
  ARM: at91: pm: Move global variables into at91_pm_data
  ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S
  ARM: at91: pm: Simplify at91rm9200_standby
  ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1
    memories.
  ARM: at91: pm: Tie the memory controller type to the ramc id
  ARM: at91: pm: Tie the USB clock mask to the pmc
  ARM: at91: pm: Merge all at91sam9*_pm_init
  ARM: at91: pm: Remove at91_pm_set_standby
  ARM: at91: pm: correct typo

 arch/arm/mach-at91/Makefile          |  33 ++++++
 arch/arm/mach-at91/at91sam9.c        |  45 +-------
 arch/arm/mach-at91/generic.h         |   8 +-
 arch/arm/mach-at91/pm.c              | 199 +++++++++++++++++------------------
 arch/arm/mach-at91/pm.h              |  24 ++---
 arch/arm/mach-at91/pm_data-offsets.c |  13 +++
 arch/arm/mach-at91/pm_suspend.S      |  31 +++---
 7 files changed, 172 insertions(+), 181 deletions(-)
 create mode 100644 arch/arm/mach-at91/pm_data-offsets.c

-- 
2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 01/11] ARM: at91: pm: Cleanup headers
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Remove unnecessary header inclusions and reorder the remaining ones.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a277981f414d..9e2b5c1e503e 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -10,28 +10,17 @@
  * (at your option) any later version.
  */
 
-#include <linux/gpio.h>
-#include <linux/suspend.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
 #include <linux/genalloc.h>
-#include <linux/interrupt.h>
-#include <linux/sysfs.h>
-#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/atmel.h>
-#include <linux/io.h>
+#include <linux/suspend.h>
+
 #include <linux/clk/at91_pmc.h>
 
-#include <asm/irq.h>
-#include <linux/atomic.h>
-#include <asm/mach/time.h>
-#include <asm/mach/irq.h>
-#include <asm/fncpy.h>
 #include <asm/cacheflush.h>
+#include <asm/fncpy.h>
 #include <asm/system_misc.h>
 
 #include "generic.h"
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 01/11] ARM: at91: pm: Cleanup headers
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Remove unnecessary header inclusions and reorder the remaining ones.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a277981f414d..9e2b5c1e503e 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -10,28 +10,17 @@
  * (at your option) any later version.
  */
 
-#include <linux/gpio.h>
-#include <linux/suspend.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
 #include <linux/genalloc.h>
-#include <linux/interrupt.h>
-#include <linux/sysfs.h>
-#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/atmel.h>
-#include <linux/io.h>
+#include <linux/suspend.h>
+
 #include <linux/clk/at91_pmc.h>
 
-#include <asm/irq.h>
-#include <linux/atomic.h>
-#include <asm/mach/time.h>
-#include <asm/mach/irq.h>
-#include <asm/fncpy.h>
 #include <asm/cacheflush.h>
+#include <asm/fncpy.h>
 #include <asm/system_misc.h>
 
 #include "generic.h"
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Those macros are only used in pm.c, move them there so we can remove the
test on __ASSEMBLY__.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 6 ++++++
 arch/arm/mach-at91/pm.h | 8 --------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 9e2b5c1e503e..41789aa4df86 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -45,6 +45,12 @@ static struct {
 } at91_pm_data;
 
 static void __iomem *at91_ramc_base[2];
+#define at91_ramc_read(id, field) \
+	__raw_readl(at91_ramc_base[id] + field)
+
+#define at91_ramc_write(id, field, value) \
+	__raw_writel(value, at91_ramc_base[id] + field)
+
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index bf980c6ef294..8eed156ef19a 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -17,14 +17,6 @@
 #include <soc/at91/at91sam9_ddrsdr.h>
 #include <soc/at91/at91sam9_sdramc.h>
 
-#ifndef __ASSEMBLY__
-#define at91_ramc_read(id, field) \
-	__raw_readl(at91_ramc_base[id] + field)
-
-#define at91_ramc_write(id, field, value) \
-	__raw_writel(value, at91_ramc_base[id] + field)
-#endif
-
 #define AT91_MEMCTRL_MC		0
 #define AT91_MEMCTRL_SDRAMC	1
 #define AT91_MEMCTRL_DDRSDR	2
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Those macros are only used in pm.c, move them there so we can remove the
test on __ASSEMBLY__.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 6 ++++++
 arch/arm/mach-at91/pm.h | 8 --------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 9e2b5c1e503e..41789aa4df86 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -45,6 +45,12 @@ static struct {
 } at91_pm_data;
 
 static void __iomem *at91_ramc_base[2];
+#define at91_ramc_read(id, field) \
+	__raw_readl(at91_ramc_base[id] + field)
+
+#define at91_ramc_write(id, field, value) \
+	__raw_writel(value, at91_ramc_base[id] + field)
+
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index bf980c6ef294..8eed156ef19a 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -17,14 +17,6 @@
 #include <soc/at91/at91sam9_ddrsdr.h>
 #include <soc/at91/at91sam9_sdramc.h>
 
-#ifndef __ASSEMBLY__
-#define at91_ramc_read(id, field) \
-	__raw_readl(at91_ramc_base[id] + field)
-
-#define at91_ramc_write(id, field, value) \
-	__raw_writel(value, at91_ramc_base[id] + field)
-#endif
-
 #define AT91_MEMCTRL_MC		0
 #define AT91_MEMCTRL_SDRAMC	1
 #define AT91_MEMCTRL_DDRSDR	2
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 03/11] ARM: at91: pm: Move global variables into at91_pm_data
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Instead of having separate global variables to hold IP addresses, move them
to struct at91_pm_data.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 44 +++++++++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 41789aa4df86..c780dda3b604 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -26,8 +26,6 @@
 #include "generic.h"
 #include "pm.h"
 
-static void __iomem *pmc;
-
 /*
  * FIXME: this is needed to communicate between the pinctrl driver and
  * the PM implementation in the machine. Possibly part of the PM
@@ -40,17 +38,17 @@ extern void at91_pinctrl_gpio_resume(void);
 #endif
 
 static struct {
+	void __iomem *pmc;
+	void __iomem *ramc[2];
 	unsigned long uhp_udp_mask;
 	int memctrl;
 } at91_pm_data;
 
-static void __iomem *at91_ramc_base[2];
 #define at91_ramc_read(id, field) \
-	__raw_readl(at91_ramc_base[id] + field)
+	__raw_readl(at91_pm_data.ramc[id] + field)
 
 #define at91_ramc_write(id, field, value) \
-	__raw_writel(value, at91_ramc_base[id] + field)
-
+	__raw_writel(value, at91_pm_data.ramc[id] + field)
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
@@ -86,7 +84,7 @@ static int at91_pm_verify_clocks(void)
 	unsigned long scsr;
 	int i;
 
-	scsr = readl(pmc + AT91_PMC_SCSR);
+	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
 
 	/* USB must not be using PLLB */
 	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
@@ -100,7 +98,7 @@ static int at91_pm_verify_clocks(void)
 
 		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
 			continue;
-		css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
 			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
@@ -143,8 +141,8 @@ static void at91_pm_suspend(suspend_state_t state)
 	flush_cache_all();
 	outer_disable();
 
-	at91_suspend_sram_fn(pmc, at91_ramc_base[0],
-			     at91_ramc_base[1], pm_data);
+	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
+			     at91_pm_data.ramc[1], pm_data);
 
 	outer_resume();
 }
@@ -247,7 +245,7 @@ static void at91rm9200_standby(void)
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
 		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (at91_ramc_base[0]), "r" (AT91_MC_SDRAMC_LPR),
+		: "r" (0), "r" (at91_pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
 		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
 		  "r" (lpr));
 }
@@ -262,7 +260,7 @@ static void at91_ddr_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_ramc_base[1]) {
+	if (at91_pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -274,13 +272,13 @@ static void at91_ddr_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
@@ -308,7 +306,7 @@ static void at91sam9_sdram_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_ramc_base[1]) {
+	if (at91_pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
 		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -320,13 +318,13 @@ static void at91sam9_sdram_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
@@ -346,8 +344,8 @@ static __init void at91_dt_ramc(void)
 	const void *standby = NULL;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
-		at91_ramc_base[idx] = of_iomap(np, 0);
-		if (!at91_ramc_base[idx])
+		at91_pm_data.ramc[idx] = of_iomap(np, 0);
+		if (!at91_pm_data.ramc[idx])
 			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 
 		if (!standby)
@@ -373,12 +371,12 @@ static void at91rm9200_idle(void)
 	 * Disable the processor clock.  The processor will be automatically
 	 * re-enabled by an interrupt or by a reset.
 	 */
-	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
 }
 
 static void at91sam9_idle(void)
 {
-	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
 	cpu_do_idle();
 }
 
@@ -447,8 +445,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 		platform_device_register(&at91_cpuidle_device);
 
 	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
-	pmc = of_iomap(pmc_np, 0);
-	if (!pmc) {
+	at91_pm_data.pmc = of_iomap(pmc_np, 0);
+	if (!at91_pm_data.pmc) {
 		pr_err("AT91: PM not supported, PMC not found\n");
 		return;
 	}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 03/11] ARM: at91: pm: Move global variables into at91_pm_data
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of having separate global variables to hold IP addresses, move them
to struct at91_pm_data.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 44 +++++++++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 41789aa4df86..c780dda3b604 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -26,8 +26,6 @@
 #include "generic.h"
 #include "pm.h"
 
-static void __iomem *pmc;
-
 /*
  * FIXME: this is needed to communicate between the pinctrl driver and
  * the PM implementation in the machine. Possibly part of the PM
@@ -40,17 +38,17 @@ extern void at91_pinctrl_gpio_resume(void);
 #endif
 
 static struct {
+	void __iomem *pmc;
+	void __iomem *ramc[2];
 	unsigned long uhp_udp_mask;
 	int memctrl;
 } at91_pm_data;
 
-static void __iomem *at91_ramc_base[2];
 #define at91_ramc_read(id, field) \
-	__raw_readl(at91_ramc_base[id] + field)
+	__raw_readl(at91_pm_data.ramc[id] + field)
 
 #define at91_ramc_write(id, field, value) \
-	__raw_writel(value, at91_ramc_base[id] + field)
-
+	__raw_writel(value, at91_pm_data.ramc[id] + field)
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
@@ -86,7 +84,7 @@ static int at91_pm_verify_clocks(void)
 	unsigned long scsr;
 	int i;
 
-	scsr = readl(pmc + AT91_PMC_SCSR);
+	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
 
 	/* USB must not be using PLLB */
 	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
@@ -100,7 +98,7 @@ static int at91_pm_verify_clocks(void)
 
 		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
 			continue;
-		css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
 			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
@@ -143,8 +141,8 @@ static void at91_pm_suspend(suspend_state_t state)
 	flush_cache_all();
 	outer_disable();
 
-	at91_suspend_sram_fn(pmc, at91_ramc_base[0],
-			     at91_ramc_base[1], pm_data);
+	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
+			     at91_pm_data.ramc[1], pm_data);
 
 	outer_resume();
 }
@@ -247,7 +245,7 @@ static void at91rm9200_standby(void)
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
 		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (at91_ramc_base[0]), "r" (AT91_MC_SDRAMC_LPR),
+		: "r" (0), "r" (at91_pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
 		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
 		  "r" (lpr));
 }
@@ -262,7 +260,7 @@ static void at91_ddr_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_ramc_base[1]) {
+	if (at91_pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -274,13 +272,13 @@ static void at91_ddr_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
@@ -308,7 +306,7 @@ static void at91sam9_sdram_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_ramc_base[1]) {
+	if (at91_pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
 		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -320,13 +318,13 @@ static void at91sam9_sdram_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
-	if (at91_ramc_base[1])
+	if (at91_pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
@@ -346,8 +344,8 @@ static __init void at91_dt_ramc(void)
 	const void *standby = NULL;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
-		at91_ramc_base[idx] = of_iomap(np, 0);
-		if (!at91_ramc_base[idx])
+		at91_pm_data.ramc[idx] = of_iomap(np, 0);
+		if (!at91_pm_data.ramc[idx])
 			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 
 		if (!standby)
@@ -373,12 +371,12 @@ static void at91rm9200_idle(void)
 	 * Disable the processor clock.  The processor will be automatically
 	 * re-enabled by an interrupt or by a reset.
 	 */
-	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
 }
 
 static void at91sam9_idle(void)
 {
-	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
 	cpu_do_idle();
 }
 
@@ -447,8 +445,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 		platform_device_register(&at91_cpuidle_device);
 
 	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
-	pmc = of_iomap(pmc_np, 0);
-	if (!pmc) {
+	at91_pm_data.pmc = of_iomap(pmc_np, 0);
+	if (!at91_pm_data.pmc) {
 		pr_err("AT91: PM not supported, PMC not found\n");
 		return;
 	}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

The number of register we can safely pass to at91_pm_suspend_in_sram is
limited. Instead, pass the address to the at91_pm_data structure.

The offsets are automatically generated to avoid hardcoding them.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/Makefile          | 33 +++++++++++++++
 arch/arm/mach-at91/pm.c              | 78 +++++++++++++++---------------------
 arch/arm/mach-at91/pm.h              | 16 +++++---
 arch/arm/mach-at91/pm_data-offsets.c | 13 ++++++
 arch/arm/mach-at91/pm_suspend.S      | 29 ++++++--------
 5 files changed, 102 insertions(+), 67 deletions(-)
 create mode 100644 arch/arm/mach-at91/pm_data-offsets.c

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c5bbf8bb8c0f..858ef14f961c 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -18,3 +18,36 @@ endif
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
 endif
+
+# Default sed regexp - multiline due to syntax constraints
+define sed-y
+	"/^->/{s:->#\(.*\):/* \1 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:->::; p;}"
+endef
+
+# Use filechk to avoid rebuilds when a header changes, but the resulting file
+# does not
+define filechk_offsets
+	(set -e; \
+	 echo "#ifndef $2"; \
+	 echo "#define $2"; \
+	 echo "/*"; \
+	 echo " * DO NOT MODIFY."; \
+	 echo " *"; \
+	 echo " * This file was generated by Kbuild"; \
+	 echo " */"; \
+	 echo ""; \
+	 sed -ne $(sed-y); \
+	 echo ""; \
+	 echo "#endif" )
+endef
+
+arch/arm/mach-at91/pm_data-offsets.s: arch/arm/mach-at91/pm_data-offsets.c
+	$(call if_changed_dep,cc_s_c)
+
+include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-offsets.s FORCE
+	$(call filechk,offsets,__PM_DATA_OFFSETS_H__)
+
+arch/arm/mach-at91/pm_suspend.o: include/generated/at91_pm_data-offsets.h
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index c780dda3b604..a35b1541b328 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -37,18 +37,13 @@ extern void at91_pinctrl_gpio_suspend(void);
 extern void at91_pinctrl_gpio_resume(void);
 #endif
 
-static struct {
-	void __iomem *pmc;
-	void __iomem *ramc[2];
-	unsigned long uhp_udp_mask;
-	int memctrl;
-} at91_pm_data;
+static struct at91_pm_data pm_data;
 
 #define at91_ramc_read(id, field) \
-	__raw_readl(at91_pm_data.ramc[id] + field)
+	__raw_readl(pm_data.ramc[id] + field)
 
 #define at91_ramc_write(id, field, value) \
-	__raw_writel(value, at91_pm_data.ramc[id] + field)
+	__raw_writel(value, pm_data.ramc[id] + field)
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
@@ -84,10 +79,10 @@ static int at91_pm_verify_clocks(void)
 	unsigned long scsr;
 	int i;
 
-	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
+	scsr = readl(pm_data.pmc + AT91_PMC_SCSR);
 
 	/* USB must not be using PLLB */
-	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
+	if ((scsr & pm_data.uhp_udp_mask) != 0) {
 		pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 		return 0;
 	}
@@ -98,7 +93,7 @@ static int at91_pm_verify_clocks(void)
 
 		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
 			continue;
-		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+		css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
 			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
@@ -124,25 +119,18 @@ int at91_suspend_entering_slow_clock(void)
 }
 EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
 
-static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
-			  void __iomem *ramc1, int memctrl);
-
-extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
-			    void __iomem *ramc1, int memctrl);
+static void (*at91_suspend_sram_fn)(struct at91_pm_data *);
+extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
 extern u32 at91_pm_suspend_in_sram_sz;
 
 static void at91_pm_suspend(suspend_state_t state)
 {
-	unsigned int pm_data = at91_pm_data.memctrl;
-
-	pm_data |= (state == PM_SUSPEND_MEM) ?
-				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
+	pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
 
 	flush_cache_all();
 	outer_disable();
 
-	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
-			     at91_pm_data.ramc[1], pm_data);
+	at91_suspend_sram_fn(&pm_data);
 
 	outer_resume();
 }
@@ -245,7 +233,7 @@ static void at91rm9200_standby(void)
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
 		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (at91_pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
+		: "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
 		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
 		  "r" (lpr));
 }
@@ -260,7 +248,7 @@ static void at91_ddr_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_pm_data.ramc[1]) {
+	if (pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -272,13 +260,13 @@ static void at91_ddr_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
@@ -306,7 +294,7 @@ static void at91sam9_sdram_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_pm_data.ramc[1]) {
+	if (pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
 		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -318,13 +306,13 @@ static void at91sam9_sdram_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
@@ -344,8 +332,8 @@ static __init void at91_dt_ramc(void)
 	const void *standby = NULL;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
-		at91_pm_data.ramc[idx] = of_iomap(np, 0);
-		if (!at91_pm_data.ramc[idx])
+		pm_data.ramc[idx] = of_iomap(np, 0);
+		if (!pm_data.ramc[idx])
 			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 
 		if (!standby)
@@ -371,12 +359,12 @@ static void at91rm9200_idle(void)
 	 * Disable the processor clock.  The processor will be automatically
 	 * re-enabled by an interrupt or by a reset.
 	 */
-	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
 }
 
 static void at91sam9_idle(void)
 {
-	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
 	cpu_do_idle();
 }
 
@@ -445,8 +433,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 		platform_device_register(&at91_cpuidle_device);
 
 	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
-	at91_pm_data.pmc = of_iomap(pmc_np, 0);
-	if (!at91_pm_data.pmc) {
+	pm_data.pmc = of_iomap(pmc_np, 0);
+	if (!pm_data.pmc) {
 		pr_err("AT91: PM not supported, PMC not found\n");
 		return;
 	}
@@ -471,8 +459,8 @@ void __init at91rm9200_pm_init(void)
 	 */
 	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 
-	at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_MC;
+	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_MC;
 
 	at91_pm_init(at91rm9200_idle);
 }
@@ -480,31 +468,31 @@ void __init at91rm9200_pm_init(void)
 void __init at91sam9260_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9g45_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9x5_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init sama5_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(NULL);
 }
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 8eed156ef19a..fc0f7d048187 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -21,12 +21,16 @@
 #define AT91_MEMCTRL_SDRAMC	1
 #define AT91_MEMCTRL_DDRSDR	2
 
-#define	AT91_PM_MEMTYPE_MASK	0x0f
-
-#define	AT91_PM_MODE_OFFSET	4
-#define	AT91_PM_MODE_MASK	0x01
-#define	AT91_PM_MODE(x)		(((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET)
-
 #define	AT91_PM_SLOW_CLOCK	0x01
 
+#ifndef __ASSEMBLY__
+struct at91_pm_data {
+	void __iomem *pmc;
+	void __iomem *ramc[2];
+	unsigned long uhp_udp_mask;
+	unsigned int memctrl;
+	unsigned int mode;
+};
+#endif
+
 #endif
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
new file mode 100644
index 000000000000..30302cb16df0
--- /dev/null
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -0,0 +1,13 @@
+#include <linux/stddef.h>
+#include <linux/kbuild.h>
+#include "pm.h"
+
+int main(void)
+{
+	DEFINE(PM_DATA_PMC,		offsetof(struct at91_pm_data, pmc));
+	DEFINE(PM_DATA_RAMC0,		offsetof(struct at91_pm_data, ramc[0]));
+	DEFINE(PM_DATA_RAMC1,		offsetof(struct at91_pm_data, ramc[1]));
+	DEFINE(PM_DATA_MEMCTRL,	offsetof(struct at91_pm_data, memctrl));
+	DEFINE(PM_DATA_MODE,		offsetof(struct at91_pm_data, mode));
+	return 0;
+}
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index a25defda3d22..ed317657e760 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -14,6 +14,7 @@
 #include <linux/linkage.h>
 #include <linux/clk/at91_pmc.h>
 #include "pm.h"
+#include "generated/at91_pm_data-offsets.h"
 
 #define	SRAMC_SELF_FRESH_ACTIVE		0x01
 #define	SRAMC_SELF_FRESH_EXIT		0x00
@@ -72,13 +73,9 @@ tmp2	.req	r5
 	.arm
 
 /*
- * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
- *			void __iomem *ramc1, int memctrl)
+ * void at91_suspend_sram_fn(struct at91_pm_data*)
  * @input param:
- * 	@r0: base address of AT91_PMC
- *  	@r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
- *	@r2: base address of second SDRAM Controller or 0 if not present
- *	@r3: pm information
+ * 	@r0: base address of struct at91_pm_data
  */
 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
 	.align 3
@@ -90,16 +87,16 @@ ENTRY(at91_pm_suspend_in_sram)
 	mov	tmp1, #0
 	mcr	p15, 0, tmp1, c7, c10, 4
 
-	str	r0, .pmc_base
-	str	r1, .sramc_base
-	str	r2, .sramc1_base
-
-	and	r0, r3, #AT91_PM_MEMTYPE_MASK
-	str	r0, .memtype
-
-	lsr	r0, r3, #AT91_PM_MODE_OFFSET
-	and	r0, r0, #AT91_PM_MODE_MASK
-	str	r0, .pm_mode
+	ldr	tmp1, [r0, #PM_DATA_PMC]
+	str	tmp1, .pmc_base
+	ldr	tmp1, [r0, #PM_DATA_RAMC0]
+	str	tmp1, .sramc_base
+	ldr	tmp1, [r0, #PM_DATA_RAMC1]
+	str	tmp1, .sramc1_base
+	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
+	str	tmp1, .memtype
+	ldr	tmp1, [r0, #PM_DATA_MODE]
+	str	tmp1, .pm_mode
 
 	/* Active the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

The number of register we can safely pass to at91_pm_suspend_in_sram is
limited. Instead, pass the address to the at91_pm_data structure.

The offsets are automatically generated to avoid hardcoding them.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/Makefile          | 33 +++++++++++++++
 arch/arm/mach-at91/pm.c              | 78 +++++++++++++++---------------------
 arch/arm/mach-at91/pm.h              | 16 +++++---
 arch/arm/mach-at91/pm_data-offsets.c | 13 ++++++
 arch/arm/mach-at91/pm_suspend.S      | 29 ++++++--------
 5 files changed, 102 insertions(+), 67 deletions(-)
 create mode 100644 arch/arm/mach-at91/pm_data-offsets.c

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c5bbf8bb8c0f..858ef14f961c 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -18,3 +18,36 @@ endif
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
 endif
+
+# Default sed regexp - multiline due to syntax constraints
+define sed-y
+	"/^->/{s:->#\(.*\):/* \1 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:->::; p;}"
+endef
+
+# Use filechk to avoid rebuilds when a header changes, but the resulting file
+# does not
+define filechk_offsets
+	(set -e; \
+	 echo "#ifndef $2"; \
+	 echo "#define $2"; \
+	 echo "/*"; \
+	 echo " * DO NOT MODIFY."; \
+	 echo " *"; \
+	 echo " * This file was generated by Kbuild"; \
+	 echo " */"; \
+	 echo ""; \
+	 sed -ne $(sed-y); \
+	 echo ""; \
+	 echo "#endif" )
+endef
+
+arch/arm/mach-at91/pm_data-offsets.s: arch/arm/mach-at91/pm_data-offsets.c
+	$(call if_changed_dep,cc_s_c)
+
+include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-offsets.s FORCE
+	$(call filechk,offsets,__PM_DATA_OFFSETS_H__)
+
+arch/arm/mach-at91/pm_suspend.o: include/generated/at91_pm_data-offsets.h
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index c780dda3b604..a35b1541b328 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -37,18 +37,13 @@ extern void at91_pinctrl_gpio_suspend(void);
 extern void at91_pinctrl_gpio_resume(void);
 #endif
 
-static struct {
-	void __iomem *pmc;
-	void __iomem *ramc[2];
-	unsigned long uhp_udp_mask;
-	int memctrl;
-} at91_pm_data;
+static struct at91_pm_data pm_data;
 
 #define at91_ramc_read(id, field) \
-	__raw_readl(at91_pm_data.ramc[id] + field)
+	__raw_readl(pm_data.ramc[id] + field)
 
 #define at91_ramc_write(id, field, value) \
-	__raw_writel(value, at91_pm_data.ramc[id] + field)
+	__raw_writel(value, pm_data.ramc[id] + field)
 
 static int at91_pm_valid_state(suspend_state_t state)
 {
@@ -84,10 +79,10 @@ static int at91_pm_verify_clocks(void)
 	unsigned long scsr;
 	int i;
 
-	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
+	scsr = readl(pm_data.pmc + AT91_PMC_SCSR);
 
 	/* USB must not be using PLLB */
-	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
+	if ((scsr & pm_data.uhp_udp_mask) != 0) {
 		pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 		return 0;
 	}
@@ -98,7 +93,7 @@ static int at91_pm_verify_clocks(void)
 
 		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
 			continue;
-		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+		css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
 			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
@@ -124,25 +119,18 @@ int at91_suspend_entering_slow_clock(void)
 }
 EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
 
-static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
-			  void __iomem *ramc1, int memctrl);
-
-extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
-			    void __iomem *ramc1, int memctrl);
+static void (*at91_suspend_sram_fn)(struct at91_pm_data *);
+extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
 extern u32 at91_pm_suspend_in_sram_sz;
 
 static void at91_pm_suspend(suspend_state_t state)
 {
-	unsigned int pm_data = at91_pm_data.memctrl;
-
-	pm_data |= (state == PM_SUSPEND_MEM) ?
-				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
+	pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
 
 	flush_cache_all();
 	outer_disable();
 
-	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
-			     at91_pm_data.ramc[1], pm_data);
+	at91_suspend_sram_fn(&pm_data);
 
 	outer_resume();
 }
@@ -245,7 +233,7 @@ static void at91rm9200_standby(void)
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
 		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (at91_pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
+		: "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
 		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
 		  "r" (lpr));
 }
@@ -260,7 +248,7 @@ static void at91_ddr_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_pm_data.ramc[1]) {
+	if (pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -272,13 +260,13 @@ static void at91_ddr_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
@@ -306,7 +294,7 @@ static void at91sam9_sdram_standby(void)
 	u32 lpr0, lpr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
-	if (at91_pm_data.ramc[1]) {
+	if (pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
 		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -318,13 +306,13 @@ static void at91sam9_sdram_standby(void)
 
 	/* self-refresh mode now */
 	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
 
 	cpu_do_idle();
 
 	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
-	if (at91_pm_data.ramc[1])
+	if (pm_data.ramc[1])
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
@@ -344,8 +332,8 @@ static __init void at91_dt_ramc(void)
 	const void *standby = NULL;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
-		at91_pm_data.ramc[idx] = of_iomap(np, 0);
-		if (!at91_pm_data.ramc[idx])
+		pm_data.ramc[idx] = of_iomap(np, 0);
+		if (!pm_data.ramc[idx])
 			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 
 		if (!standby)
@@ -371,12 +359,12 @@ static void at91rm9200_idle(void)
 	 * Disable the processor clock.  The processor will be automatically
 	 * re-enabled by an interrupt or by a reset.
 	 */
-	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
 }
 
 static void at91sam9_idle(void)
 {
-	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
+	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
 	cpu_do_idle();
 }
 
@@ -445,8 +433,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 		platform_device_register(&at91_cpuidle_device);
 
 	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
-	at91_pm_data.pmc = of_iomap(pmc_np, 0);
-	if (!at91_pm_data.pmc) {
+	pm_data.pmc = of_iomap(pmc_np, 0);
+	if (!pm_data.pmc) {
 		pr_err("AT91: PM not supported, PMC not found\n");
 		return;
 	}
@@ -471,8 +459,8 @@ void __init at91rm9200_pm_init(void)
 	 */
 	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 
-	at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_MC;
+	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_MC;
 
 	at91_pm_init(at91rm9200_idle);
 }
@@ -480,31 +468,31 @@ void __init at91rm9200_pm_init(void)
 void __init at91sam9260_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9g45_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9x5_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init sama5_pm_init(void)
 {
 	at91_dt_ramc();
-	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(NULL);
 }
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 8eed156ef19a..fc0f7d048187 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -21,12 +21,16 @@
 #define AT91_MEMCTRL_SDRAMC	1
 #define AT91_MEMCTRL_DDRSDR	2
 
-#define	AT91_PM_MEMTYPE_MASK	0x0f
-
-#define	AT91_PM_MODE_OFFSET	4
-#define	AT91_PM_MODE_MASK	0x01
-#define	AT91_PM_MODE(x)		(((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET)
-
 #define	AT91_PM_SLOW_CLOCK	0x01
 
+#ifndef __ASSEMBLY__
+struct at91_pm_data {
+	void __iomem *pmc;
+	void __iomem *ramc[2];
+	unsigned long uhp_udp_mask;
+	unsigned int memctrl;
+	unsigned int mode;
+};
+#endif
+
 #endif
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
new file mode 100644
index 000000000000..30302cb16df0
--- /dev/null
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -0,0 +1,13 @@
+#include <linux/stddef.h>
+#include <linux/kbuild.h>
+#include "pm.h"
+
+int main(void)
+{
+	DEFINE(PM_DATA_PMC,		offsetof(struct at91_pm_data, pmc));
+	DEFINE(PM_DATA_RAMC0,		offsetof(struct at91_pm_data, ramc[0]));
+	DEFINE(PM_DATA_RAMC1,		offsetof(struct at91_pm_data, ramc[1]));
+	DEFINE(PM_DATA_MEMCTRL,	offsetof(struct at91_pm_data, memctrl));
+	DEFINE(PM_DATA_MODE,		offsetof(struct at91_pm_data, mode));
+	return 0;
+}
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index a25defda3d22..ed317657e760 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -14,6 +14,7 @@
 #include <linux/linkage.h>
 #include <linux/clk/at91_pmc.h>
 #include "pm.h"
+#include "generated/at91_pm_data-offsets.h"
 
 #define	SRAMC_SELF_FRESH_ACTIVE		0x01
 #define	SRAMC_SELF_FRESH_EXIT		0x00
@@ -72,13 +73,9 @@ tmp2	.req	r5
 	.arm
 
 /*
- * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
- *			void __iomem *ramc1, int memctrl)
+ * void at91_suspend_sram_fn(struct at91_pm_data*)
  * @input param:
- * 	@r0: base address of AT91_PMC
- *  	@r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
- *	@r2: base address of second SDRAM Controller or 0 if not present
- *	@r3: pm information
+ * 	@r0: base address of struct at91_pm_data
  */
 /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
 	.align 3
@@ -90,16 +87,16 @@ ENTRY(at91_pm_suspend_in_sram)
 	mov	tmp1, #0
 	mcr	p15, 0, tmp1, c7, c10, 4
 
-	str	r0, .pmc_base
-	str	r1, .sramc_base
-	str	r2, .sramc1_base
-
-	and	r0, r3, #AT91_PM_MEMTYPE_MASK
-	str	r0, .memtype
-
-	lsr	r0, r3, #AT91_PM_MODE_OFFSET
-	and	r0, r0, #AT91_PM_MODE_MASK
-	str	r0, .pm_mode
+	ldr	tmp1, [r0, #PM_DATA_PMC]
+	str	tmp1, .pmc_base
+	ldr	tmp1, [r0, #PM_DATA_RAMC0]
+	str	tmp1, .sramc_base
+	ldr	tmp1, [r0, #PM_DATA_RAMC1]
+	str	tmp1, .sramc1_base
+	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
+	str	tmp1, .memtype
+	ldr	tmp1, [r0, #PM_DATA_MODE]
+	str	tmp1, .pm_mode
 
 	/* Active the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 05/11] ARM: at91: pm: Simplify at91rm9200_standby
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Since 2008, AT91_MC_SDRAMC_LPR is set to 0 at kernel initialization. There
is no use saving, changing and restoring it.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a35b1541b328..3d68d93c11c7 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -222,20 +222,15 @@ static void at91_pm_set_standby(void (*at91_standby)(void))
  */
 static void at91rm9200_standby(void)
 {
-	u32 lpr = at91_ramc_read(0, AT91_MC_SDRAMC_LPR);
-
 	asm volatile(
 		"b    1f\n\t"
 		".align    5\n\t"
 		"1:  mcr    p15, 0, %0, c7, c10, 4\n\t"
-		"    str    %0, [%1, %2]\n\t"
-		"    str    %3, [%1, %4]\n\t"
+		"    str    %2, [%1, %3]\n\t"
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
-		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
-		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
-		  "r" (lpr));
+		: "r" (0), "r" (pm_data.ramc[0]),
+		  "r" (1), "r" (AT91_MC_SDRAMC_SRR));
 }
 
 /* We manage both DDRAM/SDRAM controllers, we need more than one value to
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 05/11] ARM: at91: pm: Simplify at91rm9200_standby
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Since 2008, AT91_MC_SDRAMC_LPR is set to 0 at kernel initialization. There
is no use saving, changing and restoring it.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a35b1541b328..3d68d93c11c7 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -222,20 +222,15 @@ static void at91_pm_set_standby(void (*at91_standby)(void))
  */
 static void at91rm9200_standby(void)
 {
-	u32 lpr = at91_ramc_read(0, AT91_MC_SDRAMC_LPR);
-
 	asm volatile(
 		"b    1f\n\t"
 		".align    5\n\t"
 		"1:  mcr    p15, 0, %0, c7, c10, 4\n\t"
-		"    str    %0, [%1, %2]\n\t"
-		"    str    %3, [%1, %4]\n\t"
+		"    str    %2, [%1, %3]\n\t"
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
-		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
-		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
-		  "r" (lpr));
+		: "r" (0), "r" (pm_data.ramc[0]),
+		  "r" (1), "r" (AT91_MC_SDRAMC_SRR));
 }
 
 /* We manage both DDRAM/SDRAM controllers, we need more than one value to
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1 memories.
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

As already explained for pm_suspend.S, the DDRSDR controller fails to put
LPDDR1 memories in self-refresh. Force the controller to think it has DDR2
memories during the self-refresh period, as the DDR2 self-refresh spec is
equivalent to LPDDR1, and is correctly implemented in the controller.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 3d68d93c11c7..488549bc2bed 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -241,12 +241,27 @@ static void at91_ddr_standby(void)
 	/* Those two values allow us to delay self-refresh activation
 	 * to the maximum. */
 	u32 lpr0, lpr1 = 0;
+	u32 mdr, saved_mdr0, saved_mdr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
+	/* LPDDR1 --> force DDR2 mode during self-refresh */
+	saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR);
+	if ((saved_mdr0 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
+		mdr = saved_mdr0 & ~AT91_DDRSDRC_MD;
+		mdr |= AT91_DDRSDRC_MD_DDR2;
+		at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
+	}
+
 	if (pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+		saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR);
+		if ((saved_mdr1 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
+			mdr = saved_mdr1 & ~AT91_DDRSDRC_MD;
+			mdr |= AT91_DDRSDRC_MD_DDR2;
+			at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr);
+		}
 	}
 
 	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
@@ -260,9 +275,12 @@ static void at91_ddr_standby(void)
 
 	cpu_do_idle();
 
+	at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
-	if (pm_data.ramc[1])
+	if (pm_data.ramc[1]) {
+		at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
+	}
 }
 
 static void sama5d3_ddr_standby(void)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1 memories.
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

As already explained for pm_suspend.S, the DDRSDR controller fails to put
LPDDR1 memories in self-refresh. Force the controller to think it has DDR2
memories during the self-refresh period, as the DDR2 self-refresh spec is
equivalent to LPDDR1, and is correctly implemented in the controller.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 3d68d93c11c7..488549bc2bed 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -241,12 +241,27 @@ static void at91_ddr_standby(void)
 	/* Those two values allow us to delay self-refresh activation
 	 * to the maximum. */
 	u32 lpr0, lpr1 = 0;
+	u32 mdr, saved_mdr0, saved_mdr1 = 0;
 	u32 saved_lpr0, saved_lpr1 = 0;
 
+	/* LPDDR1 --> force DDR2 mode during self-refresh */
+	saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR);
+	if ((saved_mdr0 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
+		mdr = saved_mdr0 & ~AT91_DDRSDRC_MD;
+		mdr |= AT91_DDRSDRC_MD_DDR2;
+		at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
+	}
+
 	if (pm_data.ramc[1]) {
 		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
 		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+		saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR);
+		if ((saved_mdr1 & AT91_DDRSDRC_MD) == AT91_DDRSDRC_MD_LOW_POWER_DDR) {
+			mdr = saved_mdr1 & ~AT91_DDRSDRC_MD;
+			mdr |= AT91_DDRSDRC_MD_DDR2;
+			at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr);
+		}
 	}
 
 	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
@@ -260,9 +275,12 @@ static void at91_ddr_standby(void)
 
 	cpu_do_idle();
 
+	at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
-	if (pm_data.ramc[1])
+	if (pm_data.ramc[1]) {
+		at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
 		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
+	}
 }
 
 static void sama5d3_ddr_standby(void)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the ramc id
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Instead of relying on the SoC type to select the memory controller type,
use the device tree ids as they are parsed anyway.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 488549bc2bed..ddf62a006635 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -329,11 +329,23 @@ static void at91sam9_sdram_standby(void)
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
+struct ramc_info {
+	void (*idle)(void);
+	unsigned int memctrl;
+};
+
+static const struct ramc_info ramc_infos[] __initconst = {
+	{ .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC},
+	{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
+	{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+	{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+};
+
 static const struct of_device_id const ramc_ids[] __initconst = {
-	{ .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
-	{ .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
-	{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
-	{ .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
+	{ .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
+	{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
+	{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
+	{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
 	{ /*sentinel*/ }
 };
 
@@ -343,14 +355,17 @@ static __init void at91_dt_ramc(void)
 	const struct of_device_id *of_id;
 	int idx = 0;
 	const void *standby = NULL;
+	const struct ramc_info *ramc;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
 		pm_data.ramc[idx] = of_iomap(np, 0);
 		if (!pm_data.ramc[idx])
 			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 
+		ramc = of_id->data;
 		if (!standby)
-			standby = of_id->data;
+			standby = ramc->idle;
+		pm_data.memctrl = ramc->memctrl;
 
 		idx++;
 	}
@@ -473,7 +488,6 @@ void __init at91rm9200_pm_init(void)
 	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 
 	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
-	pm_data.memctrl = AT91_MEMCTRL_MC;
 
 	at91_pm_init(at91rm9200_idle);
 }
@@ -481,7 +495,6 @@ void __init at91rm9200_pm_init(void)
 void __init at91sam9260_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
@@ -490,7 +503,6 @@ void __init at91sam9g45_pm_init(void)
 {
 	at91_dt_ramc();
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
-	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
@@ -498,7 +510,6 @@ void __init at91sam9x5_pm_init(void)
 {
 	at91_dt_ramc();
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
@@ -506,6 +517,5 @@ void __init sama5_pm_init(void)
 {
 	at91_dt_ramc();
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(NULL);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the ramc id
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of relying on the SoC type to select the memory controller type,
use the device tree ids as they are parsed anyway.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 488549bc2bed..ddf62a006635 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -329,11 +329,23 @@ static void at91sam9_sdram_standby(void)
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
+struct ramc_info {
+	void (*idle)(void);
+	unsigned int memctrl;
+};
+
+static const struct ramc_info ramc_infos[] __initconst = {
+	{ .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC},
+	{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
+	{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+	{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+};
+
 static const struct of_device_id const ramc_ids[] __initconst = {
-	{ .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
-	{ .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
-	{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
-	{ .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
+	{ .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
+	{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
+	{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
+	{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
 	{ /*sentinel*/ }
 };
 
@@ -343,14 +355,17 @@ static __init void at91_dt_ramc(void)
 	const struct of_device_id *of_id;
 	int idx = 0;
 	const void *standby = NULL;
+	const struct ramc_info *ramc;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
 		pm_data.ramc[idx] = of_iomap(np, 0);
 		if (!pm_data.ramc[idx])
 			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
 
+		ramc = of_id->data;
 		if (!standby)
-			standby = of_id->data;
+			standby = ramc->idle;
+		pm_data.memctrl = ramc->memctrl;
 
 		idx++;
 	}
@@ -473,7 +488,6 @@ void __init at91rm9200_pm_init(void)
 	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 
 	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
-	pm_data.memctrl = AT91_MEMCTRL_MC;
 
 	at91_pm_init(at91rm9200_idle);
 }
@@ -481,7 +495,6 @@ void __init at91rm9200_pm_init(void)
 void __init at91sam9260_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
@@ -490,7 +503,6 @@ void __init at91sam9g45_pm_init(void)
 {
 	at91_dt_ramc();
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
-	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
@@ -498,7 +510,6 @@ void __init at91sam9x5_pm_init(void)
 {
 	at91_dt_ramc();
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(at91sam9_idle);
 }
 
@@ -506,6 +517,5 @@ void __init sama5_pm_init(void)
 {
 	at91_dt_ramc();
 	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
 	at91_pm_init(NULL);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

The USB clocks mask (uhp_udp_mask) depends on the pmc. Tie it to the pmc id
instead of the SoC.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ddf62a006635..a7c047f0d21f 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -442,31 +442,46 @@ static void __init at91_pm_sram_init(void)
 			&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
 }
 
+struct pmc_info {
+	unsigned long uhp_udp_mask;
+};
+
+static const struct pmc_info pmc_infos[] __initconst = {
+	{ .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP },
+	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP },
+	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP },
+};
+
 static const struct of_device_id atmel_pmc_ids[] __initconst = {
-	{ .compatible = "atmel,at91rm9200-pmc"  },
-	{ .compatible = "atmel,at91sam9260-pmc" },
-	{ .compatible = "atmel,at91sam9g45-pmc" },
-	{ .compatible = "atmel,at91sam9n12-pmc" },
-	{ .compatible = "atmel,at91sam9x5-pmc" },
-	{ .compatible = "atmel,sama5d3-pmc" },
-	{ .compatible = "atmel,sama5d2-pmc" },
+	{ .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
+	{ .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
+	{ .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
 	{ /* sentinel */ },
 };
 
 static void __init at91_pm_init(void (*pm_idle)(void))
 {
 	struct device_node *pmc_np;
+	const struct of_device_id *of_id;
+	const struct pmc_info *pmc;
 
 	if (at91_cpuidle_device.dev.platform_data)
 		platform_device_register(&at91_cpuidle_device);
 
-	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
+	pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);
 	pm_data.pmc = of_iomap(pmc_np, 0);
 	if (!pm_data.pmc) {
 		pr_err("AT91: PM not supported, PMC not found\n");
 		return;
 	}
 
+	pmc = of_id->data;
+	pm_data.uhp_udp_mask = pmc->uhp_udp_mask;
+
 	if (pm_idle)
 		arm_pm_idle = pm_idle;
 
@@ -487,35 +502,29 @@ void __init at91rm9200_pm_init(void)
 	 */
 	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 
-	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
-
 	at91_pm_init(at91rm9200_idle);
 }
 
 void __init at91sam9260_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9g45_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9x5_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init sama5_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(NULL);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

The USB clocks mask (uhp_udp_mask) depends on the pmc. Tie it to the pmc id
instead of the SoC.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ddf62a006635..a7c047f0d21f 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -442,31 +442,46 @@ static void __init at91_pm_sram_init(void)
 			&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
 }
 
+struct pmc_info {
+	unsigned long uhp_udp_mask;
+};
+
+static const struct pmc_info pmc_infos[] __initconst = {
+	{ .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP },
+	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP },
+	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP },
+};
+
 static const struct of_device_id atmel_pmc_ids[] __initconst = {
-	{ .compatible = "atmel,at91rm9200-pmc"  },
-	{ .compatible = "atmel,at91sam9260-pmc" },
-	{ .compatible = "atmel,at91sam9g45-pmc" },
-	{ .compatible = "atmel,at91sam9n12-pmc" },
-	{ .compatible = "atmel,at91sam9x5-pmc" },
-	{ .compatible = "atmel,sama5d3-pmc" },
-	{ .compatible = "atmel,sama5d2-pmc" },
+	{ .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
+	{ .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
+	{ .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
+	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
 	{ /* sentinel */ },
 };
 
 static void __init at91_pm_init(void (*pm_idle)(void))
 {
 	struct device_node *pmc_np;
+	const struct of_device_id *of_id;
+	const struct pmc_info *pmc;
 
 	if (at91_cpuidle_device.dev.platform_data)
 		platform_device_register(&at91_cpuidle_device);
 
-	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
+	pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id);
 	pm_data.pmc = of_iomap(pmc_np, 0);
 	if (!pm_data.pmc) {
 		pr_err("AT91: PM not supported, PMC not found\n");
 		return;
 	}
 
+	pmc = of_id->data;
+	pm_data.uhp_udp_mask = pmc->uhp_udp_mask;
+
 	if (pm_idle)
 		arm_pm_idle = pm_idle;
 
@@ -487,35 +502,29 @@ void __init at91rm9200_pm_init(void)
 	 */
 	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
 
-	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
-
 	at91_pm_init(at91rm9200_idle);
 }
 
 void __init at91sam9260_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9g45_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9x5_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(at91sam9_idle);
 }
 
 void __init sama5_pm_init(void)
 {
 	at91_dt_ramc();
-	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_init(NULL);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

The PM initialization is now identical for all at91sam9. Merge the
functions.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/at91sam9.c | 45 +++----------------------------------------
 arch/arm/mach-at91/generic.h  |  8 ++------
 arch/arm/mach-at91/pm.c       | 14 +-------------
 3 files changed, 6 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
index ba28e9cc584d..c089bfd0dc2f 100644
--- a/arch/arm/mach-at91/at91sam9.c
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -52,7 +52,7 @@ static const struct at91_soc at91sam9_socs[] = {
 	{ /* sentinel */ },
 };
 
-static void __init at91sam9_common_init(void)
+static void __init at91sam9_init(void)
 {
 	struct soc_device *soc;
 	struct device *soc_dev = NULL;
@@ -62,12 +62,8 @@ static void __init at91sam9_common_init(void)
 		soc_dev = soc_device_to_device(soc);
 
 	of_platform_default_populate(NULL, NULL, soc_dev);
-}
 
-static void __init at91sam9_dt_device_init(void)
-{
-	at91sam9_common_init();
-	at91sam9260_pm_init();
+	at91sam9_pm_init();
 }
 
 static const char *const at91_dt_board_compat[] __initconst = {
@@ -77,41 +73,6 @@ static const char *const at91_dt_board_compat[] __initconst = {
 
 DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
 	/* Maintainer: Atmel */
-	.init_machine	= at91sam9_dt_device_init,
+	.init_machine	= at91sam9_init,
 	.dt_compat	= at91_dt_board_compat,
 MACHINE_END
-
-static void __init at91sam9g45_dt_device_init(void)
-{
-	at91sam9_common_init();
-	at91sam9g45_pm_init();
-}
-
-static const char *const at91sam9g45_board_compat[] __initconst = {
-	"atmel,at91sam9g45",
-	NULL
-};
-
-DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
-	/* Maintainer: Atmel */
-	.init_machine	= at91sam9g45_dt_device_init,
-	.dt_compat	= at91sam9g45_board_compat,
-MACHINE_END
-
-static void __init at91sam9x5_dt_device_init(void)
-{
-	at91sam9_common_init();
-	at91sam9x5_pm_init();
-}
-
-static const char *const at91sam9x5_board_compat[] __initconst = {
-	"atmel,at91sam9x5",
-	"atmel,at91sam9n12",
-	NULL
-};
-
-DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
-	/* Maintainer: Atmel */
-	.init_machine	= at91sam9x5_dt_device_init,
-	.dt_compat	= at91sam9x5_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 28ca57a2060f..f1ead0f13c19 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -13,15 +13,11 @@
 
 #ifdef CONFIG_PM
 extern void __init at91rm9200_pm_init(void);
-extern void __init at91sam9260_pm_init(void);
-extern void __init at91sam9g45_pm_init(void);
-extern void __init at91sam9x5_pm_init(void);
+extern void __init at91sam9_pm_init(void);
 extern void __init sama5_pm_init(void);
 #else
 static inline void __init at91rm9200_pm_init(void) { }
-static inline void __init at91sam9260_pm_init(void) { }
-static inline void __init at91sam9g45_pm_init(void) { }
-static inline void __init at91sam9x5_pm_init(void) { }
+static inline void __init at91sam9_pm_init(void) { }
 static inline void __init sama5_pm_init(void) { }
 #endif
 
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a7c047f0d21f..dedfe9038336 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -505,19 +505,7 @@ void __init at91rm9200_pm_init(void)
 	at91_pm_init(at91rm9200_idle);
 }
 
-void __init at91sam9260_pm_init(void)
-{
-	at91_dt_ramc();
-	at91_pm_init(at91sam9_idle);
-}
-
-void __init at91sam9g45_pm_init(void)
-{
-	at91_dt_ramc();
-	at91_pm_init(at91sam9_idle);
-}
-
-void __init at91sam9x5_pm_init(void)
+void __init at91sam9_pm_init(void)
 {
 	at91_dt_ramc();
 	at91_pm_init(at91sam9_idle);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

The PM initialization is now identical for all at91sam9. Merge the
functions.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/at91sam9.c | 45 +++----------------------------------------
 arch/arm/mach-at91/generic.h  |  8 ++------
 arch/arm/mach-at91/pm.c       | 14 +-------------
 3 files changed, 6 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
index ba28e9cc584d..c089bfd0dc2f 100644
--- a/arch/arm/mach-at91/at91sam9.c
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -52,7 +52,7 @@ static const struct at91_soc at91sam9_socs[] = {
 	{ /* sentinel */ },
 };
 
-static void __init at91sam9_common_init(void)
+static void __init at91sam9_init(void)
 {
 	struct soc_device *soc;
 	struct device *soc_dev = NULL;
@@ -62,12 +62,8 @@ static void __init at91sam9_common_init(void)
 		soc_dev = soc_device_to_device(soc);
 
 	of_platform_default_populate(NULL, NULL, soc_dev);
-}
 
-static void __init at91sam9_dt_device_init(void)
-{
-	at91sam9_common_init();
-	at91sam9260_pm_init();
+	at91sam9_pm_init();
 }
 
 static const char *const at91_dt_board_compat[] __initconst = {
@@ -77,41 +73,6 @@ static const char *const at91_dt_board_compat[] __initconst = {
 
 DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
 	/* Maintainer: Atmel */
-	.init_machine	= at91sam9_dt_device_init,
+	.init_machine	= at91sam9_init,
 	.dt_compat	= at91_dt_board_compat,
 MACHINE_END
-
-static void __init at91sam9g45_dt_device_init(void)
-{
-	at91sam9_common_init();
-	at91sam9g45_pm_init();
-}
-
-static const char *const at91sam9g45_board_compat[] __initconst = {
-	"atmel,at91sam9g45",
-	NULL
-};
-
-DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
-	/* Maintainer: Atmel */
-	.init_machine	= at91sam9g45_dt_device_init,
-	.dt_compat	= at91sam9g45_board_compat,
-MACHINE_END
-
-static void __init at91sam9x5_dt_device_init(void)
-{
-	at91sam9_common_init();
-	at91sam9x5_pm_init();
-}
-
-static const char *const at91sam9x5_board_compat[] __initconst = {
-	"atmel,at91sam9x5",
-	"atmel,at91sam9n12",
-	NULL
-};
-
-DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
-	/* Maintainer: Atmel */
-	.init_machine	= at91sam9x5_dt_device_init,
-	.dt_compat	= at91sam9x5_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 28ca57a2060f..f1ead0f13c19 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -13,15 +13,11 @@
 
 #ifdef CONFIG_PM
 extern void __init at91rm9200_pm_init(void);
-extern void __init at91sam9260_pm_init(void);
-extern void __init at91sam9g45_pm_init(void);
-extern void __init at91sam9x5_pm_init(void);
+extern void __init at91sam9_pm_init(void);
 extern void __init sama5_pm_init(void);
 #else
 static inline void __init at91rm9200_pm_init(void) { }
-static inline void __init at91sam9260_pm_init(void) { }
-static inline void __init at91sam9g45_pm_init(void) { }
-static inline void __init at91sam9x5_pm_init(void) { }
+static inline void __init at91sam9_pm_init(void) { }
 static inline void __init sama5_pm_init(void) { }
 #endif
 
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a7c047f0d21f..dedfe9038336 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -505,19 +505,7 @@ void __init at91rm9200_pm_init(void)
 	at91_pm_init(at91rm9200_idle);
 }
 
-void __init at91sam9260_pm_init(void)
-{
-	at91_dt_ramc();
-	at91_pm_init(at91sam9_idle);
-}
-
-void __init at91sam9g45_pm_init(void)
-{
-	at91_dt_ramc();
-	at91_pm_init(at91sam9_idle);
-}
-
-void __init at91sam9x5_pm_init(void)
+void __init at91sam9_pm_init(void)
 {
 	at91_dt_ramc();
 	at91_pm_init(at91sam9_idle);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Merge at91_pm_set_standby() in at91_dt_ramc as this is the only callsite.
That moves it to the init section.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index dedfe9038336..2cd27c830ab6 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -205,12 +205,6 @@ static struct platform_device at91_cpuidle_device = {
 	.name = "cpuidle-at91",
 };
 
-static void at91_pm_set_standby(void (*at91_standby)(void))
-{
-	if (at91_standby)
-		at91_cpuidle_device.dev.platform_data = at91_standby;
-}
-
 /*
  * The AT91RM9200 goes into self-refresh mode with this command, and will
  * terminate self-refresh automatically on the next SDRAM access.
@@ -354,7 +348,7 @@ static __init void at91_dt_ramc(void)
 	struct device_node *np;
 	const struct of_device_id *of_id;
 	int idx = 0;
-	const void *standby = NULL;
+	void *standby = NULL;
 	const struct ramc_info *ramc;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
@@ -378,7 +372,7 @@ static __init void at91_dt_ramc(void)
 		return;
 	}
 
-	at91_pm_set_standby(standby);
+	at91_cpuidle_device.dev.platform_data = standby;
 }
 
 static void at91rm9200_idle(void)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Merge at91_pm_set_standby() in at91_dt_ramc as this is the only callsite.
That moves it to the init section.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index dedfe9038336..2cd27c830ab6 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -205,12 +205,6 @@ static struct platform_device at91_cpuidle_device = {
 	.name = "cpuidle-at91",
 };
 
-static void at91_pm_set_standby(void (*at91_standby)(void))
-{
-	if (at91_standby)
-		at91_cpuidle_device.dev.platform_data = at91_standby;
-}
-
 /*
  * The AT91RM9200 goes into self-refresh mode with this command, and will
  * terminate self-refresh automatically on the next SDRAM access.
@@ -354,7 +348,7 @@ static __init void at91_dt_ramc(void)
 	struct device_node *np;
 	const struct of_device_id *of_id;
 	int idx = 0;
-	const void *standby = NULL;
+	void *standby = NULL;
 	const struct ramc_info *ramc;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
@@ -378,7 +372,7 @@ static __init void at91_dt_ramc(void)
 		return;
 	}
 
-	at91_pm_set_standby(standby);
+	at91_cpuidle_device.dev.platform_data = standby;
 }
 
 static void at91rm9200_idle(void)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 11/11] ARM: at91: pm: correct typo
  2017-03-28 11:19 ` Alexandre Belloni
@ 2017-03-28 11:19   ` Alexandre Belloni
  -1 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: linux-kernel, linux-arm-kernel, Boris Brezillon, Wenyou.Yang,
	Alexandre Belloni

Add a missing bracket at the end of Anti's email

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm_suspend.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index ed317657e760..96781daa671a 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -4,7 +4,7 @@
  *  Copyright (C) 2006 Savin Zlobec
  *
  * AT91SAM9 support:
- *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
+ *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
  *
  * 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
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v2 11/11] ARM: at91: pm: correct typo
@ 2017-03-28 11:19   ` Alexandre Belloni
  0 siblings, 0 replies; 42+ messages in thread
From: Alexandre Belloni @ 2017-03-28 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

Add a missing bracket at the end of Anti's email

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm_suspend.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index ed317657e760..96781daa671a 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -4,7 +4,7 @@
  *  Copyright (C) 2006 Savin Zlobec
  *
  * AT91SAM9 support:
- *  Copyright (C) 2007 Anti Sullin <anti.sullin at artecdesign.ee
+ *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee>
  *
  * 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
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 01/11] ARM: at91: pm: Cleanup headers
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:49     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:49 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:19
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 01/11] ARM: at91: pm: Cleanup headers
> 
> Remove unnecessary header inclusions and reorder the remaining ones.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 21 +++++----------------
>  1 file changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> a277981f414d..9e2b5c1e503e 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -10,28 +10,17 @@
>   * (at your option) any later version.
>   */
> 
> -#include <linux/gpio.h>
> -#include <linux/suspend.h>
> -#include <linux/sched.h>
> -#include <linux/proc_fs.h>
>  #include <linux/genalloc.h>
> -#include <linux/interrupt.h>
> -#include <linux/sysfs.h>
> -#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> -#include <linux/of_address.h>
> -#include <linux/platform_device.h>
> -#include <linux/platform_data/atmel.h>
> -#include <linux/io.h>
> +#include <linux/suspend.h>
> +
>  #include <linux/clk/at91_pmc.h>
> 
> -#include <asm/irq.h>
> -#include <linux/atomic.h>
> -#include <asm/mach/time.h>
> -#include <asm/mach/irq.h>
> -#include <asm/fncpy.h>
>  #include <asm/cacheflush.h>
> +#include <asm/fncpy.h>
>  #include <asm/system_misc.h>
> 
>  #include "generic.h"
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 01/11] ARM: at91: pm: Cleanup headers
@ 2017-03-29  4:49     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:49 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:19
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 01/11] ARM: at91: pm: Cleanup headers
> 
> Remove unnecessary header inclusions and reorder the remaining ones.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 21 +++++----------------
>  1 file changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> a277981f414d..9e2b5c1e503e 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -10,28 +10,17 @@
>   * (at your option) any later version.
>   */
> 
> -#include <linux/gpio.h>
> -#include <linux/suspend.h>
> -#include <linux/sched.h>
> -#include <linux/proc_fs.h>
>  #include <linux/genalloc.h>
> -#include <linux/interrupt.h>
> -#include <linux/sysfs.h>
> -#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> -#include <linux/of_address.h>
> -#include <linux/platform_device.h>
> -#include <linux/platform_data/atmel.h>
> -#include <linux/io.h>
> +#include <linux/suspend.h>
> +
>  #include <linux/clk/at91_pmc.h>
> 
> -#include <asm/irq.h>
> -#include <linux/atomic.h>
> -#include <asm/mach/time.h>
> -#include <asm/mach/irq.h>
> -#include <asm/fncpy.h>
>  #include <asm/cacheflush.h>
> +#include <asm/fncpy.h>
>  #include <asm/system_misc.h>
> 
>  #include "generic.h"
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:50     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:50 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:19
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c
> 
> Those macros are only used in pm.c, move them there so we can remove the test
> on __ASSEMBLY__.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 6 ++++++
>  arch/arm/mach-at91/pm.h | 8 --------
>  2 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 9e2b5c1e503e..41789aa4df86 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -45,6 +45,12 @@ static struct {
>  } at91_pm_data;
> 
>  static void __iomem *at91_ramc_base[2];
> +#define at91_ramc_read(id, field) \
> +	__raw_readl(at91_ramc_base[id] + field)
> +
> +#define at91_ramc_write(id, field, value) \
> +	__raw_writel(value, at91_ramc_base[id] + field)
> +
> 
>  static int at91_pm_valid_state(suspend_state_t state)  { diff --git
> a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index
> bf980c6ef294..8eed156ef19a 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -17,14 +17,6 @@
>  #include <soc/at91/at91sam9_ddrsdr.h>
>  #include <soc/at91/at91sam9_sdramc.h>
> 
> -#ifndef __ASSEMBLY__
> -#define at91_ramc_read(id, field) \
> -	__raw_readl(at91_ramc_base[id] + field)
> -
> -#define at91_ramc_write(id, field, value) \
> -	__raw_writel(value, at91_ramc_base[id] + field)
> -#endif
> -
>  #define AT91_MEMCTRL_MC		0
>  #define AT91_MEMCTRL_SDRAMC	1
>  #define AT91_MEMCTRL_DDRSDR	2
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c
@ 2017-03-29  4:50     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:50 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:19
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c
> 
> Those macros are only used in pm.c, move them there so we can remove the test
> on __ASSEMBLY__.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 6 ++++++
>  arch/arm/mach-at91/pm.h | 8 --------
>  2 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 9e2b5c1e503e..41789aa4df86 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -45,6 +45,12 @@ static struct {
>  } at91_pm_data;
> 
>  static void __iomem *at91_ramc_base[2];
> +#define at91_ramc_read(id, field) \
> +	__raw_readl(at91_ramc_base[id] + field)
> +
> +#define at91_ramc_write(id, field, value) \
> +	__raw_writel(value, at91_ramc_base[id] + field)
> +
> 
>  static int at91_pm_valid_state(suspend_state_t state)  { diff --git
> a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index
> bf980c6ef294..8eed156ef19a 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -17,14 +17,6 @@
>  #include <soc/at91/at91sam9_ddrsdr.h>
>  #include <soc/at91/at91sam9_sdramc.h>
> 
> -#ifndef __ASSEMBLY__
> -#define at91_ramc_read(id, field) \
> -	__raw_readl(at91_ramc_base[id] + field)
> -
> -#define at91_ramc_write(id, field, value) \
> -	__raw_writel(value, at91_ramc_base[id] + field)
> -#endif
> -
>  #define AT91_MEMCTRL_MC		0
>  #define AT91_MEMCTRL_SDRAMC	1
>  #define AT91_MEMCTRL_DDRSDR	2
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 03/11] ARM: at91: pm: Move global variables into at91_pm_data
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:51     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:51 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 03/11] ARM: at91: pm: Move global variables into
> at91_pm_data
> 
> Instead of having separate global variables to hold IP addresses, move them to
> struct at91_pm_data.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 44 +++++++++++++++++++++-----------------------
>  1 file changed, 21 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 41789aa4df86..c780dda3b604 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -26,8 +26,6 @@
>  #include "generic.h"
>  #include "pm.h"
> 
> -static void __iomem *pmc;
> -
>  /*
>   * FIXME: this is needed to communicate between the pinctrl driver and
>   * the PM implementation in the machine. Possibly part of the PM @@ -40,17
> +38,17 @@ extern void at91_pinctrl_gpio_resume(void);  #endif
> 
>  static struct {
> +	void __iomem *pmc;
> +	void __iomem *ramc[2];
>  	unsigned long uhp_udp_mask;
>  	int memctrl;
>  } at91_pm_data;
> 
> -static void __iomem *at91_ramc_base[2];  #define at91_ramc_read(id, field) \
> -	__raw_readl(at91_ramc_base[id] + field)
> +	__raw_readl(at91_pm_data.ramc[id] + field)
> 
>  #define at91_ramc_write(id, field, value) \
> -	__raw_writel(value, at91_ramc_base[id] + field)
> -
> +	__raw_writel(value, at91_pm_data.ramc[id] + field)
> 
>  static int at91_pm_valid_state(suspend_state_t state)  { @@ -86,7 +84,7 @@
> static int at91_pm_verify_clocks(void)
>  	unsigned long scsr;
>  	int i;
> 
> -	scsr = readl(pmc + AT91_PMC_SCSR);
> +	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
> 
>  	/* USB must not be using PLLB */
>  	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { @@ -100,7 +98,7 @@
> static int at91_pm_verify_clocks(void)
> 
>  		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
>  			continue;
> -		css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
> +		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) &
> AT91_PMC_CSS;
>  		if (css != AT91_PMC_CSS_SLOW) {
>  			pr_err("AT91: PM - Suspend-to-RAM with PCK%d
> src %d\n", i, css);
>  			return 0;
> @@ -143,8 +141,8 @@ static void at91_pm_suspend(suspend_state_t state)
>  	flush_cache_all();
>  	outer_disable();
> 
> -	at91_suspend_sram_fn(pmc, at91_ramc_base[0],
> -			     at91_ramc_base[1], pm_data);
> +	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
> +			     at91_pm_data.ramc[1], pm_data);
> 
>  	outer_resume();
>  }
> @@ -247,7 +245,7 @@ static void at91rm9200_standby(void)
>  		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
>  		"    str    %5, [%1, %2]"
>  		:
> -		: "r" (0), "r" (at91_ramc_base[0]), "r" (AT91_MC_SDRAMC_LPR),
> +		: "r" (0), "r" (at91_pm_data.ramc[0]), "r"
> (AT91_MC_SDRAMC_LPR),
>  		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
>  		  "r" (lpr));
>  }
> @@ -262,7 +260,7 @@ static void at91_ddr_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_ramc_base[1]) {
> +	if (at91_pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
>  		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; @@ -274,13
> +272,13 @@ static void at91_ddr_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);  }
> 
> @@ -308,7 +306,7 @@ static void at91sam9_sdram_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_ramc_base[1]) {
> +	if (at91_pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
>  		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; @@ -320,13
> +318,13 @@ static void at91sam9_sdram_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);  }
> 
> @@ -346,8 +344,8 @@ static __init void at91_dt_ramc(void)
>  	const void *standby = NULL;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
> -		at91_ramc_base[idx] = of_iomap(np, 0);
> -		if (!at91_ramc_base[idx])
> +		at91_pm_data.ramc[idx] = of_iomap(np, 0);
> +		if (!at91_pm_data.ramc[idx])
>  			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"),
> idx);
> 
>  		if (!standby)
> @@ -373,12 +371,12 @@ static void at91rm9200_idle(void)
>  	 * Disable the processor clock.  The processor will be automatically
>  	 * re-enabled by an interrupt or by a reset.
>  	 */
> -	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
>  }
> 
>  static void at91sam9_idle(void)
>  {
> -	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
>  	cpu_do_idle();
>  }
> 
> @@ -447,8 +445,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
>  		platform_device_register(&at91_cpuidle_device);
> 
>  	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
> -	pmc = of_iomap(pmc_np, 0);
> -	if (!pmc) {
> +	at91_pm_data.pmc = of_iomap(pmc_np, 0);
> +	if (!at91_pm_data.pmc) {
>  		pr_err("AT91: PM not supported, PMC not found\n");
>  		return;
>  	}
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 03/11] ARM: at91: pm: Move global variables into at91_pm_data
@ 2017-03-29  4:51     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:51 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 03/11] ARM: at91: pm: Move global variables into
> at91_pm_data
> 
> Instead of having separate global variables to hold IP addresses, move them to
> struct at91_pm_data.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 44 +++++++++++++++++++++-----------------------
>  1 file changed, 21 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 41789aa4df86..c780dda3b604 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -26,8 +26,6 @@
>  #include "generic.h"
>  #include "pm.h"
> 
> -static void __iomem *pmc;
> -
>  /*
>   * FIXME: this is needed to communicate between the pinctrl driver and
>   * the PM implementation in the machine. Possibly part of the PM @@ -40,17
> +38,17 @@ extern void at91_pinctrl_gpio_resume(void);  #endif
> 
>  static struct {
> +	void __iomem *pmc;
> +	void __iomem *ramc[2];
>  	unsigned long uhp_udp_mask;
>  	int memctrl;
>  } at91_pm_data;
> 
> -static void __iomem *at91_ramc_base[2];  #define at91_ramc_read(id, field) \
> -	__raw_readl(at91_ramc_base[id] + field)
> +	__raw_readl(at91_pm_data.ramc[id] + field)
> 
>  #define at91_ramc_write(id, field, value) \
> -	__raw_writel(value, at91_ramc_base[id] + field)
> -
> +	__raw_writel(value, at91_pm_data.ramc[id] + field)
> 
>  static int at91_pm_valid_state(suspend_state_t state)  { @@ -86,7 +84,7 @@
> static int at91_pm_verify_clocks(void)
>  	unsigned long scsr;
>  	int i;
> 
> -	scsr = readl(pmc + AT91_PMC_SCSR);
> +	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
> 
>  	/* USB must not be using PLLB */
>  	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { @@ -100,7 +98,7 @@
> static int at91_pm_verify_clocks(void)
> 
>  		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
>  			continue;
> -		css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
> +		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) &
> AT91_PMC_CSS;
>  		if (css != AT91_PMC_CSS_SLOW) {
>  			pr_err("AT91: PM - Suspend-to-RAM with PCK%d
> src %d\n", i, css);
>  			return 0;
> @@ -143,8 +141,8 @@ static void at91_pm_suspend(suspend_state_t state)
>  	flush_cache_all();
>  	outer_disable();
> 
> -	at91_suspend_sram_fn(pmc, at91_ramc_base[0],
> -			     at91_ramc_base[1], pm_data);
> +	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
> +			     at91_pm_data.ramc[1], pm_data);
> 
>  	outer_resume();
>  }
> @@ -247,7 +245,7 @@ static void at91rm9200_standby(void)
>  		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
>  		"    str    %5, [%1, %2]"
>  		:
> -		: "r" (0), "r" (at91_ramc_base[0]), "r" (AT91_MC_SDRAMC_LPR),
> +		: "r" (0), "r" (at91_pm_data.ramc[0]), "r"
> (AT91_MC_SDRAMC_LPR),
>  		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
>  		  "r" (lpr));
>  }
> @@ -262,7 +260,7 @@ static void at91_ddr_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_ramc_base[1]) {
> +	if (at91_pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
>  		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; @@ -274,13
> +272,13 @@ static void at91_ddr_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);  }
> 
> @@ -308,7 +306,7 @@ static void at91sam9_sdram_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_ramc_base[1]) {
> +	if (at91_pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
>  		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; @@ -320,13
> +318,13 @@ static void at91sam9_sdram_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
> -	if (at91_ramc_base[1])
> +	if (at91_pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);  }
> 
> @@ -346,8 +344,8 @@ static __init void at91_dt_ramc(void)
>  	const void *standby = NULL;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
> -		at91_ramc_base[idx] = of_iomap(np, 0);
> -		if (!at91_ramc_base[idx])
> +		at91_pm_data.ramc[idx] = of_iomap(np, 0);
> +		if (!at91_pm_data.ramc[idx])
>  			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"),
> idx);
> 
>  		if (!standby)
> @@ -373,12 +371,12 @@ static void at91rm9200_idle(void)
>  	 * Disable the processor clock.  The processor will be automatically
>  	 * re-enabled by an interrupt or by a reset.
>  	 */
> -	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
>  }
> 
>  static void at91sam9_idle(void)
>  {
> -	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
>  	cpu_do_idle();
>  }
> 
> @@ -447,8 +445,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
>  		platform_device_register(&at91_cpuidle_device);
> 
>  	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
> -	pmc = of_iomap(pmc_np, 0);
> -	if (!pmc) {
> +	at91_pm_data.pmc = of_iomap(pmc_np, 0);
> +	if (!at91_pm_data.pmc) {
>  		pr_err("AT91: PM not supported, PMC not found\n");
>  		return;
>  	}
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:52     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:52 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in
> pm_suspend.S
> 
> The number of register we can safely pass to at91_pm_suspend_in_sram is
> limited. Instead, pass the address to the at91_pm_data structure.
> 
> The offsets are automatically generated to avoid hardcoding them.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/Makefile          | 33 +++++++++++++++
>  arch/arm/mach-at91/pm.c              | 78 +++++++++++++++---------------------
>  arch/arm/mach-at91/pm.h              | 16 +++++---
>  arch/arm/mach-at91/pm_data-offsets.c | 13 ++++++
>  arch/arm/mach-at91/pm_suspend.S      | 29 ++++++--------
>  5 files changed, 102 insertions(+), 67 deletions(-)  create mode 100644
> arch/arm/mach-at91/pm_data-offsets.c
> 
> diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index
> c5bbf8bb8c0f..858ef14f961c 100644
> --- a/arch/arm/mach-at91/Makefile
> +++ b/arch/arm/mach-at91/Makefile
> @@ -18,3 +18,36 @@ endif
>  ifeq ($(CONFIG_PM_DEBUG),y)
>  CFLAGS_pm.o += -DDEBUG
>  endif
> +
> +# Default sed regexp - multiline due to syntax constraints define sed-y
> +	"/^->/{s:->#\(.*\):/* \1 */:; \
> +	s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
> +	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
> +	s:->::; p;}"
> +endef
> +
> +# Use filechk to avoid rebuilds when a header changes, but the
> +resulting file # does not define filechk_offsets
> +	(set -e; \
> +	 echo "#ifndef $2"; \
> +	 echo "#define $2"; \
> +	 echo "/*"; \
> +	 echo " * DO NOT MODIFY."; \
> +	 echo " *"; \
> +	 echo " * This file was generated by Kbuild"; \
> +	 echo " */"; \
> +	 echo ""; \
> +	 sed -ne $(sed-y); \
> +	 echo ""; \
> +	 echo "#endif" )
> +endef
> +
> +arch/arm/mach-at91/pm_data-offsets.s: arch/arm/mach-at91/pm_data-offsets.c
> +	$(call if_changed_dep,cc_s_c)
> +
> +include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-
> offsets.s FORCE
> +	$(call filechk,offsets,__PM_DATA_OFFSETS_H__)
> +
> +arch/arm/mach-at91/pm_suspend.o:
> +include/generated/at91_pm_data-offsets.h
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> c780dda3b604..a35b1541b328 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -37,18 +37,13 @@ extern void at91_pinctrl_gpio_suspend(void);  extern void
> at91_pinctrl_gpio_resume(void);  #endif
> 
> -static struct {
> -	void __iomem *pmc;
> -	void __iomem *ramc[2];
> -	unsigned long uhp_udp_mask;
> -	int memctrl;
> -} at91_pm_data;
> +static struct at91_pm_data pm_data;
> 
>  #define at91_ramc_read(id, field) \
> -	__raw_readl(at91_pm_data.ramc[id] + field)
> +	__raw_readl(pm_data.ramc[id] + field)
> 
>  #define at91_ramc_write(id, field, value) \
> -	__raw_writel(value, at91_pm_data.ramc[id] + field)
> +	__raw_writel(value, pm_data.ramc[id] + field)
> 
>  static int at91_pm_valid_state(suspend_state_t state)  { @@ -84,10 +79,10 @@
> static int at91_pm_verify_clocks(void)
>  	unsigned long scsr;
>  	int i;
> 
> -	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
> +	scsr = readl(pm_data.pmc + AT91_PMC_SCSR);
> 
>  	/* USB must not be using PLLB */
> -	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
> +	if ((scsr & pm_data.uhp_udp_mask) != 0) {
>  		pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
>  		return 0;
>  	}
> @@ -98,7 +93,7 @@ static int at91_pm_verify_clocks(void)
> 
>  		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
>  			continue;
> -		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) &
> AT91_PMC_CSS;
> +		css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) &
> AT91_PMC_CSS;
>  		if (css != AT91_PMC_CSS_SLOW) {
>  			pr_err("AT91: PM - Suspend-to-RAM with PCK%d
> src %d\n", i, css);
>  			return 0;
> @@ -124,25 +119,18 @@ int at91_suspend_entering_slow_clock(void)
>  }
>  EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
> 
> -static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
> -			  void __iomem *ramc1, int memctrl);
> -
> -extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem
> *ramc0,
> -			    void __iomem *ramc1, int memctrl);
> +static void (*at91_suspend_sram_fn)(struct at91_pm_data *); extern void
> +at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
>  extern u32 at91_pm_suspend_in_sram_sz;
> 
>  static void at91_pm_suspend(suspend_state_t state)  {
> -	unsigned int pm_data = at91_pm_data.memctrl;
> -
> -	pm_data |= (state == PM_SUSPEND_MEM) ?
> -				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
> +	pm_data.mode = (state == PM_SUSPEND_MEM) ?
> AT91_PM_SLOW_CLOCK : 0;
> 
>  	flush_cache_all();
>  	outer_disable();
> 
> -	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
> -			     at91_pm_data.ramc[1], pm_data);
> +	at91_suspend_sram_fn(&pm_data);
> 
>  	outer_resume();
>  }
> @@ -245,7 +233,7 @@ static void at91rm9200_standby(void)
>  		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
>  		"    str    %5, [%1, %2]"
>  		:
> -		: "r" (0), "r" (at91_pm_data.ramc[0]), "r"
> (AT91_MC_SDRAMC_LPR),
> +		: "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
>  		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
>  		  "r" (lpr));
>  }
> @@ -260,7 +248,7 @@ static void at91_ddr_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_pm_data.ramc[1]) {
> +	if (pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
>  		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; @@ -272,13
> +260,13 @@ static void at91_ddr_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);  }
> 
> @@ -306,7 +294,7 @@ static void at91sam9_sdram_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_pm_data.ramc[1]) {
> +	if (pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
>  		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; @@ -318,13
> +306,13 @@ static void at91sam9_sdram_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);  }
> 
> @@ -344,8 +332,8 @@ static __init void at91_dt_ramc(void)
>  	const void *standby = NULL;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
> -		at91_pm_data.ramc[idx] = of_iomap(np, 0);
> -		if (!at91_pm_data.ramc[idx])
> +		pm_data.ramc[idx] = of_iomap(np, 0);
> +		if (!pm_data.ramc[idx])
>  			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"),
> idx);
> 
>  		if (!standby)
> @@ -371,12 +359,12 @@ static void at91rm9200_idle(void)
>  	 * Disable the processor clock.  The processor will be automatically
>  	 * re-enabled by an interrupt or by a reset.
>  	 */
> -	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
>  }
> 
>  static void at91sam9_idle(void)
>  {
> -	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
>  	cpu_do_idle();
>  }
> 
> @@ -445,8 +433,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
>  		platform_device_register(&at91_cpuidle_device);
> 
>  	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
> -	at91_pm_data.pmc = of_iomap(pmc_np, 0);
> -	if (!at91_pm_data.pmc) {
> +	pm_data.pmc = of_iomap(pmc_np, 0);
> +	if (!pm_data.pmc) {
>  		pr_err("AT91: PM not supported, PMC not found\n");
>  		return;
>  	}
> @@ -471,8 +459,8 @@ void __init at91rm9200_pm_init(void)
>  	 */
>  	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
> 
> -	at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_MC;
> +	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_MC;
> 
>  	at91_pm_init(at91rm9200_idle);
>  }
> @@ -480,31 +468,31 @@ void __init at91rm9200_pm_init(void)  void __init
> at91sam9260_pm_init(void)  {
>  	at91_dt_ramc();
> -	at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9g45_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
> +	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9x5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init sama5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(NULL);
>  }
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index
> 8eed156ef19a..fc0f7d048187 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -21,12 +21,16 @@
>  #define AT91_MEMCTRL_SDRAMC	1
>  #define AT91_MEMCTRL_DDRSDR	2
> 
> -#define	AT91_PM_MEMTYPE_MASK	0x0f
> -
> -#define	AT91_PM_MODE_OFFSET	4
> -#define	AT91_PM_MODE_MASK	0x01
> -#define	AT91_PM_MODE(x)		(((x) & AT91_PM_MODE_MASK)
> << AT91_PM_MODE_OFFSET)
> -
>  #define	AT91_PM_SLOW_CLOCK	0x01
> 
> +#ifndef __ASSEMBLY__
> +struct at91_pm_data {
> +	void __iomem *pmc;
> +	void __iomem *ramc[2];
> +	unsigned long uhp_udp_mask;
> +	unsigned int memctrl;
> +	unsigned int mode;
> +};
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-
> offsets.c
> new file mode 100644
> index 000000000000..30302cb16df0
> --- /dev/null
> +++ b/arch/arm/mach-at91/pm_data-offsets.c
> @@ -0,0 +1,13 @@
> +#include <linux/stddef.h>
> +#include <linux/kbuild.h>
> +#include "pm.h"
> +
> +int main(void)
> +{
> +	DEFINE(PM_DATA_PMC,		offsetof(struct at91_pm_data,
> pmc));
> +	DEFINE(PM_DATA_RAMC0,		offsetof(struct at91_pm_data,
> ramc[0]));
> +	DEFINE(PM_DATA_RAMC1,		offsetof(struct at91_pm_data,
> ramc[1]));
> +	DEFINE(PM_DATA_MEMCTRL,	offsetof(struct at91_pm_data,
> memctrl));
> +	DEFINE(PM_DATA_MODE,		offsetof(struct at91_pm_data,
> mode));
> +	return 0;
> +}
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-
> at91/pm_suspend.S index a25defda3d22..ed317657e760 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -14,6 +14,7 @@
>  #include <linux/linkage.h>
>  #include <linux/clk/at91_pmc.h>
>  #include "pm.h"
> +#include "generated/at91_pm_data-offsets.h"
> 
>  #define	SRAMC_SELF_FRESH_ACTIVE		0x01
>  #define	SRAMC_SELF_FRESH_EXIT		0x00
> @@ -72,13 +73,9 @@ tmp2	.req	r5
>  	.arm
> 
>  /*
> - * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
> - *			void __iomem *ramc1, int memctrl)
> + * void at91_suspend_sram_fn(struct at91_pm_data*)
>   * @input param:
> - * 	@r0: base address of AT91_PMC
> - *  	@r1: base address of SDRAM Controller (SDRAM, DDRSDR, or
> AT91_SYS)
> - *	@r2: base address of second SDRAM Controller or 0 if not present
> - *	@r3: pm information
> + * 	@r0: base address of struct at91_pm_data
>   */
>  /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of
> fncpy() */
>  	.align 3
> @@ -90,16 +87,16 @@ ENTRY(at91_pm_suspend_in_sram)
>  	mov	tmp1, #0
>  	mcr	p15, 0, tmp1, c7, c10, 4
> 
> -	str	r0, .pmc_base
> -	str	r1, .sramc_base
> -	str	r2, .sramc1_base
> -
> -	and	r0, r3, #AT91_PM_MEMTYPE_MASK
> -	str	r0, .memtype
> -
> -	lsr	r0, r3, #AT91_PM_MODE_OFFSET
> -	and	r0, r0, #AT91_PM_MODE_MASK
> -	str	r0, .pm_mode
> +	ldr	tmp1, [r0, #PM_DATA_PMC]
> +	str	tmp1, .pmc_base
> +	ldr	tmp1, [r0, #PM_DATA_RAMC0]
> +	str	tmp1, .sramc_base
> +	ldr	tmp1, [r0, #PM_DATA_RAMC1]
> +	str	tmp1, .sramc1_base
> +	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
> +	str	tmp1, .memtype
> +	ldr	tmp1, [r0, #PM_DATA_MODE]
> +	str	tmp1, .pm_mode
> 
>  	/* Active the self-refresh mode */
>  	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S
@ 2017-03-29  4:52     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:52 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in
> pm_suspend.S
> 
> The number of register we can safely pass to at91_pm_suspend_in_sram is
> limited. Instead, pass the address to the at91_pm_data structure.
> 
> The offsets are automatically generated to avoid hardcoding them.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/Makefile          | 33 +++++++++++++++
>  arch/arm/mach-at91/pm.c              | 78 +++++++++++++++---------------------
>  arch/arm/mach-at91/pm.h              | 16 +++++---
>  arch/arm/mach-at91/pm_data-offsets.c | 13 ++++++
>  arch/arm/mach-at91/pm_suspend.S      | 29 ++++++--------
>  5 files changed, 102 insertions(+), 67 deletions(-)  create mode 100644
> arch/arm/mach-at91/pm_data-offsets.c
> 
> diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index
> c5bbf8bb8c0f..858ef14f961c 100644
> --- a/arch/arm/mach-at91/Makefile
> +++ b/arch/arm/mach-at91/Makefile
> @@ -18,3 +18,36 @@ endif
>  ifeq ($(CONFIG_PM_DEBUG),y)
>  CFLAGS_pm.o += -DDEBUG
>  endif
> +
> +# Default sed regexp - multiline due to syntax constraints define sed-y
> +	"/^->/{s:->#\(.*\):/* \1 */:; \
> +	s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
> +	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
> +	s:->::; p;}"
> +endef
> +
> +# Use filechk to avoid rebuilds when a header changes, but the
> +resulting file # does not define filechk_offsets
> +	(set -e; \
> +	 echo "#ifndef $2"; \
> +	 echo "#define $2"; \
> +	 echo "/*"; \
> +	 echo " * DO NOT MODIFY."; \
> +	 echo " *"; \
> +	 echo " * This file was generated by Kbuild"; \
> +	 echo " */"; \
> +	 echo ""; \
> +	 sed -ne $(sed-y); \
> +	 echo ""; \
> +	 echo "#endif" )
> +endef
> +
> +arch/arm/mach-at91/pm_data-offsets.s: arch/arm/mach-at91/pm_data-offsets.c
> +	$(call if_changed_dep,cc_s_c)
> +
> +include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-
> offsets.s FORCE
> +	$(call filechk,offsets,__PM_DATA_OFFSETS_H__)
> +
> +arch/arm/mach-at91/pm_suspend.o:
> +include/generated/at91_pm_data-offsets.h
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> c780dda3b604..a35b1541b328 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -37,18 +37,13 @@ extern void at91_pinctrl_gpio_suspend(void);  extern void
> at91_pinctrl_gpio_resume(void);  #endif
> 
> -static struct {
> -	void __iomem *pmc;
> -	void __iomem *ramc[2];
> -	unsigned long uhp_udp_mask;
> -	int memctrl;
> -} at91_pm_data;
> +static struct at91_pm_data pm_data;
> 
>  #define at91_ramc_read(id, field) \
> -	__raw_readl(at91_pm_data.ramc[id] + field)
> +	__raw_readl(pm_data.ramc[id] + field)
> 
>  #define at91_ramc_write(id, field, value) \
> -	__raw_writel(value, at91_pm_data.ramc[id] + field)
> +	__raw_writel(value, pm_data.ramc[id] + field)
> 
>  static int at91_pm_valid_state(suspend_state_t state)  { @@ -84,10 +79,10 @@
> static int at91_pm_verify_clocks(void)
>  	unsigned long scsr;
>  	int i;
> 
> -	scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
> +	scsr = readl(pm_data.pmc + AT91_PMC_SCSR);
> 
>  	/* USB must not be using PLLB */
> -	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
> +	if ((scsr & pm_data.uhp_udp_mask) != 0) {
>  		pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
>  		return 0;
>  	}
> @@ -98,7 +93,7 @@ static int at91_pm_verify_clocks(void)
> 
>  		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
>  			continue;
> -		css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) &
> AT91_PMC_CSS;
> +		css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) &
> AT91_PMC_CSS;
>  		if (css != AT91_PMC_CSS_SLOW) {
>  			pr_err("AT91: PM - Suspend-to-RAM with PCK%d
> src %d\n", i, css);
>  			return 0;
> @@ -124,25 +119,18 @@ int at91_suspend_entering_slow_clock(void)
>  }
>  EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
> 
> -static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
> -			  void __iomem *ramc1, int memctrl);
> -
> -extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem
> *ramc0,
> -			    void __iomem *ramc1, int memctrl);
> +static void (*at91_suspend_sram_fn)(struct at91_pm_data *); extern void
> +at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
>  extern u32 at91_pm_suspend_in_sram_sz;
> 
>  static void at91_pm_suspend(suspend_state_t state)  {
> -	unsigned int pm_data = at91_pm_data.memctrl;
> -
> -	pm_data |= (state == PM_SUSPEND_MEM) ?
> -				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
> +	pm_data.mode = (state == PM_SUSPEND_MEM) ?
> AT91_PM_SLOW_CLOCK : 0;
> 
>  	flush_cache_all();
>  	outer_disable();
> 
> -	at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
> -			     at91_pm_data.ramc[1], pm_data);
> +	at91_suspend_sram_fn(&pm_data);
> 
>  	outer_resume();
>  }
> @@ -245,7 +233,7 @@ static void at91rm9200_standby(void)
>  		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
>  		"    str    %5, [%1, %2]"
>  		:
> -		: "r" (0), "r" (at91_pm_data.ramc[0]), "r"
> (AT91_MC_SDRAMC_LPR),
> +		: "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
>  		  "r" (1), "r" (AT91_MC_SDRAMC_SRR),
>  		  "r" (lpr));
>  }
> @@ -260,7 +248,7 @@ static void at91_ddr_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_pm_data.ramc[1]) {
> +	if (pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
>  		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; @@ -272,13
> +260,13 @@ static void at91_ddr_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);  }
> 
> @@ -306,7 +294,7 @@ static void at91sam9_sdram_standby(void)
>  	u32 lpr0, lpr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> -	if (at91_pm_data.ramc[1]) {
> +	if (pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
>  		lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; @@ -318,13
> +306,13 @@ static void at91sam9_sdram_standby(void)
> 
>  	/* self-refresh mode now */
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
> 
>  	cpu_do_idle();
> 
>  	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
> -	if (at91_pm_data.ramc[1])
> +	if (pm_data.ramc[1])
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);  }
> 
> @@ -344,8 +332,8 @@ static __init void at91_dt_ramc(void)
>  	const void *standby = NULL;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
> -		at91_pm_data.ramc[idx] = of_iomap(np, 0);
> -		if (!at91_pm_data.ramc[idx])
> +		pm_data.ramc[idx] = of_iomap(np, 0);
> +		if (!pm_data.ramc[idx])
>  			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"),
> idx);
> 
>  		if (!standby)
> @@ -371,12 +359,12 @@ static void at91rm9200_idle(void)
>  	 * Disable the processor clock.  The processor will be automatically
>  	 * re-enabled by an interrupt or by a reset.
>  	 */
> -	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
>  }
> 
>  static void at91sam9_idle(void)
>  {
> -	writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
> +	writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
>  	cpu_do_idle();
>  }
> 
> @@ -445,8 +433,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
>  		platform_device_register(&at91_cpuidle_device);
> 
>  	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
> -	at91_pm_data.pmc = of_iomap(pmc_np, 0);
> -	if (!at91_pm_data.pmc) {
> +	pm_data.pmc = of_iomap(pmc_np, 0);
> +	if (!pm_data.pmc) {
>  		pr_err("AT91: PM not supported, PMC not found\n");
>  		return;
>  	}
> @@ -471,8 +459,8 @@ void __init at91rm9200_pm_init(void)
>  	 */
>  	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
> 
> -	at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_MC;
> +	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_MC;
> 
>  	at91_pm_init(at91rm9200_idle);
>  }
> @@ -480,31 +468,31 @@ void __init at91rm9200_pm_init(void)  void __init
> at91sam9260_pm_init(void)  {
>  	at91_dt_ramc();
> -	at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9g45_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
> +	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9x5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init sama5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
> +	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> +	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(NULL);
>  }
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index
> 8eed156ef19a..fc0f7d048187 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -21,12 +21,16 @@
>  #define AT91_MEMCTRL_SDRAMC	1
>  #define AT91_MEMCTRL_DDRSDR	2
> 
> -#define	AT91_PM_MEMTYPE_MASK	0x0f
> -
> -#define	AT91_PM_MODE_OFFSET	4
> -#define	AT91_PM_MODE_MASK	0x01
> -#define	AT91_PM_MODE(x)		(((x) & AT91_PM_MODE_MASK)
> << AT91_PM_MODE_OFFSET)
> -
>  #define	AT91_PM_SLOW_CLOCK	0x01
> 
> +#ifndef __ASSEMBLY__
> +struct at91_pm_data {
> +	void __iomem *pmc;
> +	void __iomem *ramc[2];
> +	unsigned long uhp_udp_mask;
> +	unsigned int memctrl;
> +	unsigned int mode;
> +};
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-
> offsets.c
> new file mode 100644
> index 000000000000..30302cb16df0
> --- /dev/null
> +++ b/arch/arm/mach-at91/pm_data-offsets.c
> @@ -0,0 +1,13 @@
> +#include <linux/stddef.h>
> +#include <linux/kbuild.h>
> +#include "pm.h"
> +
> +int main(void)
> +{
> +	DEFINE(PM_DATA_PMC,		offsetof(struct at91_pm_data,
> pmc));
> +	DEFINE(PM_DATA_RAMC0,		offsetof(struct at91_pm_data,
> ramc[0]));
> +	DEFINE(PM_DATA_RAMC1,		offsetof(struct at91_pm_data,
> ramc[1]));
> +	DEFINE(PM_DATA_MEMCTRL,	offsetof(struct at91_pm_data,
> memctrl));
> +	DEFINE(PM_DATA_MODE,		offsetof(struct at91_pm_data,
> mode));
> +	return 0;
> +}
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-
> at91/pm_suspend.S index a25defda3d22..ed317657e760 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -14,6 +14,7 @@
>  #include <linux/linkage.h>
>  #include <linux/clk/at91_pmc.h>
>  #include "pm.h"
> +#include "generated/at91_pm_data-offsets.h"
> 
>  #define	SRAMC_SELF_FRESH_ACTIVE		0x01
>  #define	SRAMC_SELF_FRESH_EXIT		0x00
> @@ -72,13 +73,9 @@ tmp2	.req	r5
>  	.arm
> 
>  /*
> - * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
> - *			void __iomem *ramc1, int memctrl)
> + * void at91_suspend_sram_fn(struct at91_pm_data*)
>   * @input param:
> - * 	@r0: base address of AT91_PMC
> - *  	@r1: base address of SDRAM Controller (SDRAM, DDRSDR, or
> AT91_SYS)
> - *	@r2: base address of second SDRAM Controller or 0 if not present
> - *	@r3: pm information
> + * 	@r0: base address of struct at91_pm_data
>   */
>  /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of
> fncpy() */
>  	.align 3
> @@ -90,16 +87,16 @@ ENTRY(at91_pm_suspend_in_sram)
>  	mov	tmp1, #0
>  	mcr	p15, 0, tmp1, c7, c10, 4
> 
> -	str	r0, .pmc_base
> -	str	r1, .sramc_base
> -	str	r2, .sramc1_base
> -
> -	and	r0, r3, #AT91_PM_MEMTYPE_MASK
> -	str	r0, .memtype
> -
> -	lsr	r0, r3, #AT91_PM_MODE_OFFSET
> -	and	r0, r0, #AT91_PM_MODE_MASK
> -	str	r0, .pm_mode
> +	ldr	tmp1, [r0, #PM_DATA_PMC]
> +	str	tmp1, .pmc_base
> +	ldr	tmp1, [r0, #PM_DATA_RAMC0]
> +	str	tmp1, .sramc_base
> +	ldr	tmp1, [r0, #PM_DATA_RAMC1]
> +	str	tmp1, .sramc1_base
> +	ldr	tmp1, [r0, #PM_DATA_MEMCTRL]
> +	str	tmp1, .memtype
> +	ldr	tmp1, [r0, #PM_DATA_MODE]
> +	str	tmp1, .pm_mode
> 
>  	/* Active the self-refresh mode */
>  	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1 memories.
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:53     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:53 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh
> bug with LPDDR1 memories.
> 
> As already explained for pm_suspend.S, the DDRSDR controller fails to put
> LPDDR1 memories in self-refresh. Force the controller to think it has DDR2
> memories during the self-refresh period, as the DDR2 self-refresh spec is
> equivalent to LPDDR1, and is correctly implemented in the controller.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 3d68d93c11c7..488549bc2bed 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -241,12 +241,27 @@ static void at91_ddr_standby(void)
>  	/* Those two values allow us to delay self-refresh activation
>  	 * to the maximum. */
>  	u32 lpr0, lpr1 = 0;
> +	u32 mdr, saved_mdr0, saved_mdr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> +	/* LPDDR1 --> force DDR2 mode during self-refresh */
> +	saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR);
> +	if ((saved_mdr0 & AT91_DDRSDRC_MD) ==
> AT91_DDRSDRC_MD_LOW_POWER_DDR) {
> +		mdr = saved_mdr0 & ~AT91_DDRSDRC_MD;
> +		mdr |= AT91_DDRSDRC_MD_DDR2;
> +		at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
> +	}
> +
>  	if (pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
>  		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
> +		saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR);
> +		if ((saved_mdr1 & AT91_DDRSDRC_MD) ==
> AT91_DDRSDRC_MD_LOW_POWER_DDR) {
> +			mdr = saved_mdr1 & ~AT91_DDRSDRC_MD;
> +			mdr |= AT91_DDRSDRC_MD_DDR2;
> +			at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr);
> +		}
>  	}
> 
>  	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); @@ -260,9
> +275,12 @@ static void at91_ddr_standby(void)
> 
>  	cpu_do_idle();
> 
> +	at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
> -	if (pm_data.ramc[1])
> +	if (pm_data.ramc[1]) {
> +		at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
> +	}
>  }
> 
>  static void sama5d3_ddr_standby(void)
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1 memories.
@ 2017-03-29  4:53     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:53 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh
> bug with LPDDR1 memories.
> 
> As already explained for pm_suspend.S, the DDRSDR controller fails to put
> LPDDR1 memories in self-refresh. Force the controller to think it has DDR2
> memories during the self-refresh period, as the DDR2 self-refresh spec is
> equivalent to LPDDR1, and is correctly implemented in the controller.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 3d68d93c11c7..488549bc2bed 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -241,12 +241,27 @@ static void at91_ddr_standby(void)
>  	/* Those two values allow us to delay self-refresh activation
>  	 * to the maximum. */
>  	u32 lpr0, lpr1 = 0;
> +	u32 mdr, saved_mdr0, saved_mdr1 = 0;
>  	u32 saved_lpr0, saved_lpr1 = 0;
> 
> +	/* LPDDR1 --> force DDR2 mode during self-refresh */
> +	saved_mdr0 = at91_ramc_read(0, AT91_DDRSDRC_MDR);
> +	if ((saved_mdr0 & AT91_DDRSDRC_MD) ==
> AT91_DDRSDRC_MD_LOW_POWER_DDR) {
> +		mdr = saved_mdr0 & ~AT91_DDRSDRC_MD;
> +		mdr |= AT91_DDRSDRC_MD_DDR2;
> +		at91_ramc_write(0, AT91_DDRSDRC_MDR, mdr);
> +	}
> +
>  	if (pm_data.ramc[1]) {
>  		saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
>  		lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
>  		lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
> +		saved_mdr1 = at91_ramc_read(1, AT91_DDRSDRC_MDR);
> +		if ((saved_mdr1 & AT91_DDRSDRC_MD) ==
> AT91_DDRSDRC_MD_LOW_POWER_DDR) {
> +			mdr = saved_mdr1 & ~AT91_DDRSDRC_MD;
> +			mdr |= AT91_DDRSDRC_MD_DDR2;
> +			at91_ramc_write(1, AT91_DDRSDRC_MDR, mdr);
> +		}
>  	}
> 
>  	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); @@ -260,9
> +275,12 @@ static void at91_ddr_standby(void)
> 
>  	cpu_do_idle();
> 
> +	at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr0);
>  	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
> -	if (pm_data.ramc[1])
> +	if (pm_data.ramc[1]) {
> +		at91_ramc_write(0, AT91_DDRSDRC_MDR, saved_mdr1);
>  		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
> +	}
>  }
> 
>  static void sama5d3_ddr_standby(void)
> --
> 2.11.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the ramc id
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:53     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:53 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the
> ramc id
> 
> Instead of relying on the SoC type to select the memory controller type, use the
> device tree ids as they are parsed anyway.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 30 ++++++++++++++++++++----------
>  1 file changed, 20 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 488549bc2bed..ddf62a006635 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -329,11 +329,23 @@ static void at91sam9_sdram_standby(void)
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);  }
> 
> +struct ramc_info {
> +	void (*idle)(void);
> +	unsigned int memctrl;
> +};
> +
> +static const struct ramc_info ramc_infos[] __initconst = {
> +	{ .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC},
> +	{ .idle = at91sam9_sdram_standby, .memctrl =
> AT91_MEMCTRL_SDRAMC},
> +	{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
> +	{ .idle = sama5d3_ddr_standby, .memctrl =
> AT91_MEMCTRL_DDRSDR}, };
> +
>  static const struct of_device_id const ramc_ids[] __initconst = {
> -	{ .compatible = "atmel,at91rm9200-sdramc", .data =
> at91rm9200_standby },
> -	{ .compatible = "atmel,at91sam9260-sdramc", .data =
> at91sam9_sdram_standby },
> -	{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
> -	{ .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
> +	{ .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
> +	{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
> +	{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
> +	{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
>  	{ /*sentinel*/ }
>  };
> 
> @@ -343,14 +355,17 @@ static __init void at91_dt_ramc(void)
>  	const struct of_device_id *of_id;
>  	int idx = 0;
>  	const void *standby = NULL;
> +	const struct ramc_info *ramc;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
>  		pm_data.ramc[idx] = of_iomap(np, 0);
>  		if (!pm_data.ramc[idx])
>  			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"),
> idx);
> 
> +		ramc = of_id->data;
>  		if (!standby)
> -			standby = of_id->data;
> +			standby = ramc->idle;
> +		pm_data.memctrl = ramc->memctrl;
> 
>  		idx++;
>  	}
> @@ -473,7 +488,6 @@ void __init at91rm9200_pm_init(void)
>  	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
> 
>  	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> -	pm_data.memctrl = AT91_MEMCTRL_MC;
> 
>  	at91_pm_init(at91rm9200_idle);
>  }
> @@ -481,7 +495,6 @@ void __init at91rm9200_pm_init(void)  void __init
> at91sam9260_pm_init(void)  {
>  	at91_dt_ramc();
> -	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> @@ -490,7 +503,6 @@ void __init at91sam9g45_pm_init(void)  {
>  	at91_dt_ramc();
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
> -	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
> @@ -498,7 +510,6 @@ void __init at91sam9x5_pm_init(void)  {
>  	at91_dt_ramc();
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
> @@ -506,6 +517,5 @@ void __init sama5_pm_init(void)  {
>  	at91_dt_ramc();
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(NULL);
>  }
> --
> 2.11.0


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the ramc id
@ 2017-03-29  4:53     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:53 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the
> ramc id
> 
> Instead of relying on the SoC type to select the memory controller type, use the
> device tree ids as they are parsed anyway.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 30 ++++++++++++++++++++----------
>  1 file changed, 20 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> 488549bc2bed..ddf62a006635 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -329,11 +329,23 @@ static void at91sam9_sdram_standby(void)
>  		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);  }
> 
> +struct ramc_info {
> +	void (*idle)(void);
> +	unsigned int memctrl;
> +};
> +
> +static const struct ramc_info ramc_infos[] __initconst = {
> +	{ .idle = at91rm9200_standby, .memctrl = AT91_MEMCTRL_MC},
> +	{ .idle = at91sam9_sdram_standby, .memctrl =
> AT91_MEMCTRL_SDRAMC},
> +	{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
> +	{ .idle = sama5d3_ddr_standby, .memctrl =
> AT91_MEMCTRL_DDRSDR}, };
> +
>  static const struct of_device_id const ramc_ids[] __initconst = {
> -	{ .compatible = "atmel,at91rm9200-sdramc", .data =
> at91rm9200_standby },
> -	{ .compatible = "atmel,at91sam9260-sdramc", .data =
> at91sam9_sdram_standby },
> -	{ .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
> -	{ .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
> +	{ .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
> +	{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
> +	{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
> +	{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
>  	{ /*sentinel*/ }
>  };
> 
> @@ -343,14 +355,17 @@ static __init void at91_dt_ramc(void)
>  	const struct of_device_id *of_id;
>  	int idx = 0;
>  	const void *standby = NULL;
> +	const struct ramc_info *ramc;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
>  		pm_data.ramc[idx] = of_iomap(np, 0);
>  		if (!pm_data.ramc[idx])
>  			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"),
> idx);
> 
> +		ramc = of_id->data;
>  		if (!standby)
> -			standby = of_id->data;
> +			standby = ramc->idle;
> +		pm_data.memctrl = ramc->memctrl;
> 
>  		idx++;
>  	}
> @@ -473,7 +488,6 @@ void __init at91rm9200_pm_init(void)
>  	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
> 
>  	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> -	pm_data.memctrl = AT91_MEMCTRL_MC;
> 
>  	at91_pm_init(at91rm9200_idle);
>  }
> @@ -481,7 +495,6 @@ void __init at91rm9200_pm_init(void)  void __init
> at91sam9260_pm_init(void)  {
>  	at91_dt_ramc();
> -	pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> @@ -490,7 +503,6 @@ void __init at91sam9g45_pm_init(void)  {
>  	at91_dt_ramc();
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
> -	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
> @@ -498,7 +510,6 @@ void __init at91sam9x5_pm_init(void)  {
>  	at91_dt_ramc();
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
> @@ -506,6 +517,5 @@ void __init sama5_pm_init(void)  {
>  	at91_dt_ramc();
>  	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
> -	pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
>  	at91_pm_init(NULL);
>  }
> --
> 2.11.0


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:54     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:54 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc
> 
> The USB clocks mask (uhp_udp_mask) depends on the pmc. Tie it to the pmc id
> instead of the SoC.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 37 +++++++++++++++++++++++--------------
>  1 file changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> ddf62a006635..a7c047f0d21f 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -442,31 +442,46 @@ static void __init at91_pm_sram_init(void)
>  			&at91_pm_suspend_in_sram,
> at91_pm_suspend_in_sram_sz);  }
> 
> +struct pmc_info {
> +	unsigned long uhp_udp_mask;
> +};
> +
> +static const struct pmc_info pmc_infos[] __initconst = {
> +	{ .uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP },
> +	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP },
> +	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP }, };
> +
>  static const struct of_device_id atmel_pmc_ids[] __initconst = {
> -	{ .compatible = "atmel,at91rm9200-pmc"  },
> -	{ .compatible = "atmel,at91sam9260-pmc" },
> -	{ .compatible = "atmel,at91sam9g45-pmc" },
> -	{ .compatible = "atmel,at91sam9n12-pmc" },
> -	{ .compatible = "atmel,at91sam9x5-pmc" },
> -	{ .compatible = "atmel,sama5d3-pmc" },
> -	{ .compatible = "atmel,sama5d2-pmc" },
> +	{ .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
> +	{ .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
> +	{ .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
>  	{ /* sentinel */ },
>  };
> 
>  static void __init at91_pm_init(void (*pm_idle)(void))  {
>  	struct device_node *pmc_np;
> +	const struct of_device_id *of_id;
> +	const struct pmc_info *pmc;
> 
>  	if (at91_cpuidle_device.dev.platform_data)
>  		platform_device_register(&at91_cpuidle_device);
> 
> -	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
> +	pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids,
> &of_id);
>  	pm_data.pmc = of_iomap(pmc_np, 0);
>  	if (!pm_data.pmc) {
>  		pr_err("AT91: PM not supported, PMC not found\n");
>  		return;
>  	}
> 
> +	pmc = of_id->data;
> +	pm_data.uhp_udp_mask = pmc->uhp_udp_mask;
> +
>  	if (pm_idle)
>  		arm_pm_idle = pm_idle;
> 
> @@ -487,35 +502,29 @@ void __init at91rm9200_pm_init(void)
>  	 */
>  	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
> 
> -	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> -
>  	at91_pm_init(at91rm9200_idle);
>  }
> 
>  void __init at91sam9260_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9g45_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9x5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init sama5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(NULL);
>  }
> --
> 2.11.0


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc
@ 2017-03-29  4:54     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:54 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc
> 
> The USB clocks mask (uhp_udp_mask) depends on the pmc. Tie it to the pmc id
> instead of the SoC.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 37 +++++++++++++++++++++++--------------
>  1 file changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> ddf62a006635..a7c047f0d21f 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -442,31 +442,46 @@ static void __init at91_pm_sram_init(void)
>  			&at91_pm_suspend_in_sram,
> at91_pm_suspend_in_sram_sz);  }
> 
> +struct pmc_info {
> +	unsigned long uhp_udp_mask;
> +};
> +
> +static const struct pmc_info pmc_infos[] __initconst = {
> +	{ .uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP },
> +	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP },
> +	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP }, };
> +
>  static const struct of_device_id atmel_pmc_ids[] __initconst = {
> -	{ .compatible = "atmel,at91rm9200-pmc"  },
> -	{ .compatible = "atmel,at91sam9260-pmc" },
> -	{ .compatible = "atmel,at91sam9g45-pmc" },
> -	{ .compatible = "atmel,at91sam9n12-pmc" },
> -	{ .compatible = "atmel,at91sam9x5-pmc" },
> -	{ .compatible = "atmel,sama5d3-pmc" },
> -	{ .compatible = "atmel,sama5d2-pmc" },
> +	{ .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
> +	{ .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
> +	{ .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
> +	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
>  	{ /* sentinel */ },
>  };
> 
>  static void __init at91_pm_init(void (*pm_idle)(void))  {
>  	struct device_node *pmc_np;
> +	const struct of_device_id *of_id;
> +	const struct pmc_info *pmc;
> 
>  	if (at91_cpuidle_device.dev.platform_data)
>  		platform_device_register(&at91_cpuidle_device);
> 
> -	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
> +	pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids,
> &of_id);
>  	pm_data.pmc = of_iomap(pmc_np, 0);
>  	if (!pm_data.pmc) {
>  		pr_err("AT91: PM not supported, PMC not found\n");
>  		return;
>  	}
> 
> +	pmc = of_id->data;
> +	pm_data.uhp_udp_mask = pmc->uhp_udp_mask;
> +
>  	if (pm_idle)
>  		arm_pm_idle = pm_idle;
> 
> @@ -487,35 +502,29 @@ void __init at91rm9200_pm_init(void)
>  	 */
>  	at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
> 
> -	pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP |
> AT91RM9200_PMC_UDP;
> -
>  	at91_pm_init(at91rm9200_idle);
>  }
> 
>  void __init at91sam9260_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9g45_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init at91sam9x5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(at91sam9_idle);
>  }
> 
>  void __init sama5_pm_init(void)
>  {
>  	at91_dt_ramc();
> -	pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP |
> AT91SAM926x_PMC_UDP;
>  	at91_pm_init(NULL);
>  }
> --
> 2.11.0


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:54     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:54 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init
> 
> The PM initialization is now identical for all at91sam9. Merge the functions.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/at91sam9.c | 45 +++----------------------------------------
>  arch/arm/mach-at91/generic.h  |  8 ++------
>  arch/arm/mach-at91/pm.c       | 14 +-------------
>  3 files changed, 6 insertions(+), 61 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
> index ba28e9cc584d..c089bfd0dc2f 100644
> --- a/arch/arm/mach-at91/at91sam9.c
> +++ b/arch/arm/mach-at91/at91sam9.c
> @@ -52,7 +52,7 @@ static const struct at91_soc at91sam9_socs[] = {
>  	{ /* sentinel */ },
>  };
> 
> -static void __init at91sam9_common_init(void)
> +static void __init at91sam9_init(void)
>  {
>  	struct soc_device *soc;
>  	struct device *soc_dev = NULL;
> @@ -62,12 +62,8 @@ static void __init at91sam9_common_init(void)
>  		soc_dev = soc_device_to_device(soc);
> 
>  	of_platform_default_populate(NULL, NULL, soc_dev); -}
> 
> -static void __init at91sam9_dt_device_init(void) -{
> -	at91sam9_common_init();
> -	at91sam9260_pm_init();
> +	at91sam9_pm_init();
>  }
> 
>  static const char *const at91_dt_board_compat[] __initconst = { @@ -77,41
> +73,6 @@ static const char *const at91_dt_board_compat[] __initconst = {
> 
>  DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
>  	/* Maintainer: Atmel */
> -	.init_machine	= at91sam9_dt_device_init,
> +	.init_machine	= at91sam9_init,
>  	.dt_compat	= at91_dt_board_compat,
>  MACHINE_END
> -
> -static void __init at91sam9g45_dt_device_init(void) -{
> -	at91sam9_common_init();
> -	at91sam9g45_pm_init();
> -}
> -
> -static const char *const at91sam9g45_board_compat[] __initconst = {
> -	"atmel,at91sam9g45",
> -	NULL
> -};
> -
> -DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
> -	/* Maintainer: Atmel */
> -	.init_machine	= at91sam9g45_dt_device_init,
> -	.dt_compat	= at91sam9g45_board_compat,
> -MACHINE_END
> -
> -static void __init at91sam9x5_dt_device_init(void) -{
> -	at91sam9_common_init();
> -	at91sam9x5_pm_init();
> -}
> -
> -static const char *const at91sam9x5_board_compat[] __initconst = {
> -	"atmel,at91sam9x5",
> -	"atmel,at91sam9n12",
> -	NULL
> -};
> -
> -DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
> -	/* Maintainer: Atmel */
> -	.init_machine	= at91sam9x5_dt_device_init,
> -	.dt_compat	= at91sam9x5_board_compat,
> -MACHINE_END
> diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index
> 28ca57a2060f..f1ead0f13c19 100644
> --- a/arch/arm/mach-at91/generic.h
> +++ b/arch/arm/mach-at91/generic.h
> @@ -13,15 +13,11 @@
> 
>  #ifdef CONFIG_PM
>  extern void __init at91rm9200_pm_init(void); -extern void __init
> at91sam9260_pm_init(void); -extern void __init at91sam9g45_pm_init(void); -
> extern void __init at91sam9x5_pm_init(void);
> +extern void __init at91sam9_pm_init(void);
>  extern void __init sama5_pm_init(void);  #else  static inline void __init
> at91rm9200_pm_init(void) { } -static inline void __init at91sam9260_pm_init(void)
> { } -static inline void __init at91sam9g45_pm_init(void) { } -static inline void __init
> at91sam9x5_pm_init(void) { }
> +static inline void __init at91sam9_pm_init(void) { }
>  static inline void __init sama5_pm_init(void) { }  #endif
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> a7c047f0d21f..dedfe9038336 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -505,19 +505,7 @@ void __init at91rm9200_pm_init(void)
>  	at91_pm_init(at91rm9200_idle);
>  }
> 
> -void __init at91sam9260_pm_init(void)
> -{
> -	at91_dt_ramc();
> -	at91_pm_init(at91sam9_idle);
> -}
> -
> -void __init at91sam9g45_pm_init(void)
> -{
> -	at91_dt_ramc();
> -	at91_pm_init(at91sam9_idle);
> -}
> -
> -void __init at91sam9x5_pm_init(void)
> +void __init at91sam9_pm_init(void)
>  {
>  	at91_dt_ramc();
>  	at91_pm_init(at91sam9_idle);
> --
> 2.11.0


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init
@ 2017-03-29  4:54     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:54 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init
> 
> The PM initialization is now identical for all at91sam9. Merge the functions.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/at91sam9.c | 45 +++----------------------------------------
>  arch/arm/mach-at91/generic.h  |  8 ++------
>  arch/arm/mach-at91/pm.c       | 14 +-------------
>  3 files changed, 6 insertions(+), 61 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
> index ba28e9cc584d..c089bfd0dc2f 100644
> --- a/arch/arm/mach-at91/at91sam9.c
> +++ b/arch/arm/mach-at91/at91sam9.c
> @@ -52,7 +52,7 @@ static const struct at91_soc at91sam9_socs[] = {
>  	{ /* sentinel */ },
>  };
> 
> -static void __init at91sam9_common_init(void)
> +static void __init at91sam9_init(void)
>  {
>  	struct soc_device *soc;
>  	struct device *soc_dev = NULL;
> @@ -62,12 +62,8 @@ static void __init at91sam9_common_init(void)
>  		soc_dev = soc_device_to_device(soc);
> 
>  	of_platform_default_populate(NULL, NULL, soc_dev); -}
> 
> -static void __init at91sam9_dt_device_init(void) -{
> -	at91sam9_common_init();
> -	at91sam9260_pm_init();
> +	at91sam9_pm_init();
>  }
> 
>  static const char *const at91_dt_board_compat[] __initconst = { @@ -77,41
> +73,6 @@ static const char *const at91_dt_board_compat[] __initconst = {
> 
>  DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
>  	/* Maintainer: Atmel */
> -	.init_machine	= at91sam9_dt_device_init,
> +	.init_machine	= at91sam9_init,
>  	.dt_compat	= at91_dt_board_compat,
>  MACHINE_END
> -
> -static void __init at91sam9g45_dt_device_init(void) -{
> -	at91sam9_common_init();
> -	at91sam9g45_pm_init();
> -}
> -
> -static const char *const at91sam9g45_board_compat[] __initconst = {
> -	"atmel,at91sam9g45",
> -	NULL
> -};
> -
> -DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
> -	/* Maintainer: Atmel */
> -	.init_machine	= at91sam9g45_dt_device_init,
> -	.dt_compat	= at91sam9g45_board_compat,
> -MACHINE_END
> -
> -static void __init at91sam9x5_dt_device_init(void) -{
> -	at91sam9_common_init();
> -	at91sam9x5_pm_init();
> -}
> -
> -static const char *const at91sam9x5_board_compat[] __initconst = {
> -	"atmel,at91sam9x5",
> -	"atmel,at91sam9n12",
> -	NULL
> -};
> -
> -DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
> -	/* Maintainer: Atmel */
> -	.init_machine	= at91sam9x5_dt_device_init,
> -	.dt_compat	= at91sam9x5_board_compat,
> -MACHINE_END
> diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index
> 28ca57a2060f..f1ead0f13c19 100644
> --- a/arch/arm/mach-at91/generic.h
> +++ b/arch/arm/mach-at91/generic.h
> @@ -13,15 +13,11 @@
> 
>  #ifdef CONFIG_PM
>  extern void __init at91rm9200_pm_init(void); -extern void __init
> at91sam9260_pm_init(void); -extern void __init at91sam9g45_pm_init(void); -
> extern void __init at91sam9x5_pm_init(void);
> +extern void __init at91sam9_pm_init(void);
>  extern void __init sama5_pm_init(void);  #else  static inline void __init
> at91rm9200_pm_init(void) { } -static inline void __init at91sam9260_pm_init(void)
> { } -static inline void __init at91sam9g45_pm_init(void) { } -static inline void __init
> at91sam9x5_pm_init(void) { }
> +static inline void __init at91sam9_pm_init(void) { }
>  static inline void __init sama5_pm_init(void) { }  #endif
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> a7c047f0d21f..dedfe9038336 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -505,19 +505,7 @@ void __init at91rm9200_pm_init(void)
>  	at91_pm_init(at91rm9200_idle);
>  }
> 
> -void __init at91sam9260_pm_init(void)
> -{
> -	at91_dt_ramc();
> -	at91_pm_init(at91sam9_idle);
> -}
> -
> -void __init at91sam9g45_pm_init(void)
> -{
> -	at91_dt_ramc();
> -	at91_pm_init(at91sam9_idle);
> -}
> -
> -void __init at91sam9x5_pm_init(void)
> +void __init at91sam9_pm_init(void)
>  {
>  	at91_dt_ramc();
>  	at91_pm_init(at91sam9_idle);
> --
> 2.11.0


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* RE: [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby
  2017-03-28 11:19   ` Alexandre Belloni
@ 2017-03-29  4:55     ` Wenyou.Yang at microchip.com
  -1 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang @ 2017-03-29  4:55 UTC (permalink / raw)
  To: alexandre.belloni, Nicolas.Ferre
  Cc: linux-kernel, linux-arm-kernel, boris.brezillon



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2017年3月28日 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby
> 
> Merge at91_pm_set_standby() in at91_dt_ramc as this is the only callsite.
> That moves it to the init section.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> dedfe9038336..2cd27c830ab6 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -205,12 +205,6 @@ static struct platform_device at91_cpuidle_device = {
>  	.name = "cpuidle-at91",
>  };
> 
> -static void at91_pm_set_standby(void (*at91_standby)(void)) -{
> -	if (at91_standby)
> -		at91_cpuidle_device.dev.platform_data = at91_standby;
> -}
> -
>  /*
>   * The AT91RM9200 goes into self-refresh mode with this command, and will
>   * terminate self-refresh automatically on the next SDRAM access.
> @@ -354,7 +348,7 @@ static __init void at91_dt_ramc(void)
>  	struct device_node *np;
>  	const struct of_device_id *of_id;
>  	int idx = 0;
> -	const void *standby = NULL;
> +	void *standby = NULL;
>  	const struct ramc_info *ramc;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) { @@ -378,7
> +372,7 @@ static __init void at91_dt_ramc(void)
>  		return;
>  	}
> 
> -	at91_pm_set_standby(standby);
> +	at91_cpuidle_device.dev.platform_data = standby;
>  }
> 
>  static void at91rm9200_idle(void)
> --
> 2.11.0

Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby
@ 2017-03-29  4:55     ` Wenyou.Yang at microchip.com
  0 siblings, 0 replies; 42+ messages in thread
From: Wenyou.Yang at microchip.com @ 2017-03-29  4:55 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?3?28? 19:20
> To: Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>
> Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Boris
> Brezillon <boris.brezillon@free-electrons.com>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; Alexandre Belloni <alexandre.belloni@free-
> electrons.com>
> Subject: [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby
> 
> Merge at91_pm_set_standby() in at91_dt_ramc as this is the only callsite.
> That moves it to the init section.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Acked-by: Wenyou Yang <wenyou.yang@atmel.com>

> ---
>  arch/arm/mach-at91/pm.c | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> dedfe9038336..2cd27c830ab6 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -205,12 +205,6 @@ static struct platform_device at91_cpuidle_device = {
>  	.name = "cpuidle-at91",
>  };
> 
> -static void at91_pm_set_standby(void (*at91_standby)(void)) -{
> -	if (at91_standby)
> -		at91_cpuidle_device.dev.platform_data = at91_standby;
> -}
> -
>  /*
>   * The AT91RM9200 goes into self-refresh mode with this command, and will
>   * terminate self-refresh automatically on the next SDRAM access.
> @@ -354,7 +348,7 @@ static __init void at91_dt_ramc(void)
>  	struct device_node *np;
>  	const struct of_device_id *of_id;
>  	int idx = 0;
> -	const void *standby = NULL;
> +	void *standby = NULL;
>  	const struct ramc_info *ramc;
> 
>  	for_each_matching_node_and_match(np, ramc_ids, &of_id) { @@ -378,7
> +372,7 @@ static __init void at91_dt_ramc(void)
>  		return;
>  	}
> 
> -	at91_pm_set_standby(standby);
> +	at91_cpuidle_device.dev.platform_data = standby;
>  }
> 
>  static void at91rm9200_idle(void)
> --
> 2.11.0

Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2017-03-29  5:06 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-28 11:19 [PATCH v2 00/11] ARM: at91: pm: cleanup Alexandre Belloni
2017-03-28 11:19 ` Alexandre Belloni
2017-03-28 11:19 ` [PATCH v2 01/11] ARM: at91: pm: Cleanup headers Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:49   ` Wenyou.Yang
2017-03-29  4:49     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 02/11] ARM: at91: pm: Move at91_ramc_read/write to pm.c Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:50   ` Wenyou.Yang
2017-03-29  4:50     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 03/11] ARM: at91: pm: Move global variables into at91_pm_data Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:51   ` Wenyou.Yang
2017-03-29  4:51     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 04/11] ARM: at91: pm: Use struct at91_pm_data in pm_suspend.S Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:52   ` Wenyou.Yang
2017-03-29  4:52     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 05/11] ARM: at91: pm: Simplify at91rm9200_standby Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-28 11:19 ` [PATCH v2 06/11] ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1 memories Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:53   ` Wenyou.Yang
2017-03-29  4:53     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 07/11] ARM: at91: pm: Tie the memory controller type to the ramc id Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:53   ` Wenyou.Yang
2017-03-29  4:53     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 08/11] ARM: at91: pm: Tie the USB clock mask to the pmc Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:54   ` Wenyou.Yang
2017-03-29  4:54     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 09/11] ARM: at91: pm: Merge all at91sam9*_pm_init Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:54   ` Wenyou.Yang
2017-03-29  4:54     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 10/11] ARM: at91: pm: Remove at91_pm_set_standby Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni
2017-03-29  4:55   ` Wenyou.Yang
2017-03-29  4:55     ` Wenyou.Yang at microchip.com
2017-03-28 11:19 ` [PATCH v2 11/11] ARM: at91: pm: correct typo Alexandre Belloni
2017-03-28 11:19   ` Alexandre Belloni

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.