Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1572430 > unrolled thread

[PATCH 00/13] ARM: at91; pm: cleanup

Started byAlexandre Belloni <alexandre.belloni@free-electrons.com>
First post2017-02-02 15:50 +0100
Last post2017-02-02 16:00 +0100
Articles 7 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/13] ARM: at91; pm: cleanup Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 15:50 +0100
    [PATCH 12/13] ARM: at91: pm: use C functions for standby Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 15:50 +0100
    [PATCH 10/13] ARM: at91: pm: merge all at91sam9*_pm_init Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 15:50 +0100
    [PATCH 01/13] ARM: at91: pm: cleanup headers Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
    [PATCH 04/13] ARM: at91: pm: use struct at91_pm_data in pm_suspend.S Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
    [PATCH 03/13] ARM: at91: pm: Move global variables into at91_pm_data Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
    [PATCH 02/13] ARM: at91: pm: move at91_ramc_read/write to pm.c Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100

#1572430 — [PATCH 00/13] ARM: at91; pm: cleanup

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 15:50 +0100
Subject[PATCH 00/13] ARM: at91; pm: cleanup
Message-ID<t6qRX-5if-5@gated-at.bofh.it>
Hi,

The following patch set is a cleanup of the AT91 PM code.

The main feautres is that it is now using a struct to pass arguments
between the C and the assembly code, allowing for more than 4 variables
to be passed.
It also removes instructions so it is actually faster.

The standby path is also faster now because it is only handled using C,
removing the need for a few comparisons before enabling DRAM self
refresh. This also allows to always propose standby, even when the sram
allocation failed.

Finally, the PM initialization functions are merge, removing the need
for separate paths on at91sam9*

Alexandre Belloni (13):
  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: use struct members directly
  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: use C functions for standby
  ARM: at91: pm: Allow PM even if SRAM allocation failed

 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              | 212 +++++++++++++++++------------------
 arch/arm/mach-at91/pm.h              |  27 ++---
 arch/arm/mach-at91/pm_data-offsets.c |  12 ++
 arch/arm/mach-at91/pm_suspend.S      |  55 ++-------
 7 files changed, 176 insertions(+), 216 deletions(-)
 create mode 100644 arch/arm/mach-at91/pm_data-offsets.c

-- 
2.11.0

[toc] | [next] | [standalone]


#1572431 — [PATCH 12/13] ARM: at91: pm: use C functions for standby

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 15:50 +0100
Subject[PATCH 12/13] ARM: at91: pm: use C functions for standby
Message-ID<t6qRY-5if-35@gated-at.bofh.it>
In reply to#1572430
When going to standby, there is no point calling the assembly function
at91_pm_suspend_in_sram(). It does exactly the same operations as the C
standby functions.
This allows to remove a few loads and tests in the suspend/resume path.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c              |  8 +++++---
 arch/arm/mach-at91/pm.h              |  4 +---
 arch/arm/mach-at91/pm_data-offsets.c |  1 -
 arch/arm/mach-at91/pm_suspend.S      | 14 --------------
 4 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 553bcfc5545e..1992ad8b1c3d 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -125,12 +125,13 @@ extern u32 at91_pm_suspend_in_sram_sz;
 
 static void at91_pm_suspend(suspend_state_t state)
 {
-	pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
-
 	flush_cache_all();
 	outer_disable();
 
-	at91_suspend_sram_fn(&pm_data);
+	if (state == PM_SUSPEND_MEM)
+		at91_suspend_sram_fn(&pm_data);
+	else
+		pm_data.standby();
 
 	outer_resume();
 }
@@ -342,6 +343,7 @@ static __init void at91_dt_ramc(void)
 		ramc = of_id->data;
 		if (!standby)
 			standby = ramc->standby;
+		pm_data.standby = standby;
 		pm_data.memctrl = ramc->memctrl;
 
 		idx++;
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index fc0f7d048187..2317e39248b7 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -21,15 +21,13 @@
 #define AT91_MEMCTRL_SDRAMC	1
 #define AT91_MEMCTRL_DDRSDR	2
 
-#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;
+	void (*standby)(void);
 };
 #endif
 
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
index 30302cb16df0..c4e6d648644f 100644
--- a/arch/arm/mach-at91/pm_data-offsets.c
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -8,6 +8,5 @@ int main(void)
 	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 3ee282c051e0..a8b32faaea5b 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -94,10 +94,6 @@ ENTRY(at91_pm_suspend_in_sram)
 	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
 	bl	at91_sramc_self_refresh
 
