aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi221
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts84
-rw-r--r--arch/arm/boot/dts/emev2-kzm9d.dts26
-rw-r--r--arch/arm/boot/dts/emev2.dtsi63
-rw-r--r--arch/arm/mach-at91/Kconfig8
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/Makefile.boot2
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c233
-rw-r--r--arch/arm/mach-at91/clock.c15
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9n12.h60
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9n12_matrix.h53
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h10
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h1
-rw-r--r--arch/arm/mach-at91/setup.c6
-rw-r--r--arch/arm/mach-at91/soc.h5
-rw-r--r--arch/arm/mach-shmobile/Kconfig11
-rw-r--r--arch/arm/mach-shmobile/Makefile3
-rw-r--r--arch/arm/mach-shmobile/board-kzm9d.c85
-rw-r--r--arch/arm/mach-shmobile/clock-emev2.c249
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c125
-rw-r--r--arch/arm/mach-shmobile/include/mach/emev2.h19
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h34
-rw-r--r--arch/arm/mach-shmobile/pfc-r8a7740.c39
-rw-r--r--arch/arm/mach-shmobile/platsmp.c18
-rw-r--r--arch/arm/mach-shmobile/setup-emev2.c452
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c12
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c10
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c97
-rw-r--r--arch/arm/mach-shmobile/timer.c3
-rw-r--r--arch/arm/mach-ux500/board-mop500-uib.c2
-rw-r--r--arch/arm/mach-ux500/cache-l2x0.c16
-rw-r--r--arch/arm/mach-ux500/clock.c2
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c24
-rw-r--r--arch/arm/mach-ux500/cpu.c4
-rw-r--r--arch/arm/mach-ux500/id.c9
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h6
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h3
-rw-r--r--arch/arm/mach-ux500/include/mach/id.h17
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-ux500/platsmp.c4
-rw-r--r--arch/arm/mach-ux500/timer.c2
-rw-r--r--drivers/cpufreq/db8500-cpufreq.c2
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-em.c418
-rw-r--r--include/linux/platform_data/gpio-em.h10
47 files changed, 2439 insertions, 36 deletions
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
new file mode 100644
index 000000000000..cb84de791b5a
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -0,0 +1,221 @@
1/*
2 * at91sam9n12.dtsi - Device Tree include file for AT91SAM9N12 SoC
3 *
4 * Copyright (C) 2012 Atmel,
5 * 2012 Hong Xu <hong.xu@atmel.com>
6 *
7 * Licensed under GPLv2 or later.
8 */
9
10/include/ "skeleton.dtsi"
11
12/ {
13 model = "Atmel AT91SAM9N12 SoC";
14 compatible = "atmel,at91sam9n12";
15 interrupt-parent = <&aic>;
16
17 aliases {
18 serial0 = &dbgu;
19 serial1 = &usart0;
20 serial2 = &usart1;
21 serial3 = &usart2;
22 serial4 = &usart3;
23 gpio0 = &pioA;
24 gpio1 = &pioB;
25 gpio2 = &pioC;
26 gpio3 = &pioD;
27 tcb0 = &tcb0;
28 tcb1 = &tcb1;
29 };
30 cpus {
31 cpu@0 {
32 compatible = "arm,arm926ejs";
33 };
34 };
35
36 memory {
37 reg = <0x20000000 0x10000000>;
38 };
39
40 ahb {
41 compatible = "simple-bus";
42 #address-cells = <1>;
43 #size-cells = <1>;
44 ranges;
45
46 apb {
47 compatible = "simple-bus";
48 #address-cells = <1>;
49 #size-cells = <1>;
50 ranges;
51
52 aic: interrupt-controller@fffff000 {
53 #interrupt-cells = <2>;
54 compatible = "atmel,at91rm9200-aic";
55 interrupt-controller;
56 reg = <0xfffff000 0x200>;
57 };
58
59 ramc0: ramc@ffffe800 {
60 compatible = "atmel,at91sam9g45-ddramc";
61 reg = <0xffffe800 0x200>;
62 };
63
64 pmc: pmc@fffffc00 {
65 compatible = "atmel,at91rm9200-pmc";
66 reg = <0xfffffc00 0x100>;
67 };
68
69 rstc@fffffe00 {
70 compatible = "atmel,at91sam9g45-rstc";
71 reg = <0xfffffe00 0x10>;
72 };
73
74 pit: timer@fffffe30 {
75 compatible = "atmel,at91sam9260-pit";
76 reg = <0xfffffe30 0xf>;
77 interrupts = <1 4>;
78 };
79
80 shdwc@fffffe10 {
81 compatible = "atmel,at91sam9x5-shdwc";
82 reg = <0xfffffe10 0x10>;
83 };
84
85 tcb0: timer@f8008000 {
86 compatible = "atmel,at91sam9x5-tcb";
87 reg = <0xf8008000 0x100>;
88 interrupts = <17 4>;
89 };
90
91 tcb1: timer@f800c000 {
92 compatible = "atmel,at91sam9x5-tcb";
93 reg = <0xf800c000 0x100>;
94 interrupts = <17 4>;
95 };
96
97 dma: dma-controller@ffffec00 {
98 compatible = "atmel,at91sam9g45-dma";
99 reg = <0xffffec00 0x200>;
100 interrupts = <20 4>;
101 };
102
103 pioA: gpio@fffff400 {
104 compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
105 reg = <0xfffff400 0x100>;
106 interrupts = <2 4>;
107 #gpio-cells = <2>;
108 gpio-controller;
109 interrupt-controller;
110 };
111
112 pioB: gpio@fffff600 {
113 compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
114 reg = <0xfffff600 0x100>;
115 interrupts = <2 4>;
116 #gpio-cells = <2>;
117 gpio-controller;
118 interrupt-controller;
119 };
120
121 pioC: gpio@fffff800 {
122 compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
123 reg = <0xfffff800 0x100>;
124 interrupts = <3 4>;
125 #gpio-cells = <2>;
126 gpio-controller;
127 interrupt-controller;
128 };
129
130 pioD: gpio@fffffa00 {
131 compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
132 reg = <0xfffffa00 0x100>;
133 interrupts = <3 4>;
134 #gpio-cells = <2>;
135 gpio-controller;
136 interrupt-controller;
137 };
138
139 dbgu: serial@fffff200 {
140 compatible = "atmel,at91sam9260-usart";
141 reg = <0xfffff200 0x200>;
142 interrupts = <1 4>;
143 status = "disabled";
144 };
145
146 usart0: serial@f801c000 {
147 compatible = "atmel,at91sam9260-usart";
148 reg = <0xf801c000 0x4000>;
149 interrupts = <5 4>;
150 atmel,use-dma-rx;
151 atmel,use-dma-tx;
152 status = "disabled";
153 };
154
155 usart1: serial@f8020000 {
156 compatible = "atmel,at91sam9260-usart";
157 reg = <0xf8020000 0x4000>;
158 interrupts = <6 4>;
159 atmel,use-dma-rx;
160 atmel,use-dma-tx;
161 status = "disabled";
162 };
163
164 usart2: serial@f8024000 {
165 compatible = "atmel,at91sam9260-usart";
166 reg = <0xf8024000 0x4000>;
167 interrupts = <7 4>;
168 atmel,use-dma-rx;
169 atmel,use-dma-tx;
170 status = "disabled";
171 };
172
173 usart3: serial@f8028000 {
174 compatible = "atmel,at91sam9260-usart";
175 reg = <0xf8028000 0x4000>;
176 interrupts = <8 4>;
177 atmel,use-dma-rx;
178 atmel,use-dma-tx;
179 status = "disabled";
180 };
181 };
182
183 nand0: nand@40000000 {
184 compatible = "atmel,at91rm9200-nand";
185 #address-cells = <1>;
186 #size-cells = <1>;
187 reg = < 0x40000000 0x10000000
188 0xffffe000 0x00000600
189 0xffffe600 0x00000200
190 0x00100000 0x00100000
191 >;
192 atmel,nand-addr-offset = <21>;
193 atmel,nand-cmd-offset = <22>;
194 gpios = <&pioD 5 0
195 &pioD 4 0
196 0
197 >;
198 status = "disabled";
199 };
200
201 usb0: ohci@00500000 {
202 compatible = "atmel,at91rm9200-ohci", "usb-ohci";
203 reg = <0x00500000 0x00100000>;
204 interrupts = <22 4>;
205 status = "disabled";
206 };
207 };
208
209 i2c@0 {
210 compatible = "i2c-gpio";
211 gpios = <&pioA 30 0 /* sda */
212 &pioA 31 0 /* scl */
213 >;
214 i2c-gpio,sda-open-drain;
215 i2c-gpio,scl-open-drain;
216 i2c-gpio,delay-us = <2>; /* ~100 kHz */
217 #address-cells = <1>;
218 #size-cells = <0>;
219 status = "disabled";
220 };
221};
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
new file mode 100644
index 000000000000..f4e43e38f3a1
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -0,0 +1,84 @@
1/*
2 * at91sam9n12ek.dts - Device Tree file for AT91SAM9N12-EK board
3 *
4 * Copyright (C) 2012 Atmel,
5 * 2012 Hong Xu <hong.xu@atmel.com>
6 *
7 * Licensed under GPLv2 or later.
8 */
9/dts-v1/;
10/include/ "at91sam9n12.dtsi"
11
12/ {
13 model = "Atmel AT91SAM9N12-EK";
14 compatible = "atmel,at91sam9n12ek", "atmel,at91sam9n12", "atmel,at91sam9";
15
16 chosen {
17 bootargs = "mem=128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
18 };
19
20 memory {
21 reg = <0x20000000 0x10000000>;
22 };
23
24 clocks {
25 #address-cells = <1>;
26 #size-cells = <1>;
27 ranges;
28
29 main_clock: clock@0 {
30 compatible = "atmel,osc", "fixed-clock";
31 clock-frequency = <16000000>;
32 };
33 };
34
35 ahb {
36 apb {
37 dbgu: serial@fffff200 {
38 status = "okay";
39 };
40 };
41
42 nand0: nand@40000000 {
43 nand-bus-width = <8>;
44 nand-ecc-mode = "soft";
45 nand-on-flash-bbt;
46 status = "okay";
47 };
48 };
49
50 leds {
51 compatible = "gpio-leds";
52
53 d8 {
54 label = "d8";
55 gpios = <&pioB 4 1>;
56 linux,default-trigger = "mmc0";
57 };
58
59 d9 {
60 label = "d6";
61 gpios = <&pioB 5 1>;
62 linux,default-trigger = "nand-disk";
63 };
64
65 d10 {
66 label = "d7";
67 gpios = <&pioB 6 0>;
68 linux,default-trigger = "heartbeat";
69 };
70 };
71
72 gpio_keys {
73 compatible = "gpio-keys";
74 #address-cells = <1>;
75 #size-cells = <0>;
76
77 enter {
78 label = "Enter";
79 gpios = <&pioB 4 1>;
80 linux,code = <28>;
81 gpio-key,wakeup;
82 };
83 };
84};
diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts
new file mode 100644
index 000000000000..297e3baba71c
--- /dev/null
+++ b/arch/arm/boot/dts/emev2-kzm9d.dts
@@ -0,0 +1,26 @@
1/*
2 * Device Tree Source for the KZM9D board
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10/dts-v1/;
11
12/include/ "emev2.dtsi"
13
14/ {
15 model = "EMEV2 KZM9D Board";
16 compatible = "renesas,kzm9d", "renesas,emev2";
17
18 memory {
19 device_type = "memory";
20 reg = <0x40000000 0x8000000>;
21 };
22
23 chosen {
24 bootargs = "console=ttyS1,115200n81";
25 };
26};
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
new file mode 100644
index 000000000000..eb504a6c0f4a
--- /dev/null
+++ b/arch/arm/boot/dts/emev2.dtsi
@@ -0,0 +1,63 @@
1/*
2 * Device Tree Source for the EMEV2 SoC
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11/include/ "skeleton.dtsi"
12
13/ {
14 compatible = "renesas,emev2";
15 interrupt-parent = <&gic>;
16
17 cpus {
18 cpu@0 {
19 compatible = "arm,cortex-a9";
20 };
21 cpu@1 {
22 compatible = "arm,cortex-a9";
23 };
24 };
25
26 gic: interrupt-controller@e0020000 {
27 compatible = "arm,cortex-a9-gic";
28 interrupt-controller;
29 #interrupt-cells = <3>;
30 reg = <0xe0028000 0x1000>,
31 <0xe0020000 0x0100>;
32 };
33
34 sti@e0180000 {
35 compatible = "renesas,em-sti";
36 reg = <0xe0180000 0x54>;
37 interrupts = <0 125 0>;
38 };
39
40 uart@e1020000 {
41 compatible = "renesas,em-uart";
42 reg = <0xe1020000 0x38>;
43 interrupts = <0 8 0>;
44 };
45
46 uart@e1030000 {
47 compatible = "renesas,em-uart";
48 reg = <0xe1030000 0x38>;
49 interrupts = <0 9 0>;
50 };
51
52 uart@e1040000 {
53 compatible = "renesas,em-uart";
54 reg = <0xe1040000 0x38>;
55 interrupts = <0 10 0>;
56 };
57
58 uart@e1050000 {
59 compatible = "renesas,em-uart";
60 reg = <0xe1050000 0x38>;
61 interrupts = <0 11 0>;
62 };
63};
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 98a42f3472d5..19505c0a3f01 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -91,6 +91,14 @@ config SOC_AT91SAM9X5
91 This support covers AT91SAM9G15, AT91SAM9G25, AT91SAM9X25, AT91SAM9G35 91 This support covers AT91SAM9G15, AT91SAM9G25, AT91SAM9X25, AT91SAM9G35
92 and AT91SAM9X35. 92 and AT91SAM9X35.
93 93
94config SOC_AT91SAM9N12
95 bool "AT91SAM9N12 family"
96 select SOC_AT91SAM9
97 select HAVE_AT91_DBGU0
98 select HAVE_FB_ATMEL
99 help
100 Select this if you are using Atmel's AT91SAM9N12 SoC.
101
94choice 102choice
95 prompt "Atmel AT91 Processor Devices for non DT boards" 103 prompt "Atmel AT91 Processor Devices for non DT boards"
96 104
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 79d0f60af0b2..3bb7a51efc9d 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SOC_AT91SAM9260) += at91sam9260.o
18obj-$(CONFIG_SOC_AT91SAM9261) += at91sam9261.o 18obj-$(CONFIG_SOC_AT91SAM9261) += at91sam9261.o
19obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o 19obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o
20obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o 20obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o
21obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o
21obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o 22obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o
22obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o 23obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o
23 24
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index c03417ddbf0c..9e84fe4f2aaa 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -30,5 +30,7 @@ dtb-$(CONFIG_MACH_AT91SAM_DT) += tny_a9g20.dtb
30dtb-$(CONFIG_MACH_AT91SAM_DT) += usb_a9g20.dtb 30dtb-$(CONFIG_MACH_AT91SAM_DT) += usb_a9g20.dtb
31# sam9g45 31# sam9g45
32dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb 32dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb
33# sam9n12
34dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9n12ek.dtb
33# sam9x5 35# sam9x5
34dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9g25ek.dtb 36dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9g25ek.dtb
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
new file mode 100644
index 000000000000..08494664ab78
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -0,0 +1,233 @@
1/*
2 * SoC specific setup code for the AT91SAM9N12
3 *
4 * Copyright (C) 2012 Atmel Corporation.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/module.h>
10#include <linux/dma-mapping.h>
11
12#include <asm/irq.h>
13#include <asm/mach/arch.h>
14#include <asm/mach/map.h>
15#include <mach/at91sam9n12.h>
16#include <mach/at91_pmc.h>
17#include <mach/cpu.h>
18#include <mach/board.h>
19
20#include "soc.h"
21#include "generic.h"
22#include "clock.h"
23#include "sam9_smc.h"
24
25/* --------------------------------------------------------------------
26 * Clocks
27 * -------------------------------------------------------------------- */
28
29/*
30 * The peripheral clocks.
31 */
32static struct clk pioAB_clk = {
33 .name = "pioAB_clk",
34 .pmc_mask = 1 << AT91SAM9N12_ID_PIOAB,
35 .type = CLK_TYPE_PERIPHERAL,
36};
37static struct clk pioCD_clk = {
38 .name = "pioCD_clk",
39 .pmc_mask = 1 << AT91SAM9N12_ID_PIOCD,
40 .type = CLK_TYPE_PERIPHERAL,
41};
42static struct clk usart0_clk = {
43 .name = "usart0_clk",
44 .pmc_mask = 1 << AT91SAM9N12_ID_USART0,
45 .type = CLK_TYPE_PERIPHERAL,
46};
47static struct clk usart1_clk = {
48 .name = "usart1_clk",
49 .pmc_mask = 1 << AT91SAM9N12_ID_USART1,
50 .type = CLK_TYPE_PERIPHERAL,
51};
52static struct clk usart2_clk = {
53 .name = "usart2_clk",
54 .pmc_mask = 1 << AT91SAM9N12_ID_USART2,
55 .type = CLK_TYPE_PERIPHERAL,
56};
57static struct clk usart3_clk = {
58 .name = "usart3_clk",
59 .pmc_mask = 1 << AT91SAM9N12_ID_USART3,
60 .type = CLK_TYPE_PERIPHERAL,
61};
62static struct clk twi0_clk = {
63 .name = "twi0_clk",
64 .pmc_mask = 1 << AT91SAM9N12_ID_TWI0,
65 .type = CLK_TYPE_PERIPHERAL,
66};
67static struct clk twi1_clk = {
68 .name = "twi1_clk",
69 .pmc_mask = 1 << AT91SAM9N12_ID_TWI1,
70 .type = CLK_TYPE_PERIPHERAL,
71};
72static struct clk mmc_clk = {
73 .name = "mci_clk",
74 .pmc_mask = 1 << AT91SAM9N12_ID_MCI,
75 .type = CLK_TYPE_PERIPHERAL,
76};
77static struct clk spi0_clk = {
78 .name = "spi0_clk",
79 .pmc_mask = 1 << AT91SAM9N12_ID_SPI0,
80 .type = CLK_TYPE_PERIPHERAL,
81};
82static struct clk spi1_clk = {
83 .name = "spi1_clk",
84 .pmc_mask = 1 << AT91SAM9N12_ID_SPI1,
85 .type = CLK_TYPE_PERIPHERAL,
86};
87static struct clk uart0_clk = {
88 .name = "uart0_clk",
89 .pmc_mask = 1 << AT91SAM9N12_ID_UART0,
90 .type = CLK_TYPE_PERIPHERAL,
91};
92static struct clk uart1_clk = {
93 .name = "uart1_clk",
94 .pmc_mask = 1 << AT91SAM9N12_ID_UART1,
95 .type = CLK_TYPE_PERIPHERAL,
96};
97static struct clk tcb_clk = {
98 .name = "tcb_clk",
99 .pmc_mask = 1 << AT91SAM9N12_ID_TCB,
100 .type = CLK_TYPE_PERIPHERAL,
101};
102static struct clk pwm_clk = {
103 .name = "pwm_clk",
104 .pmc_mask = 1 << AT91SAM9N12_ID_PWM,
105 .type = CLK_TYPE_PERIPHERAL,
106};
107static struct clk adc_clk = {
108 .name = "adc_clk",
109 .pmc_mask = 1 << AT91SAM9N12_ID_ADC,
110 .type = CLK_TYPE_PERIPHERAL,
111};
112static struct clk dma_clk = {
113 .name = "dma_clk",
114 .pmc_mask = 1 << AT91SAM9N12_ID_DMA,
115 .type = CLK_TYPE_PERIPHERAL,
116};
117static struct clk uhp_clk = {
118 .name = "uhp",
119 .pmc_mask = 1 << AT91SAM9N12_ID_UHP,
120 .type = CLK_TYPE_PERIPHERAL,
121};
122static struct clk udp_clk = {
123 .name = "udp_clk",
124 .pmc_mask = 1 << AT91SAM9N12_ID_UDP,
125 .type = CLK_TYPE_PERIPHERAL,
126};
127static struct clk lcdc_clk = {
128 .name = "lcdc_clk",
129 .pmc_mask = 1 << AT91SAM9N12_ID_LCDC,
130 .type = CLK_TYPE_PERIPHERAL,
131};
132static struct clk ssc_clk = {
133 .name = "ssc_clk",
134 .pmc_mask = 1 << AT91SAM9N12_ID_SSC,
135 .type = CLK_TYPE_PERIPHERAL,
136};
137
138static struct clk *periph_clocks[] __initdata = {
139 &pioAB_clk,
140 &pioCD_clk,
141 &usart0_clk,
142 &usart1_clk,
143 &usart2_clk,
144 &usart3_clk,
145 &twi0_clk,
146 &twi1_clk,
147 &mmc_clk,
148 &spi0_clk,
149 &spi1_clk,
150 &lcdc_clk,
151 &uart0_clk,
152 &uart1_clk,
153 &tcb_clk,
154 &pwm_clk,
155 &adc_clk,
156 &dma_clk,
157 &uhp_clk,
158 &udp_clk,
159 &ssc_clk,
160};
161
162static struct clk_lookup periph_clocks_lookups[] = {
163 /* lookup table for DT entries */
164 CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
165 CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk),
166 CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk),
167 CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk),
168 CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
169 CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk),
170 CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk),
171 CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk),
172 CLKDEV_CON_ID("pioA", &pioAB_clk),
173 CLKDEV_CON_ID("pioB", &pioAB_clk),
174 CLKDEV_CON_ID("pioC", &pioCD_clk),
175 CLKDEV_CON_ID("pioD", &pioCD_clk),
176 /* additional fake clock for macb_hclk */
177 CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk),
178 CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk),
179};
180
181/*
182 * The two programmable clocks.
183 * You must configure pin multiplexing to bring these signals out.
184 */
185static struct clk pck0 = {
186 .name = "pck0",
187 .pmc_mask = AT91_PMC_PCK0,
188 .type = CLK_TYPE_PROGRAMMABLE,
189 .id = 0,
190};
191static struct clk pck1 = {
192 .name = "pck1",
193 .pmc_mask = AT91_PMC_PCK1,
194 .type = CLK_TYPE_PROGRAMMABLE,
195 .id = 1,
196};
197
198static void __init at91sam9n12_register_clocks(void)
199{
200 int i;
201
202 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
203 clk_register(periph_clocks[i]);
204 clk_register(&pck0);
205 clk_register(&pck1);
206
207 clkdev_add_table(periph_clocks_lookups,
208 ARRAY_SIZE(periph_clocks_lookups));
209
210}
211
212/* --------------------------------------------------------------------
213 * AT91SAM9N12 processor initialization
214 * -------------------------------------------------------------------- */
215
216static void __init at91sam9n12_map_io(void)
217{
218 at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
219}
220
221void __init at91sam9n12_initialize(void)
222{
223 at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0);
224
225 /* Register GPIO subsystem (using DT) */
226 at91_gpio_init(NULL, 0);
227}
228
229struct at91_init_soc __initdata at91sam9n12_soc = {
230 .map_io = at91sam9n12_map_io,
231 .register_clocks = at91sam9n12_register_clocks,
232 .init = at91sam9n12_initialize,
233};
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 6b692824c988..de2ec6b8fea7 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -58,13 +58,15 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);
58 58
59#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ 59#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
60 || cpu_is_at91sam9g45() \ 60 || cpu_is_at91sam9g45() \
61 || cpu_is_at91sam9x5()) 61 || cpu_is_at91sam9x5() \
62 || cpu_is_at91sam9n12())
62 63
63#define cpu_has_300M_plla() (cpu_is_at91sam9g10()) 64#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
64 65
65#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ 66#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
66 || cpu_is_at91sam9g45() \ 67 || cpu_is_at91sam9g45() \
67 || cpu_is_at91sam9x5())) 68 || cpu_is_at91sam9x5() \
69 || cpu_is_at91sam9n12()))
68 70
69#define cpu_has_upll() (cpu_is_at91sam9g45() \ 71#define cpu_has_upll() (cpu_is_at91sam9g45() \
70 || cpu_is_at91sam9x5()) 72 || cpu_is_at91sam9x5())
@@ -78,12 +80,15 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);
78 || cpu_is_at91sam9x5())) 80 || cpu_is_at91sam9x5()))
79 81
80#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ 82#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \
81 || cpu_is_at91sam9x5()) 83 || cpu_is_at91sam9x5() \
84 || cpu_is_at91sam9n12())
82 85
83#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ 86#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \
84 || cpu_is_at91sam9x5()) 87 || cpu_is_at91sam9x5() \
88 || cpu_is_at91sam9n12())
85 89
86#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5()) 90#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \
91 || cpu_is_at91sam9n12())
87 92
88static LIST_HEAD(clocks); 93static LIST_HEAD(clocks);
89static DEFINE_SPINLOCK(clk_lock); 94static DEFINE_SPINLOCK(clk_lock);
diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12.h b/arch/arm/mach-at91/include/mach/at91sam9n12.h
new file mode 100644
index 000000000000..d374b87c0459
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9n12.h
@@ -0,0 +1,60 @@
1/*
2 * SoC specific header file for the AT91SAM9N12
3 *
4 * Copyright (C) 2012 Atmel Corporation
5 *
6 * Common definitions, based on AT91SAM9N12 SoC datasheet
7 *
8 * Licensed under GPLv2 or later
9 */
10
11#ifndef _AT91SAM9N12_H_
12#define _AT91SAM9N12_H_
13
14/*
15 * Peripheral identifiers/interrupts.
16 */
17#define AT91SAM9N12_ID_PIOAB 2 /* Parallel I/O Controller A and B */
18#define AT91SAM9N12_ID_PIOCD 3 /* Parallel I/O Controller C and D */
19#define AT91SAM9N12_ID_FUSE 4 /* FUSE Controller */
20#define AT91SAM9N12_ID_USART0 5 /* USART 0 */
21#define AT91SAM9N12_ID_USART1 6 /* USART 1 */
22#define AT91SAM9N12_ID_USART2 7 /* USART 2 */
23#define AT91SAM9N12_ID_USART3 8 /* USART 3 */
24#define AT91SAM9N12_ID_TWI0 9 /* Two-Wire Interface 0 */
25#define AT91SAM9N12_ID_TWI1 10 /* Two-Wire Interface 1 */
26#define AT91SAM9N12_ID_MCI 12 /* High Speed Multimedia Card Interface */
27#define AT91SAM9N12_ID_SPI0 13 /* Serial Peripheral Interface 0 */
28#define AT91SAM9N12_ID_SPI1 14 /* Serial Peripheral Interface 1 */
29#define AT91SAM9N12_ID_UART0 15 /* UART 0 */
30#define AT91SAM9N12_ID_UART1 16 /* UART 1 */
31#define AT91SAM9N12_ID_TCB 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */
32#define AT91SAM9N12_ID_PWM 18 /* Pulse Width Modulation Controller */
33#define AT91SAM9N12_ID_ADC 19 /* ADC Controller */
34#define AT91SAM9N12_ID_DMA 20 /* DMA Controller */
35#define AT91SAM9N12_ID_UHP 22 /* USB Host High Speed */
36#define AT91SAM9N12_ID_UDP 23 /* USB Device High Speed */
37#define AT91SAM9N12_ID_LCDC 25 /* LCD Controller */
38#define AT91SAM9N12_ID_ISI 25 /* Image Sensor Interface */
39#define AT91SAM9N12_ID_SSC 28 /* Synchronous Serial Controller */
40#define AT91SAM9N12_ID_TRNG 30 /* TRNG */
41#define AT91SAM9N12_ID_IRQ0 31 /* Advanced Interrupt Controller */
42
43/*
44 * User Peripheral physical base addresses.
45 */
46#define AT91SAM9N12_BASE_USART0 0xf801c000
47#define AT91SAM9N12_BASE_USART1 0xf8020000
48#define AT91SAM9N12_BASE_USART2 0xf8024000
49#define AT91SAM9N12_BASE_USART3 0xf8028000
50
51/*
52 * Internal Memory.
53 */
54#define AT91SAM9N12_SRAM_BASE 0x00300000 /* Internal SRAM base address */
55#define AT91SAM9N12_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */
56
57#define AT91SAM9N12_ROM_BASE 0x00100000 /* Internal ROM base address */
58#define AT91SAM9N12_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */
59
60#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9n12_matrix.h
new file mode 100644
index 000000000000..40060cd62fa9
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9n12_matrix.h
@@ -0,0 +1,53 @@
1/*
2 * Matrix-centric header file for the AT91SAM9N12
3 *
4 * Copyright (C) 2012 Atmel Corporation.
5 *
6 * Only EBI related registers.
7 * Write Protect register definitions may be useful.
8 *
9 * Licensed under GPLv2 or later.
10 */
11
12#ifndef _AT91SAM9N12_MATRIX_H_
13#define _AT91SAM9N12_MATRIX_H_
14
15#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x118) /* EBI Chip Select Assignment Register */
16#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
17#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
18#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
19#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
20#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
21#define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3)
22#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
23#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
24#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
25#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
26#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
27#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
28#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
29#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
30#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
31#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
32#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
33#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
34#define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */
35#define AT91_MATRIX_NFD0_ON_D0 (0 << 24)
36#define AT91_MATRIX_NFD0_ON_D16 (1 << 24)
37#define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */
38#define AT91_MATRIX_MP_OFF (0 << 25)
39#define AT91_MATRIX_MP_ON (1 << 25)
40
41#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
42#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
43#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
44#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
45#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
46
47#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
48#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
49#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
50#define AT91_MATRIX_WPSR_WPV (1 << 0)
51#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
52
53#endif
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 73d2fd209ce4..b6504c19d55c 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -25,6 +25,7 @@
25#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ 25#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
26#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ 26#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
27#define ARCH_ID_AT91SAM9X5 0x819a05a0 27#define ARCH_ID_AT91SAM9X5 0x819a05a0
28#define ARCH_ID_AT91SAM9N12 0x819a07a0
28 29
29#define ARCH_ID_AT91SAM9XE128 0x329973a0 30#define ARCH_ID_AT91SAM9XE128 0x329973a0
30#define ARCH_ID_AT91SAM9XE256 0x329a93a0 31#define ARCH_ID_AT91SAM9XE256 0x329a93a0
@@ -71,6 +72,9 @@ enum at91_soc_type {
71 /* SAM9X5 */ 72 /* SAM9X5 */
72 AT91_SOC_SAM9X5, 73 AT91_SOC_SAM9X5,
73 74
75 /* SAM9N12 */
76 AT91_SOC_SAM9N12,
77
74 /* Unknown type */ 78 /* Unknown type */
75 AT91_SOC_NONE 79 AT91_SOC_NONE
76}; 80};
@@ -177,6 +181,12 @@ static inline int at91_soc_is_detected(void)
177#define cpu_is_at91sam9x25() (0) 181#define cpu_is_at91sam9x25() (0)
178#endif 182#endif
179 183
184#ifdef CONFIG_SOC_AT91SAM9N12
185#define cpu_is_at91sam9n12() (at91_soc_initdata.type == AT91_SOC_SAM9N12)
186#else
187#define cpu_is_at91sam9n12() (0)
188#endif
189
180/* 190/*
181 * Since this is ARM, we will never run on any AVR32 CPU. But these 191 * Since this is ARM, we will never run on any AVR32 CPU. But these
182 * definitions may reduce clutter in common drivers. 192 * definitions may reduce clutter in common drivers.
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index ef5786299c60..09242b67d277 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -32,6 +32,7 @@
32#include <mach/at91sam9rl.h> 32#include <mach/at91sam9rl.h>
33#include <mach/at91sam9g45.h> 33#include <mach/at91sam9g45.h>
34#include <mach/at91sam9x5.h> 34#include <mach/at91sam9x5.h>
35#include <mach/at91sam9n12.h>
35 36
36/* 37/*
37 * On all at91 except rm9200 and x40 have the System Controller starts 38 * On all at91 except rm9200 and x40 have the System Controller starts
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index f44a2e7272e3..944bffb08991 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -143,6 +143,11 @@ static void __init soc_detect(u32 dbgu_base)
143 at91_soc_initdata.type = AT91_SOC_SAM9X5; 143 at91_soc_initdata.type = AT91_SOC_SAM9X5;
144 at91_boot_soc = at91sam9x5_soc; 144 at91_boot_soc = at91sam9x5_soc;
145 break; 145 break;
146
147 case ARCH_ID_AT91SAM9N12:
148 at91_soc_initdata.type = AT91_SOC_SAM9N12;
149 at91_boot_soc = at91sam9n12_soc;
150 break;
146 } 151 }
147 152
148 /* at91sam9g10 */ 153 /* at91sam9g10 */
@@ -210,6 +215,7 @@ static const char *soc_name[] = {
210 [AT91_SOC_SAM9G45] = "at91sam9g45", 215 [AT91_SOC_SAM9G45] = "at91sam9g45",
211 [AT91_SOC_SAM9RL] = "at91sam9rl", 216 [AT91_SOC_SAM9RL] = "at91sam9rl",
212 [AT91_SOC_SAM9X5] = "at91sam9x5", 217 [AT91_SOC_SAM9X5] = "at91sam9x5",
218 [AT91_SOC_SAM9N12] = "at91sam9n12",
213 [AT91_SOC_NONE] = "Unknown" 219 [AT91_SOC_NONE] = "Unknown"
214}; 220};
215 221
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 683dddfd8b13..a9cfeb153719 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -20,6 +20,7 @@ extern struct at91_init_soc at91sam9263_soc;
20extern struct at91_init_soc at91sam9g45_soc; 20extern struct at91_init_soc at91sam9g45_soc;
21extern struct at91_init_soc at91sam9rl_soc; 21extern struct at91_init_soc at91sam9rl_soc;
22extern struct at91_init_soc at91sam9x5_soc; 22extern struct at91_init_soc at91sam9x5_soc;
23extern struct at91_init_soc at91sam9n12_soc;
23 24
24static inline int at91_soc_is_enabled(void) 25static inline int at91_soc_is_enabled(void)
25{ 26{
@@ -53,3 +54,7 @@ static inline int at91_soc_is_enabled(void)
53#if !defined(CONFIG_SOC_AT91SAM9X5) 54#if !defined(CONFIG_SOC_AT91SAM9X5)
54#define at91sam9x5_soc at91_boot_soc 55#define at91sam9x5_soc at91_boot_soc
55#endif 56#endif
57
58#if !defined(CONFIG_SOC_AT91SAM9N12)
59#define at91sam9n12_soc at91_boot_soc
60#endif
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 34560cab45d9..7dcf08ee979d 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -41,6 +41,12 @@ config ARCH_R8A7779
41 select ARM_GIC 41 select ARM_GIC
42 select ARCH_WANT_OPTIONAL_GPIOLIB 42 select ARCH_WANT_OPTIONAL_GPIOLIB
43 43
44config ARCH_EMEV2
45 bool "Emma Mobile EV2"
46 select CPU_V7
47 select ARM_GIC
48 select ARCH_WANT_OPTIONAL_GPIOLIB
49
44comment "SH-Mobile Board Type" 50comment "SH-Mobile Board Type"
45 51
46config MACH_G3EVM 52config MACH_G3EVM
@@ -98,6 +104,11 @@ config MACH_MARZEN
98 depends on ARCH_R8A7779 104 depends on ARCH_R8A7779
99 select ARCH_REQUIRE_GPIOLIB 105 select ARCH_REQUIRE_GPIOLIB
100 106
107config MACH_KZM9D
108 bool "KZM9D board"
109 depends on ARCH_EMEV2
110 select USE_OF
111
101comment "SH-Mobile System Configuration" 112comment "SH-Mobile System Configuration"
102 113
103config CPU_HAS_INTEVT 114config CPU_HAS_INTEVT
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index e7c2590b75d9..c795335931c9 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -12,12 +12,14 @@ obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
12obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o 12obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
13obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o clock-r8a7740.o intc-r8a7740.o 13obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o clock-r8a7740.o intc-r8a7740.o
14obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o 14obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o
15obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o
15 16
16# SMP objects 17# SMP objects
17smp-y := platsmp.o headsmp.o 18smp-y := platsmp.o headsmp.o
18smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o 19smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
19smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o 20smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
20smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o 21smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
22smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o
21 23
22# Pinmux setup 24# Pinmux setup
23pfc-y := 25pfc-y :=
@@ -49,6 +51,7 @@ obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
49obj-$(CONFIG_MACH_KOTA2) += board-kota2.o 51obj-$(CONFIG_MACH_KOTA2) += board-kota2.o
50obj-$(CONFIG_MACH_BONITO) += board-bonito.o 52obj-$(CONFIG_MACH_BONITO) += board-bonito.o
51obj-$(CONFIG_MACH_MARZEN) += board-marzen.o 53obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
54obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o
52 55
53# Framework support 56# Framework support
54obj-$(CONFIG_SMP) += $(smp-y) 57obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c
new file mode 100644
index 000000000000..7bc5e7d39f9b
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-kzm9d.c
@@ -0,0 +1,85 @@
1/*
2 * kzm9d board support
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Copyright (C) 2012 Magnus Damm
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/interrupt.h>
23#include <linux/platform_device.h>
24#include <linux/smsc911x.h>
25#include <mach/common.h>
26#include <mach/emev2.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/hardware/gic.h>
30
31/* Ether */
32static struct resource smsc911x_resources[] = {
33 [0] = {
34 .start = 0x20000000,
35 .end = 0x2000ffff,
36 .flags = IORESOURCE_MEM,
37 },
38 [1] = {
39 .start = EMEV2_GPIO_IRQ(1),
40 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
41 },
42};
43
44static struct smsc911x_platform_config smsc911x_platdata = {
45 .flags = SMSC911X_USE_32BIT,
46 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
47 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
48};
49
50static struct platform_device smsc91x_device = {
51 .name = "smsc911x",
52 .id = 0,
53 .dev = {
54 .platform_data = &smsc911x_platdata,
55 },
56 .num_resources = ARRAY_SIZE(smsc911x_resources),
57 .resource = smsc911x_resources,
58};
59
60static struct platform_device *kzm9d_devices[] __initdata = {
61 &smsc91x_device,
62};
63
64void __init kzm9d_add_standard_devices(void)
65{
66 emev2_add_standard_devices();
67
68 platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices));
69}
70
71static const char *kzm9d_boards_compat_dt[] __initdata = {
72 "renesas,kzm9d",
73 NULL,
74};
75
76DT_MACHINE_START(KZM9D_DT, "kzm9d")
77 .map_io = emev2_map_io,
78 .init_early = emev2_add_early_devices,
79 .nr_irqs = NR_IRQS_LEGACY,
80 .init_irq = emev2_init_irq,
81 .handle_irq = gic_handle_irq,
82 .init_machine = kzm9d_add_standard_devices,
83 .timer = &shmobile_timer,
84 .dt_compat = kzm9d_boards_compat_dt,
85MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c
new file mode 100644
index 000000000000..4710f1847bb7
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-emev2.c
@@ -0,0 +1,249 @@
1/*
2 * Emma Mobile EV2 clock framework support
3 *
4 * Copyright (C) 2012 Magnus Damm
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, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/io.h>
22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
24#include <mach/common.h>
25
26#define EMEV2_SMU_BASE 0xe0110000
27
28/* EMEV2 SMU registers */
29#define USIAU0_RSTCTRL 0x094
30#define USIBU1_RSTCTRL 0x0ac
31#define USIBU2_RSTCTRL 0x0b0
32#define USIBU3_RSTCTRL 0x0b4
33#define STI_RSTCTRL 0x124
34#define USIAU0GCLKCTRL 0x4a0
35#define USIBU1GCLKCTRL 0x4b8
36#define USIBU2GCLKCTRL 0x4bc
37#define USIBU3GCLKCTRL 0x04c0
38#define STIGCLKCTRL 0x528
39#define USIAU0SCLKDIV 0x61c
40#define USIB2SCLKDIV 0x65c
41#define USIB3SCLKDIV 0x660
42#define STI_CLKSEL 0x688
43#define SMU_GENERAL_REG0 0x7c0
44
45/* not pretty, but hey */
46static void __iomem *smu_base;
47
48static void emev2_smu_write(unsigned long value, int offs)
49{
50 BUG_ON(!smu_base || (offs >= PAGE_SIZE));
51 iowrite32(value, smu_base + offs);
52}
53
54void emev2_set_boot_vector(unsigned long value)
55{
56 emev2_smu_write(value, SMU_GENERAL_REG0);
57}
58
59static struct clk_mapping smu_mapping = {
60 .phys = EMEV2_SMU_BASE,
61 .len = PAGE_SIZE,
62};
63
64/* Fixed 32 KHz root clock from C32K pin */
65static struct clk c32k_clk = {
66 .rate = 32768,
67 .mapping = &smu_mapping,
68};
69
70/* PLL3 multiplies C32K with 7000 */
71static unsigned long pll3_recalc(struct clk *clk)
72{
73 return clk->parent->rate * 7000;
74}
75
76static struct sh_clk_ops pll3_clk_ops = {
77 .recalc = pll3_recalc,
78};
79
80static struct clk pll3_clk = {
81 .ops = &pll3_clk_ops,
82 .parent = &c32k_clk,
83};
84
85static struct clk *main_clks[] = {
86 &c32k_clk,
87 &pll3_clk,
88};
89
90enum { SCLKDIV_USIAU0, SCLKDIV_USIBU2, SCLKDIV_USIBU1, SCLKDIV_USIBU3,
91 SCLKDIV_NR };
92
93#define SCLKDIV(_reg, _shift) \
94{ \
95 .parent = &pll3_clk, \
96 .enable_reg = IOMEM(EMEV2_SMU_BASE + (_reg)), \
97 .enable_bit = _shift, \
98}
99
100static struct clk sclkdiv_clks[SCLKDIV_NR] = {
101 [SCLKDIV_USIAU0] = SCLKDIV(USIAU0SCLKDIV, 0),
102 [SCLKDIV_USIBU2] = SCLKDIV(USIB2SCLKDIV, 16),
103 [SCLKDIV_USIBU1] = SCLKDIV(USIB2SCLKDIV, 0),
104 [SCLKDIV_USIBU3] = SCLKDIV(USIB3SCLKDIV, 0),
105};
106
107enum { GCLK_USIAU0_SCLK, GCLK_USIBU1_SCLK, GCLK_USIBU2_SCLK, GCLK_USIBU3_SCLK,
108 GCLK_STI_SCLK,
109 GCLK_NR };
110
111#define GCLK_SCLK(_parent, _reg) \
112{ \
113 .parent = _parent, \
114 .enable_reg = IOMEM(EMEV2_SMU_BASE + (_reg)), \
115 .enable_bit = 1, /* SCLK_GCC */ \
116}
117
118static struct clk gclk_clks[GCLK_NR] = {
119 [GCLK_USIAU0_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIAU0],
120 USIAU0GCLKCTRL),
121 [GCLK_USIBU1_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU1],
122 USIBU1GCLKCTRL),
123 [GCLK_USIBU2_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU2],
124 USIBU2GCLKCTRL),
125 [GCLK_USIBU3_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU3],
126 USIBU3GCLKCTRL),
127 [GCLK_STI_SCLK] = GCLK_SCLK(&c32k_clk, STIGCLKCTRL),
128};
129
130static int emev2_gclk_enable(struct clk *clk)
131{
132 iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
133 clk->mapped_reg);
134 return 0;
135}
136
137static void emev2_gclk_disable(struct clk *clk)
138{
139 iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
140 clk->mapped_reg);
141}
142
143static struct sh_clk_ops emev2_gclk_clk_ops = {
144 .enable = emev2_gclk_enable,
145 .disable = emev2_gclk_disable,
146 .recalc = followparent_recalc,
147};
148
149static int __init emev2_gclk_register(struct clk *clks, int nr)
150{
151 struct clk *clkp;
152 int ret = 0;
153 int k;
154
155 for (k = 0; !ret && (k < nr); k++) {
156 clkp = clks + k;
157 clkp->ops = &emev2_gclk_clk_ops;
158 ret |= clk_register(clkp);
159 }
160
161 return ret;
162}
163
164static unsigned long emev2_sclkdiv_recalc(struct clk *clk)
165{
166 unsigned int sclk_div;
167
168 sclk_div = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0xff;
169
170 return clk->parent->rate / (sclk_div + 1);
171}
172
173static struct sh_clk_ops emev2_sclkdiv_clk_ops = {
174 .recalc = emev2_sclkdiv_recalc,
175};
176
177static int __init emev2_sclkdiv_register(struct clk *clks, int nr)
178{
179 struct clk *clkp;
180 int ret = 0;
181 int k;
182
183 for (k = 0; !ret && (k < nr); k++) {
184 clkp = clks + k;
185 clkp->ops = &emev2_sclkdiv_clk_ops;
186 ret |= clk_register(clkp);
187 }
188
189 return ret;
190}
191
192static struct clk_lookup lookups[] = {
193 CLKDEV_DEV_ID("serial8250-em.0", &gclk_clks[GCLK_USIAU0_SCLK]),
194 CLKDEV_DEV_ID("e1020000.uart", &gclk_clks[GCLK_USIAU0_SCLK]),
195 CLKDEV_DEV_ID("serial8250-em.1", &gclk_clks[GCLK_USIBU1_SCLK]),
196 CLKDEV_DEV_ID("e1030000.uart", &gclk_clks[GCLK_USIBU1_SCLK]),
197 CLKDEV_DEV_ID("serial8250-em.2", &gclk_clks[GCLK_USIBU2_SCLK]),
198 CLKDEV_DEV_ID("e1040000.uart", &gclk_clks[GCLK_USIBU2_SCLK]),
199 CLKDEV_DEV_ID("serial8250-em.3", &gclk_clks[GCLK_USIBU3_SCLK]),
200 CLKDEV_DEV_ID("e1050000.uart", &gclk_clks[GCLK_USIBU3_SCLK]),
201 CLKDEV_DEV_ID("em_sti.0", &gclk_clks[GCLK_STI_SCLK]),
202 CLKDEV_DEV_ID("e0180000.sti", &gclk_clks[GCLK_STI_SCLK]),
203};
204
205void __init emev2_clock_init(void)
206{
207 int k, ret = 0;
208 static int is_setup;
209
210 /* yuck, this is ugly as hell, but the non-smp case of clocks
211 * code is now designed to rely on ioremap() instead of static
212 * entity maps. in the case of smp we need access to the SMU
213 * register earlier than ioremap() is actually working without
214 * any static maps. to enable SMP in ugly but with dynamic
215 * mappings we have to call emev2_clock_init() from different
216 * places depending on UP and SMP...
217 */
218 if (is_setup++)
219 return;
220
221 smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE);
222 BUG_ON(!smu_base);
223
224 /* setup STI timer to run on 37.768 kHz and deassert reset */
225 emev2_smu_write(0, STI_CLKSEL);
226 emev2_smu_write(1, STI_RSTCTRL);
227
228 /* deassert reset for UART0->UART3 */
229 emev2_smu_write(2, USIAU0_RSTCTRL);
230 emev2_smu_write(2, USIBU1_RSTCTRL);
231 emev2_smu_write(2, USIBU2_RSTCTRL);
232 emev2_smu_write(2, USIBU3_RSTCTRL);
233
234 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
235 ret = clk_register(main_clks[k]);
236
237 if (!ret)
238 ret = emev2_sclkdiv_register(sclkdiv_clks, SCLKDIV_NR);
239
240 if (!ret)
241 ret = emev2_gclk_register(gclk_clks, GCLK_NR);
242
243 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
244
245 if (!ret)
246 shmobile_clk_init();
247 else
248 panic("failed to setup emev2 clocks\n");
249}
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 99c4d743a99c..81b54a6af20f 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -47,6 +47,7 @@
47#define PLLC01CR 0xe6150028 47#define PLLC01CR 0xe6150028
48 48
49#define SUBCKCR 0xe6150080 49#define SUBCKCR 0xe6150080
50#define USBCKCR 0xe615008c
50 51
51#define MSTPSR0 0xe6150030 52#define MSTPSR0 0xe6150030
52#define MSTPSR1 0xe6150038 53#define MSTPSR1 0xe6150038
@@ -181,6 +182,95 @@ static struct clk pllc1_div2_clk = {
181 .parent = &pllc1_clk, 182 .parent = &pllc1_clk,
182}; 183};
183 184
185/* USB clock */
186static struct clk *usb24s_parents[] = {
187 [0] = &system_clk,
188 [1] = &extal2_clk
189};
190
191static int usb24s_enable(struct clk *clk)
192{
193 __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
194
195 return 0;
196}
197
198static void usb24s_disable(struct clk *clk)
199{
200 __raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
201}
202
203static int usb24s_set_parent(struct clk *clk, struct clk *parent)
204{
205 int i, ret;
206 u32 val;
207
208 if (!clk->parent_table || !clk->parent_num)
209 return -EINVAL;
210
211 /* Search the parent */
212 for (i = 0; i < clk->parent_num; i++)
213 if (clk->parent_table[i] == parent)
214 break;
215
216 if (i == clk->parent_num)
217 return -ENODEV;
218
219 ret = clk_reparent(clk, parent);
220 if (ret < 0)
221 return ret;
222
223 val = __raw_readl(USBCKCR);
224 val &= ~(1 << 7);
225 val |= i << 7;
226 __raw_writel(val, USBCKCR);
227
228 return 0;
229}
230
231static struct sh_clk_ops usb24s_clk_ops = {
232 .recalc = followparent_recalc,
233 .enable = usb24s_enable,
234 .disable = usb24s_disable,
235 .set_parent = usb24s_set_parent,
236};
237
238static struct clk usb24s_clk = {
239 .ops = &usb24s_clk_ops,
240 .parent_table = usb24s_parents,
241 .parent_num = ARRAY_SIZE(usb24s_parents),
242 .parent = &system_clk,
243};
244
245static unsigned long usb24_recalc(struct clk *clk)
246{
247 return clk->parent->rate /
248 ((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
249};
250
251static int usb24_set_rate(struct clk *clk, unsigned long rate)
252{
253 u32 val;
254
255 /* closer to which ? parent->rate or parent->rate/2 */
256 val = __raw_readl(USBCKCR);
257 val &= ~(1 << 6);
258 val |= (rate > (clk->parent->rate / 4) * 3) << 6;
259 __raw_writel(val, USBCKCR);
260
261 return 0;
262}
263
264static struct sh_clk_ops usb24_clk_ops = {
265 .recalc = usb24_recalc,
266 .set_rate = usb24_set_rate,
267};
268
269static struct clk usb24_clk = {
270 .ops = &usb24_clk_ops,
271 .parent = &usb24s_clk,
272};
273
184struct clk *main_clks[] = { 274struct clk *main_clks[] = {
185 &extalr_clk, 275 &extalr_clk,
186 &extal1_clk, 276 &extal1_clk,
@@ -196,6 +286,8 @@ struct clk *main_clks[] = {
196 &pllc0_clk, 286 &pllc0_clk,
197 &pllc1_clk, 287 &pllc1_clk,
198 &pllc1_div2_clk, 288 &pllc1_div2_clk,
289 &usb24s_clk,
290 &usb24_clk,
199}; 291};
200 292
201static void div4_kick(struct clk *clk) 293static void div4_kick(struct clk *clk)
@@ -223,7 +315,7 @@ static struct clk_div4_table div4_table = {
223 315
224enum { 316enum {
225 DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP, 317 DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
226 DIV4_HPP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP, 318 DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
227 DIV4_NR 319 DIV4_NR
228}; 320};
229 321
@@ -234,6 +326,7 @@ struct clk div4_clks[DIV4_NR] = {
234 [DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT), 326 [DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
235 [DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0), 327 [DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0),
236 [DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0), 328 [DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
329 [DIV4_USBP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
237 [DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0), 330 [DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
238 [DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0), 331 [DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0),
239 [DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0), 332 [DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0),
@@ -257,7 +350,10 @@ enum {
257 MSTP222, 350 MSTP222,
258 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, 351 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
259 352
260 MSTP329, MSTP323, 353 MSTP329, MSTP328, MSTP323, MSTP320,
354 MSTP314, MSTP313, MSTP312,
355
356 MSTP416, MSTP415, MSTP407, MSTP406,
261 357
262 MSTP_NR 358 MSTP_NR
263}; 359};
@@ -280,7 +376,17 @@ static struct clk mstp_clks[MSTP_NR] = {
280 [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ 376 [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
281 377
282 [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ 378 [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
379 [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /* FSI */
283 [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ 380 [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
381 [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
382 [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
383 [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
384 [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
385
386 [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
387 [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
388 [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-Func */
389 [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 6, 0), /* USB Phy */
284}; 390};
285 391
286static struct clk_lookup lookups[] = { 392static struct clk_lookup lookups[] = {
@@ -299,6 +405,7 @@ static struct clk_lookup lookups[] = {
299 CLKDEV_CON_ID("pllc0_clk", &pllc0_clk), 405 CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
300 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), 406 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
301 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), 407 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
408 CLKDEV_CON_ID("usb24s", &usb24s_clk),
302 409
303 /* DIV4 clocks */ 410 /* DIV4 clocks */
304 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), 411 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -334,7 +441,21 @@ static struct clk_lookup lookups[] = {
334 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), 441 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
335 442
336 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), 443 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
444 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
337 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), 445 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
446 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
447 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
448 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
449 CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
450
451 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
452
453 /* ICK */
454 CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
455 CLKDEV_ICK_ID("func", "renesas_usbhs", &mstp_clks[MSTP407]),
456 CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
457 CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
458 CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
338}; 459};
339 460
340void __init r8a7740_clock_init(u8 md_ck) 461void __init r8a7740_clock_init(u8 md_ck)
diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h
new file mode 100644
index 000000000000..e6b0c1bf4b7e
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/emev2.h
@@ -0,0 +1,19 @@
1#ifndef __ASM_EMEV2_H__
2#define __ASM_EMEV2_H__
3
4extern void emev2_map_io(void);
5extern void emev2_init_irq(void);
6extern void emev2_add_early_devices(void);
7extern void emev2_add_standard_devices(void);
8extern void emev2_clock_init(void);
9extern void emev2_set_boot_vector(unsigned long value);
10extern unsigned int emev2_get_core_count(void);
11extern int emev2_platform_cpu_kill(unsigned int cpu);
12extern void emev2_secondary_init(unsigned int cpu);
13extern int emev2_boot_secondary(unsigned int cpu);
14extern void emev2_smp_prepare_cpus(void);
15
16#define EMEV2_GPIO_BASE 200
17#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
18
19#endif /* __ASM_EMEV2_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 8254ab86f6cd..915d0093da08 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -457,6 +457,8 @@ enum {
457 SHDMA_SLAVE_SDHI1_TX, 457 SHDMA_SLAVE_SDHI1_TX,
458 SHDMA_SLAVE_SDHI2_RX, 458 SHDMA_SLAVE_SDHI2_RX,
459 SHDMA_SLAVE_SDHI2_TX, 459 SHDMA_SLAVE_SDHI2_TX,
460 SHDMA_SLAVE_FSIA_RX,
461 SHDMA_SLAVE_FSIA_TX,
460 SHDMA_SLAVE_MMCIF_RX, 462 SHDMA_SLAVE_MMCIF_RX,
461 SHDMA_SLAVE_MMCIF_TX, 463 SHDMA_SLAVE_MMCIF_TX,
462 SHDMA_SLAVE_USB0_TX, 464 SHDMA_SLAVE_USB0_TX,
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index cad57578ceed..9b3598e4f105 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -515,8 +515,36 @@ enum {
515 SHDMA_SLAVE_MMCIF_RX, 515 SHDMA_SLAVE_MMCIF_RX,
516}; 516};
517 517
518/* PINT interrupts are located at Linux IRQ 800 and up */ 518/*
519#define SH73A0_PINT0_IRQ(irq) ((irq) + 800) 519 * SH73A0 IRQ LOCATION TABLE
520#define SH73A0_PINT1_IRQ(irq) ((irq) + 832) 520 *
521 * 416 -----------------------------------------
522 * IRQ0-IRQ15
523 * 431 -----------------------------------------
524 * ...
525 * 448 -----------------------------------------
526 * sh73a0-intcs
527 * sh73a0-intca-irq-pins
528 * 680 -----------------------------------------
529 * ...
530 * 700 -----------------------------------------
531 * sh73a0-pint0
532 * 731 -----------------------------------------
533 * 732 -----------------------------------------
534 * sh73a0-pint1
535 * 739 -----------------------------------------
536 * ...
537 * 800 -----------------------------------------
538 * IRQ16-IRQ31
539 * 815 -----------------------------------------
540 * ...
541 * 928 -----------------------------------------
542 * sh73a0-intca-irq-pins
543 * 943 -----------------------------------------
544 */
545
546/* PINT interrupts are located at Linux IRQ 700 and up */
547#define SH73A0_PINT0_IRQ(irq) ((irq) + 700)
548#define SH73A0_PINT1_IRQ(irq) ((irq) + 732)
521 549
522#endif /* __ASM_SH73A0_H__ */ 550#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
index a4fff6950b03..670fe1869dbc 100644
--- a/arch/arm/mach-shmobile/pfc-r8a7740.c
+++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
@@ -22,6 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <mach/r8a7740.h> 24#include <mach/r8a7740.h>
25#include <mach/irqs.h>
25 26
26#define CPU_ALL_PORT(fn, pfx, sfx) \ 27#define CPU_ALL_PORT(fn, pfx, sfx) \
27 PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \ 28 PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \
@@ -2527,6 +2528,41 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
2527 { }, 2528 { },
2528}; 2529};
2529 2530
2531static struct pinmux_irq pinmux_irqs[] = {
2532 PINMUX_IRQ(evt2irq(0x0200), PORT2_FN0, PORT13_FN0), /* IRQ0A */
2533 PINMUX_IRQ(evt2irq(0x0220), PORT20_FN0), /* IRQ1A */
2534 PINMUX_IRQ(evt2irq(0x0240), PORT11_FN0, PORT12_FN0), /* IRQ2A */
2535 PINMUX_IRQ(evt2irq(0x0260), PORT10_FN0, PORT14_FN0), /* IRQ3A */
2536 PINMUX_IRQ(evt2irq(0x0280), PORT15_FN0, PORT172_FN0), /* IRQ4A */
2537 PINMUX_IRQ(evt2irq(0x02A0), PORT0_FN0, PORT1_FN0), /* IRQ5A */
2538 PINMUX_IRQ(evt2irq(0x02C0), PORT121_FN0, PORT173_FN0), /* IRQ6A */
2539 PINMUX_IRQ(evt2irq(0x02E0), PORT120_FN0, PORT209_FN0), /* IRQ7A */
2540 PINMUX_IRQ(evt2irq(0x0300), PORT119_FN0), /* IRQ8A */
2541 PINMUX_IRQ(evt2irq(0x0320), PORT118_FN0, PORT210_FN0), /* IRQ9A */
2542 PINMUX_IRQ(evt2irq(0x0340), PORT19_FN0), /* IRQ10A */
2543 PINMUX_IRQ(evt2irq(0x0360), PORT104_FN0), /* IRQ11A */
2544 PINMUX_IRQ(evt2irq(0x0380), PORT42_FN0, PORT97_FN0), /* IRQ12A */
2545 PINMUX_IRQ(evt2irq(0x03A0), PORT64_FN0, PORT98_FN0), /* IRQ13A */
2546 PINMUX_IRQ(evt2irq(0x03C0), PORT63_FN0, PORT99_FN0), /* IRQ14A */
2547 PINMUX_IRQ(evt2irq(0x03E0), PORT62_FN0, PORT100_FN0), /* IRQ15A */
2548 PINMUX_IRQ(evt2irq(0x3200), PORT68_FN0, PORT211_FN0), /* IRQ16A */
2549 PINMUX_IRQ(evt2irq(0x3220), PORT69_FN0), /* IRQ17A */
2550 PINMUX_IRQ(evt2irq(0x3240), PORT70_FN0), /* IRQ18A */
2551 PINMUX_IRQ(evt2irq(0x3260), PORT71_FN0), /* IRQ19A */
2552 PINMUX_IRQ(evt2irq(0x3280), PORT67_FN0), /* IRQ20A */
2553 PINMUX_IRQ(evt2irq(0x32A0), PORT202_FN0), /* IRQ21A */
2554 PINMUX_IRQ(evt2irq(0x32C0), PORT95_FN0), /* IRQ22A */
2555 PINMUX_IRQ(evt2irq(0x32E0), PORT96_FN0), /* IRQ23A */
2556 PINMUX_IRQ(evt2irq(0x3300), PORT180_FN0), /* IRQ24A */
2557 PINMUX_IRQ(evt2irq(0x3320), PORT38_FN0), /* IRQ25A */
2558 PINMUX_IRQ(evt2irq(0x3340), PORT58_FN0, PORT81_FN0), /* IRQ26A */
2559 PINMUX_IRQ(evt2irq(0x3360), PORT57_FN0, PORT168_FN0), /* IRQ27A */
2560 PINMUX_IRQ(evt2irq(0x3380), PORT56_FN0, PORT169_FN0), /* IRQ28A */
2561 PINMUX_IRQ(evt2irq(0x33A0), PORT50_FN0, PORT170_FN0), /* IRQ29A */
2562 PINMUX_IRQ(evt2irq(0x33C0), PORT49_FN0, PORT171_FN0), /* IRQ30A */
2563 PINMUX_IRQ(evt2irq(0x33E0), PORT41_FN0, PORT167_FN0), /* IRQ31A */
2564};
2565
2530static struct pinmux_info r8a7740_pinmux_info = { 2566static struct pinmux_info r8a7740_pinmux_info = {
2531 .name = "r8a7740_pfc", 2567 .name = "r8a7740_pfc",
2532 .reserved_id = PINMUX_RESERVED, 2568 .reserved_id = PINMUX_RESERVED,
@@ -2554,6 +2590,9 @@ static struct pinmux_info r8a7740_pinmux_info = {
2554 2590
2555 .gpio_data = pinmux_data, 2591 .gpio_data = pinmux_data,
2556 .gpio_data_size = ARRAY_SIZE(pinmux_data), 2592 .gpio_data_size = ARRAY_SIZE(pinmux_data),
2593
2594 .gpio_irq = pinmux_irqs,
2595 .gpio_irq_size = ARRAY_SIZE(pinmux_irqs),
2557}; 2596};
2558 2597
2559void r8a7740_pinmux_init(void) 2598void r8a7740_pinmux_init(void)
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index 45fa3924c6a1..7006cdc8b8ca 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -16,12 +16,15 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/smp.h> 17#include <linux/smp.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/of.h>
19#include <asm/hardware/gic.h> 20#include <asm/hardware/gic.h>
20#include <asm/mach-types.h> 21#include <asm/mach-types.h>
21#include <mach/common.h> 22#include <mach/common.h>
23#include <mach/emev2.h>
22 24
23#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2()) 25#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2())
24#define is_r8a7779() machine_is_marzen() 26#define is_r8a7779() machine_is_marzen()
27#define is_emev2() of_machine_is_compatible("renesas,emev2")
25 28
26static unsigned int __init shmobile_smp_get_core_count(void) 29static unsigned int __init shmobile_smp_get_core_count(void)
27{ 30{
@@ -31,6 +34,9 @@ static unsigned int __init shmobile_smp_get_core_count(void)
31 if (is_r8a7779()) 34 if (is_r8a7779())
32 return r8a7779_get_core_count(); 35 return r8a7779_get_core_count();
33 36
37 if (is_emev2())
38 return emev2_get_core_count();
39
34 return 1; 40 return 1;
35} 41}
36 42
@@ -41,6 +47,9 @@ static void __init shmobile_smp_prepare_cpus(void)
41 47
42 if (is_r8a7779()) 48 if (is_r8a7779())
43 r8a7779_smp_prepare_cpus(); 49 r8a7779_smp_prepare_cpus();
50
51 if (is_emev2())
52 emev2_smp_prepare_cpus();
44} 53}
45 54
46int shmobile_platform_cpu_kill(unsigned int cpu) 55int shmobile_platform_cpu_kill(unsigned int cpu)
@@ -48,6 +57,9 @@ int shmobile_platform_cpu_kill(unsigned int cpu)
48 if (is_r8a7779()) 57 if (is_r8a7779())
49 return r8a7779_platform_cpu_kill(cpu); 58 return r8a7779_platform_cpu_kill(cpu);
50 59
60 if (is_emev2())
61 return emev2_platform_cpu_kill(cpu);
62
51 return 1; 63 return 1;
52} 64}
53 65
@@ -60,6 +72,9 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
60 72
61 if (is_r8a7779()) 73 if (is_r8a7779())
62 r8a7779_secondary_init(cpu); 74 r8a7779_secondary_init(cpu);
75
76 if (is_emev2())
77 emev2_secondary_init(cpu);
63} 78}
64 79
65int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 80int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -70,6 +85,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
70 if (is_r8a7779()) 85 if (is_r8a7779())
71 return r8a7779_boot_secondary(cpu); 86 return r8a7779_boot_secondary(cpu);
72 87
88 if (is_emev2())
89 return emev2_boot_secondary(cpu);
90
73 return -ENOSYS; 91 return -ENOSYS;
74} 92}
75 93
diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
new file mode 100644
index 000000000000..dae9aa68bb09
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-emev2.c
@@ -0,0 +1,452 @@
1/*
2 * Emma Mobile EV2 processor support
3 *
4 * Copyright (C) 2012 Magnus Damm
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, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/platform_device.h>
24#include <linux/platform_data/gpio-em.h>
25#include <linux/of_platform.h>
26#include <linux/delay.h>
27#include <linux/input.h>
28#include <linux/io.h>
29#include <linux/of_irq.h>
30#include <mach/hardware.h>
31#include <mach/common.h>
32#include <mach/emev2.h>
33#include <mach/irqs.h>
34#include <asm/mach-types.h>
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach/time.h>
38#include <asm/hardware/gic.h>
39
40static struct map_desc emev2_io_desc[] __initdata = {
41#ifdef CONFIG_SMP
42 /* 128K entity map for 0xe0100000 (SMU) */
43 {
44 .virtual = 0xe0100000,
45 .pfn = __phys_to_pfn(0xe0100000),
46 .length = SZ_128K,
47 .type = MT_DEVICE
48 },
49 /* 2M mapping for SCU + L2 controller */
50 {
51 .virtual = 0xf0000000,
52 .pfn = __phys_to_pfn(0x1e000000),
53 .length = SZ_2M,
54 .type = MT_DEVICE
55 },
56#endif
57};
58
59void __init emev2_map_io(void)
60{
61 iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
62}
63
64/* UART */
65static struct resource uart0_resources[] = {
66 [0] = {
67 .start = 0xe1020000,
68 .end = 0xe1020037,
69 .flags = IORESOURCE_MEM,
70 },
71 [1] = {
72 .start = 40,
73 .flags = IORESOURCE_IRQ,
74 }
75};
76
77static struct platform_device uart0_device = {
78 .name = "serial8250-em",
79 .id = 0,
80 .num_resources = ARRAY_SIZE(uart0_resources),
81 .resource = uart0_resources,
82};
83
84static struct resource uart1_resources[] = {
85 [0] = {
86 .start = 0xe1030000,
87 .end = 0xe1030037,
88 .flags = IORESOURCE_MEM,
89 },
90 [1] = {
91 .start = 41,
92 .flags = IORESOURCE_IRQ,
93 }
94};
95
96static struct platform_device uart1_device = {
97 .name = "serial8250-em",
98 .id = 1,
99 .num_resources = ARRAY_SIZE(uart1_resources),
100 .resource = uart1_resources,
101};
102
103static struct resource uart2_resources[] = {
104 [0] = {
105 .start = 0xe1040000,
106 .end = 0xe1040037,
107 .flags = IORESOURCE_MEM,
108 },
109 [1] = {
110 .start = 42,
111 .flags = IORESOURCE_IRQ,
112 }
113};
114
115static struct platform_device uart2_device = {
116 .name = "serial8250-em",
117 .id = 2,
118 .num_resources = ARRAY_SIZE(uart2_resources),
119 .resource = uart2_resources,
120};
121
122static struct resource uart3_resources[] = {
123 [0] = {
124 .start = 0xe1050000,
125 .end = 0xe1050037,
126 .flags = IORESOURCE_MEM,
127 },
128 [1] = {
129 .start = 43,
130 .flags = IORESOURCE_IRQ,
131 }
132};
133
134static struct platform_device uart3_device = {
135 .name = "serial8250-em",
136 .id = 3,
137 .num_resources = ARRAY_SIZE(uart3_resources),
138 .resource = uart3_resources,
139};
140
141/* STI */
142static struct resource sti_resources[] = {
143 [0] = {
144 .name = "STI",
145 .start = 0xe0180000,
146 .end = 0xe0180053,
147 .flags = IORESOURCE_MEM,
148 },
149 [1] = {
150 .start = 157,
151 .flags = IORESOURCE_IRQ,
152 },
153};
154
155static struct platform_device sti_device = {
156 .name = "em_sti",
157 .id = 0,
158 .resource = sti_resources,
159 .num_resources = ARRAY_SIZE(sti_resources),
160};
161
162
163/* GIO */
164static struct gpio_em_config gio0_config = {
165 .gpio_base = 0,
166 .irq_base = EMEV2_GPIO_IRQ(0),
167 .number_of_pins = 32,
168};
169
170static struct resource gio0_resources[] = {
171 [0] = {
172 .name = "GIO_000",
173 .start = 0xe0050000,
174 .end = 0xe005002b,
175 .flags = IORESOURCE_MEM,
176 },
177 [1] = {
178 .name = "GIO_000",
179 .start = 0xe0050040,
180 .end = 0xe005005f,
181 .flags = IORESOURCE_MEM,
182 },
183 [2] = {
184 .start = 99,
185 .flags = IORESOURCE_IRQ,
186 },
187 [3] = {
188 .start = 100,
189 .flags = IORESOURCE_IRQ,
190 },
191};
192
193static struct platform_device gio0_device = {
194 .name = "em_gio",
195 .id = 0,
196 .resource = gio0_resources,
197 .num_resources = ARRAY_SIZE(gio0_resources),
198 .dev = {
199 .platform_data = &gio0_config,
200 },
201};
202
203static struct gpio_em_config gio1_config = {
204 .gpio_base = 32,
205 .irq_base = EMEV2_GPIO_IRQ(32),
206 .number_of_pins = 32,
207};
208
209static struct resource gio1_resources[] = {
210 [0] = {
211 .name = "GIO_032",
212 .start = 0xe0050080,
213 .end = 0xe00500ab,
214 .flags = IORESOURCE_MEM,
215 },
216 [1] = {
217 .name = "GIO_032",
218 .start = 0xe00500c0,
219 .end = 0xe00500df,
220 .flags = IORESOURCE_MEM,
221 },
222 [2] = {
223 .start = 101,
224 .flags = IORESOURCE_IRQ,
225 },
226 [3] = {
227 .start = 102,
228 .flags = IORESOURCE_IRQ,
229 },
230};
231
232static struct platform_device gio1_device = {
233 .name = "em_gio",
234 .id = 1,
235 .resource = gio1_resources,
236 .num_resources = ARRAY_SIZE(gio1_resources),
237 .dev = {
238 .platform_data = &gio1_config,
239 },
240};
241
242static struct gpio_em_config gio2_config = {
243 .gpio_base = 64,
244 .irq_base = EMEV2_GPIO_IRQ(64),
245 .number_of_pins = 32,
246};
247
248static struct resource gio2_resources[] = {
249 [0] = {
250 .name = "GIO_064",
251 .start = 0xe0050100,
252 .end = 0xe005012b,
253 .flags = IORESOURCE_MEM,
254 },
255 [1] = {
256 .name = "GIO_064",
257 .start = 0xe0050140,
258 .end = 0xe005015f,
259 .flags = IORESOURCE_MEM,
260 },
261 [2] = {
262 .start = 103,
263 .flags = IORESOURCE_IRQ,
264 },
265 [3] = {
266 .start = 104,
267 .flags = IORESOURCE_IRQ,
268 },
269};
270
271static struct platform_device gio2_device = {
272 .name = "em_gio",
273 .id = 2,
274 .resource = gio2_resources,
275 .num_resources = ARRAY_SIZE(gio2_resources),
276 .dev = {
277 .platform_data = &gio2_config,
278 },
279};
280
281static struct gpio_em_config gio3_config = {
282 .gpio_base = 96,
283 .irq_base = EMEV2_GPIO_IRQ(96),
284 .number_of_pins = 32,
285};
286
287static struct resource gio3_resources[] = {
288 [0] = {
289 .name = "GIO_096",
290 .start = 0xe0050100,
291 .end = 0xe005012b,
292 .flags = IORESOURCE_MEM,
293 },
294 [1] = {
295 .name = "GIO_096",
296 .start = 0xe0050140,
297 .end = 0xe005015f,
298 .flags = IORESOURCE_MEM,
299 },
300 [2] = {
301 .start = 105,
302 .flags = IORESOURCE_IRQ,
303 },
304 [3] = {
305 .start = 106,
306 .flags = IORESOURCE_IRQ,
307 },
308};
309
310static struct platform_device gio3_device = {
311 .name = "em_gio",
312 .id = 3,
313 .resource = gio3_resources,
314 .num_resources = ARRAY_SIZE(gio3_resources),
315 .dev = {
316 .platform_data = &gio3_config,
317 },
318};
319
320static struct gpio_em_config gio4_config = {
321 .gpio_base = 128,
322 .irq_base = EMEV2_GPIO_IRQ(128),
323 .number_of_pins = 31,
324};
325
326static struct resource gio4_resources[] = {
327 [0] = {
328 .name = "GIO_128",
329 .start = 0xe0050200,
330 .end = 0xe005022b,
331 .flags = IORESOURCE_MEM,
332 },
333 [1] = {
334 .name = "GIO_128",
335 .start = 0xe0050240,
336 .end = 0xe005025f,
337 .flags = IORESOURCE_MEM,
338 },
339 [2] = {
340 .start = 107,
341 .flags = IORESOURCE_IRQ,
342 },
343 [3] = {
344 .start = 108,
345 .flags = IORESOURCE_IRQ,
346 },
347};
348
349static struct platform_device gio4_device = {
350 .name = "em_gio",
351 .id = 4,
352 .resource = gio4_resources,
353 .num_resources = ARRAY_SIZE(gio4_resources),
354 .dev = {
355 .platform_data = &gio4_config,
356 },
357};
358
359static struct platform_device *emev2_early_devices[] __initdata = {
360 &uart0_device,
361 &uart1_device,
362 &uart2_device,
363 &uart3_device,
364};
365
366static struct platform_device *emev2_late_devices[] __initdata = {
367 &sti_device,
368 &gio0_device,
369 &gio1_device,
370 &gio2_device,
371 &gio3_device,
372 &gio4_device,
373};
374
375void __init emev2_add_standard_devices(void)
376{
377 emev2_clock_init();
378
379 platform_add_devices(emev2_early_devices,
380 ARRAY_SIZE(emev2_early_devices));
381
382 platform_add_devices(emev2_late_devices,
383 ARRAY_SIZE(emev2_late_devices));
384}
385
386void __init emev2_init_delay(void)
387{
388 shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
389}
390
391void __init emev2_add_early_devices(void)
392{
393 emev2_init_delay();
394
395 early_platform_add_devices(emev2_early_devices,
396 ARRAY_SIZE(emev2_early_devices));
397
398 /* setup early console here as well */
399 shmobile_setup_console();
400}
401
402void __init emev2_init_irq(void)
403{
404 void __iomem *gic_dist_base;
405 void __iomem *gic_cpu_base;
406
407 /* Static mappings, never released */
408 gic_dist_base = ioremap(0xe0028000, PAGE_SIZE);
409 gic_cpu_base = ioremap(0xe0020000, PAGE_SIZE);
410 BUG_ON(!gic_dist_base || !gic_cpu_base);
411
412 /* Use GIC to handle interrupts */
413 gic_init(0, 29, gic_dist_base, gic_cpu_base);
414}
415
416#ifdef CONFIG_USE_OF
417static const struct of_dev_auxdata emev2_auxdata_lookup[] __initconst = {
418 { }
419};
420
421void __init emev2_add_standard_devices_dt(void)
422{
423 of_platform_populate(NULL, of_default_bus_match_table,
424 emev2_auxdata_lookup, NULL);
425}
426
427static const struct of_device_id emev2_dt_irq_match[] = {
428 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
429 {},
430};
431
432static const char *emev2_boards_compat_dt[] __initdata = {
433 "renesas,emev2",
434 NULL,
435};
436
437void __init emev2_init_irq_dt(void)
438{
439 of_irq_init(emev2_dt_irq_match);
440}
441
442DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
443 .init_early = emev2_init_delay,
444 .nr_irqs = NR_IRQS_LEGACY,
445 .init_irq = emev2_init_irq_dt,
446 .handle_irq = gic_handle_irq,
447 .init_machine = emev2_add_standard_devices_dt,
448 .timer = &shmobile_timer,
449 .dt_compat = emev2_boards_compat_dt,
450MACHINE_END
451
452#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 14edb5cffa7f..34a1548dbda6 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -350,19 +350,19 @@ static void r8a7740_i2c_workaround(struct platform_device *pdev)
350 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10); 350 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
351 i2c_read(reg, ICSTART); /* dummy read */ 351 i2c_read(reg, ICSTART); /* dummy read */
352 352
353 mdelay(100); 353 udelay(10);
354 354
355 i2c_write(reg, ICCR, 0x01); 355 i2c_write(reg, ICCR, 0x01);
356 i2c_read(reg, ICCR);
357 i2c_write(reg, ICSTART, 0x00); 356 i2c_write(reg, ICSTART, 0x00);
358 i2c_read(reg, ICSTART); 357
358 udelay(10);
359 359
360 i2c_write(reg, ICCR, 0x10); 360 i2c_write(reg, ICCR, 0x10);
361 mdelay(100); 361 udelay(10);
362 i2c_write(reg, ICCR, 0x00); 362 i2c_write(reg, ICCR, 0x00);
363 mdelay(100); 363 udelay(10);
364 i2c_write(reg, ICCR, 0x10); 364 i2c_write(reg, ICCR, 0x10);
365 mdelay(100); 365 udelay(10);
366 366
367 iounmap(reg); 367 iounmap(reg);
368} 368}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 4c7fece5ef92..6a4bd582c028 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -462,6 +462,16 @@ static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
462 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), 462 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
463 .mid_rid = 0xce, 463 .mid_rid = 0xce,
464 }, { 464 }, {
465 .slave_id = SHDMA_SLAVE_FSIA_TX,
466 .addr = 0xfe1f0024,
467 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
468 .mid_rid = 0xb1,
469 }, {
470 .slave_id = SHDMA_SLAVE_FSIA_RX,
471 .addr = 0xfe1f0020,
472 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
473 .mid_rid = 0xb2,
474 }, {
465 .slave_id = SHDMA_SLAVE_MMCIF_TX, 475 .slave_id = SHDMA_SLAVE_MMCIF_TX,
466 .addr = 0xe6bd0034, 476 .addr = 0xe6bd0034,
467 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), 477 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
new file mode 100644
index 000000000000..6a35c4a31e6c
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -0,0 +1,97 @@
1/*
2 * SMP support for Emma Mobile EV2
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Copyright (C) 2012 Magnus Damm
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/smp.h>
23#include <linux/spinlock.h>
24#include <linux/io.h>
25#include <linux/delay.h>
26#include <mach/common.h>
27#include <mach/emev2.h>
28#include <asm/smp_plat.h>
29#include <asm/smp_scu.h>
30#include <asm/hardware/gic.h>
31#include <asm/cacheflush.h>
32
33#define EMEV2_SCU_BASE 0x1e000000
34
35static DEFINE_SPINLOCK(scu_lock);
36static void __iomem *scu_base;
37
38static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
39{
40 unsigned long tmp;
41
42 /* we assume this code is running on a different cpu
43 * than the one that is changing coherency setting */
44 spin_lock(&scu_lock);
45 tmp = readl(scu_base + 8);
46 tmp &= ~clr;
47 tmp |= set;
48 writel(tmp, scu_base + 8);
49 spin_unlock(&scu_lock);
50
51}
52
53unsigned int __init emev2_get_core_count(void)
54{
55 if (!scu_base) {
56 scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
57 emev2_clock_init(); /* need ioremapped SMU */
58 }
59
60 WARN_ON_ONCE(!scu_base);
61
62 return scu_base ? scu_get_core_count(scu_base) : 1;
63}
64
65int emev2_platform_cpu_kill(unsigned int cpu)
66{
67 return 0; /* not supported yet */
68}
69
70void __cpuinit emev2_secondary_init(unsigned int cpu)
71{
72 gic_secondary_init(0);
73}
74
75int __cpuinit emev2_boot_secondary(unsigned int cpu)
76{
77 cpu = cpu_logical_map(cpu);
78
79 /* enable cache coherency */
80 modify_scu_cpu_psr(0, 3 << (cpu * 8));
81
82 /* Tell ROM loader about our vector (in headsmp.S) */
83 emev2_set_boot_vector(__pa(shmobile_secondary_vector));
84
85 gic_raise_softirq(cpumask_of(cpu), 1);
86 return 0;
87}
88
89void __init emev2_smp_prepare_cpus(void)
90{
91 int cpu = cpu_logical_map(0);
92
93 scu_enable(scu_base);
94
95 /* enable cache coherency on CPU0 */
96 modify_scu_cpu_psr(0, 3 << (cpu * 8));
97}
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index cba39d866687..a68919727e24 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -36,7 +36,8 @@ void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
36 36
37 unsigned int value = (1000000 * mult) / (HZ * div); 37 unsigned int value = (1000000 * mult) / (HZ * div);
38 38
39 lpj_fine = max_cpu_core_mhz * value; 39 if (!preset_lpj)
40 preset_lpj = max_cpu_core_mhz * value;
40} 41}
41 42
42static void __init shmobile_late_time_init(void) 43static void __init shmobile_late_time_init(void)
diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c
index 5af36aa56c08..b29a788f498c 100644
--- a/arch/arm/mach-ux500/board-mop500-uib.c
+++ b/arch/arm/mach-ux500/board-mop500-uib.c
@@ -102,7 +102,7 @@ static int __init mop500_uib_init(void)
102 struct i2c_adapter *i2c0; 102 struct i2c_adapter *i2c0;
103 int ret; 103 int ret;
104 104
105 if (!cpu_is_u8500()) 105 if (!cpu_is_u8500_family())
106 return -ENODEV; 106 return -ENODEV;
107 107
108 if (uib) { 108 if (uib) {
diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index df91344aa2db..dc12394295d5 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -36,7 +36,9 @@ static int __init ux500_l2x0_unlock(void)
36 36
37static int __init ux500_l2x0_init(void) 37static int __init ux500_l2x0_init(void)
38{ 38{
39 if (cpu_is_u8500()) 39 u32 aux_val = 0x3e000000;
40
41 if (cpu_is_u8500_family())
40 l2x0_base = __io_address(U8500_L2CC_BASE); 42 l2x0_base = __io_address(U8500_L2CC_BASE);
41 else 43 else
42 ux500_unknown_soc(); 44 ux500_unknown_soc();
@@ -44,11 +46,19 @@ static int __init ux500_l2x0_init(void)
44 /* Unlock before init */ 46 /* Unlock before init */
45 ux500_l2x0_unlock(); 47 ux500_l2x0_unlock();
46 48
49 /* DB9540's L2 has 128KB way size */
50 if (cpu_is_u9540())
51 /* 128KB way size */
52 aux_val |= (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
53 else
54 /* 64KB way size */
55 aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
56
47 /* 64KB way size, 8 way associativity, force WA */ 57 /* 64KB way size, 8 way associativity, force WA */
48 if (of_have_populated_dt()) 58 if (of_have_populated_dt())
49 l2x0_of_init(0x3e060000, 0xc0000fff); 59 l2x0_of_init(aux_val, 0xc0000fff);
50 else 60 else
51 l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); 61 l2x0_init(l2x0_base, aux_val, 0xc0000fff);
52 62
53 /* 63 /*
54 * We can't disable l2 as we are in non secure mode, currently 64 * We can't disable l2 as we are in non secure mode, currently
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 9feb6bc7f20e..063f3dbd45a9 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -149,7 +149,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
149 unsigned long mturate; 149 unsigned long mturate;
150 unsigned long retclk; 150 unsigned long retclk;
151 151
152 if (cpu_is_u8500()) 152 if (cpu_is_u8500_family())
153 addr = __io_address(U8500_PRCMU_BASE); 153 addr = __io_address(U8500_PRCMU_BASE);
154 else 154 else
155 ux500_unknown_soc(); 155 ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index f44a12ccddf3..76a7503a11a2 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -34,8 +34,8 @@ static struct map_desc u8500_uart_io_desc[] __initdata = {
34 __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), 34 __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K),
35 __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K), 35 __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
36}; 36};
37 37/* U8500 and U9540 common io_desc */
38static struct map_desc u8500_io_desc[] __initdata = { 38static struct map_desc u8500_common_io_desc[] __initdata = {
39 /* SCU base also covers GIC CPU BASE and TWD with its 4K page */ 39 /* SCU base also covers GIC CPU BASE and TWD with its 4K page */
40 __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), 40 __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
41 __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), 41 __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
@@ -49,12 +49,23 @@ static struct map_desc u8500_io_desc[] __initdata = {
49 __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), 49 __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K),
50 __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), 50 __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K),
51 51
52 __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
53 __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), 52 __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
54 __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), 53 __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
55 __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), 54 __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
56 __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), 55 __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
56};
57
58/* U8500 IO map specific description */
59static struct map_desc u8500_io_desc[] __initdata = {
60 __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
57 __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), 61 __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
62
63};
64
65/* U9540 IO map specific description */
66static struct map_desc u9540_io_desc[] __initdata = {
67 __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K + SZ_8K),
68 __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K + SZ_8K),
58}; 69};
59 70
60void __init u8500_map_io(void) 71void __init u8500_map_io(void)
@@ -66,7 +77,12 @@ void __init u8500_map_io(void)
66 77
67 ux500_map_io(); 78 ux500_map_io();
68 79
69 iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); 80 iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc));
81
82 if (cpu_is_u9540())
83 iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
84 else
85 iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
70 86
71 _PRCMU_BASE = __io_address(U8500_PRCMU_BASE); 87 _PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
72} 88}
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 4b4e59b30d81..0982279f51f3 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -39,7 +39,7 @@ void __init ux500_init_irq(void)
39 void __iomem *dist_base; 39 void __iomem *dist_base;
40 void __iomem *cpu_base; 40 void __iomem *cpu_base;
41 41
42 if (cpu_is_u8500()) { 42 if (cpu_is_u8500_family()) {
43 dist_base = __io_address(U8500_GIC_DIST_BASE); 43 dist_base = __io_address(U8500_GIC_DIST_BASE);
44 cpu_base = __io_address(U8500_GIC_CPU_BASE); 44 cpu_base = __io_address(U8500_GIC_CPU_BASE);
45 } else 45 } else
@@ -56,7 +56,7 @@ void __init ux500_init_irq(void)
56 * Init clocks here so that they are available for system timer 56 * Init clocks here so that they are available for system timer
57 * initialization. 57 * initialization.
58 */ 58 */
59 if (cpu_is_u8500()) 59 if (cpu_is_u8500_family())
60 db8500_prcmu_early_init(); 60 db8500_prcmu_early_init();
61 clk_init(); 61 clk_init();
62} 62}
diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c
index 15a0f63b2e2b..d1579920139f 100644
--- a/arch/arm/mach-ux500/id.c
+++ b/arch/arm/mach-ux500/id.c
@@ -23,7 +23,7 @@ static unsigned int ux500_read_asicid(phys_addr_t addr)
23{ 23{
24 phys_addr_t base = addr & ~0xfff; 24 phys_addr_t base = addr & ~0xfff;
25 struct map_desc desc = { 25 struct map_desc desc = {
26 .virtual = IO_ADDRESS(base), 26 .virtual = UX500_VIRT_ROM,
27 .pfn = __phys_to_pfn(base), 27 .pfn = __phys_to_pfn(base),
28 .length = SZ_16K, 28 .length = SZ_16K,
29 .type = MT_DEVICE, 29 .type = MT_DEVICE,
@@ -35,7 +35,7 @@ static unsigned int ux500_read_asicid(phys_addr_t addr)
35 local_flush_tlb_all(); 35 local_flush_tlb_all();
36 flush_cache_all(); 36 flush_cache_all();
37 37
38 return readl(__io_address(addr)); 38 return readl(IOMEM(UX500_VIRT_ROM + (addr & 0xfff)));
39} 39}
40 40
41static void ux500_print_soc_info(unsigned int asicid) 41static void ux500_print_soc_info(unsigned int asicid)
@@ -67,6 +67,7 @@ static unsigned int partnumber(unsigned int asicid)
67 * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0 67 * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0
68 * DB8520v2.2 0x412fc091 0x9001DBF4 0x008500B2 68 * DB8520v2.2 0x412fc091 0x9001DBF4 0x008500B2
69 * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0 69 * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0
70 * DB9540 0x413fc090 0xFFFFDBF4 0x009540xx
70 */ 71 */
71 72
72void __init ux500_map_io(void) 73void __init ux500_map_io(void)
@@ -91,6 +92,10 @@ void __init ux500_map_io(void)
91 /* DB5500v1 */ 92 /* DB5500v1 */
92 addr = 0x9001FFF4; 93 addr = 0x9001FFF4;
93 break; 94 break;
95
96 case 0x413fc090: /* DB9540 */
97 addr = 0xFFFFDBF4;
98 break;
94 } 99 }
95 100
96 if (addr) 101 if (addr)
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index 9ec20b96d8f2..1530d493879d 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -41,6 +41,10 @@
41/* ASIC ID is at 0xbf4 offset within this region */ 41/* ASIC ID is at 0xbf4 offset within this region */
42#define U8500_ASIC_ID_BASE 0x9001D000 42#define U8500_ASIC_ID_BASE 0x9001D000
43 43
44#define U9540_BOOT_ROM_BASE 0xFFFE0000
45/* ASIC ID is at 0xbf4 offset within this region */
46#define U9540_ASIC_ID_BASE 0xFFFFD000
47
44#define U8500_PER6_BASE 0xa03c0000 48#define U8500_PER6_BASE 0xa03c0000
45#define U8500_PER7_BASE 0xa03d0000 49#define U8500_PER7_BASE 0xa03d0000
46#define U8500_PER5_BASE 0xa03e0000 50#define U8500_PER5_BASE 0xa03e0000
@@ -96,7 +100,9 @@
96#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) 100#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000)
97#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) 101#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000)
98#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) 102#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
103#define U9540_DMC1_BASE (U8500_PER4_BASE + 0x0A000)
99#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) 104#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
105#define U9540_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x6A000)
100#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000) 106#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000)
101#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338) 107#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
102#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450) 108#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index cf6fac3d1eeb..808c1d6601c5 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -17,6 +17,8 @@
17 */ 17 */
18#define U8500_IO_VIRTUAL 0xf0000000 18#define U8500_IO_VIRTUAL 0xf0000000
19#define U8500_IO_PHYSICAL 0xa0000000 19#define U8500_IO_PHYSICAL 0xa0000000
20/* This is where we map in the ROM to check ASIC IDs */
21#define UX500_VIRT_ROM 0xf0000000
20 22
21/* This macro is used in assembly, so no cast */ 23/* This macro is used in assembly, so no cast */
22#define IO_ADDRESS(x) \ 24#define IO_ADDRESS(x) \
@@ -24,6 +26,7 @@
24 26
25/* typesafe io address */ 27/* typesafe io address */
26#define __io_address(n) IOMEM(IO_ADDRESS(n)) 28#define __io_address(n) IOMEM(IO_ADDRESS(n))
29
27/* Used by some plat-nomadik code */ 30/* Used by some plat-nomadik code */
28#define io_p2v(n) __io_address(n) 31#define io_p2v(n) __io_address(n)
29 32
diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h
index 833d6a6edc9b..c6e2db9e9e51 100644
--- a/arch/arm/mach-ux500/include/mach/id.h
+++ b/arch/arm/mach-ux500/include/mach/id.h
@@ -41,6 +41,16 @@ static inline bool __attribute_const__ cpu_is_u8500(void)
41 return dbx500_partnumber() == 0x8500; 41 return dbx500_partnumber() == 0x8500;
42} 42}
43 43
44static inline bool __attribute_const__ cpu_is_u9540(void)
45{
46 return dbx500_partnumber() == 0x9540;
47}
48
49static inline bool cpu_is_u8500_family(void)
50{
51 return cpu_is_u8500() || cpu_is_u9540();
52}
53
44static inline bool __attribute_const__ cpu_is_u5500(void) 54static inline bool __attribute_const__ cpu_is_u5500(void)
45{ 55{
46 return dbx500_partnumber() == 0x5500; 56 return dbx500_partnumber() == 0x5500;
@@ -111,7 +121,12 @@ static inline bool cpu_is_u8500v21(void)
111 121
112static inline bool cpu_is_u8500v20_or_later(void) 122static inline bool cpu_is_u8500v20_or_later(void)
113{ 123{
114 return cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11(); 124 /*
125 * U9540 has so much in common with U8500 that is is considered a
126 * U8500 variant.
127 */
128 return cpu_is_u9540() ||
129 (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11());
115} 130}
116 131
117static inline bool ux500_is_svp(void) 132static inline bool ux500_is_svp(void)
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index d06dcf6208fa..e8928548b6a3 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -24,7 +24,7 @@
24 */ 24 */
25#define IRQ_MTU0 (IRQ_SHPI_START + 4) 25#define IRQ_MTU0 (IRQ_SHPI_START + 4)
26 26
27#define DBX500_NR_INTERNAL_IRQS 160 27#define DBX500_NR_INTERNAL_IRQS 166
28 28
29/* After chip-specific IRQ numbers we have the GPIO ones */ 29/* After chip-specific IRQ numbers we have the GPIO ones */
30#define NOMADIK_NR_GPIO 288 30#define NOMADIK_NR_GPIO 288
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index e8cd51aa61e4..da1d5ad5bd45 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -48,7 +48,7 @@ static void write_pen_release(int val)
48 48
49static void __iomem *scu_base_addr(void) 49static void __iomem *scu_base_addr(void)
50{ 50{
51 if (cpu_is_u8500()) 51 if (cpu_is_u8500_family())
52 return __io_address(U8500_SCU_BASE); 52 return __io_address(U8500_SCU_BASE);
53 else 53 else
54 ux500_unknown_soc(); 54 ux500_unknown_soc();
@@ -118,7 +118,7 @@ static void __init wakeup_secondary(void)
118{ 118{
119 void __iomem *backupram; 119 void __iomem *backupram;
120 120
121 if (cpu_is_u8500()) 121 if (cpu_is_u8500_family())
122 backupram = __io_address(U8500_BACKUPRAM0_BASE); 122 backupram = __io_address(U8500_BACKUPRAM0_BASE);
123 else 123 else
124 ux500_unknown_soc(); 124 ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index bd8e110cbcc2..741e71feca78 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -54,7 +54,7 @@ static void __init ux500_timer_init(void)
54 void __iomem *tmp_base; 54 void __iomem *tmp_base;
55 struct device_node *np; 55 struct device_node *np;
56 56
57 if (cpu_is_u8500()) { 57 if (cpu_is_u8500_family()) {
58 mtu_timer_base = __io_address(U8500_MTU0_BASE); 58 mtu_timer_base = __io_address(U8500_MTU0_BASE);
59 prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); 59 prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
60 } else { 60 } else {
diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c
index 0bf1b8910eeb..74b830b635a6 100644
--- a/drivers/cpufreq/db8500-cpufreq.c
+++ b/drivers/cpufreq/db8500-cpufreq.c
@@ -161,7 +161,7 @@ static struct cpufreq_driver db8500_cpufreq_driver = {
161 161
162static int __init db8500_cpufreq_register(void) 162static int __init db8500_cpufreq_register(void)
163{ 163{
164 if (!cpu_is_u8500v20_or_later()) 164 if (!cpu_is_u8500_family())
165 return -ENODEV; 165 return -ENODEV;
166 166
167 pr_info("cpufreq for DB8500 started\n"); 167 pr_info("cpufreq for DB8500 started\n");
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e03653d69357..eb80ba300452 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -91,6 +91,12 @@ config GPIO_IT8761E
91 help 91 help
92 Say yes here to support GPIO functionality of IT8761E super I/O chip. 92 Say yes here to support GPIO functionality of IT8761E super I/O chip.
93 93
94config GPIO_EM
95 tristate "Emma Mobile GPIO"
96 depends on ARM
97 help
98 Say yes here to support GPIO on Renesas Emma Mobile SoCs.
99
94config GPIO_EP93XX 100config GPIO_EP93XX
95 def_bool y 101 def_bool y
96 depends on ARCH_EP93XX 102 depends on ARCH_EP93XX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 007f54bd0081..3f1f829260bb 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
15obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o 15obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
16obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o 16obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
17obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o 17obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
18obj-$(CONFIG_GPIO_EM) += gpio-em.o
18obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o 19obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
19obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o 20obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
20obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o 21obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
new file mode 100644
index 000000000000..150d9768811d
--- /dev/null
+++ b/drivers/gpio/gpio-em.c
@@ -0,0 +1,418 @@
1/*
2 * Emma Mobile GPIO Support - GIO
3 *
4 * Copyright (C) 2012 Magnus Damm
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; either 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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/spinlock.h>
23#include <linux/interrupt.h>
24#include <linux/ioport.h>
25#include <linux/io.h>
26#include <linux/irq.h>
27#include <linux/irqdomain.h>
28#include <linux/bitops.h>
29#include <linux/err.h>
30#include <linux/gpio.h>
31#include <linux/slab.h>
32#include <linux/module.h>
33#include <linux/platform_data/gpio-em.h>
34
35struct em_gio_priv {
36 void __iomem *base0;
37 void __iomem *base1;
38 unsigned int irq_base;
39 spinlock_t sense_lock;
40 struct platform_device *pdev;
41 struct gpio_chip gpio_chip;
42 struct irq_chip irq_chip;
43 struct irq_domain *irq_domain;
44};
45
46#define GIO_E1 0x00
47#define GIO_E0 0x04
48#define GIO_EM 0x04
49#define GIO_OL 0x08
50#define GIO_OH 0x0c
51#define GIO_I 0x10
52#define GIO_IIA 0x14
53#define GIO_IEN 0x18
54#define GIO_IDS 0x1c
55#define GIO_IIM 0x1c
56#define GIO_RAW 0x20
57#define GIO_MST 0x24
58#define GIO_IIR 0x28
59
60#define GIO_IDT0 0x40
61#define GIO_IDT1 0x44
62#define GIO_IDT2 0x48
63#define GIO_IDT3 0x4c
64#define GIO_RAWBL 0x50
65#define GIO_RAWBH 0x54
66#define GIO_IRBL 0x58
67#define GIO_IRBH 0x5c
68
69#define GIO_IDT(n) (GIO_IDT0 + ((n) * 4))
70
71static inline unsigned long em_gio_read(struct em_gio_priv *p, int offs)
72{
73 if (offs < GIO_IDT0)
74 return ioread32(p->base0 + offs);
75 else
76 return ioread32(p->base1 + (offs - GIO_IDT0));
77}
78
79static inline void em_gio_write(struct em_gio_priv *p, int offs,
80 unsigned long value)
81{
82 if (offs < GIO_IDT0)
83 iowrite32(value, p->base0 + offs);
84 else
85 iowrite32(value, p->base1 + (offs - GIO_IDT0));
86}
87
88static inline struct em_gio_priv *irq_to_priv(struct irq_data *d)
89{
90 struct irq_chip *chip = irq_data_get_irq_chip(d);
91 return container_of(chip, struct em_gio_priv, irq_chip);
92}
93
94static void em_gio_irq_disable(struct irq_data *d)
95{
96 struct em_gio_priv *p = irq_to_priv(d);
97
98 em_gio_write(p, GIO_IDS, BIT(irqd_to_hwirq(d)));
99}
100
101static void em_gio_irq_enable(struct irq_data *d)
102{
103 struct em_gio_priv *p = irq_to_priv(d);
104
105 em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d)));
106}
107
108#define GIO_ASYNC(x) (x + 8)
109
110static unsigned char em_gio_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
111 [IRQ_TYPE_EDGE_RISING] = GIO_ASYNC(0x00),
112 [IRQ_TYPE_EDGE_FALLING] = GIO_ASYNC(0x01),
113 [IRQ_TYPE_LEVEL_HIGH] = GIO_ASYNC(0x02),
114 [IRQ_TYPE_LEVEL_LOW] = GIO_ASYNC(0x03),
115 [IRQ_TYPE_EDGE_BOTH] = GIO_ASYNC(0x04),
116};
117
118static int em_gio_irq_set_type(struct irq_data *d, unsigned int type)
119{
120 unsigned char value = em_gio_sense_table[type & IRQ_TYPE_SENSE_MASK];
121 struct em_gio_priv *p = irq_to_priv(d);
122 unsigned int reg, offset, shift;
123 unsigned long flags;
124 unsigned long tmp;
125
126 if (!value)
127 return -EINVAL;
128
129 offset = irqd_to_hwirq(d);
130
131 pr_debug("gio: sense irq = %d, mode = %d\n", offset, value);
132
133 /* 8 x 4 bit fields in 4 IDT registers */
134 reg = GIO_IDT(offset >> 3);
135 shift = (offset & 0x07) << 4;
136
137 spin_lock_irqsave(&p->sense_lock, flags);
138
139 /* disable the interrupt in IIA */
140 tmp = em_gio_read(p, GIO_IIA);
141 tmp &= ~BIT(offset);
142 em_gio_write(p, GIO_IIA, tmp);
143
144 /* change the sense setting in IDT */
145 tmp = em_gio_read(p, reg);
146 tmp &= ~(0xf << shift);
147 tmp |= value << shift;
148 em_gio_write(p, reg, tmp);
149
150 /* clear pending interrupts */
151 em_gio_write(p, GIO_IIR, BIT(offset));
152
153 /* enable the interrupt in IIA */
154 tmp = em_gio_read(p, GIO_IIA);
155 tmp |= BIT(offset);
156 em_gio_write(p, GIO_IIA, tmp);
157
158 spin_unlock_irqrestore(&p->sense_lock, flags);
159
160 return 0;
161}
162
163static irqreturn_t em_gio_irq_handler(int irq, void *dev_id)
164{
165 struct em_gio_priv *p = dev_id;
166 unsigned long pending;
167 unsigned int offset, irqs_handled = 0;
168
169 while ((pending = em_gio_read(p, GIO_MST))) {
170 offset = __ffs(pending);
171 em_gio_write(p, GIO_IIR, BIT(offset));
172 generic_handle_irq(irq_find_mapping(p->irq_domain, offset));
173 irqs_handled++;
174 }
175
176 return irqs_handled ? IRQ_HANDLED : IRQ_NONE;
177}
178
179static inline struct em_gio_priv *gpio_to_priv(struct gpio_chip *chip)
180{
181 return container_of(chip, struct em_gio_priv, gpio_chip);
182}
183
184static int em_gio_direction_input(struct gpio_chip *chip, unsigned offset)
185{
186 em_gio_write(gpio_to_priv(chip), GIO_E0, BIT(offset));
187 return 0;
188}
189
190static int em_gio_get(struct gpio_chip *chip, unsigned offset)
191{
192 return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & BIT(offset));
193}
194
195static void __em_gio_set(struct gpio_chip *chip, unsigned int reg,
196 unsigned shift, int value)
197{
198 /* upper 16 bits contains mask and lower 16 actual value */
199 em_gio_write(gpio_to_priv(chip), reg,
200 (1 << (shift + 16)) | (value << shift));
201}
202
203static void em_gio_set(struct gpio_chip *chip, unsigned offset, int value)
204{
205 /* output is split into two registers */
206 if (offset < 16)
207 __em_gio_set(chip, GIO_OL, offset, value);
208 else
209 __em_gio_set(chip, GIO_OH, offset - 16, value);
210}
211
212static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
213 int value)
214{
215 /* write GPIO value to output before selecting output mode of pin */
216 em_gio_set(chip, offset, value);
217 em_gio_write(gpio_to_priv(chip), GIO_E1, BIT(offset));
218 return 0;
219}
220
221static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
222{
223 return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset);
224}
225
226static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq,
227 irq_hw_number_t hw)
228{
229 struct em_gio_priv *p = h->host_data;
230
231 pr_debug("gio: map hw irq = %d, virq = %d\n", (int)hw, virq);
232
233 irq_set_chip_data(virq, h->host_data);
234 irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq);
235 set_irq_flags(virq, IRQF_VALID); /* kill me now */
236 return 0;
237}
238
239static struct irq_domain_ops em_gio_irq_domain_ops = {
240 .map = em_gio_irq_domain_map,
241};
242
243static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)
244{
245 struct platform_device *pdev = p->pdev;
246 struct gpio_em_config *pdata = pdev->dev.platform_data;
247
248 p->irq_base = irq_alloc_descs(pdata->irq_base, 0,
249 pdata->number_of_pins, numa_node_id());
250 if (IS_ERR_VALUE(p->irq_base)) {
251 dev_err(&pdev->dev, "cannot get irq_desc\n");
252 return -ENXIO;
253 }
254 pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n",
255 pdata->gpio_base, pdata->number_of_pins, p->irq_base);
256
257 p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
258 pdata->number_of_pins,
259 p->irq_base, 0,
260 &em_gio_irq_domain_ops, p);
261 if (!p->irq_domain) {
262 irq_free_descs(p->irq_base, pdata->number_of_pins);
263 return -ENXIO;
264 }
265
266 return 0;
267}
268
269static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p)
270{
271 struct gpio_em_config *pdata = p->pdev->dev.platform_data;
272
273 irq_free_descs(p->irq_base, pdata->number_of_pins);
274 /* FIXME: irq domain wants to be freed! */
275}
276
277static int __devinit em_gio_probe(struct platform_device *pdev)
278{
279 struct gpio_em_config *pdata = pdev->dev.platform_data;
280 struct em_gio_priv *p;
281 struct resource *io[2], *irq[2];
282 struct gpio_chip *gpio_chip;
283 struct irq_chip *irq_chip;
284 const char *name = dev_name(&pdev->dev);
285 int ret;
286
287 p = kzalloc(sizeof(*p), GFP_KERNEL);
288 if (!p) {
289 dev_err(&pdev->dev, "failed to allocate driver data\n");
290 ret = -ENOMEM;
291 goto err0;
292 }
293
294 p->pdev = pdev;
295 platform_set_drvdata(pdev, p);
296 spin_lock_init(&p->sense_lock);
297
298 io[0] = platform_get_resource(pdev, IORESOURCE_MEM, 0);
299 io[1] = platform_get_resource(pdev, IORESOURCE_MEM, 1);
300 irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
301 irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
302
303 if (!io[0] || !io[1] || !irq[0] || !irq[1] || !pdata) {
304 dev_err(&pdev->dev, "missing IRQ, IOMEM or configuration\n");
305 ret = -EINVAL;
306 goto err1;
307 }
308
309 p->base0 = ioremap_nocache(io[0]->start, resource_size(io[0]));
310 if (!p->base0) {
311 dev_err(&pdev->dev, "failed to remap low I/O memory\n");
312 ret = -ENXIO;
313 goto err1;
314 }
315
316 p->base1 = ioremap_nocache(io[1]->start, resource_size(io[1]));
317 if (!p->base1) {
318 dev_err(&pdev->dev, "failed to remap high I/O memory\n");
319 ret = -ENXIO;
320 goto err2;
321 }
322
323 gpio_chip = &p->gpio_chip;
324 gpio_chip->direction_input = em_gio_direction_input;
325 gpio_chip->get = em_gio_get;
326 gpio_chip->direction_output = em_gio_direction_output;
327 gpio_chip->set = em_gio_set;
328 gpio_chip->to_irq = em_gio_to_irq;
329 gpio_chip->label = name;
330 gpio_chip->owner = THIS_MODULE;
331 gpio_chip->base = pdata->gpio_base;
332 gpio_chip->ngpio = pdata->number_of_pins;
333
334 irq_chip = &p->irq_chip;
335 irq_chip->name = name;
336 irq_chip->irq_mask = em_gio_irq_disable;
337 irq_chip->irq_unmask = em_gio_irq_enable;
338 irq_chip->irq_enable = em_gio_irq_enable;
339 irq_chip->irq_disable = em_gio_irq_disable;
340 irq_chip->irq_set_type = em_gio_irq_set_type;
341 irq_chip->flags = IRQCHIP_SKIP_SET_WAKE;
342
343 ret = em_gio_irq_domain_init(p);
344 if (ret) {
345 dev_err(&pdev->dev, "cannot initialize irq domain\n");
346 goto err3;
347 }
348
349 if (request_irq(irq[0]->start, em_gio_irq_handler, 0, name, p)) {
350 dev_err(&pdev->dev, "failed to request low IRQ\n");
351 ret = -ENOENT;
352 goto err4;
353 }
354
355 if (request_irq(irq[1]->start, em_gio_irq_handler, 0, name, p)) {
356 dev_err(&pdev->dev, "failed to request high IRQ\n");
357 ret = -ENOENT;
358 goto err5;
359 }
360
361 ret = gpiochip_add(gpio_chip);
362 if (ret) {
363 dev_err(&pdev->dev, "failed to add GPIO controller\n");
364 goto err6;
365 }
366 return 0;
367
368err6:
369 free_irq(irq[1]->start, pdev);
370err5:
371 free_irq(irq[0]->start, pdev);
372err4:
373 em_gio_irq_domain_cleanup(p);
374err3:
375 iounmap(p->base1);
376err2:
377 iounmap(p->base0);
378err1:
379 kfree(p);
380err0:
381 return ret;
382}
383
384static int __devexit em_gio_remove(struct platform_device *pdev)
385{
386 struct em_gio_priv *p = platform_get_drvdata(pdev);
387 struct resource *irq[2];
388 int ret;
389
390 ret = gpiochip_remove(&p->gpio_chip);
391 if (ret)
392 return ret;
393
394 irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
395 irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
396
397 free_irq(irq[1]->start, pdev);
398 free_irq(irq[0]->start, pdev);
399 em_gio_irq_domain_cleanup(p);
400 iounmap(p->base1);
401 iounmap(p->base0);
402 kfree(p);
403 return 0;
404}
405
406static struct platform_driver em_gio_device_driver = {
407 .probe = em_gio_probe,
408 .remove = __devexit_p(em_gio_remove),
409 .driver = {
410 .name = "em_gio",
411 }
412};
413
414module_platform_driver(em_gio_device_driver);
415
416MODULE_AUTHOR("Magnus Damm");
417MODULE_DESCRIPTION("Renesas Emma Mobile GIO Driver");
418MODULE_LICENSE("GPL v2");
diff --git a/include/linux/platform_data/gpio-em.h b/include/linux/platform_data/gpio-em.h
new file mode 100644
index 000000000000..573edfb046c4
--- /dev/null
+++ b/include/linux/platform_data/gpio-em.h
@@ -0,0 +1,10 @@
1#ifndef __GPIO_EM_H__
2#define __GPIO_EM_H__
3
4struct gpio_em_config {
5 unsigned int gpio_base;
6 unsigned int irq_base;
7 unsigned int number_of_pins;
8};
9
10#endif /* __GPIO_EM_H__ */