aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-09-05 16:26:40 -0400
committerArnd Bergmann <arnd@arndb.de>2014-09-05 16:26:40 -0400
commit6ce041aba36c6f4702cd4f6efb7af3ceb3eb9e35 (patch)
treecac60ba1592bda6dcfede622e350e6c1337c395a
parent52addcf9d6669fa439387610bc65c92fa0980cef (diff)
parent405a72c5e78b5c560c8b2711d4000fa5eb063e1b (diff)
Merge tag 'at91-drivers' of git://github.com/at91linux/linux-at91 into next/drivers
Merge "First batch of AT91 drivers for 3.18" from Nicolas Ferre: - reset, poweroff and ram drivers are moved to their proper location instead of being in mach-at91 directory. They now use the appropriate frameworks. - big amount of removal of these machine specific drivers and use of the newly created drivers. This lead to an overhaul of the setup.c AT91 startup code. Signed-off-by: Arnd Bergmann <arnd@arndb.de> * tag 'at91-drivers' of git://github.com/at91linux/linux-at91: (31 commits) power: reset: at91-poweroff: fix wakeup status register index ARM: at91/power/reset: fix Kconfig "depends on" directive ARM: at91: fix ramc standby function registration ARM: at91: Remove rstc and shdwc headers ARM: at91: Remove rstc and shdwnc global base addresses ARM: at91/pm: Remove show_reset_status function ARM: at91: Remove poweroff code ARM: at91: Register the poweroff driver ARM: at91: Remove poweroff DT probing ARM: at91: Remove reset code from the machine code ARM: at91: Call at91_register_devices in the board files ARM: at91: Probe the reset driver ARM: at91/soc: Introduce register_devices callback ARM: at91: Remove the old-style reset probing ARM: at91: Rework ramc mapping code ARM: at91: setup: Switch to pr_fmt ARM: at91: remove old irq material ARM: at91: make use of the new AIC driver for dt enabled boards ARM: at91: enclose at91_aic_xx calls in IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks ARM: at91: introduce OLD_IRQ_AT91 Kconfig option ...
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt8
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi10
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi10
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi2
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi14
-rw-r--r--arch/arm/mach-at91/Kconfig25
-rw-r--r--arch/arm/mach-at91/Kconfig.non_dt6
-rw-r--r--arch/arm/mach-at91/Makefile5
-rw-r--r--arch/arm/mach-at91/at91_rstc.h53
-rw-r--r--arch/arm/mach-at91/at91_shdwc.h50
-rw-r--r--arch/arm/mach-at91/at91sam9260.c45
-rw-r--r--arch/arm/mach-at91/at91sam9261.c45
-rw-r--r--arch/arm/mach-at91/at91sam9263.c45
-rw-r--r--arch/arm/mach-at91/at91sam9_alt_reset.S40
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c49
-rw-r--r--arch/arm/mach-at91/at91sam9g45_reset.S45
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c45
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c2
-rw-r--r--arch/arm/mach-at91/board-cam60.c2
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c2
-rw-r--r--arch/arm/mach-at91/board-dt-rm9200.c13
-rw-r--r--arch/arm/mach-at91/board-dt-sam9.c13
-rw-r--r--arch/arm/mach-at91/board-dt-sama5.c13
-rw-r--r--arch/arm/mach-at91/board-flexibity.c2
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c2
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c3
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c3
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c3
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c3
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c3
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c2
-rw-r--r--arch/arm/mach-at91/generic.h10
-rw-r--r--arch/arm/mach-at91/irq.c270
-rw-r--r--arch/arm/mach-at91/pm.c104
-rw-r--r--arch/arm/mach-at91/setup.c183
-rw-r--r--arch/arm/mach-at91/soc.h1
-rw-r--r--drivers/clk/at91/clk-system.c8
-rw-r--r--drivers/memory/Kconfig10
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/atmel-sdramc.c98
-rw-r--r--drivers/power/reset/Kconfig33
-rw-r--r--drivers/power/reset/Makefile2
-rw-r--r--drivers/power/reset/at91-poweroff.c156
-rw-r--r--drivers/power/reset/at91-reset.c252
45 files changed, 891 insertions, 802 deletions
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index 16f60b41c147..6e3e3e5c611f 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -61,8 +61,8 @@ RAMC SDRAM/DDR Controller required properties:
61- compatible: Should be "atmel,at91rm9200-sdramc", 61- compatible: Should be "atmel,at91rm9200-sdramc",
62 "atmel,at91sam9260-sdramc", 62 "atmel,at91sam9260-sdramc",
63 "atmel,at91sam9g45-ddramc", 63 "atmel,at91sam9g45-ddramc",
64 "atmel,sama5d3-ddramc",
64- reg: Should contain registers location and length 65- reg: Should contain registers location and length
65 For at91sam9263 and at91sam9g45 you must specify 2 entries.
66 66
67Examples: 67Examples:
68 68
@@ -71,12 +71,6 @@ Examples:
71 reg = <0xffffe800 0x200>; 71 reg = <0xffffe800 0x200>;
72 }; 72 };
73 73
74 ramc0: ramc@ffffe400 {
75 compatible = "atmel,at91sam9g45-ddramc";
76 reg = <0xffffe400 0x200
77 0xffffe600 0x200>;
78 };
79
80SHDWC Shutdown Controller 74SHDWC Shutdown Controller
81 75
82required properties: 76required properties:
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index bb23c2d33cf8..840958ba556c 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -345,10 +345,14 @@
345 }; 345 };
346 }; 346 };
347 347
348 ramc: ramc@ffffe200 { 348 ramc0: ramc@ffffe200 {
349 compatible = "atmel,at91sam9260-sdramc"; 349 compatible = "atmel,at91sam9260-sdramc";
350 reg = <0xffffe200 0x200 350 reg = <0xffffe200 0x200>;
351 0xffffe800 0x200>; 351 };
352
353 ramc1: ramc@ffffe800 {
354 compatible = "atmel,at91sam9260-sdramc";
355 reg = <0xffffe800 0x200>;
352 }; 356 };
353 357
354 pit: timer@fffffd30 { 358 pit: timer@fffffd30 {
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 932a669156af..857fd3e0b8a0 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -96,8 +96,14 @@
96 96
97 ramc0: ramc@ffffe400 { 97 ramc0: ramc@ffffe400 {
98 compatible = "atmel,at91sam9g45-ddramc"; 98 compatible = "atmel,at91sam9g45-ddramc";
99 reg = <0xffffe400 0x200 99 reg = <0xffffe400 0x200>;
100 0xffffe600 0x200>; 100 clocks = <&ddrck>;
101 clock-names = "ddrck";
102 };
103
104 ramc1: ramc@ffffe600 {
105 compatible = "atmel,at91sam9g45-ddramc";
106 reg = <0xffffe600 0x200>;
101 clocks = <&ddrck>; 107 clocks = <&ddrck>;
102 clock-names = "ddrck"; 108 clock-names = "ddrck";
103 }; 109 };
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 2bfac310dbec..68eb9aded164 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -87,6 +87,8 @@
87 ramc0: ramc@ffffe800 { 87 ramc0: ramc@ffffe800 {
88 compatible = "atmel,at91sam9g45-ddramc"; 88 compatible = "atmel,at91sam9g45-ddramc";
89 reg = <0xffffe800 0x200>; 89 reg = <0xffffe800 0x200>;
90 clocks = <&ddrck>;
91 clock-names = "ddrck";
90 }; 92 };
91 93
92 pmc: pmc@fffffc00 { 94 pmc: pmc@fffffc00 {
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index e1a5c70b885c..765a1e39858e 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -95,6 +95,8 @@
95 ramc0: ramc@ffffe800 { 95 ramc0: ramc@ffffe800 {
96 compatible = "atmel,at91sam9g45-ddramc"; 96 compatible = "atmel,at91sam9g45-ddramc";
97 reg = <0xffffe800 0x200>; 97 reg = <0xffffe800 0x200>;
98 clocks = <&ddrck>;
99 clock-names = "ddrck";
98 }; 100 };
99 101
100 pmc: pmc@fffffc00 { 102 pmc: pmc@fffffc00 {
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 45013b867c8d..7702a0d120cb 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -402,8 +402,10 @@
402 }; 402 };
403 403
404 ramc0: ramc@ffffea00 { 404 ramc0: ramc@ffffea00 {
405 compatible = "atmel,at91sam9g45-ddramc"; 405 compatible = "atmel,sama5d3-ddramc";
406 reg = <0xffffea00 0x200>; 406 reg = <0xffffea00 0x200>;
407 clocks = <&ddrck>, <&mpddr_clk>;
408 clock-names = "ddrck", "mpddr";
407 }; 409 };
408 410
409 dbgu: serial@ffffee00 { 411 dbgu: serial@ffffee00 {
@@ -1170,6 +1172,11 @@
1170 #clock-cells = <0>; 1172 #clock-cells = <0>;
1171 reg = <48>; 1173 reg = <48>;
1172 }; 1174 };
1175
1176 mpddr_clk: mpddr_clk {
1177 #clock-cells = <0>;
1178 reg = <49>;
1179 };
1173 }; 1180 };
1174 }; 1181 };
1175 1182
@@ -1178,6 +1185,11 @@
1178 reg = <0xfffffe00 0x10>; 1185 reg = <0xfffffe00 0x10>;
1179 }; 1186 };
1180 1187
1188 shutdown-controller@fffffe10 {
1189 compatible = "atmel,at91sam9x5-shdwc";
1190 reg = <0xfffffe10 0x10>;
1191 };
1192
1181 pit: timer@fffffe30 { 1193 pit: timer@fffffe30 {
1182 compatible = "atmel,at91sam9260-pit"; 1194 compatible = "atmel,at91sam9260-pit";
1183 reg = <0xfffffe30 0xf>; 1195 reg = <0xfffffe30 0xf>;
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 6cc6f7aebdae..6eb3c658761d 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -28,13 +28,10 @@ config OLD_CLK_AT91
28 bool 28 bool
29 default AT91_PMC_UNIT && AT91_USE_OLD_CLK 29 default AT91_PMC_UNIT && AT91_USE_OLD_CLK
30 30
31config AT91_SAM9_ALT_RESET 31config OLD_IRQ_AT91
32 bool 32 bool
33 default !ARCH_AT91X40 33 select MULTI_IRQ_HANDLER
34 34 select SPARSE_IRQ
35config AT91_SAM9G45_RESET
36 bool
37 default !ARCH_AT91X40
38 35
39config AT91_SAM9_TIME 36config AT91_SAM9_TIME
40 bool 37 bool
@@ -45,19 +42,21 @@ config HAVE_AT91_SMD
45config SOC_AT91SAM9 42config SOC_AT91SAM9
46 bool 43 bool
47 select AT91_SAM9_TIME 44 select AT91_SAM9_TIME
45 select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
48 select CPU_ARM926T 46 select CPU_ARM926T
49 select GENERIC_CLOCKEVENTS 47 select GENERIC_CLOCKEVENTS
50 select MULTI_IRQ_HANDLER 48 select MEMORY if USE_OF
51 select SPARSE_IRQ 49 select ATMEL_SDRAMC if USE_OF
52 50
53config SOC_SAMA5 51config SOC_SAMA5
54 bool 52 bool
55 select AT91_SAM9_TIME 53 select AT91_SAM9_TIME
54 select ATMEL_AIC5_IRQ
56 select CPU_V7 55 select CPU_V7
57 select GENERIC_CLOCKEVENTS 56 select GENERIC_CLOCKEVENTS
58 select MULTI_IRQ_HANDLER
59 select SPARSE_IRQ
60 select USE_OF 57 select USE_OF
58 select MEMORY
59 select ATMEL_SDRAMC
61 60
62menu "Atmel AT91 System-on-Chip" 61menu "Atmel AT91 System-on-Chip"
63 62
@@ -70,8 +69,7 @@ config ARCH_AT91X40
70 depends on !MMU 69 depends on !MMU
71 select CPU_ARM7TDMI 70 select CPU_ARM7TDMI
72 select ARCH_USES_GETTIMEOFFSET 71 select ARCH_USES_GETTIMEOFFSET
73 select MULTI_IRQ_HANDLER 72 select OLD_IRQ_AT91
74 select SPARSE_IRQ
75 73
76 help 74 help
77 Select this if you are using one of Atmel's AT91X40 SoC. 75 Select this if you are using one of Atmel's AT91X40 SoC.
@@ -108,11 +106,10 @@ endif
108if SOC_SAM_V4_V5 106if SOC_SAM_V4_V5
109config SOC_AT91RM9200 107config SOC_AT91RM9200
110 bool "AT91RM9200" 108 bool "AT91RM9200"
109 select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
111 select CPU_ARM920T 110 select CPU_ARM920T
112 select GENERIC_CLOCKEVENTS 111 select GENERIC_CLOCKEVENTS
113 select HAVE_AT91_DBGU0 112 select HAVE_AT91_DBGU0
114 select MULTI_IRQ_HANDLER
115 select SPARSE_IRQ
116 select HAVE_AT91_USB_CLK 113 select HAVE_AT91_USB_CLK
117 114
118config SOC_AT91SAM9260 115config SOC_AT91SAM9260
diff --git a/arch/arm/mach-at91/Kconfig.non_dt b/arch/arm/mach-at91/Kconfig.non_dt
index 44ace320d2e1..b774c3d3c632 100644
--- a/arch/arm/mach-at91/Kconfig.non_dt
+++ b/arch/arm/mach-at91/Kconfig.non_dt
@@ -14,31 +14,37 @@ config ARCH_AT91RM9200
14 bool "AT91RM9200" 14 bool "AT91RM9200"
15 select SOC_AT91RM9200 15 select SOC_AT91RM9200
16 select AT91_USE_OLD_CLK 16 select AT91_USE_OLD_CLK
17 select OLD_IRQ_AT91
17 18
18config ARCH_AT91SAM9260 19config ARCH_AT91SAM9260
19 bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20" 20 bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
20 select SOC_AT91SAM9260 21 select SOC_AT91SAM9260
21 select AT91_USE_OLD_CLK 22 select AT91_USE_OLD_CLK
23 select OLD_IRQ_AT91
22 24
23config ARCH_AT91SAM9261 25config ARCH_AT91SAM9261
24 bool "AT91SAM9261 or AT91SAM9G10" 26 bool "AT91SAM9261 or AT91SAM9G10"
25 select SOC_AT91SAM9261 27 select SOC_AT91SAM9261
26 select AT91_USE_OLD_CLK 28 select AT91_USE_OLD_CLK
29 select OLD_IRQ_AT91
27 30
28config ARCH_AT91SAM9263 31config ARCH_AT91SAM9263
29 bool "AT91SAM9263" 32 bool "AT91SAM9263"
30 select SOC_AT91SAM9263 33 select SOC_AT91SAM9263
31 select AT91_USE_OLD_CLK 34 select AT91_USE_OLD_CLK
35 select OLD_IRQ_AT91
32 36
33config ARCH_AT91SAM9RL 37config ARCH_AT91SAM9RL
34 bool "AT91SAM9RL" 38 bool "AT91SAM9RL"
35 select SOC_AT91SAM9RL 39 select SOC_AT91SAM9RL
36 select AT91_USE_OLD_CLK 40 select AT91_USE_OLD_CLK
41 select OLD_IRQ_AT91
37 42
38config ARCH_AT91SAM9G45 43config ARCH_AT91SAM9G45
39 bool "AT91SAM9G45" 44 bool "AT91SAM9G45"
40 select SOC_AT91SAM9G45 45 select SOC_AT91SAM9G45
41 select AT91_USE_OLD_CLK 46 select AT91_USE_OLD_CLK
47 select OLD_IRQ_AT91
42 48
43endchoice 49endchoice
44 50
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 78e9cec282f4..306c82b3d45c 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,14 +2,13 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5obj-y := irq.o gpio.o setup.o sysirq_mask.o 5obj-y := gpio.o setup.o sysirq_mask.o
6obj-m := 6obj-m :=
7obj-n := 7obj-n :=
8obj- := 8obj- :=
9 9
10obj-$(CONFIG_OLD_IRQ_AT91) += irq.o
10obj-$(CONFIG_OLD_CLK_AT91) += clock.o 11obj-$(CONFIG_OLD_CLK_AT91) += clock.o
11obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
12obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
13obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o 12obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o
14obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o 13obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
15 14
diff --git a/arch/arm/mach-at91/at91_rstc.h b/arch/arm/mach-at91/at91_rstc.h
deleted file mode 100644
index a600e6992920..000000000000
--- a/arch/arm/mach-at91/at91_rstc.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * arch/arm/mach-at91/include/mach/at91_rstc.h
3 *
4 * Copyright (C) 2007 Andrew Victor
5 * Copyright (C) 2007 Atmel Corporation.
6 *
7 * Reset Controller (RSTC) - System peripherals regsters.
8 * Based on AT91SAM9261 datasheet revision D.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_RSTC_H
17#define AT91_RSTC_H
18
19#ifndef __ASSEMBLY__
20extern void __iomem *at91_rstc_base;
21
22#define at91_rstc_read(field) \
23 __raw_readl(at91_rstc_base + field)
24
25#define at91_rstc_write(field, value) \
26 __raw_writel(value, at91_rstc_base + field)
27#else
28.extern at91_rstc_base
29#endif
30
31#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
32#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
33#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
34#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
35#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
36
37#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
38#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
39#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */
40#define AT91_RSTC_RSTTYP_GENERAL (0 << 8)
41#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8)
42#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8)
43#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8)
44#define AT91_RSTC_RSTTYP_USER (4 << 8)
45#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */
46#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */
47
48#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
49#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
50#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
51#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
52
53#endif
diff --git a/arch/arm/mach-at91/at91_shdwc.h b/arch/arm/mach-at91/at91_shdwc.h
deleted file mode 100644
index 9e29f31ec9a6..000000000000
--- a/arch/arm/mach-at91/at91_shdwc.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * arch/arm/mach-at91/include/mach/at91_shdwc.h
3 *
4 * Copyright (C) 2007 Andrew Victor
5 * Copyright (C) 2007 Atmel Corporation.
6 *
7 * Shutdown Controller (SHDWC) - System peripherals regsters.
8 * Based on AT91SAM9261 datasheet revision D.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_SHDWC_H
17#define AT91_SHDWC_H
18
19#ifndef __ASSEMBLY__
20extern void __iomem *at91_shdwc_base;
21
22#define at91_shdwc_read(field) \
23 __raw_readl(at91_shdwc_base + field)
24
25#define at91_shdwc_write(field, value) \
26 __raw_writel(value, at91_shdwc_base + field)
27#endif
28
29#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
30#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */
31#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
32
33#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
34#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */
35#define AT91_SHDW_WKMODE0_NONE 0
36#define AT91_SHDW_WKMODE0_HIGH 1
37#define AT91_SHDW_WKMODE0_LOW 2
38#define AT91_SHDW_WKMODE0_ANYLEVEL 3
39#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
40#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
41#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
42#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
43#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */
44
45#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
46#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
47#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */
48#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */
49
50#endif
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 3477ba94c4c5..b6948d677ca9 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h>
14#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
15 16
16#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
@@ -24,7 +25,6 @@
24#include <mach/hardware.h> 25#include <mach/hardware.h>
25 26
26#include "at91_aic.h" 27#include "at91_aic.h"
27#include "at91_rstc.h"
28#include "soc.h" 28#include "soc.h"
29#include "generic.h" 29#include "generic.h"
30#include "sam9_smc.h" 30#include "sam9_smc.h"
@@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void)
342 342
343static void __init at91sam9260_ioremap_registers(void) 343static void __init at91sam9260_ioremap_registers(void)
344{ 344{
345 at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
346 at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
347 at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512); 345 at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512);
348 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); 346 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
349 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); 347 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
@@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void)
354static void __init at91sam9260_initialize(void) 352static void __init at91sam9260_initialize(void)
355{ 353{
356 arm_pm_idle = at91sam9_idle; 354 arm_pm_idle = at91sam9_idle;
357 arm_pm_restart = at91sam9_alt_restart;
358 355
359 at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT); 356 at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
360 357
@@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void)
362 at91_gpio_init(at91sam9260_gpio, 3); 359 at91_gpio_init(at91sam9260_gpio, 3);
363} 360}
364 361
362static struct resource rstc_resources[] = {
363 [0] = {
364 .start = AT91SAM9260_BASE_RSTC,
365 .end = AT91SAM9260_BASE_RSTC + SZ_16 - 1,
366 .flags = IORESOURCE_MEM,
367 },
368 [1] = {
369 .start = AT91SAM9260_BASE_SDRAMC,
370 .end = AT91SAM9260_BASE_SDRAMC + SZ_512 - 1,
371 .flags = IORESOURCE_MEM,
372 },
373};
374
375static struct platform_device rstc_device = {
376 .name = "at91-sam9260-reset",
377 .resource = rstc_resources,
378 .num_resources = ARRAY_SIZE(rstc_resources),
379};
380
381static struct resource shdwc_resources[] = {
382 [0] = {
383 .start = AT91SAM9260_BASE_SHDWC,
384 .end = AT91SAM9260_BASE_SHDWC + SZ_16 - 1,
385 .flags = IORESOURCE_MEM,
386 },
387};
388
389static struct platform_device shdwc_device = {
390 .name = "at91-poweroff",
391 .resource = shdwc_resources,
392 .num_resources = ARRAY_SIZE(shdwc_resources),
393};
394
395static void __init at91sam9260_register_devices(void)
396{
397 platform_device_register(&rstc_device);
398 platform_device_register(&shdwc_device);
399}
400
365/* -------------------------------------------------------------------- 401/* --------------------------------------------------------------------
366 * Interrupt initialization 402 * Interrupt initialization
367 * -------------------------------------------------------------------- */ 403 * -------------------------------------------------------------------- */
@@ -411,5 +447,6 @@ AT91_SOC_START(at91sam9260)
411 | (1 << AT91SAM9260_ID_IRQ2), 447 | (1 << AT91SAM9260_ID_IRQ2),
412 .ioremap_registers = at91sam9260_ioremap_registers, 448 .ioremap_registers = at91sam9260_ioremap_registers,
413 .register_clocks = at91sam9260_register_clocks, 449 .register_clocks = at91sam9260_register_clocks,
450 .register_devices = at91sam9260_register_devices,
414 .init = at91sam9260_initialize, 451 .init = at91sam9260_initialize,
415AT91_SOC_END 452AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index fb164a5d04a9..c07339e370ee 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h>
14#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
15 16
16#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
@@ -23,7 +24,6 @@
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24 25
25#include "at91_aic.h" 26#include "at91_aic.h"
26#include "at91_rstc.h"
27#include "soc.h" 27#include "soc.h"
28#include "generic.h" 28#include "generic.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
@@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void)
301 301
302static void __init at91sam9261_ioremap_registers(void) 302static void __init at91sam9261_ioremap_registers(void)
303{ 303{
304 at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
305 at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
306 at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512); 304 at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
307 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); 305 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
308 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); 306 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
@@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void)
313static void __init at91sam9261_initialize(void) 311static void __init at91sam9261_initialize(void)
314{ 312{
315 arm_pm_idle = at91sam9_idle; 313 arm_pm_idle = at91sam9_idle;
316 arm_pm_restart = at91sam9_alt_restart;
317 314
318 at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT); 315 at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
319 316
@@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void)
321 at91_gpio_init(at91sam9261_gpio, 3); 318 at91_gpio_init(at91sam9261_gpio, 3);
322} 319}
323 320
321static struct resource rstc_resources[] = {
322 [0] = {
323 .start = AT91SAM9261_BASE_RSTC,
324 .end = AT91SAM9261_BASE_RSTC + SZ_16 - 1,
325 .flags = IORESOURCE_MEM,
326 },
327 [1] = {
328 .start = AT91SAM9261_BASE_SDRAMC,
329 .end = AT91SAM9261_BASE_SDRAMC + SZ_512 - 1,
330 .flags = IORESOURCE_MEM,
331 },
332};
333
334static struct platform_device rstc_device = {
335 .name = "at91-sam9260-reset",
336 .resource = rstc_resources,
337 .num_resources = ARRAY_SIZE(rstc_resources),
338};
339
340static struct resource shdwc_resources[] = {
341 [0] = {
342 .start = AT91SAM9261_BASE_SHDWC,
343 .end = AT91SAM9261_BASE_SHDWC + SZ_16 - 1,
344 .flags = IORESOURCE_MEM,
345 },
346};
347
348static struct platform_device shdwc_device = {
349 .name = "at91-poweroff",
350 .resource = shdwc_resources,
351 .num_resources = ARRAY_SIZE(shdwc_resources),
352};
353
354static void __init at91sam9261_register_devices(void)
355{
356 platform_device_register(&rstc_device);
357 platform_device_register(&shdwc_device);
358}
359
324/* -------------------------------------------------------------------- 360/* --------------------------------------------------------------------
325 * Interrupt initialization 361 * Interrupt initialization
326 * -------------------------------------------------------------------- */ 362 * -------------------------------------------------------------------- */
@@ -370,5 +406,6 @@ AT91_SOC_START(at91sam9261)
370 | (1 << AT91SAM9261_ID_IRQ2), 406 | (1 << AT91SAM9261_ID_IRQ2),
371 .ioremap_registers = at91sam9261_ioremap_registers, 407 .ioremap_registers = at91sam9261_ioremap_registers,
372 .register_clocks = at91sam9261_register_clocks, 408 .register_clocks = at91sam9261_register_clocks,
409 .register_devices = at91sam9261_register_devices,
373 .init = at91sam9261_initialize, 410 .init = at91sam9261_initialize,
374AT91_SOC_END 411AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 810fa5f15a51..33ab06ec5365 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h>
14#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
15 16
16#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
@@ -22,7 +23,6 @@
22#include <mach/hardware.h> 23#include <mach/hardware.h>
23 24
24#include "at91_aic.h" 25#include "at91_aic.h"
25#include "at91_rstc.h"
26#include "soc.h" 26#include "soc.h"
27#include "generic.h" 27#include "generic.h"
28#include "sam9_smc.h" 28#include "sam9_smc.h"
@@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void)
321 321
322static void __init at91sam9263_ioremap_registers(void) 322static void __init at91sam9263_ioremap_registers(void)
323{ 323{
324 at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
325 at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
326 at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512); 324 at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512);
327 at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); 325 at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512);
328 at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); 326 at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
@@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void)
335static void __init at91sam9263_initialize(void) 333static void __init at91sam9263_initialize(void)
336{ 334{
337 arm_pm_idle = at91sam9_idle; 335 arm_pm_idle = at91sam9_idle;
338 arm_pm_restart = at91sam9_alt_restart;
339 336
340 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0); 337 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
341 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1); 338 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
@@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void)
344 at91_gpio_init(at91sam9263_gpio, 5); 341 at91_gpio_init(at91sam9263_gpio, 5);
345} 342}
346 343
344static struct resource rstc_resources[] = {
345 [0] = {
346 .start = AT91SAM9263_BASE_RSTC,
347 .end = AT91SAM9263_BASE_RSTC + SZ_16 - 1,
348 .flags = IORESOURCE_MEM,
349 },
350 [1] = {
351 .start = AT91SAM9263_BASE_SDRAMC0,
352 .end = AT91SAM9263_BASE_SDRAMC0 + SZ_512 - 1,
353 .flags = IORESOURCE_MEM,
354 },
355};
356
357static struct platform_device rstc_device = {
358 .name = "at91-sam9260-reset",
359 .resource = rstc_resources,
360 .num_resources = ARRAY_SIZE(rstc_resources),
361};
362
363static struct resource shdwc_resources[] = {
364 [0] = {
365 .start = AT91SAM9263_BASE_SHDWC,
366 .end = AT91SAM9263_BASE_SHDWC + SZ_16 - 1,
367 .flags = IORESOURCE_MEM,
368 },
369};
370
371static struct platform_device shdwc_device = {
372 .name = "at91-poweroff",
373 .resource = shdwc_resources,
374 .num_resources = ARRAY_SIZE(shdwc_resources),
375};
376
377static void __init at91sam9263_register_devices(void)
378{
379 platform_device_register(&rstc_device);
380 platform_device_register(&shdwc_device);
381}
382
347/* -------------------------------------------------------------------- 383/* --------------------------------------------------------------------
348 * Interrupt initialization 384 * Interrupt initialization
349 * -------------------------------------------------------------------- */ 385 * -------------------------------------------------------------------- */
@@ -392,5 +428,6 @@ AT91_SOC_START(at91sam9263)
392 .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1), 428 .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1),
393 .ioremap_registers = at91sam9263_ioremap_registers, 429 .ioremap_registers = at91sam9263_ioremap_registers,
394 .register_clocks = at91sam9263_register_clocks, 430 .register_clocks = at91sam9263_register_clocks,
431 .register_devices = at91sam9263_register_devices,
395 .init = at91sam9263_initialize, 432 .init = at91sam9263_initialize,
396AT91_SOC_END 433AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S
deleted file mode 100644
index f039538d3bdb..000000000000
--- a/arch/arm/mach-at91/at91sam9_alt_reset.S
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * reset AT91SAM9G20 as per errata
3 *
4 * (C) BitBox Ltd 2010
5 *
6 * unless the SDRAM is cleanly shutdown before we hit the
7 * reset register it can be left driving the data bus and
8 * killing the chance of a subsequent boot from NAND
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#include <linux/linkage.h>
17#include <mach/hardware.h>
18#include <mach/at91_ramc.h>
19#include "at91_rstc.h"
20
21 .arm
22
23 .globl at91sam9_alt_restart
24
25at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants
26 ldr r0, [r0]
27 ldr r4, =at91_rstc_base
28 ldr r1, [r4]
29
30 mov r2, #1
31 mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
32 ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
33
34 .balign 32 @ align to cache line
35
36 str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
37 str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
38 str r4, [r1, #AT91_RSTC_CR] @ reset processor
39
40 b .
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 9d45496e4932..7a329703f31a 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
16#include <linux/platform_device.h>
16 17
17#include <asm/irq.h> 18#include <asm/irq.h>
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
@@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void)
371 372
372static void __init at91sam9g45_ioremap_registers(void) 373static void __init at91sam9g45_ioremap_registers(void)
373{ 374{
374 at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
375 at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
376 at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512); 375 at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512);
377 at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); 376 at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512);
378 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); 377 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
@@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void)
384static void __init at91sam9g45_initialize(void) 383static void __init at91sam9g45_initialize(void)
385{ 384{
386 arm_pm_idle = at91sam9_idle; 385 arm_pm_idle = at91sam9_idle;
387 arm_pm_restart = at91sam9g45_restart;
388 386
389 at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC); 387 at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
390 at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT); 388 at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
@@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void)
393 at91_gpio_init(at91sam9g45_gpio, 5); 391 at91_gpio_init(at91sam9g45_gpio, 5);
394} 392}
395 393
394static struct resource rstc_resources[] = {
395 [0] = {
396 .start = AT91SAM9G45_BASE_RSTC,
397 .end = AT91SAM9G45_BASE_RSTC + SZ_16 - 1,
398 .flags = IORESOURCE_MEM,
399 },
400 [1] = {
401 .start = AT91SAM9G45_BASE_DDRSDRC1,
402 .end = AT91SAM9G45_BASE_DDRSDRC1 + SZ_512 - 1,
403 .flags = IORESOURCE_MEM,
404 },
405 [2] = {
406 .start = AT91SAM9G45_BASE_DDRSDRC0,
407 .end = AT91SAM9G45_BASE_DDRSDRC0 + SZ_512 - 1,
408 .flags = IORESOURCE_MEM,
409 },
410};
411
412static struct platform_device rstc_device = {
413 .name = "at91-sam9g45-reset",
414 .resource = rstc_resources,
415 .num_resources = ARRAY_SIZE(rstc_resources),
416};
417
418static struct resource shdwc_resources[] = {
419 [0] = {
420 .start = AT91SAM9G45_BASE_SHDWC,
421 .end = AT91SAM9G45_BASE_SHDWC + SZ_16 - 1,
422 .flags = IORESOURCE_MEM,
423 },
424};
425
426static struct platform_device shdwc_device = {
427 .name = "at91-poweroff",
428 .resource = shdwc_resources,
429 .num_resources = ARRAY_SIZE(shdwc_resources),
430};
431
432static void __init at91sam9g45_register_devices(void)
433{
434 platform_device_register(&rstc_device);
435 platform_device_register(&shdwc_device);
436}
437
396/* -------------------------------------------------------------------- 438/* --------------------------------------------------------------------
397 * Interrupt initialization 439 * Interrupt initialization
398 * -------------------------------------------------------------------- */ 440 * -------------------------------------------------------------------- */
@@ -441,5 +483,6 @@ AT91_SOC_START(at91sam9g45)
441 .extern_irq = (1 << AT91SAM9G45_ID_IRQ0), 483 .extern_irq = (1 << AT91SAM9G45_ID_IRQ0),
442 .ioremap_registers = at91sam9g45_ioremap_registers, 484 .ioremap_registers = at91sam9g45_ioremap_registers,
443 .register_clocks = at91sam9g45_register_clocks, 485 .register_clocks = at91sam9g45_register_clocks,
486 .register_devices = at91sam9g45_register_devices,
444 .init = at91sam9g45_initialize, 487 .init = at91sam9g45_initialize,
445AT91_SOC_END 488AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
deleted file mode 100644
index c40c1e2ef80f..000000000000
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * reset AT91SAM9G45 as per errata
3 *
4 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
5 *
6 * unless the SDRAM is cleanly shutdown before we hit the
7 * reset register it can be left driving the data bus and
8 * killing the chance of a subsequent boot from NAND
9 *
10 * GPLv2 Only
11 */
12
13#include <linux/linkage.h>
14#include <mach/hardware.h>
15#include <mach/at91_ramc.h>
16#include "at91_rstc.h"
17 .arm
18
19/*
20 * at91_ramc_base is an array void*
21 * init at NULL if only one DDR controler is present in or DT
22 */
23 .globl at91sam9g45_restart
24
25at91sam9g45_restart:
26 ldr r5, =at91_ramc_base @ preload constants
27 ldr r0, [r5]
28 ldr r5, [r5, #4] @ ddr1
29 cmp r5, #0
30 ldr r4, =at91_rstc_base
31 ldr r1, [r4]
32
33 mov r2, #1
34 mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
35 ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
36
37 .balign 32 @ align to cache line
38
39 strne r2, [r5, #AT91_DDRSDRC_RTR] @ disable DDR1 access
40 strne r3, [r5, #AT91_DDRSDRC_LPR] @ power down DDR1
41 str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access
42 str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0
43 str r4, [r1, #AT91_RSTC_CR] @ reset processor
44
45 b .
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 878d5015daab..264999f33594 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h>
13#include <linux/clk/at91_pmc.h> 14#include <linux/clk/at91_pmc.h>
14 15
15#include <asm/proc-fns.h> 16#include <asm/proc-fns.h>
@@ -23,7 +24,6 @@
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24 25
25#include "at91_aic.h" 26#include "at91_aic.h"
26#include "at91_rstc.h"
27#include "soc.h" 27#include "soc.h"
28#include "generic.h" 28#include "generic.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
@@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void)
311 311
312static void __init at91sam9rl_ioremap_registers(void) 312static void __init at91sam9rl_ioremap_registers(void)
313{ 313{
314 at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
315 at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
316 at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512); 314 at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512);
317 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); 315 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
318 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); 316 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
@@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void)
323static void __init at91sam9rl_initialize(void) 321static void __init at91sam9rl_initialize(void)
324{ 322{
325 arm_pm_idle = at91sam9_idle; 323 arm_pm_idle = at91sam9_idle;
326 arm_pm_restart = at91sam9_alt_restart;
327 324
328 at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC); 325 at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
329 at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT); 326 at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
@@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void)
332 at91_gpio_init(at91sam9rl_gpio, 4); 329 at91_gpio_init(at91sam9rl_gpio, 4);
333} 330}
334 331
332static struct resource rstc_resources[] = {
333 [0] = {
334 .start = AT91SAM9RL_BASE_RSTC,
335 .end = AT91SAM9RL_BASE_RSTC + SZ_16 - 1,
336 .flags = IORESOURCE_MEM,
337 },
338 [1] = {
339 .start = AT91SAM9RL_BASE_SDRAMC,
340 .end = AT91SAM9RL_BASE_SDRAMC + SZ_512 - 1,
341 .flags = IORESOURCE_MEM,
342 },
343};
344
345static struct platform_device rstc_device = {
346 .name = "at91-sam9260-reset",
347 .resource = rstc_resources,
348 .num_resources = ARRAY_SIZE(rstc_resources),
349};
350
351static struct resource shdwc_resources[] = {
352 [0] = {
353 .start = AT91SAM9RL_BASE_SHDWC,
354 .end = AT91SAM9RL_BASE_SHDWC + SZ_16 - 1,
355 .flags = IORESOURCE_MEM,
356 },
357};
358
359static struct platform_device shdwc_device = {
360 .name = "at91-poweroff",
361 .resource = shdwc_resources,
362 .num_resources = ARRAY_SIZE(shdwc_resources),
363};
364
365static void __init at91sam9rl_register_devices(void)
366{
367 platform_device_register(&rstc_device);
368 platform_device_register(&shdwc_device);
369}
370
335/* -------------------------------------------------------------------- 371/* --------------------------------------------------------------------
336 * Interrupt initialization 372 * Interrupt initialization
337 * -------------------------------------------------------------------- */ 373 * -------------------------------------------------------------------- */
@@ -382,5 +418,6 @@ AT91_SOC_START(at91sam9rl)
382#if defined(CONFIG_OLD_CLK_AT91) 418#if defined(CONFIG_OLD_CLK_AT91)
383 .register_clocks = at91sam9rl_register_clocks, 419 .register_clocks = at91sam9rl_register_clocks,
384#endif 420#endif
421 .register_devices = at91sam9rl_register_devices,
385 .init = at91sam9rl_initialize, 422 .init = at91sam9rl_initialize,
386AT91_SOC_END 423AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 597c649170aa..fc9621ccb606 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = {
167 167
168static void __init afeb9260_board_init(void) 168static void __init afeb9260_board_init(void)
169{ 169{
170 at91_register_devices();
171
170 /* Serial */ 172 /* Serial */
171 /* DBGU on ttyS0. (Rx & Tx only) */ 173 /* DBGU on ttyS0. (Rx & Tx only) */
172 at91_register_uart(0, 0, 0); 174 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
index a30502c8d379..283655bd86c1 100644
--- a/arch/arm/mach-at91/board-cam60.c
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void)
170 170
171static void __init cam60_board_init(void) 171static void __init cam60_board_init(void)
172{ 172{
173 at91_register_devices();
174
173 /* Serial */ 175 /* Serial */
174 /* DBGU on ttyS0. (Rx & Tx only) */ 176 /* DBGU on ttyS0. (Rx & Tx only) */
175 at91_register_uart(0, 0, 0); 177 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
index 2037f78c84e7..29a89032bb9a 100644
--- a/arch/arm/mach-at91/board-cpu9krea.c
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = {
322 322
323static void __init cpu9krea_board_init(void) 323static void __init cpu9krea_board_init(void)
324{ 324{
325 at91_register_devices();
326
325 /* NOR */ 327 /* NOR */
326 cpu9krea_add_device_nor(); 328 cpu9krea_add_device_nor();
327 /* Serial */ 329 /* Serial */
diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c
index 3a185faee795..61ea21445664 100644
--- a/arch/arm/mach-at91/board-dt-rm9200.c
+++ b/arch/arm/mach-at91/board-dt-rm9200.c
@@ -24,17 +24,6 @@
24#include "at91_aic.h" 24#include "at91_aic.h"
25#include "generic.h" 25#include "generic.h"
26 26
27
28static const struct of_device_id irq_of_match[] __initconst = {
29 { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
30 { /*sentinel*/ }
31};
32
33static void __init at91rm9200_dt_init_irq(void)
34{
35 of_irq_init(irq_of_match);
36}
37
38static const char *at91rm9200_dt_board_compat[] __initdata = { 27static const char *at91rm9200_dt_board_compat[] __initdata = {
39 "atmel,at91rm9200", 28 "atmel,at91rm9200",
40 NULL 29 NULL
@@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = {
43DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") 32DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
44 .init_time = at91rm9200_timer_init, 33 .init_time = at91rm9200_timer_init,
45 .map_io = at91_map_io, 34 .map_io = at91_map_io,
46 .handle_irq = at91_aic_handle_irq,
47 .init_early = at91rm9200_dt_initialize, 35 .init_early = at91rm9200_dt_initialize,
48 .init_irq = at91rm9200_dt_init_irq,
49 .dt_compat = at91rm9200_dt_board_compat, 36 .dt_compat = at91rm9200_dt_board_compat,
50MACHINE_END 37MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c
index 575b0be66ca8..dfa8d48146fe 100644
--- a/arch/arm/mach-at91/board-dt-sam9.c
+++ b/arch/arm/mach-at91/board-dt-sam9.c
@@ -34,17 +34,6 @@ static void __init sam9_dt_timer_init(void)
34 at91sam926x_pit_init(); 34 at91sam926x_pit_init();
35} 35}
36 36
37static const struct of_device_id irq_of_match[] __initconst = {
38
39 { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
40 { /*sentinel*/ }
41};
42
43static void __init at91_dt_init_irq(void)
44{
45 of_irq_init(irq_of_match);
46}
47
48static const char *at91_dt_board_compat[] __initdata = { 37static const char *at91_dt_board_compat[] __initdata = {
49 "atmel,at91sam9", 38 "atmel,at91sam9",
50 NULL 39 NULL
@@ -54,8 +43,6 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
54 /* Maintainer: Atmel */ 43 /* Maintainer: Atmel */
55 .init_time = sam9_dt_timer_init, 44 .init_time = sam9_dt_timer_init,
56 .map_io = at91_map_io, 45 .map_io = at91_map_io,
57 .handle_irq = at91_aic_handle_irq,
58 .init_early = at91_dt_initialize, 46 .init_early = at91_dt_initialize,
59 .init_irq = at91_dt_init_irq,
60 .dt_compat = at91_dt_board_compat, 47 .dt_compat = at91_dt_board_compat,
61MACHINE_END 48MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c
index 075ec0576ada..d6fe04bcaabd 100644
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ b/arch/arm/mach-at91/board-dt-sama5.c
@@ -35,17 +35,6 @@ static void __init sama5_dt_timer_init(void)
35 at91sam926x_pit_init(); 35 at91sam926x_pit_init();
36} 36}
37 37
38static const struct of_device_id irq_of_match[] __initconst = {
39
40 { .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init },
41 { /*sentinel*/ }
42};
43
44static void __init at91_dt_init_irq(void)
45{
46 of_irq_init(irq_of_match);
47}
48
49static int ksz9021rn_phy_fixup(struct phy_device *phy) 38static int ksz9021rn_phy_fixup(struct phy_device *phy)
50{ 39{
51 int value; 40 int value;
@@ -82,9 +71,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
82 /* Maintainer: Atmel */ 71 /* Maintainer: Atmel */
83 .init_time = sama5_dt_timer_init, 72 .init_time = sama5_dt_timer_init,
84 .map_io = at91_map_io, 73 .map_io = at91_map_io,
85 .handle_irq = at91_aic5_handle_irq,
86 .init_early = at91_dt_initialize, 74 .init_early = at91_dt_initialize,
87 .init_irq = at91_dt_init_irq,
88 .init_machine = sama5_dt_device_init, 75 .init_machine = sama5_dt_device_init,
89 .dt_compat = sama5_dt_board_compat, 76 .dt_compat = sama5_dt_board_compat,
90MACHINE_END 77MACHINE_END
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
index 68f1ab6bd08f..79bd411b0cee 100644
--- a/arch/arm/mach-at91/board-flexibity.c
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = {
138 138
139static void __init flexibity_board_init(void) 139static void __init flexibity_board_init(void)
140{ 140{
141 at91_register_devices();
142
141 /* Serial */ 143 /* Serial */
142 /* DBGU on ttyS0. (Rx & Tx only) */ 144 /* DBGU on ttyS0. (Rx & Tx only) */
143 at91_register_uart(0, 0, 0); 145 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
index d24dda67e2d3..70309404f366 100644
--- a/arch/arm/mach-at91/board-sam9-l9260.c
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = {
187 187
188static void __init ek_board_init(void) 188static void __init ek_board_init(void)
189{ 189{
190 at91_register_devices();
191
190 /* Serial */ 192 /* Serial */
191 /* DBGU on ttyS0. (Rx & Tx only) */ 193 /* DBGU on ttyS0. (Rx & Tx only) */
192 at91_register_uart(0, 0, 0); 194 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 65dea12d685e..18f49c93f3f3 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -45,7 +45,6 @@
45#include <mach/system_rev.h> 45#include <mach/system_rev.h>
46 46
47#include "at91_aic.h" 47#include "at91_aic.h"
48#include "at91_shdwc.h"
49#include "board.h" 48#include "board.h"
50#include "sam9_smc.h" 49#include "sam9_smc.h"
51#include "generic.h" 50#include "generic.h"
@@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {}
307 306
308static void __init ek_board_init(void) 307static void __init ek_board_init(void)
309{ 308{
309 at91_register_devices();
310
310 /* Serial */ 311 /* Serial */
311 /* DBGU on ttyS0. (Rx & Tx only) */ 312 /* DBGU on ttyS0. (Rx & Tx only) */
312 at91_register_uart(0, 0, 0); 313 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 4637432de08f..5a23e7211203 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -49,7 +49,6 @@
49#include <mach/system_rev.h> 49#include <mach/system_rev.h>
50 50
51#include "at91_aic.h" 51#include "at91_aic.h"
52#include "at91_shdwc.h"
53#include "board.h" 52#include "board.h"
54#include "sam9_smc.h" 53#include "sam9_smc.h"
55#include "generic.h" 54#include "generic.h"
@@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = {
561 560
562static void __init ek_board_init(void) 561static void __init ek_board_init(void)
563{ 562{
563 at91_register_devices();
564
564 /* Serial */ 565 /* Serial */
565 /* DBGU on ttyS0. (Rx & Tx only) */ 566 /* DBGU on ttyS0. (Rx & Tx only) */
566 at91_register_uart(0, 0, 0); 567 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index fc446097f410..e8685652a73e 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -50,7 +50,6 @@
50#include <mach/system_rev.h> 50#include <mach/system_rev.h>
51 51
52#include "at91_aic.h" 52#include "at91_aic.h"
53#include "at91_shdwc.h"
54#include "board.h" 53#include "board.h"
55#include "sam9_smc.h" 54#include "sam9_smc.h"
56#include "generic.h" 55#include "generic.h"
@@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = {
439 438
440static void __init ek_board_init(void) 439static void __init ek_board_init(void)
441{ 440{
441 at91_register_devices();
442
442 /* Serial */ 443 /* Serial */
443 /* DBGU on ttyS0. (Rx & Tx only) */ 444 /* DBGU on ttyS0. (Rx & Tx only) */
444 at91_register_uart(0, 0, 0); 445 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index b227732b0c83..0fc4bea272ea 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -48,7 +48,6 @@
48#include <mach/system_rev.h> 48#include <mach/system_rev.h>
49 49
50#include "at91_aic.h" 50#include "at91_aic.h"
51#include "at91_shdwc.h"
52#include "board.h" 51#include "board.h"
53#include "sam9_smc.h" 52#include "sam9_smc.h"
54#include "generic.h" 53#include "generic.h"
@@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = {
471 470
472static void __init ek_board_init(void) 471static void __init ek_board_init(void)
473{ 472{
473 at91_register_devices();
474
474 /* Serial */ 475 /* Serial */
475 /* DGBU on ttyS0. (Rx & Tx only) */ 476 /* DGBU on ttyS0. (Rx & Tx only) */
476 at91_register_uart(0, 0, 0); 477 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index b64648b4a1fc..5cb82464be1a 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -35,7 +35,6 @@
35 35
36 36
37#include "at91_aic.h" 37#include "at91_aic.h"
38#include "at91_shdwc.h"
39#include "board.h" 38#include "board.h"
40#include "sam9_smc.h" 39#include "sam9_smc.h"
41#include "generic.h" 40#include "generic.h"
@@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {}
292 291
293static void __init ek_board_init(void) 292static void __init ek_board_init(void)
294{ 293{
294 at91_register_devices();
295
295 /* Serial */ 296 /* Serial */
296 /* DBGU on ttyS0. (Rx & Tx only) */ 297 /* DBGU on ttyS0. (Rx & Tx only) */
297 at91_register_uart(0, 0, 0); 298 at91_register_uart(0, 0, 0);
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
index 1b870e6def0c..2a817b85569f 100644
--- a/arch/arm/mach-at91/board-snapper9260.c
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void)
154 154
155static void __init snapper9260_board_init(void) 155static void __init snapper9260_board_init(void)
156{ 156{
157 at91_register_devices();
158
157 at91_add_device_i2c(snapper9260_i2c_devices, 159 at91_add_device_i2c(snapper9260_i2c_devices,
158 ARRAY_SIZE(snapper9260_i2c_devices)); 160 ARRAY_SIZE(snapper9260_i2c_devices));
159 161
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 631fa3b8c16d..f42b0490ad98 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -37,6 +37,8 @@ extern int __init at91_aic5_of_init(struct device_node *node,
37extern void __init at91_sysirq_mask_rtc(u32 rtc_base); 37extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
38extern void __init at91_sysirq_mask_rtt(u32 rtt_base); 38extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
39 39
40 /* Devices */
41extern void __init at91_register_devices(void);
40 42
41 /* Timer */ 43 /* Timer */
42extern void at91rm9200_ioremap_st(u32 addr); 44extern void at91rm9200_ioremap_st(u32 addr);
@@ -62,14 +64,6 @@ extern void at91_irq_resume(void);
62/* idle */ 64/* idle */
63extern void at91sam9_idle(void); 65extern void at91sam9_idle(void);
64 66
65/* reset */
66extern void at91_ioremap_rstc(u32 base_addr);
67extern void at91sam9_alt_restart(enum reboot_mode, const char *);
68extern void at91sam9g45_restart(enum reboot_mode, const char *);
69
70/* shutdown */
71extern void at91_ioremap_shdwc(u32 base_addr);
72
73/* Matrix */ 67/* Matrix */
74extern void at91_ioremap_matrix(u32 base_addr); 68extern void at91_ioremap_matrix(u32 base_addr);
75 69
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index 3d192c5aee66..cdb3ec9efd2b 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -48,11 +48,6 @@ void __iomem *at91_aic_base;
48static struct irq_domain *at91_aic_domain; 48static struct irq_domain *at91_aic_domain;
49static struct device_node *at91_aic_np; 49static struct device_node *at91_aic_np;
50static unsigned int n_irqs = NR_AIC_IRQS; 50static unsigned int n_irqs = NR_AIC_IRQS;
51static unsigned long at91_aic_caps = 0;
52
53/* AIC5 introduces a Source Select Register */
54#define AT91_AIC_CAP_AIC5 (1 << 0)
55#define has_aic5() (at91_aic_caps & AT91_AIC_CAP_AIC5)
56 51
57#ifdef CONFIG_PM 52#ifdef CONFIG_PM
58 53
@@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
92 87
93void at91_irq_suspend(void) 88void at91_irq_suspend(void)
94{ 89{
95 int bit = -1; 90 at91_aic_write(AT91_AIC_IDCR, *backups);
96 91 at91_aic_write(AT91_AIC_IECR, *wakeups);
97 if (has_aic5()) {
98 /* disable enabled irqs */
99 while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
100 at91_aic_write(AT91_AIC5_SSR,
101 bit & AT91_AIC5_INTSEL_MSK);
102 at91_aic_write(AT91_AIC5_IDCR, 1);
103 }
104 /* enable wakeup irqs */
105 bit = -1;
106 while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
107 at91_aic_write(AT91_AIC5_SSR,
108 bit & AT91_AIC5_INTSEL_MSK);
109 at91_aic_write(AT91_AIC5_IECR, 1);
110 }
111 } else {
112 at91_aic_write(AT91_AIC_IDCR, *backups);
113 at91_aic_write(AT91_AIC_IECR, *wakeups);
114 }
115} 92}
116 93
117void at91_irq_resume(void) 94void at91_irq_resume(void)
118{ 95{
119 int bit = -1; 96 at91_aic_write(AT91_AIC_IDCR, *wakeups);
120 97 at91_aic_write(AT91_AIC_IECR, *backups);
121 if (has_aic5()) {
122 /* disable wakeup irqs */
123 while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
124 at91_aic_write(AT91_AIC5_SSR,
125 bit & AT91_AIC5_INTSEL_MSK);
126 at91_aic_write(AT91_AIC5_IDCR, 1);
127 }
128 /* enable irqs disabled for suspend */
129 bit = -1;
130 while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
131 at91_aic_write(AT91_AIC5_SSR,
132 bit & AT91_AIC5_INTSEL_MSK);
133 at91_aic_write(AT91_AIC5_IECR, 1);
134 }
135 } else {
136 at91_aic_write(AT91_AIC_IDCR, *wakeups);
137 at91_aic_write(AT91_AIC_IECR, *backups);
138 }
139} 98}
140 99
141#else 100#else
@@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs)
169 handle_IRQ(irqnr, regs); 128 handle_IRQ(irqnr, regs);
170} 129}
171 130
172asmlinkage void __exception_irq_entry
173at91_aic5_handle_irq(struct pt_regs *regs)
174{
175 u32 irqnr;
176 u32 irqstat;
177
178 irqnr = at91_aic_read(AT91_AIC5_IVR);
179 irqstat = at91_aic_read(AT91_AIC5_ISR);
180
181 if (!irqstat)
182 at91_aic_write(AT91_AIC5_EOICR, 0);
183 else
184 handle_IRQ(irqnr, regs);
185}
186
187static void at91_aic_mask_irq(struct irq_data *d) 131static void at91_aic_mask_irq(struct irq_data *d)
188{ 132{
189 /* Disable interrupt on AIC */ 133 /* Disable interrupt on AIC */
@@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d)
192 clear_backup(d->hwirq); 136 clear_backup(d->hwirq);
193} 137}
194 138
195static void __maybe_unused at91_aic5_mask_irq(struct irq_data *d)
196{
197 /* Disable interrupt on AIC5 */
198 at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
199 at91_aic_write(AT91_AIC5_IDCR, 1);
200 /* Update ISR cache */
201 clear_backup(d->hwirq);
202}
203
204static void at91_aic_unmask_irq(struct irq_data *d) 139static void at91_aic_unmask_irq(struct irq_data *d)
205{ 140{
206 /* Enable interrupt on AIC */ 141 /* Enable interrupt on AIC */
@@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d)
209 set_backup(d->hwirq); 144 set_backup(d->hwirq);
210} 145}
211 146
212static void __maybe_unused at91_aic5_unmask_irq(struct irq_data *d)
213{
214 /* Enable interrupt on AIC5 */
215 at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
216 at91_aic_write(AT91_AIC5_IECR, 1);
217 /* Update ISR cache */
218 set_backup(d->hwirq);
219}
220
221static void at91_aic_eoi(struct irq_data *d) 147static void at91_aic_eoi(struct irq_data *d)
222{ 148{
223 /* 149 /*
@@ -227,11 +153,6 @@ static void at91_aic_eoi(struct irq_data *d)
227 at91_aic_write(AT91_AIC_EOICR, 0); 153 at91_aic_write(AT91_AIC_EOICR, 0);
228} 154}
229 155
230static void __maybe_unused at91_aic5_eoi(struct irq_data *d)
231{
232 at91_aic_write(AT91_AIC5_EOICR, 0);
233}
234
235static unsigned long *at91_extern_irq; 156static unsigned long *at91_extern_irq;
236 157
237u32 at91_get_extern_irq(void) 158u32 at91_get_extern_irq(void)
@@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
282 if (srctype < 0) 203 if (srctype < 0)
283 return srctype; 204 return srctype;
284 205
285 if (has_aic5()) { 206 smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE;
286 at91_aic_write(AT91_AIC5_SSR, 207 at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
287 d->hwirq & AT91_AIC5_INTSEL_MSK);
288 smr = at91_aic_read(AT91_AIC5_SMR) & ~AT91_AIC_SRCTYPE;
289 at91_aic_write(AT91_AIC5_SMR, smr | srctype);
290 } else {
291 smr = at91_aic_read(AT91_AIC_SMR(d->hwirq))
292 & ~AT91_AIC_SRCTYPE;
293 at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
294 }
295 208
296 return 0; 209 return 0;
297} 210}
@@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector)
331 at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); 244 at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
332} 245}
333 246
334static void __init __maybe_unused at91_aic5_hw_init(unsigned int spu_vector)
335{
336 int i;
337
338 /*
339 * Perform 8 End Of Interrupt Command to make sure AIC
340 * will not Lock out nIRQ
341 */
342 for (i = 0; i < 8; i++)
343 at91_aic_write(AT91_AIC5_EOICR, 0);
344
345 /*
346 * Spurious Interrupt ID in Spurious Vector Register.
347 * When there is no current interrupt, the IRQ Vector Register
348 * reads the value stored in AIC_SPU
349 */
350 at91_aic_write(AT91_AIC5_SPU, spu_vector);
351
352 /* No debugging in AIC: Debug (Protect) Control Register */
353 at91_aic_write(AT91_AIC5_DCR, 0);
354
355 /* Disable and clear all interrupts initially */
356 for (i = 0; i < n_irqs; i++) {
357 at91_aic_write(AT91_AIC5_SSR, i & AT91_AIC5_INTSEL_MSK);
358 at91_aic_write(AT91_AIC5_IDCR, 1);
359 at91_aic_write(AT91_AIC5_ICCR, 1);
360 }
361}
362
363#if defined(CONFIG_OF)
364static unsigned int *at91_aic_irq_priorities;
365
366static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq,
367 irq_hw_number_t hw)
368{
369 /* Put virq number in Source Vector Register */
370 at91_aic_write(AT91_AIC_SVR(hw), virq);
371
372 /* Active Low interrupt, with priority */
373 at91_aic_write(AT91_AIC_SMR(hw),
374 AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
375
376 irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
377 set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
378
379 return 0;
380}
381
382static int at91_aic5_irq_map(struct irq_domain *h, unsigned int virq,
383 irq_hw_number_t hw)
384{
385 at91_aic_write(AT91_AIC5_SSR, hw & AT91_AIC5_INTSEL_MSK);
386
387 /* Put virq number in Source Vector Register */
388 at91_aic_write(AT91_AIC5_SVR, virq);
389
390 /* Active Low interrupt, with priority */
391 at91_aic_write(AT91_AIC5_SMR,
392 AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
393
394 irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
395 set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
396
397 return 0;
398}
399
400static int at91_aic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
401 const u32 *intspec, unsigned int intsize,
402 irq_hw_number_t *out_hwirq, unsigned int *out_type)
403{
404 if (WARN_ON(intsize < 3))
405 return -EINVAL;
406 if (WARN_ON(intspec[0] >= n_irqs))
407 return -EINVAL;
408 if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY)
409 || (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY)))
410 return -EINVAL;
411
412 *out_hwirq = intspec[0];
413 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
414 at91_aic_irq_priorities[*out_hwirq] = intspec[2];
415
416 return 0;
417}
418
419static struct irq_domain_ops at91_aic_irq_ops = {
420 .map = at91_aic_irq_map,
421 .xlate = at91_aic_irq_domain_xlate,
422};
423
424int __init at91_aic_of_common_init(struct device_node *node,
425 struct device_node *parent)
426{
427 struct property *prop;
428 const __be32 *p;
429 u32 val;
430
431 at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs)
432 * sizeof(*at91_extern_irq), GFP_KERNEL);
433 if (!at91_extern_irq)
434 return -ENOMEM;
435
436 if (at91_aic_pm_init()) {
437 kfree(at91_extern_irq);
438 return -ENOMEM;
439 }
440
441 at91_aic_irq_priorities = kzalloc(n_irqs
442 * sizeof(*at91_aic_irq_priorities),
443 GFP_KERNEL);
444 if (!at91_aic_irq_priorities)
445 return -ENOMEM;
446
447 at91_aic_base = of_iomap(node, 0);
448 at91_aic_np = node;
449
450 at91_aic_domain = irq_domain_add_linear(at91_aic_np, n_irqs,
451 &at91_aic_irq_ops, NULL);
452 if (!at91_aic_domain)
453 panic("Unable to add AIC irq domain (DT)\n");
454
455 of_property_for_each_u32(node, "atmel,external-irqs", prop, p, val) {
456 if (val >= n_irqs)
457 pr_warn("AIC: external irq %d >= %d skip it\n",
458 val, n_irqs);
459 else
460 set_bit(val, at91_extern_irq);
461 }
462
463 irq_set_default_host(at91_aic_domain);
464
465 return 0;
466}
467
468int __init at91_aic_of_init(struct device_node *node,
469 struct device_node *parent)
470{
471 int err;
472
473 err = at91_aic_of_common_init(node, parent);
474 if (err)
475 return err;
476
477 at91_aic_hw_init(n_irqs);
478
479 return 0;
480}
481
482int __init at91_aic5_of_init(struct device_node *node,
483 struct device_node *parent)
484{
485 int err;
486
487 at91_aic_caps |= AT91_AIC_CAP_AIC5;
488 n_irqs = NR_AIC5_IRQS;
489 at91_aic_chip.irq_ack = at91_aic5_mask_irq;
490 at91_aic_chip.irq_mask = at91_aic5_mask_irq;
491 at91_aic_chip.irq_unmask = at91_aic5_unmask_irq;
492 at91_aic_chip.irq_eoi = at91_aic5_eoi;
493 at91_aic_irq_ops.map = at91_aic5_irq_map;
494
495 err = at91_aic_of_common_init(node, parent);
496 if (err)
497 return err;
498
499 at91_aic5_hw_init(n_irqs);
500
501 return 0;
502}
503#endif
504
505/* 247/*
506 * Initialize the AIC interrupt controller. 248 * Initialize the AIC interrupt controller.
507 */ 249 */
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index e95554532987..4073ab7f38f3 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -34,79 +34,8 @@
34#include "pm.h" 34#include "pm.h"
35#include "gpio.h" 35#include "gpio.h"
36 36
37/*
38 * Show the reason for the previous system reset.
39 */
40
41#include "at91_rstc.h"
42#include "at91_shdwc.h"
43
44static void (*at91_pm_standby)(void); 37static void (*at91_pm_standby)(void);
45 38
46static void __init show_reset_status(void)
47{
48 static char reset[] __initdata = "reset";
49
50 static char general[] __initdata = "general";
51 static char wakeup[] __initdata = "wakeup";
52 static char watchdog[] __initdata = "watchdog";
53 static char software[] __initdata = "software";
54 static char user[] __initdata = "user";
55 static char unknown[] __initdata = "unknown";
56
57 static char signal[] __initdata = "signal";
58 static char rtc[] __initdata = "rtc";
59 static char rtt[] __initdata = "rtt";
60 static char restore[] __initdata = "power-restored";
61
62 char *reason, *r2 = reset;
63 u32 reset_type, wake_type;
64
65 if (!at91_shdwc_base || !at91_rstc_base)
66 return;
67
68 reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
69 wake_type = at91_shdwc_read(AT91_SHDW_SR);
70
71 switch (reset_type) {
72 case AT91_RSTC_RSTTYP_GENERAL:
73 reason = general;
74 break;
75 case AT91_RSTC_RSTTYP_WAKEUP:
76 /* board-specific code enabled the wakeup sources */
77 reason = wakeup;
78
79 /* "wakeup signal" */
80 if (wake_type & AT91_SHDW_WAKEUP0)
81 r2 = signal;
82 else {
83 r2 = reason;
84 if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */
85 reason = rtt;
86 else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */
87 reason = rtc;
88 else if (wake_type == 0) /* power-restored wakeup */
89 reason = restore;
90 else /* unknown wakeup */
91 reason = unknown;
92 }
93 break;
94 case AT91_RSTC_RSTTYP_WATCHDOG:
95 reason = watchdog;
96 break;
97 case AT91_RSTC_RSTTYP_SOFTWARE:
98 reason = software;
99 break;
100 case AT91_RSTC_RSTTYP_USER:
101 reason = user;
102 break;
103 default:
104 reason = unknown;
105 break;
106 }
107 pr_info("AT91: Starting after %s %s\n", reason, r2);
108}
109
110static int at91_pm_valid_state(suspend_state_t state) 39static int at91_pm_valid_state(suspend_state_t state)
111{ 40{
112 switch (state) { 41 switch (state) {
@@ -206,16 +135,19 @@ static int at91_pm_enter(suspend_state_t state)
206 at91_pinctrl_gpio_suspend(); 135 at91_pinctrl_gpio_suspend();
207 else 136 else
208 at91_gpio_suspend(); 137 at91_gpio_suspend();
209 at91_irq_suspend();
210 138
211 pr_debug("AT91: PM - wake mask %08x, pm state %d\n", 139 if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) {
212 /* remember all the always-wake irqs */ 140 at91_irq_suspend();
213 (at91_pmc_read(AT91_PMC_PCSR) 141
214 | (1 << AT91_ID_FIQ) 142 pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
215 | (1 << AT91_ID_SYS) 143 /* remember all the always-wake irqs */
216 | (at91_get_extern_irq())) 144 (at91_pmc_read(AT91_PMC_PCSR)
217 & at91_aic_read(AT91_AIC_IMR), 145 | (1 << AT91_ID_FIQ)
218 state); 146 | (1 << AT91_ID_SYS)
147 | (at91_get_extern_irq()))
148 & at91_aic_read(AT91_AIC_IMR),
149 state);
150 }
219 151
220 switch (state) { 152 switch (state) {
221 /* 153 /*
@@ -280,12 +212,17 @@ static int at91_pm_enter(suspend_state_t state)
280 goto error; 212 goto error;
281 } 213 }
282 214
283 pr_debug("AT91: PM - wakeup %08x\n", 215 if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
284 at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); 216 pr_debug("AT91: PM - wakeup %08x\n",
217 at91_aic_read(AT91_AIC_IPR) &
218 at91_aic_read(AT91_AIC_IMR));
285 219
286error: 220error:
287 target_state = PM_SUSPEND_ON; 221 target_state = PM_SUSPEND_ON;
288 at91_irq_resume(); 222
223 if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
224 at91_irq_resume();
225
289 if (of_have_populated_dt()) 226 if (of_have_populated_dt())
290 at91_pinctrl_gpio_resume(); 227 at91_pinctrl_gpio_resume();
291 else 228 else
@@ -338,7 +275,6 @@ static int __init at91_pm_init(void)
338 275
339 suspend_set_ops(&at91_pm_ops); 276 suspend_set_ops(&at91_pm_ops);
340 277
341 show_reset_status();
342 return 0; 278 return 0;
343} 279}
344arch_initcall(at91_pm_init); 280arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index f7a07a58ebb6..d2cade21ebd7 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -5,6 +5,8 @@
5 * Under GPLv2 5 * Under GPLv2
6 */ 6 */
7 7
8#define pr_fmt(fmt) "AT91: " fmt
9
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/io.h> 11#include <linux/io.h>
10#include <linux/mm.h> 12#include <linux/mm.h>
@@ -20,7 +22,6 @@
20#include <mach/cpu.h> 22#include <mach/cpu.h>
21#include <mach/at91_dbgu.h> 23#include <mach/at91_dbgu.h>
22 24
23#include "at91_shdwc.h"
24#include "soc.h" 25#include "soc.h"
25#include "generic.h" 26#include "generic.h"
26#include "pm.h" 27#include "pm.h"
@@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type)
37 else 38 else
38 at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; 39 at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
39 40
40 pr_info("AT91: filled in soc subtype: %s\n", 41 pr_info("filled in soc subtype: %s\n",
41 at91_get_soc_subtype(&at91_soc_initdata)); 42 at91_get_soc_subtype(&at91_soc_initdata));
42} 43}
43 44
@@ -49,7 +50,8 @@ void __init at91_init_irq_default(void)
49void __init at91_init_interrupts(unsigned int *priority) 50void __init at91_init_interrupts(unsigned int *priority)
50{ 51{
51 /* Initialize the AIC interrupt controller */ 52 /* Initialize the AIC interrupt controller */
52 at91_aic_init(priority, at91_boot_soc.extern_irq); 53 if (IS_ENABLED(CONFIG_OLD_IRQ_AT91))
54 at91_aic_init(priority, at91_boot_soc.extern_irq);
53 55
54 /* Enable GPIO interrupts */ 56 /* Enable GPIO interrupts */
55 at91_gpio_irq_setup(); 57 at91_gpio_irq_setup();
@@ -66,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
66 } 68 }
67 at91_ramc_base[id] = ioremap(addr, size); 69 at91_ramc_base[id] = ioremap(addr, size);
68 if (!at91_ramc_base[id]) 70 if (!at91_ramc_base[id])
69 panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr); 71 panic(pr_fmt("Impossible to ioremap ramc.%d 0x%x\n"), id, addr);
70} 72}
71 73
72static struct map_desc sram_desc[2] __initdata; 74static struct map_desc sram_desc[2] __initdata;
@@ -83,7 +85,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
83 desc->length = length; 85 desc->length = length;
84 desc->type = MT_MEMORY_RWX_NONCACHED; 86 desc->type = MT_MEMORY_RWX_NONCACHED;
85 87
86 pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", 88 pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n",
87 base, length, desc->virtual); 89 base, length, desc->virtual);
88 90
89 iotable_init(desc, 1); 91 iotable_init(desc, 1);
@@ -302,45 +304,21 @@ void __init at91_map_io(void)
302 soc_detect(AT91_BASE_DBGU1); 304 soc_detect(AT91_BASE_DBGU1);
303 305
304 if (!at91_soc_is_detected()) 306 if (!at91_soc_is_detected())
305 panic("AT91: Impossible to detect the SOC type"); 307 panic(pr_fmt("Impossible to detect the SOC type"));
306 308
307 pr_info("AT91: Detected soc type: %s\n", 309 pr_info("Detected soc type: %s\n",
308 at91_get_soc_type(&at91_soc_initdata)); 310 at91_get_soc_type(&at91_soc_initdata));
309 if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE) 311 if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
310 pr_info("AT91: Detected soc subtype: %s\n", 312 pr_info("Detected soc subtype: %s\n",
311 at91_get_soc_subtype(&at91_soc_initdata)); 313 at91_get_soc_subtype(&at91_soc_initdata));
312 314
313 if (!at91_soc_is_enabled()) 315 if (!at91_soc_is_enabled())
314 panic("AT91: Soc not enabled"); 316 panic(pr_fmt("Soc not enabled"));
315 317
316 if (at91_boot_soc.map_io) 318 if (at91_boot_soc.map_io)
317 at91_boot_soc.map_io(); 319 at91_boot_soc.map_io();
318} 320}
319 321
320void __iomem *at91_shdwc_base = NULL;
321
322static void at91sam9_poweroff(void)
323{
324 at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
325}
326
327void __init at91_ioremap_shdwc(u32 base_addr)
328{
329 at91_shdwc_base = ioremap(base_addr, 16);
330 if (!at91_shdwc_base)
331 panic("Impossible to ioremap at91_shdwc_base\n");
332 pm_power_off = at91sam9_poweroff;
333}
334
335void __iomem *at91_rstc_base;
336
337void __init at91_ioremap_rstc(u32 base_addr)
338{
339 at91_rstc_base = ioremap(base_addr, 16);
340 if (!at91_rstc_base)
341 panic("Impossible to ioremap at91_rstc_base\n");
342}
343
344void __iomem *at91_matrix_base; 322void __iomem *at91_matrix_base;
345EXPORT_SYMBOL_GPL(at91_matrix_base); 323EXPORT_SYMBOL_GPL(at91_matrix_base);
346 324
@@ -348,42 +326,15 @@ void __init at91_ioremap_matrix(u32 base_addr)
348{ 326{
349 at91_matrix_base = ioremap(base_addr, 512); 327 at91_matrix_base = ioremap(base_addr, 512);
350 if (!at91_matrix_base) 328 if (!at91_matrix_base)
351 panic("Impossible to ioremap at91_matrix_base\n"); 329 panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
352} 330}
353 331
354#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40) 332#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40)
355static struct of_device_id rstc_ids[] = {
356 { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
357 { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
358 { /*sentinel*/ }
359};
360
361static void at91_dt_rstc(void)
362{
363 struct device_node *np;
364 const struct of_device_id *of_id;
365
366 np = of_find_matching_node(NULL, rstc_ids);
367 if (!np)
368 panic("unable to find compatible rstc node in dtb\n");
369
370 at91_rstc_base = of_iomap(np, 0);
371 if (!at91_rstc_base)
372 panic("unable to map rstc cpu registers\n");
373
374 of_id = of_match_node(rstc_ids, np);
375 if (!of_id)
376 panic("AT91: rtsc no restart function available\n");
377
378 arm_pm_restart = of_id->data;
379
380 of_node_put(np);
381}
382
383static struct of_device_id ramc_ids[] = { 333static struct of_device_id ramc_ids[] = {
384 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, 334 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
385 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, 335 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
386 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, 336 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
337 { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
387 { /*sentinel*/ } 338 { /*sentinel*/ }
388}; 339};
389 340
@@ -391,100 +342,29 @@ static void at91_dt_ramc(void)
391{ 342{
392 struct device_node *np; 343 struct device_node *np;
393 const struct of_device_id *of_id; 344 const struct of_device_id *of_id;
345 int idx = 0;
346 const void *standby = NULL;
394 347
395 np = of_find_matching_node(NULL, ramc_ids); 348 for_each_matching_node_and_match(np, ramc_ids, &of_id) {
396 if (!np) 349 at91_ramc_base[idx] = of_iomap(np, 0);
397 panic("unable to find compatible ram controller node in dtb\n"); 350 if (!at91_ramc_base[idx])
351 panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
398 352
399 at91_ramc_base[0] = of_iomap(np, 0); 353 if (!standby)
400 if (!at91_ramc_base[0]) 354 standby = of_id->data;
401 panic("unable to map ramc[0] cpu registers\n");
402 /* the controller may have 2 banks */
403 at91_ramc_base[1] = of_iomap(np, 1);
404 355
405 of_id = of_match_node(ramc_ids, np); 356 idx++;
406 if (!of_id)
407 pr_warn("AT91: ramc no standby function available\n");
408 else
409 at91_pm_set_standby(of_id->data);
410
411 of_node_put(np);
412}
413
414static struct of_device_id shdwc_ids[] = {
415 { .compatible = "atmel,at91sam9260-shdwc", },
416 { .compatible = "atmel,at91sam9rl-shdwc", },
417 { .compatible = "atmel,at91sam9x5-shdwc", },
418 { /*sentinel*/ }
419};
420
421static const char *shdwc_wakeup_modes[] = {
422 [AT91_SHDW_WKMODE0_NONE] = "none",
423 [AT91_SHDW_WKMODE0_HIGH] = "high",
424 [AT91_SHDW_WKMODE0_LOW] = "low",
425 [AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
426};
427
428const int at91_dtget_shdwc_wakeup_mode(struct device_node *np)
429{
430 const char *pm;
431 int err, i;
432
433 err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
434 if (err < 0)
435 return AT91_SHDW_WKMODE0_ANYLEVEL;
436
437 for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
438 if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
439 return i;
440
441 return -ENODEV;
442}
443
444static void at91_dt_shdwc(void)
445{
446 struct device_node *np;
447 int wakeup_mode;
448 u32 reg;
449 u32 mode = 0;
450
451 np = of_find_matching_node(NULL, shdwc_ids);
452 if (!np) {
453 pr_debug("AT91: unable to find compatible shutdown (shdwc) controller node in dtb\n");
454 return;
455 } 357 }
456 358
457 at91_shdwc_base = of_iomap(np, 0); 359 if (!idx)
458 if (!at91_shdwc_base) 360 panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
459 panic("AT91: unable to map shdwc cpu registers\n");
460
461 wakeup_mode = at91_dtget_shdwc_wakeup_mode(np);
462 if (wakeup_mode < 0) {
463 pr_warn("AT91: shdwc unknown wakeup mode\n");
464 goto end;
465 }
466 361
467 if (!of_property_read_u32(np, "atmel,wakeup-counter", &reg)) { 362 if (!standby) {
468 if (reg > AT91_SHDW_CPTWK0_MAX) { 363 pr_warn("ramc no standby function available\n");
469 pr_warn("AT91: shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n", 364 return;
470 reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
471 reg = AT91_SHDW_CPTWK0_MAX;
472 }
473 mode |= AT91_SHDW_CPTWK0_(reg);
474 } 365 }
475 366
476 if (of_property_read_bool(np, "atmel,wakeup-rtc-timer")) 367 at91_pm_set_standby(standby);
477 mode |= AT91_SHDW_RTCWKEN;
478
479 if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
480 mode |= AT91_SHDW_RTTWKEN;
481
482 at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode);
483
484end:
485 pm_power_off = at91sam9_poweroff;
486
487 of_node_put(np);
488} 368}
489 369
490void __init at91rm9200_dt_initialize(void) 370void __init at91rm9200_dt_initialize(void)
@@ -503,9 +383,7 @@ void __init at91rm9200_dt_initialize(void)
503 383
504void __init at91_dt_initialize(void) 384void __init at91_dt_initialize(void)
505{ 385{
506 at91_dt_rstc();
507 at91_dt_ramc(); 386 at91_dt_ramc();
508 at91_dt_shdwc();
509 387
510 /* Init clock subsystem */ 388 /* Init clock subsystem */
511 at91_dt_clock_init(); 389 at91_dt_clock_init();
@@ -533,3 +411,8 @@ void __init at91_initialize(unsigned long main_clock)
533 411
534 pinctrl_provide_dummies(); 412 pinctrl_provide_dummies();
535} 413}
414
415void __init at91_register_devices(void)
416{
417 at91_boot_soc.register_devices();
418}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index a1e1482c6da8..ab983f2cc7dd 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -11,6 +11,7 @@ struct at91_init_soc {
11 void (*map_io)(void); 11 void (*map_io)(void);
12 void (*ioremap_registers)(void); 12 void (*ioremap_registers)(void);
13 void (*register_clocks)(void); 13 void (*register_clocks)(void);
14 void (*register_devices)(void);
14 void (*init)(void); 15 void (*init)(void);
15}; 16};
16 17
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 8c96307d7363..a76d03fd577b 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -119,13 +119,7 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
119 init.ops = &system_ops; 119 init.ops = &system_ops;
120 init.parent_names = &parent_name; 120 init.parent_names = &parent_name;
121 init.num_parents = 1; 121 init.num_parents = 1;
122 /* 122 init.flags = CLK_SET_RATE_PARENT;
123 * CLK_IGNORE_UNUSED is used to avoid ddrck switch off.
124 * TODO : we should implement a driver supporting at91 ddr controller
125 * (see drivers/memory) which would request and enable the ddrck clock.
126 * When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
127 */
128 init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
129 123
130 sys->id = id; 124 sys->id = id;
131 sys->hw.init = &init; 125 sys->hw.init = &init;
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index fab81a143bd7..6d91c27fd4c8 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -7,6 +7,16 @@ menuconfig MEMORY
7 7
8if MEMORY 8if MEMORY
9 9
10config ATMEL_SDRAMC
11 bool "Atmel (Multi-port DDR-)SDRAM Controller"
12 default y
13 depends on ARCH_AT91 && OF
14 help
15 This driver is for Atmel SDRAM Controller or Atmel Multi-port
16 DDR-SDRAM Controller available on Atmel AT91SAM9 and SAMA5 SoCs.
17 Starting with the at91sam9g45, this controller supports SDR, DDR and
18 LP-DDR memories.
19
10config TI_AEMIF 20config TI_AEMIF
11 tristate "Texas Instruments AEMIF driver" 21 tristate "Texas Instruments AEMIF driver"
12 depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF 22 depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 4055c47f45ab..c32d31981be3 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -5,6 +5,7 @@
5ifeq ($(CONFIG_DDR),y) 5ifeq ($(CONFIG_DDR),y)
6obj-$(CONFIG_OF) += of_memory.o 6obj-$(CONFIG_OF) += of_memory.o
7endif 7endif
8obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o
8obj-$(CONFIG_TI_AEMIF) += ti-aemif.o 9obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
9obj-$(CONFIG_TI_EMIF) += emif.o 10obj-$(CONFIG_TI_EMIF) += emif.o
10obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o 11obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c
new file mode 100644
index 000000000000..fed04e8efe75
--- /dev/null
+++ b/drivers/memory/atmel-sdramc.c
@@ -0,0 +1,98 @@
1/*
2 * Atmel (Multi-port DDR-)SDRAM Controller driver
3 *
4 * Copyright (C) 2014 Atmel
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/of_platform.h>
25#include <linux/platform_device.h>
26
27struct at91_ramc_caps {
28 bool has_ddrck;
29 bool has_mpddr_clk;
30};
31
32static const struct at91_ramc_caps at91rm9200_caps = { };
33
34static const struct at91_ramc_caps at91sam9g45_caps = {
35 .has_ddrck = 1,
36 .has_mpddr_clk = 0,
37};
38
39static const struct at91_ramc_caps sama5d3_caps = {
40 .has_ddrck = 1,
41 .has_mpddr_clk = 1,
42};
43
44static const struct of_device_id atmel_ramc_of_match[] = {
45 { .compatible = "atmel,at91rm9200-sdramc", .data = &at91rm9200_caps, },
46 { .compatible = "atmel,at91sam9260-sdramc", .data = &at91rm9200_caps, },
47 { .compatible = "atmel,at91sam9g45-ddramc", .data = &at91sam9g45_caps, },
48 { .compatible = "atmel,sama5d3-ddramc", .data = &sama5d3_caps, },
49 {},
50};
51MODULE_DEVICE_TABLE(of, atmel_ramc_of_match);
52
53static int atmel_ramc_probe(struct platform_device *pdev)
54{
55 const struct of_device_id *match;
56 const struct at91_ramc_caps *caps;
57 struct clk *clk;
58
59 match = of_match_device(atmel_ramc_of_match, &pdev->dev);
60 caps = match->data;
61
62 if (caps->has_ddrck) {
63 clk = devm_clk_get(&pdev->dev, "ddrck");
64 if (IS_ERR(clk))
65 return PTR_ERR(clk);
66 clk_prepare_enable(clk);
67 }
68
69 if (caps->has_mpddr_clk) {
70 clk = devm_clk_get(&pdev->dev, "mpddr");
71 if (IS_ERR(clk)) {
72 pr_err("AT91 RAMC: couldn't get mpddr clock\n");
73 return PTR_ERR(clk);
74 }
75 clk_prepare_enable(clk);
76 }
77
78 return 0;
79}
80
81static struct platform_driver atmel_ramc_driver = {
82 .probe = atmel_ramc_probe,
83 .driver = {
84 .name = "atmel-ramc",
85 .owner = THIS_MODULE,
86 .of_match_table = atmel_ramc_of_match,
87 },
88};
89
90static int __init atmel_ramc_init(void)
91{
92 return platform_driver_register(&atmel_ramc_driver);
93}
94module_init(atmel_ramc_init);
95
96MODULE_LICENSE("GPL v2");
97MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
98MODULE_DESCRIPTION("Atmel (Multi-port DDR-)SDRAM Controller");
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index ca41523bbebf..81b445122eea 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -6,15 +6,33 @@ menuconfig POWER_RESET
6 6
7 Say Y here to enable board reset and power off 7 Say Y here to enable board reset and power off
8 8
9if POWER_RESET
10
9config POWER_RESET_AS3722 11config POWER_RESET_AS3722
10 bool "ams AS3722 power-off driver" 12 bool "ams AS3722 power-off driver"
11 depends on MFD_AS3722 && POWER_RESET 13 depends on MFD_AS3722
12 help 14 help
13 This driver supports turning off board via a ams AS3722 power-off. 15 This driver supports turning off board via a ams AS3722 power-off.
14 16
17config POWER_RESET_AT91_POWEROFF
18 bool "Atmel AT91 poweroff driver"
19 depends on ARCH_AT91
20 default SOC_AT91SAM9 || SOC_SAMA5
21 help
22 This driver supports poweroff for Atmel AT91SAM9 and SAMA5
23 SoCs
24
25config POWER_RESET_AT91_RESET
26 bool "Atmel AT91 reset driver"
27 depends on ARCH_AT91
28 default SOC_AT91SAM9 || SOC_SAMA5
29 help
30 This driver supports restart for Atmel AT91SAM9 and SAMA5
31 SoCs
32
15config POWER_RESET_AXXIA 33config POWER_RESET_AXXIA
16 bool "LSI Axxia reset driver" 34 bool "LSI Axxia reset driver"
17 depends on POWER_RESET && ARCH_AXXIA 35 depends on ARCH_AXXIA
18 help 36 help
19 This driver supports restart for Axxia SoC. 37 This driver supports restart for Axxia SoC.
20 38
@@ -33,7 +51,7 @@ config POWER_RESET_BRCMSTB
33 51
34config POWER_RESET_GPIO 52config POWER_RESET_GPIO
35 bool "GPIO power-off driver" 53 bool "GPIO power-off driver"
36 depends on OF_GPIO && POWER_RESET 54 depends on OF_GPIO
37 help 55 help
38 This driver supports turning off your board via a GPIO line. 56 This driver supports turning off your board via a GPIO line.
39 If your board needs a GPIO high/low to power down, say Y and 57 If your board needs a GPIO high/low to power down, say Y and
@@ -47,13 +65,13 @@ config POWER_RESET_HISI
47 65
48config POWER_RESET_MSM 66config POWER_RESET_MSM
49 bool "Qualcomm MSM power-off driver" 67 bool "Qualcomm MSM power-off driver"
50 depends on POWER_RESET && ARCH_QCOM 68 depends on ARCH_QCOM
51 help 69 help
52 Power off and restart support for Qualcomm boards. 70 Power off and restart support for Qualcomm boards.
53 71
54config POWER_RESET_QNAP 72config POWER_RESET_QNAP
55 bool "QNAP power-off driver" 73 bool "QNAP power-off driver"
56 depends on OF_GPIO && POWER_RESET && PLAT_ORION 74 depends on OF_GPIO && PLAT_ORION
57 help 75 help
58 This driver supports turning off QNAP NAS devices by sending 76 This driver supports turning off QNAP NAS devices by sending
59 commands to the microcontroller which controls the main power. 77 commands to the microcontroller which controls the main power.
@@ -71,14 +89,13 @@ config POWER_RESET_RESTART
71config POWER_RESET_SUN6I 89config POWER_RESET_SUN6I
72 bool "Allwinner A31 SoC reset driver" 90 bool "Allwinner A31 SoC reset driver"
73 depends on ARCH_SUNXI 91 depends on ARCH_SUNXI
74 depends on POWER_RESET
75 help 92 help
76 Reboot support for the Allwinner A31 SoCs. 93 Reboot support for the Allwinner A31 SoCs.
77 94
78config POWER_RESET_VEXPRESS 95config POWER_RESET_VEXPRESS
79 bool "ARM Versatile Express power-off and reset driver" 96 bool "ARM Versatile Express power-off and reset driver"
80 depends on ARM || ARM64 97 depends on ARM || ARM64
81 depends on POWER_RESET && VEXPRESS_CONFIG 98 depends on VEXPRESS_CONFIG
82 help 99 help
83 Power off and reset support for the ARM Ltd. Versatile 100 Power off and reset support for the ARM Ltd. Versatile
84 Express boards. 101 Express boards.
@@ -86,7 +103,6 @@ config POWER_RESET_VEXPRESS
86config POWER_RESET_XGENE 103config POWER_RESET_XGENE
87 bool "APM SoC X-Gene reset driver" 104 bool "APM SoC X-Gene reset driver"
88 depends on ARM64 105 depends on ARM64
89 depends on POWER_RESET
90 help 106 help
91 Reboot support for the APM SoC X-Gene Eval boards. 107 Reboot support for the APM SoC X-Gene Eval boards.
92 108
@@ -97,3 +113,4 @@ config POWER_RESET_KEYSTONE
97 help 113 help
98 Reboot support for the KEYSTONE SoCs. 114 Reboot support for the KEYSTONE SoCs.
99 115
116endif
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index a42e70edd037..4433a753fd93 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -1,4 +1,6 @@
1obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o 1obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o
2obj-$(CONFIG_POWER_RESET_AT91_POWEROFF) += at91-poweroff.o
3obj-$(CONFIG_POWER_RESET_AT91_RESET) += at91-reset.o
2obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o 4obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o
3obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o 5obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
4obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o 6obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
new file mode 100644
index 000000000000..c61000333bb9
--- /dev/null
+++ b/drivers/power/reset/at91-poweroff.c
@@ -0,0 +1,156 @@
1/*
2 * Atmel AT91 SAM9 SoCs reset code
3 *
4 * Copyright (C) 2007 Atmel Corporation.
5 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
6 * Copyright (C) 2014 Free Electrons
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/platform_device.h>
17#include <linux/printk.h>
18
19#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
20#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
21#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
22
23#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
24#define AT91_SHDW_WKMODE0 GENMASK(2, 0) /* Wake-up 0 Mode Selection */
25#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
26#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
27#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
28#define AT91_SHDW_RTTWKEN BIT(16) /* Real Time Timer Wake-up Enable */
29#define AT91_SHDW_RTCWKEN BIT(17) /* Real Time Clock Wake-up Enable */
30
31#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
32#define AT91_SHDW_WAKEUP0 BIT(0) /* Wake-up 0 Status */
33#define AT91_SHDW_RTTWK BIT(16) /* Real-time Timer Wake-up */
34#define AT91_SHDW_RTCWK BIT(17) /* Real-time Clock Wake-up [SAM9RL] */
35
36enum wakeup_type {
37 AT91_SHDW_WKMODE0_NONE = 0,
38 AT91_SHDW_WKMODE0_HIGH = 1,
39 AT91_SHDW_WKMODE0_LOW = 2,
40 AT91_SHDW_WKMODE0_ANYLEVEL = 3,
41};
42
43static const char *shdwc_wakeup_modes[] = {
44 [AT91_SHDW_WKMODE0_NONE] = "none",
45 [AT91_SHDW_WKMODE0_HIGH] = "high",
46 [AT91_SHDW_WKMODE0_LOW] = "low",
47 [AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
48};
49
50static void __iomem *at91_shdwc_base;
51
52static void __init at91_wakeup_status(void)
53{
54 u32 reg = readl(at91_shdwc_base + AT91_SHDW_SR);
55 char *reason = "unknown";
56
57 /* Simple power-on, just bail out */
58 if (!reg)
59 return;
60
61 if (reg & AT91_SHDW_RTTWK)
62 reason = "RTT";
63 else if (reg & AT91_SHDW_RTCWK)
64 reason = "RTC";
65
66 pr_info("AT91: Wake-Up source: %s\n", reason);
67}
68
69static void at91_poweroff(void)
70{
71 writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
72}
73
74const enum wakeup_type at91_poweroff_get_wakeup_mode(struct device_node *np)
75{
76 const char *pm;
77 int err, i;
78
79 err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
80 if (err < 0)
81 return AT91_SHDW_WKMODE0_ANYLEVEL;
82
83 for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
84 if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
85 return i;
86
87 return -ENODEV;
88}
89
90static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
91{
92 struct device_node *np = pdev->dev.of_node;
93 enum wakeup_type wakeup_mode;
94 u32 mode = 0, tmp;
95
96 wakeup_mode = at91_poweroff_get_wakeup_mode(np);
97 if (wakeup_mode < 0) {
98 dev_warn(&pdev->dev, "shdwc unknown wakeup mode\n");
99 return;
100 }
101
102 if (!of_property_read_u32(np, "atmel,wakeup-counter", &tmp)) {
103 if (tmp > AT91_SHDW_CPTWK0_MAX) {
104 dev_warn(&pdev->dev,
105 "shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n",
106 tmp, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
107 tmp = AT91_SHDW_CPTWK0_MAX;
108 }
109 mode |= AT91_SHDW_CPTWK0_(tmp);
110 }
111
112 if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
113 mode |= AT91_SHDW_RTCWKEN;
114
115 if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
116 mode |= AT91_SHDW_RTTWKEN;
117
118 writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR);
119}
120
121static int at91_poweroff_probe(struct platform_device *pdev)
122{
123 struct resource *res;
124
125 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
126 at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
127 if (IS_ERR(at91_shdwc_base)) {
128 dev_err(&pdev->dev, "Could not map reset controller address\n");
129 return PTR_ERR(at91_shdwc_base);
130 }
131
132 at91_wakeup_status();
133
134 if (pdev->dev.of_node)
135 at91_poweroff_dt_set_wakeup_mode(pdev);
136
137 pm_power_off = at91_poweroff;
138
139 return 0;
140}
141
142static struct of_device_id at91_poweroff_of_match[] = {
143 { .compatible = "atmel,at91sam9260-shdwc", },
144 { .compatible = "atmel,at91sam9rl-shdwc", },
145 { .compatible = "atmel,at91sam9x5-shdwc", },
146 { /*sentinel*/ }
147};
148
149static struct platform_driver at91_poweroff_driver = {
150 .probe = at91_poweroff_probe,
151 .driver = {
152 .name = "at91-poweroff",
153 .of_match_table = at91_poweroff_of_match,
154 },
155};
156module_platform_driver(at91_poweroff_driver);
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
new file mode 100644
index 000000000000..3611806c9cfd
--- /dev/null
+++ b/drivers/power/reset/at91-reset.c
@@ -0,0 +1,252 @@
1/*
2 * Atmel AT91 SAM9 SoCs reset code
3 *
4 * Copyright (C) 2007 Atmel Corporation.
5 * Copyright (C) BitBox Ltd 2010
6 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
7 * Copyright (C) 2014 Free Electrons
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18#include <linux/reboot.h>
19
20#include <asm/system_misc.h>
21
22#include <mach/at91sam9_ddrsdr.h>
23#include <mach/at91sam9_sdramc.h>
24
25#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
26#define AT91_RSTC_PROCRST BIT(0) /* Processor Reset */
27#define AT91_RSTC_PERRST BIT(2) /* Peripheral Reset */
28#define AT91_RSTC_EXTRST BIT(3) /* External Reset */
29#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
30
31#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
32#define AT91_RSTC_URSTS BIT(0) /* User Reset Status */
33#define AT91_RSTC_RSTTYP GENMASK(10, 8) /* Reset Type */
34#define AT91_RSTC_NRSTL BIT(16) /* NRST Pin Level */
35#define AT91_RSTC_SRCMP BIT(17) /* Software Reset Command in Progress */
36
37#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
38#define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */
39#define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */
40#define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */
41
42enum reset_type {
43 RESET_TYPE_GENERAL = 0,
44 RESET_TYPE_WAKEUP = 1,
45 RESET_TYPE_WATCHDOG = 2,
46 RESET_TYPE_SOFTWARE = 3,
47 RESET_TYPE_USER = 4,
48};
49
50static void __iomem *at91_ramc_base[2], *at91_rstc_base;
51
52/*
53* unless the SDRAM is cleanly shutdown before we hit the
54* reset register it can be left driving the data bus and
55* killing the chance of a subsequent boot from NAND
56*/
57static void at91sam9260_restart(enum reboot_mode mode, const char *cmd)
58{
59 asm volatile(
60 /* Align to cache lines */
61 ".balign 32\n\t"
62
63 /* Disable SDRAM accesses */
64 "str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t"
65
66 /* Power down SDRAM */
67 "str %3, [%0, #" __stringify(AT91_SDRAMC_LPR) "]\n\t"
68
69 /* Reset CPU */
70 "str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t"
71
72 "b .\n\t"
73 :
74 : "r" (at91_ramc_base[0]),
75 "r" (at91_rstc_base),
76 "r" (1),
77 "r" (AT91_SDRAMC_LPCB_POWER_DOWN),
78 "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST));
79}
80
81static void at91sam9g45_restart(enum reboot_mode mode, const char *cmd)
82{
83 asm volatile(
84 /*
85 * Test wether we have a second RAM controller to care
86 * about.
87 *
88 * First, test that we can dereference the virtual address.
89 */
90 "cmp %1, #0\n\t"
91 "beq 1f\n\t"
92
93 /* Then, test that the RAM controller is enabled */
94 "ldr r0, [%1]\n\t"
95 "cmp r0, #0\n\t"
96
97 /* Align to cache lines */
98 ".balign 32\n\t"
99
100 /* Disable SDRAM0 accesses */
101 "1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
102 /* Power down SDRAM0 */
103 " str %4, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
104 /* Disable SDRAM1 accesses */
105 " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
106 /* Power down SDRAM1 */
107 " strne %4, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
108 /* Reset CPU */
109 " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
110
111 " b .\n\t"
112 :
113 : "r" (at91_ramc_base[0]),
114 "r" (at91_ramc_base[1]),
115 "r" (at91_rstc_base),
116 "r" (1),
117 "r" (AT91_DDRSDRC_LPCB_POWER_DOWN),
118 "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)
119 : "r0");
120}
121
122static void __init at91_reset_status(struct platform_device *pdev)
123{
124 u32 reg = readl(at91_rstc_base + AT91_RSTC_SR);
125 char *reason;
126
127 switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
128 case RESET_TYPE_GENERAL:
129 reason = "general reset";
130 break;
131 case RESET_TYPE_WAKEUP:
132 reason = "wakeup";
133 break;
134 case RESET_TYPE_WATCHDOG:
135 reason = "watchdog reset";
136 break;
137 case RESET_TYPE_SOFTWARE:
138 reason = "software reset";
139 break;
140 case RESET_TYPE_USER:
141 reason = "user reset";
142 break;
143 default:
144 reason = "unknown reset";
145 break;
146 }
147
148 pr_info("AT91: Starting after %s\n", reason);
149}
150
151static struct of_device_id at91_ramc_of_match[] = {
152 { .compatible = "atmel,at91sam9260-sdramc", },
153 { .compatible = "atmel,at91sam9g45-ddramc", },
154 { .compatible = "atmel,sama5d3-ddramc", },
155 { /* sentinel */ }
156};
157
158static struct of_device_id at91_reset_of_match[] = {
159 { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart },
160 { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
161 { /* sentinel */ }
162};
163
164static int at91_reset_of_probe(struct platform_device *pdev)
165{
166 const struct of_device_id *match;
167 struct device_node *np;
168 int idx = 0;
169
170 at91_rstc_base = of_iomap(pdev->dev.of_node, 0);
171 if (!at91_rstc_base) {
172 dev_err(&pdev->dev, "Could not map reset controller address\n");
173 return -ENODEV;
174 }
175
176 for_each_matching_node(np, at91_ramc_of_match) {
177 at91_ramc_base[idx] = of_iomap(np, 0);
178 if (!at91_ramc_base[idx]) {
179 dev_err(&pdev->dev, "Could not map ram controller address\n");
180 return -ENODEV;
181 }
182 idx++;
183 }
184
185 match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
186 arm_pm_restart = match->data;
187
188 return 0;
189}
190
191static int at91_reset_platform_probe(struct platform_device *pdev)
192{
193 const struct platform_device_id *match;
194 struct resource *res;
195 int idx = 0;
196
197 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
198 at91_rstc_base = devm_ioremap_resource(&pdev->dev, res);
199 if (IS_ERR(at91_rstc_base)) {
200 dev_err(&pdev->dev, "Could not map reset controller address\n");
201 return PTR_ERR(at91_rstc_base);
202 }
203
204 for (idx = 0; idx < 2; idx++) {
205 res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 );
206 at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start,
207 resource_size(res));
208 if (IS_ERR(at91_ramc_base[idx])) {
209 dev_err(&pdev->dev, "Could not map ram controller address\n");
210 return PTR_ERR(at91_ramc_base[idx]);
211 }
212 }
213
214 match = platform_get_device_id(pdev);
215 arm_pm_restart = (void (*)(enum reboot_mode, const char*))
216 match->driver_data;
217
218 return 0;
219}
220
221static int at91_reset_probe(struct platform_device *pdev)
222{
223 int ret;
224
225 if (pdev->dev.of_node)
226 ret = at91_reset_of_probe(pdev);
227 else
228 ret = at91_reset_platform_probe(pdev);
229
230 if (ret)
231 return ret;
232
233 at91_reset_status(pdev);
234
235 return 0;
236}
237
238static struct platform_device_id at91_reset_plat_match[] = {
239 { "at91-sam9260-reset", (unsigned long)at91sam9260_restart },
240 { "at91-sam9g45-reset", (unsigned long)at91sam9g45_restart },
241 { /* sentinel */ }
242};
243
244static struct platform_driver at91_reset_driver = {
245 .probe = at91_reset_probe,
246 .driver = {
247 .name = "at91-reset",
248 .of_match_table = at91_reset_of_match,
249 },
250 .id_table = at91_reset_plat_match,
251};
252module_platform_driver(at91_reset_driver);