-	ldr	r0, [pm_data, #PM_DATA_MODE]
-	tst	r0, #AT91_PM_SLOW_CLOCK
-	beq	skip_disable_main_clock
-
 	ldr	pmc, [pm_data, #PM_DATA_PMC]
 
 	/* Save Master clock setting */
@@ -126,18 +122,9 @@ ENTRY(at91_pm_suspend_in_sram)
 	orr	tmp1, tmp1, #AT91_PMC_KEY
 	str	tmp1, [pmc, #AT91_CKGR_MOR]
 
-skip_disable_main_clock:
-	ldr	pmc, [pm_data, #PM_DATA_PMC]
-
 	/* Wait for interrupt */
 	at91_cpu_idle
 
-	ldr	r0, [pm_data, #PM_DATA_MODE]
-	tst	r0, #AT91_PM_SLOW_CLOCK
-	beq	skip_enable_main_clock
-
-	ldr	pmc, [pm_data, #PM_DATA_PMC]
-
 	/* Turn on the main oscillator */
 	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
 	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
@@ -166,7 +153,6 @@ skip_disable_main_clock:
 
 	wait_mckrdy
 
-skip_enable_main_clock:
 	/* Exit the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_EXIT
 	bl	at91_sramc_self_refresh
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1572432 — [PATCH 10/13] ARM: at91: pm: merge all at91sam9*_pm_init

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 15:50 +0100
Subject[PATCH 10/13] ARM: at91: pm: merge all at91sam9*_pm_init
Message-ID<t6qRY-5if-25@gated-at.bofh.it>
In reply to#1572430
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 c0ef1742135c..009b57f3a62e 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -488,19 +488,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

[toc] | [prev] | [next] | [standalone]


#1572433 — [PATCH 01/13] ARM: at91: pm: cleanup headers

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 16:00 +0100
Subject[PATCH 01/13] ARM: at91: pm: cleanup headers
Message-ID<t6r1D-5lK-1@gated-at.bofh.it>
In reply to#1572430
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 b4332b727e9c..3d28d1957e41 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

[toc] | [prev] | [next] | [standalone]


#1572435 — [PATCH 04/13] ARM: at91: pm: use struct at91_pm_data in pm_suspend.S

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 16:00 +0100
Subject[PATCH 04/13] ARM: at91: pm: use struct at91_pm_data in pm_suspend.S
Message-ID<t6r1D-5lK-7@gated-at.bofh.it>
In reply to#1572430
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 4253cd775738..90b78ad20a97 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);
 }
 
@@ -290,7 +278,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;
@@ -302,13 +290,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);
 }
 
@@ -328,8 +316,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)
@@ -355,12 +343,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();
 }
 
@@ -429,8 +417,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;
 	}
@@ -455,8 +443,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);
 }
@@ -464,31 +452,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

[toc] | [prev] | [next] | [standalone]


#1572442 — [PATCH 03/13] ARM: at91: pm: Move global variables into at91_pm_data

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 16:00 +0100
Subject[PATCH 03/13] ARM: at91: pm: Move global variables into at91_pm_data
Message-ID<t6r1E-5lK-35@gated-at.bofh.it>
In reply to#1572430
Instead of having separate global variables to hold IP dresses, 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 ca141f9873f2..4253cd775738 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;
 
-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);
 }
 
@@ -292,7 +290,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;
@@ -304,13 +302,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);
 }
 
@@ -330,8 +328,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)
@@ -357,12 +355,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();
 }
 
@@ -431,8 +429,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

[toc] | [prev] | [next] | [standalone]


#1572444 — [PATCH 02/13] ARM: at91: pm: move at91_ramc_read/write to pm.c

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-02-02 16:00 +0100
Subject[PATCH 02/13] ARM: at91: pm: move at91_ramc_read/write to pm.c
Message-ID<t6r1E-5lK-39@gated-at.bofh.it>
In reply to#1572430
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 | 10 ----------
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 3d28d1957e41..ca141f9873f2 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -45,6 +45,12 @@ static struct {
 } at91_pm_data;
 
 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 3fcf8810f14e..8eed156ef19a 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -17,16 +17,6 @@
 #include <soc/at91/at91sam9_ddrsdr.h>
 #include <soc/at91/at91sam9_sdramc.h>
 
-#ifndef __ASSEMBLY__
-extern void __iomem *at91_ramc_base[];
-
-#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

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web