aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-01-08 21:12:55 -0500
committerPaul Mundt <lethal@linux-sh.org>2012-01-08 21:12:55 -0500
commitca371d2854d48c0c22e7aa031df182f96dc85820 (patch)
tree1c62be8b4da0bfc82fa7ffa1ad5b0e958266cbd1 /arch/arm/mach-shmobile
parent0d376945d0bc0a8f8e00861d506b10e42e8af372 (diff)
parenta0e86bd4252519321b0d102dc4ed90557aa7bee9 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into sh-latest
Conflicts: arch/arm/mach-shmobile/clock-sh73a0.c Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/Makefile1
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c5
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c2
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c2
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c2
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c141
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c12
-rw-r--r--arch/arm/mach-shmobile/entry-gic.S18
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h5
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro.S9
-rw-r--r--arch/arm/mach-shmobile/include/mach/gpio.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/system.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h7
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c50
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c196
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c6
-rw-r--r--arch/arm/mach-shmobile/sleep-sh7372.S21
19 files changed, 354 insertions, 135 deletions
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 737bdc631b0d..5ca1f9d66995 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -28,7 +28,6 @@ pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o
28obj-$(CONFIG_ARCH_SH7367) += entry-intc.o 28obj-$(CONFIG_ARCH_SH7367) += entry-intc.o
29obj-$(CONFIG_ARCH_SH7377) += entry-intc.o 29obj-$(CONFIG_ARCH_SH7377) += entry-intc.o
30obj-$(CONFIG_ARCH_SH7372) += entry-intc.o 30obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
31obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o
32 31
33# PM objects 32# PM objects
34obj-$(CONFIG_SUSPEND) += suspend.o 33obj-$(CONFIG_SUSPEND) += suspend.o
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index b862e9f81e3e..a4e6ca04e319 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -466,8 +466,6 @@ static struct map_desc ag5evm_io_desc[] __initdata = {
466static void __init ag5evm_map_io(void) 466static void __init ag5evm_map_io(void)
467{ 467{
468 iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc)); 468 iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
469 /* DMA memory at 0xf6000000 - 0xffdfffff */
470 init_consistent_dma_size(158 << 20);
471 469
472 /* setup early devices and console here as well */ 470 /* setup early devices and console here as well */
473 sh73a0_add_early_devices(); 471 sh73a0_add_early_devices();
@@ -607,8 +605,9 @@ struct sys_timer ag5evm_timer = {
607 605
608MACHINE_START(AG5EVM, "ag5evm") 606MACHINE_START(AG5EVM, "ag5evm")
609 .map_io = ag5evm_map_io, 607 .map_io = ag5evm_map_io,
608 .nr_irqs = NR_IRQS_LEGACY,
610 .init_irq = sh73a0_init_irq, 609 .init_irq = sh73a0_init_irq,
611 .handle_irq = shmobile_handle_irq_gic, 610 .handle_irq = gic_handle_irq,
612 .init_machine = ag5evm_init, 611 .init_machine = ag5evm_init,
613 .timer = &ag5evm_timer, 612 .timer = &ag5evm_timer,
614MACHINE_END 613MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 4c865ece9ac4..6a6f9f7568c2 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1172,8 +1172,6 @@ static struct map_desc ap4evb_io_desc[] __initdata = {
1172static void __init ap4evb_map_io(void) 1172static void __init ap4evb_map_io(void)
1173{ 1173{
1174 iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); 1174 iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
1175 /* DMA memory at 0xf6000000 - 0xffdfffff */
1176 init_consistent_dma_size(158 << 20);
1177 1175
1178 /* setup early devices and console here as well */ 1176 /* setup early devices and console here as well */
1179 sh7372_add_early_devices(); 1177 sh7372_add_early_devices();
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 8b620bf06221..72d557281b1f 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -261,8 +261,6 @@ static struct map_desc g3evm_io_desc[] __initdata = {
261static void __init g3evm_map_io(void) 261static void __init g3evm_map_io(void)
262{ 262{
263 iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); 263 iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
264 /* DMA memory at 0xf6000000 - 0xffdfffff */
265 init_consistent_dma_size(158 << 20);
266 264
267 /* setup early devices and console here as well */ 265 /* setup early devices and console here as well */
268 sh7367_add_early_devices(); 266 sh7367_add_early_devices();
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 7719ddc5f591..2220b885cff5 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -275,8 +275,6 @@ static struct map_desc g4evm_io_desc[] __initdata = {
275static void __init g4evm_map_io(void) 275static void __init g4evm_map_io(void)
276{ 276{
277 iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); 277 iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
278 /* DMA memory at 0xf6000000 - 0xffdfffff */
279 init_consistent_dma_size(158 << 20);
280 278
281 /* setup early devices and console here as well */ 279 /* setup early devices and console here as well */
282 sh7377_add_early_devices(); 280 sh7377_add_early_devices();
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index bd9a78424d6b..857ceeec1bb0 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -33,6 +33,7 @@
33#include <linux/input/sh_keysc.h> 33#include <linux/input/sh_keysc.h>
34#include <linux/gpio_keys.h> 34#include <linux/gpio_keys.h>
35#include <linux/leds.h> 35#include <linux/leds.h>
36#include <linux/platform_data/leds-renesas-tpu.h>
36#include <linux/mmc/host.h> 37#include <linux/mmc/host.h>
37#include <linux/mmc/sh_mmcif.h> 38#include <linux/mmc/sh_mmcif.h>
38#include <linux/mfd/tmio.h> 39#include <linux/mfd/tmio.h>
@@ -56,7 +57,7 @@ static struct resource smsc9220_resources[] = {
56 .flags = IORESOURCE_MEM, 57 .flags = IORESOURCE_MEM,
57 }, 58 },
58 [1] = { 59 [1] = {
59 .start = gic_spi(33), /* PINTA2 @ PORT144 */ 60 .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */
60 .flags = IORESOURCE_IRQ, 61 .flags = IORESOURCE_IRQ,
61 }, 62 },
62}; 63};
@@ -157,10 +158,6 @@ static struct platform_device gpio_keys_device = {
157#define GPIO_LED(n, g) { .name = n, .gpio = g } 158#define GPIO_LED(n, g) { .name = n, .gpio = g }
158 159
159static struct gpio_led gpio_leds[] = { 160static struct gpio_led gpio_leds[] = {
160 GPIO_LED("V2513", GPIO_PORT153), /* PORT153 [TPU1T02] -> V2513 */
161 GPIO_LED("V2514", GPIO_PORT199), /* PORT199 [TPU4TO1] -> V2514 */
162 GPIO_LED("V2515", GPIO_PORT197), /* PORT197 [TPU2TO1] -> V2515 */
163 GPIO_LED("KEYLED", GPIO_PORT163), /* PORT163 [TPU3TO0] -> KEYLED */
164 GPIO_LED("G", GPIO_PORT20), /* PORT20 [GPO0] -> LED7 -> "G" */ 161 GPIO_LED("G", GPIO_PORT20), /* PORT20 [GPO0] -> LED7 -> "G" */
165 GPIO_LED("H", GPIO_PORT21), /* PORT21 [GPO1] -> LED8 -> "H" */ 162 GPIO_LED("H", GPIO_PORT21), /* PORT21 [GPO1] -> LED8 -> "H" */
166 GPIO_LED("J", GPIO_PORT22), /* PORT22 [GPO2] -> LED9 -> "J" */ 163 GPIO_LED("J", GPIO_PORT22), /* PORT22 [GPO2] -> LED9 -> "J" */
@@ -179,6 +176,119 @@ static struct platform_device gpio_leds_device = {
179 }, 176 },
180}; 177};
181 178
179/* TPU LED */
180static struct led_renesas_tpu_config led_renesas_tpu12_pdata = {
181 .name = "V2513",
182 .pin_gpio_fn = GPIO_FN_TPU1TO2,
183 .pin_gpio = GPIO_PORT153,
184 .channel_offset = 0x90,
185 .timer_bit = 2,
186 .max_brightness = 1000,
187};
188
189static struct resource tpu12_resources[] = {
190 [0] = {
191 .name = "TPU12",
192 .start = 0xe6610090,
193 .end = 0xe66100b5,
194 .flags = IORESOURCE_MEM,
195 },
196};
197
198static struct platform_device leds_tpu12_device = {
199 .name = "leds-renesas-tpu",
200 .id = 12,
201 .dev = {
202 .platform_data = &led_renesas_tpu12_pdata,
203 },
204 .num_resources = ARRAY_SIZE(tpu12_resources),
205 .resource = tpu12_resources,
206};
207
208static struct led_renesas_tpu_config led_renesas_tpu41_pdata = {
209 .name = "V2514",
210 .pin_gpio_fn = GPIO_FN_TPU4TO1,
211 .pin_gpio = GPIO_PORT199,
212 .channel_offset = 0x50,
213 .timer_bit = 1,
214 .max_brightness = 1000,
215};
216
217static struct resource tpu41_resources[] = {
218 [0] = {
219 .name = "TPU41",
220 .start = 0xe6640050,
221 .end = 0xe6640075,
222 .flags = IORESOURCE_MEM,
223 },
224};
225
226static struct platform_device leds_tpu41_device = {
227 .name = "leds-renesas-tpu",
228 .id = 41,
229 .dev = {
230 .platform_data = &led_renesas_tpu41_pdata,
231 },
232 .num_resources = ARRAY_SIZE(tpu41_resources),
233 .resource = tpu41_resources,
234};
235
236static struct led_renesas_tpu_config led_renesas_tpu21_pdata = {
237 .name = "V2515",
238 .pin_gpio_fn = GPIO_FN_TPU2TO1,
239 .pin_gpio = GPIO_PORT197,
240 .channel_offset = 0x50,
241 .timer_bit = 1,
242 .max_brightness = 1000,
243};
244
245static struct resource tpu21_resources[] = {
246 [0] = {
247 .name = "TPU21",
248 .start = 0xe6620050,
249 .end = 0xe6620075,
250 .flags = IORESOURCE_MEM,
251 },
252};
253
254static struct platform_device leds_tpu21_device = {
255 .name = "leds-renesas-tpu",
256 .id = 21,
257 .dev = {
258 .platform_data = &led_renesas_tpu21_pdata,
259 },
260 .num_resources = ARRAY_SIZE(tpu21_resources),
261 .resource = tpu21_resources,
262};
263
264static struct led_renesas_tpu_config led_renesas_tpu30_pdata = {
265 .name = "KEYLED",
266 .pin_gpio_fn = GPIO_FN_TPU3TO0,
267 .pin_gpio = GPIO_PORT163,
268 .channel_offset = 0x10,
269 .timer_bit = 0,
270 .max_brightness = 1000,
271};
272
273static struct resource tpu30_resources[] = {
274 [0] = {
275 .name = "TPU30",
276 .start = 0xe6630010,
277 .end = 0xe6630035,
278 .flags = IORESOURCE_MEM,
279 },
280};
281
282static struct platform_device leds_tpu30_device = {
283 .name = "leds-renesas-tpu",
284 .id = 30,
285 .dev = {
286 .platform_data = &led_renesas_tpu30_pdata,
287 },
288 .num_resources = ARRAY_SIZE(tpu30_resources),
289 .resource = tpu30_resources,
290};
291
182/* MMCIF */ 292/* MMCIF */
183static struct resource mmcif_resources[] = { 293static struct resource mmcif_resources[] = {
184 [0] = { 294 [0] = {
@@ -291,6 +401,10 @@ static struct platform_device *kota2_devices[] __initdata = {
291 &keysc_device, 401 &keysc_device,
292 &gpio_keys_device, 402 &gpio_keys_device,
293 &gpio_leds_device, 403 &gpio_leds_device,
404 &leds_tpu12_device,
405 &leds_tpu41_device,
406 &leds_tpu21_device,
407 &leds_tpu30_device,
294 &mmcif_device, 408 &mmcif_device,
295 &sdhi0_device, 409 &sdhi0_device,
296 &sdhi1_device, 410 &sdhi1_device,
@@ -317,18 +431,6 @@ static void __init kota2_map_io(void)
317 shmobile_setup_console(); 431 shmobile_setup_console();
318} 432}
319 433
320#define PINTER0A 0xe69000a0
321#define PINTCR0A 0xe69000b0
322
323void __init kota2_init_irq(void)
324{
325 sh73a0_init_irq();
326
327 /* setup PINT: enable PINTA2 as active low */
328 __raw_writel(1 << 29, PINTER0A);
329 __raw_writew(2 << 10, PINTCR0A);
330}
331
332static void __init kota2_init(void) 434static void __init kota2_init(void)
333{ 435{
334 sh73a0_pinmux_init(); 436 sh73a0_pinmux_init();
@@ -447,8 +549,9 @@ struct sys_timer kota2_timer = {
447 549
448MACHINE_START(KOTA2, "kota2") 550MACHINE_START(KOTA2, "kota2")
449 .map_io = kota2_map_io, 551 .map_io = kota2_map_io,
450 .init_irq = kota2_init_irq, 552 .nr_irqs = NR_IRQS_LEGACY,
451 .handle_irq = shmobile_handle_irq_gic, 553 .init_irq = sh73a0_init_irq,
554 .handle_irq = gic_handle_irq,
452 .init_machine = kota2_init, 555 .init_machine = kota2_init,
453 .timer = &kota2_timer, 556 .timer = &kota2_timer,
454MACHINE_END 557MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 9c5e598e0e3d..ed5256687397 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1390,8 +1390,6 @@ static struct map_desc mackerel_io_desc[] __initdata = {
1390static void __init mackerel_map_io(void) 1390static void __init mackerel_map_io(void)
1391{ 1391{
1392 iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc)); 1392 iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
1393 /* DMA memory at 0xf6000000 - 0xffdfffff */
1394 init_consistent_dma_size(158 << 20);
1395 1393
1396 /* setup early devices and console here as well */ 1394 /* setup early devices and console here as well */
1397 sh7372_add_early_devices(); 1395 sh7372_add_early_devices();
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 8ea8c810144b..34944d01bf1e 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -131,6 +131,7 @@ static struct clk main_clk = {
131 .ops = &main_clk_ops, 131 .ops = &main_clk_ops,
132}; 132};
133 133
134/* Divide Main clock by two */
134static struct clk main_div2_clk = { 135static struct clk main_div2_clk = {
135 .ops = &div2_clk_ops, 136 .ops = &div2_clk_ops,
136 .parent = &main_clk, 137 .parent = &main_clk,
@@ -328,7 +329,7 @@ static struct clk div6_clks[DIV6_NR] = {
328 vck_parent, ARRAY_SIZE(vck_parent), 12, 3), 329 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
329 [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0, 330 [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
330 vck_parent, ARRAY_SIZE(vck_parent), 12, 3), 331 vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
331 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, 0, 332 [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
332 pll_parent, ARRAY_SIZE(pll_parent), 7, 1), 333 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
333 [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0, 334 [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
334 pll_parent, ARRAY_SIZE(pll_parent), 7, 1), 335 pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
@@ -370,6 +371,7 @@ enum { MSTP001,
370 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, 371 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
371 MSTP331, MSTP329, MSTP325, MSTP323, MSTP318, 372 MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
372 MSTP314, MSTP313, MSTP312, MSTP311, 373 MSTP314, MSTP313, MSTP312, MSTP311,
374 MSTP303, MSTP302, MSTP301, MSTP300,
373 MSTP411, MSTP410, MSTP403, 375 MSTP411, MSTP410, MSTP403,
374 MSTP_NR }; 376 MSTP_NR };
375 377
@@ -403,6 +405,10 @@ static struct clk mstp_clks[MSTP_NR] = {
403 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ 405 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
404 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ 406 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
405 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */ 407 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
408 [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
409 [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
410 [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
411 [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
406 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */ 412 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
407 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */ 413 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
408 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ 414 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
@@ -452,6 +458,10 @@ static struct clk_lookup lookups[] = {
452 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ 458 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
453 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ 459 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
454 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ 460 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
461 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
462 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
463 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
464 CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
455 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ 465 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
456 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ 466 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
457 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 467 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
diff --git a/arch/arm/mach-shmobile/entry-gic.S b/arch/arm/mach-shmobile/entry-gic.S
deleted file mode 100644
index e20239b08c83..000000000000
--- a/arch/arm/mach-shmobile/entry-gic.S
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * ARM Interrupt demux handler using GIC
3 *
4 * Copyright (C) 2010 Magnus Damm
5 * Copyright (C) 2011 Paul Mundt
6 * Copyright (C) 2010 - 2011 Renesas Solutions Corp.
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <asm/assembler.h>
14#include <asm/entry-macro-multi.S>
15#include <asm/hardware/gic.h>
16#include <asm/hardware/entry-macro-gic.S>
17
18 arch_irq_handler shmobile_handle_irq_gic
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index d055d054ef89..13a18d343ecb 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -7,7 +7,6 @@ extern void shmobile_secondary_vector(void);
7struct clk; 7struct clk;
8extern int clk_init(void); 8extern int clk_init(void);
9extern void shmobile_handle_irq_intc(struct pt_regs *); 9extern void shmobile_handle_irq_intc(struct pt_regs *);
10extern void shmobile_handle_irq_gic(struct pt_regs *);
11extern struct platform_suspend_ops shmobile_suspend_ops; 10extern struct platform_suspend_ops shmobile_suspend_ops;
12struct cpuidle_driver; 11struct cpuidle_driver;
13extern void (*shmobile_cpuidle_modes[])(void); 12extern void (*shmobile_cpuidle_modes[])(void);
@@ -35,8 +34,8 @@ extern void sh7372_add_standard_devices(void);
35extern void sh7372_clock_init(void); 34extern void sh7372_clock_init(void);
36extern void sh7372_pinmux_init(void); 35extern void sh7372_pinmux_init(void);
37extern void sh7372_pm_init(void); 36extern void sh7372_pm_init(void);
38extern void sh7372_resume_core_standby_a3sm(void); 37extern void sh7372_resume_core_standby_sysc(void);
39extern int sh7372_do_idle_a3sm(unsigned long unused); 38extern int sh7372_do_idle_sysc(unsigned long sleep_mode);
40extern struct clk sh7372_extal1_clk; 39extern struct clk sh7372_extal1_clk;
41extern struct clk sh7372_extal2_clk; 40extern struct clk sh7372_extal2_clk;
42 41
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
index 8d4a416d4285..2a57b2964ee9 100644
--- a/arch/arm/mach-shmobile/include/mach/entry-macro.S
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
@@ -18,14 +18,5 @@
18 .macro disable_fiq 18 .macro disable_fiq
19 .endm 19 .endm
20 20
21 .macro get_irqnr_preamble, base, tmp
22 .endm
23
24 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
25 .endm
26
27 .macro test_for_ipi, irqnr, irqstat, base, tmp
28 .endm
29
30 .macro arch_ret_to_user, tmp1, tmp2 21 .macro arch_ret_to_user, tmp1, tmp2
31 .endm 22 .endm
diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h
index 7bf0890e16ba..de795b42232a 100644
--- a/arch/arm/mach-shmobile/include/mach/gpio.h
+++ b/arch/arm/mach-shmobile/include/mach/gpio.h
@@ -12,8 +12,6 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15
16#define ARCH_NR_GPIOS 1024
17#include <linux/sh_pfc.h> 15#include <linux/sh_pfc.h>
18 16
19#ifdef CONFIG_GPIOLIB 17#ifdef CONFIG_GPIOLIB
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 84532f9629b2..8254ab86f6cd 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -480,11 +480,10 @@ struct platform_device;
480struct sh7372_pm_domain { 480struct sh7372_pm_domain {
481 struct generic_pm_domain genpd; 481 struct generic_pm_domain genpd;
482 struct dev_power_governor *gov; 482 struct dev_power_governor *gov;
483 void (*suspend)(void); 483 int (*suspend)(void);
484 void (*resume)(void); 484 void (*resume)(void);
485 unsigned int bit_shift; 485 unsigned int bit_shift;
486 bool no_debug; 486 bool no_debug;
487 bool stay_on;
488}; 487};
489 488
490static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d) 489static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d)
@@ -499,6 +498,7 @@ extern struct sh7372_pm_domain sh7372_d4;
499extern struct sh7372_pm_domain sh7372_a4r; 498extern struct sh7372_pm_domain sh7372_a4r;
500extern struct sh7372_pm_domain sh7372_a3rv; 499extern struct sh7372_pm_domain sh7372_a3rv;
501extern struct sh7372_pm_domain sh7372_a3ri; 500extern struct sh7372_pm_domain sh7372_a3ri;
501extern struct sh7372_pm_domain sh7372_a4s;
502extern struct sh7372_pm_domain sh7372_a3sp; 502extern struct sh7372_pm_domain sh7372_a3sp;
503extern struct sh7372_pm_domain sh7372_a3sg; 503extern struct sh7372_pm_domain sh7372_a3sg;
504 504
@@ -515,5 +515,7 @@ extern void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
515 515
516extern void sh7372_intcs_suspend(void); 516extern void sh7372_intcs_suspend(void);
517extern void sh7372_intcs_resume(void); 517extern void sh7372_intcs_resume(void);
518extern void sh7372_intca_suspend(void);
519extern void sh7372_intca_resume(void);
518 520
519#endif /* __ASM_SH7372_H__ */ 521#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h
index 76a687eeaa22..956ac18ddbf9 100644
--- a/arch/arm/mach-shmobile/include/mach/system.h
+++ b/arch/arm/mach-shmobile/include/mach/system.h
@@ -8,7 +8,7 @@ static inline void arch_idle(void)
8 8
9static inline void arch_reset(char mode, const char *cmd) 9static inline void arch_reset(char mode, const char *cmd)
10{ 10{
11 cpu_reset(0); 11 soft_restart(0);
12} 12}
13 13
14#endif 14#endif
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
deleted file mode 100644
index 2b8fd8b942fe..000000000000
--- a/arch/arm/mach-shmobile/include/mach/vmalloc.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __ASM_MACH_VMALLOC_H
2#define __ASM_MACH_VMALLOC_H
3
4/* Vmalloc at ... - 0xe5ffffff */
5#define VMALLOC_END 0xe6000000UL
6
7#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index 2d8856df80e2..89afcaba99a1 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -535,6 +535,7 @@ static struct resource intcs_resources[] __initdata = {
535static struct intc_desc intcs_desc __initdata = { 535static struct intc_desc intcs_desc __initdata = {
536 .name = "sh7372-intcs", 536 .name = "sh7372-intcs",
537 .force_enable = ENABLED_INTCS, 537 .force_enable = ENABLED_INTCS,
538 .skip_syscore_suspend = true,
538 .resource = intcs_resources, 539 .resource = intcs_resources,
539 .num_resources = ARRAY_SIZE(intcs_resources), 540 .num_resources = ARRAY_SIZE(intcs_resources),
540 .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, 541 .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
@@ -611,3 +612,52 @@ void sh7372_intcs_resume(void)
611 for (k = 0x80; k <= 0x9c; k += 4) 612 for (k = 0x80; k <= 0x9c; k += 4)
612 __raw_writeb(ffd5[k], intcs_ffd5 + k); 613 __raw_writeb(ffd5[k], intcs_ffd5 + k);
613} 614}
615
616static unsigned short e694[0x200];
617static unsigned short e695[0x200];
618
619void sh7372_intca_suspend(void)
620{
621 int k;
622
623 for (k = 0x00; k <= 0x38; k += 4)
624 e694[k] = __raw_readw(0xe6940000 + k);
625
626 for (k = 0x80; k <= 0xb4; k += 4)
627 e694[k] = __raw_readb(0xe6940000 + k);
628
629 for (k = 0x180; k <= 0x1b4; k += 4)
630 e694[k] = __raw_readb(0xe6940000 + k);
631
632 for (k = 0x00; k <= 0x50; k += 4)
633 e695[k] = __raw_readw(0xe6950000 + k);
634
635 for (k = 0x80; k <= 0xa8; k += 4)
636 e695[k] = __raw_readb(0xe6950000 + k);
637
638 for (k = 0x180; k <= 0x1a8; k += 4)
639 e695[k] = __raw_readb(0xe6950000 + k);
640}
641
642void sh7372_intca_resume(void)
643{
644 int k;
645
646 for (k = 0x00; k <= 0x38; k += 4)
647 __raw_writew(e694[k], 0xe6940000 + k);
648
649 for (k = 0x80; k <= 0xb4; k += 4)
650 __raw_writeb(e694[k], 0xe6940000 + k);
651
652 for (k = 0x180; k <= 0x1b4; k += 4)
653 __raw_writeb(e694[k], 0xe6940000 + k);
654
655 for (k = 0x00; k <= 0x50; k += 4)
656 __raw_writew(e695[k], 0xe6950000 + k);
657
658 for (k = 0x80; k <= 0xa8; k += 4)
659 __raw_writeb(e695[k], 0xe6950000 + k);
660
661 for (k = 0x180; k <= 0x1a8; k += 4)
662 __raw_writeb(e695[k], 0xe6950000 + k);
663}
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 34bbcbfb1706..77b8fc12fc2f 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -82,11 +82,12 @@ static int pd_power_down(struct generic_pm_domain *genpd)
82 struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); 82 struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
83 unsigned int mask = 1 << sh7372_pd->bit_shift; 83 unsigned int mask = 1 << sh7372_pd->bit_shift;
84 84
85 if (sh7372_pd->suspend) 85 if (sh7372_pd->suspend) {
86 sh7372_pd->suspend(); 86 int ret = sh7372_pd->suspend();
87 87
88 if (sh7372_pd->stay_on) 88 if (ret)
89 return 0; 89 return ret;
90 }
90 91
91 if (__raw_readl(PSTR) & mask) { 92 if (__raw_readl(PSTR) & mask) {
92 unsigned int retry_count; 93 unsigned int retry_count;
@@ -101,8 +102,8 @@ static int pd_power_down(struct generic_pm_domain *genpd)
101 } 102 }
102 103
103 if (!sh7372_pd->no_debug) 104 if (!sh7372_pd->no_debug)
104 pr_debug("sh7372 power domain down 0x%08x -> PSTR = 0x%08x\n", 105 pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
105 mask, __raw_readl(PSTR)); 106 genpd->name, mask, __raw_readl(PSTR));
106 107
107 return 0; 108 return 0;
108} 109}
@@ -113,9 +114,6 @@ static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume)
113 unsigned int retry_count; 114 unsigned int retry_count;
114 int ret = 0; 115 int ret = 0;
115 116
116 if (sh7372_pd->stay_on)
117 goto out;
118
119 if (__raw_readl(PSTR) & mask) 117 if (__raw_readl(PSTR) & mask)
120 goto out; 118 goto out;
121 119
@@ -133,8 +131,8 @@ static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume)
133 ret = -EIO; 131 ret = -EIO;
134 132
135 if (!sh7372_pd->no_debug) 133 if (!sh7372_pd->no_debug)
136 pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n", 134 pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
137 mask, __raw_readl(PSTR)); 135 sh7372_pd->genpd.name, mask, __raw_readl(PSTR));
138 136
139 out: 137 out:
140 if (ret == 0 && sh7372_pd->resume && do_resume) 138 if (ret == 0 && sh7372_pd->resume && do_resume)
@@ -148,35 +146,60 @@ static int pd_power_up(struct generic_pm_domain *genpd)
148 return __pd_power_up(to_sh7372_pd(genpd), true); 146 return __pd_power_up(to_sh7372_pd(genpd), true);
149} 147}
150 148
151static void sh7372_a4r_suspend(void) 149static int sh7372_a4r_suspend(void)
152{ 150{
153 sh7372_intcs_suspend(); 151 sh7372_intcs_suspend();
154 __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */ 152 __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */
153 return 0;
155} 154}
156 155
157static bool pd_active_wakeup(struct device *dev) 156static bool pd_active_wakeup(struct device *dev)
158{ 157{
159 return true; 158 bool (*active_wakeup)(struct device *dev);
159
160 active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
161 return active_wakeup ? active_wakeup(dev) : true;
160} 162}
161 163
162static bool sh7372_power_down_forbidden(struct dev_pm_domain *domain) 164static int sh7372_stop_dev(struct device *dev)
163{ 165{
164 return false; 166 int (*stop)(struct device *dev);
167
168 stop = dev_gpd_data(dev)->ops.stop;
169 if (stop) {
170 int ret = stop(dev);
171 if (ret)
172 return ret;
173 }
174 return pm_clk_suspend(dev);
165} 175}
166 176
167struct dev_power_governor sh7372_always_on_gov = { 177static int sh7372_start_dev(struct device *dev)
168 .power_down_ok = sh7372_power_down_forbidden, 178{
169}; 179 int (*start)(struct device *dev);
180 int ret;
181
182 ret = pm_clk_resume(dev);
183 if (ret)
184 return ret;
185
186 start = dev_gpd_data(dev)->ops.start;
187 if (start)
188 ret = start(dev);
189
190 return ret;
191}
170 192
171void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd) 193void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
172{ 194{
173 struct generic_pm_domain *genpd = &sh7372_pd->genpd; 195 struct generic_pm_domain *genpd = &sh7372_pd->genpd;
196 struct dev_power_governor *gov = sh7372_pd->gov;
174 197
175 pm_genpd_init(genpd, sh7372_pd->gov, false); 198 pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
176 genpd->stop_device = pm_clk_suspend; 199 genpd->dev_ops.stop = sh7372_stop_dev;
177 genpd->start_device = pm_clk_resume; 200 genpd->dev_ops.start = sh7372_start_dev;
201 genpd->dev_ops.active_wakeup = pd_active_wakeup;
178 genpd->dev_irq_safe = true; 202 genpd->dev_irq_safe = true;
179 genpd->active_wakeup = pd_active_wakeup;
180 genpd->power_off = pd_power_down; 203 genpd->power_off = pd_power_down;
181 genpd->power_on = pd_power_up; 204 genpd->power_on = pd_power_up;
182 __pd_power_up(sh7372_pd, false); 205 __pd_power_up(sh7372_pd, false);
@@ -199,48 +222,73 @@ void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
199} 222}
200 223
201struct sh7372_pm_domain sh7372_a4lc = { 224struct sh7372_pm_domain sh7372_a4lc = {
225 .genpd.name = "A4LC",
202 .bit_shift = 1, 226 .bit_shift = 1,
203}; 227};
204 228
205struct sh7372_pm_domain sh7372_a4mp = { 229struct sh7372_pm_domain sh7372_a4mp = {
230 .genpd.name = "A4MP",
206 .bit_shift = 2, 231 .bit_shift = 2,
207}; 232};
208 233
209struct sh7372_pm_domain sh7372_d4 = { 234struct sh7372_pm_domain sh7372_d4 = {
235 .genpd.name = "D4",
210 .bit_shift = 3, 236 .bit_shift = 3,
211}; 237};
212 238
213struct sh7372_pm_domain sh7372_a4r = { 239struct sh7372_pm_domain sh7372_a4r = {
240 .genpd.name = "A4R",
214 .bit_shift = 5, 241 .bit_shift = 5,
215 .gov = &sh7372_always_on_gov,
216 .suspend = sh7372_a4r_suspend, 242 .suspend = sh7372_a4r_suspend,
217 .resume = sh7372_intcs_resume, 243 .resume = sh7372_intcs_resume,
218 .stay_on = true,
219}; 244};
220 245
221struct sh7372_pm_domain sh7372_a3rv = { 246struct sh7372_pm_domain sh7372_a3rv = {
247 .genpd.name = "A3RV",
222 .bit_shift = 6, 248 .bit_shift = 6,
223}; 249};
224 250
225struct sh7372_pm_domain sh7372_a3ri = { 251struct sh7372_pm_domain sh7372_a3ri = {
252 .genpd.name = "A3RI",
226 .bit_shift = 8, 253 .bit_shift = 8,
227}; 254};
228 255
229struct sh7372_pm_domain sh7372_a3sp = { 256static int sh7372_a4s_suspend(void)
230 .bit_shift = 11, 257{
231 .gov = &sh7372_always_on_gov, 258 /*
259 * The A4S domain contains the CPU core and therefore it should
260 * only be turned off if the CPU is in use.
261 */
262 return -EBUSY;
263}
264
265struct sh7372_pm_domain sh7372_a4s = {
266 .genpd.name = "A4S",
267 .bit_shift = 10,
268 .gov = &pm_domain_always_on_gov,
232 .no_debug = true, 269 .no_debug = true,
270 .suspend = sh7372_a4s_suspend,
233}; 271};
234 272
235static void sh7372_a3sp_init(void) 273static int sh7372_a3sp_suspend(void)
236{ 274{
237 /* serial consoles make use of SCIF hardware located in A3SP, 275 /*
276 * Serial consoles make use of SCIF hardware located in A3SP,
238 * keep such power domain on if "no_console_suspend" is set. 277 * keep such power domain on if "no_console_suspend" is set.
239 */ 278 */
240 sh7372_a3sp.stay_on = !console_suspend_enabled; 279 return console_suspend_enabled ? -EBUSY : 0;
241} 280}
242 281
282struct sh7372_pm_domain sh7372_a3sp = {
283 .genpd.name = "A3SP",
284 .bit_shift = 11,
285 .gov = &pm_domain_always_on_gov,
286 .no_debug = true,
287 .suspend = sh7372_a3sp_suspend,
288};
289
243struct sh7372_pm_domain sh7372_a3sg = { 290struct sh7372_pm_domain sh7372_a3sg = {
291 .genpd.name = "A3SG",
244 .bit_shift = 13, 292 .bit_shift = 13,
245}; 293};
246 294
@@ -257,11 +305,16 @@ static int sh7372_do_idle_core_standby(unsigned long unused)
257 return 0; 305 return 0;
258} 306}
259 307
260static void sh7372_enter_core_standby(void) 308static void sh7372_set_reset_vector(unsigned long address)
261{ 309{
262 /* set reset vector, translate 4k */ 310 /* set reset vector, translate 4k */
263 __raw_writel(__pa(sh7372_resume_core_standby_a3sm), SBAR); 311 __raw_writel(address, SBAR);
264 __raw_writel(0, APARMBAREA); 312 __raw_writel(0, APARMBAREA);
313}
314
315static void sh7372_enter_core_standby(void)
316{
317 sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
265 318
266 /* enter sleep mode with SYSTBCR to 0x10 */ 319 /* enter sleep mode with SYSTBCR to 0x10 */
267 __raw_writel(0x10, SYSTBCR); 320 __raw_writel(0x10, SYSTBCR);
@@ -274,27 +327,22 @@ static void sh7372_enter_core_standby(void)
274#endif 327#endif
275 328
276#ifdef CONFIG_SUSPEND 329#ifdef CONFIG_SUSPEND
277static void sh7372_enter_a3sm_common(int pllc0_on) 330static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode)
278{ 331{
279 /* set reset vector, translate 4k */
280 __raw_writel(__pa(sh7372_resume_core_standby_a3sm), SBAR);
281 __raw_writel(0, APARMBAREA);
282
283 if (pllc0_on) 332 if (pllc0_on)
284 __raw_writel(0, PLLC01STPCR); 333 __raw_writel(0, PLLC01STPCR);
285 else 334 else
286 __raw_writel(1 << 28, PLLC01STPCR); 335 __raw_writel(1 << 28, PLLC01STPCR);
287 336
288 __raw_writel(0, PDNSEL); /* power-down A3SM only, not A4S */
289 __raw_readl(WUPSFAC); /* read wakeup int. factor before sleep */ 337 __raw_readl(WUPSFAC); /* read wakeup int. factor before sleep */
290 cpu_suspend(0, sh7372_do_idle_a3sm); 338 cpu_suspend(sleep_mode, sh7372_do_idle_sysc);
291 __raw_readl(WUPSFAC); /* read wakeup int. factor after wakeup */ 339 __raw_readl(WUPSFAC); /* read wakeup int. factor after wakeup */
292 340
293 /* disable reset vector translation */ 341 /* disable reset vector translation */
294 __raw_writel(0, SBAR); 342 __raw_writel(0, SBAR);
295} 343}
296 344
297static int sh7372_a3sm_valid(unsigned long *mskp, unsigned long *msk2p) 345static int sh7372_sysc_valid(unsigned long *mskp, unsigned long *msk2p)
298{ 346{
299 unsigned long mstpsr0, mstpsr1, mstpsr2, mstpsr3, mstpsr4; 347 unsigned long mstpsr0, mstpsr1, mstpsr2, mstpsr3, mstpsr4;
300 unsigned long msk, msk2; 348 unsigned long msk, msk2;
@@ -382,7 +430,7 @@ static void sh7372_icr_to_irqcr(unsigned long icr, u16 *irqcr1p, u16 *irqcr2p)
382 *irqcr2p = irqcr2; 430 *irqcr2p = irqcr2;
383} 431}
384 432
385static void sh7372_setup_a3sm(unsigned long msk, unsigned long msk2) 433static void sh7372_setup_sysc(unsigned long msk, unsigned long msk2)
386{ 434{
387 u16 irqcrx_low, irqcrx_high, irqcry_low, irqcry_high; 435 u16 irqcrx_low, irqcrx_high, irqcry_low, irqcry_high;
388 unsigned long tmp; 436 unsigned long tmp;
@@ -415,6 +463,22 @@ static void sh7372_setup_a3sm(unsigned long msk, unsigned long msk2)
415 __raw_writel((irqcrx_high << 16) | irqcrx_low, IRQCR3); 463 __raw_writel((irqcrx_high << 16) | irqcrx_low, IRQCR3);
416 __raw_writel((irqcry_high << 16) | irqcry_low, IRQCR4); 464 __raw_writel((irqcry_high << 16) | irqcry_low, IRQCR4);
417} 465}
466
467static void sh7372_enter_a3sm_common(int pllc0_on)
468{
469 sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
470 sh7372_enter_sysc(pllc0_on, 1 << 12);
471}
472
473static void sh7372_enter_a4s_common(int pllc0_on)
474{
475 sh7372_intca_suspend();
476 memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
477 sh7372_set_reset_vector(SMFRAM);
478 sh7372_enter_sysc(pllc0_on, 1 << 10);
479 sh7372_intca_resume();
480}
481
418#endif 482#endif
419 483
420#ifdef CONFIG_CPU_IDLE 484#ifdef CONFIG_CPU_IDLE
@@ -448,14 +512,20 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state)
448 unsigned long msk, msk2; 512 unsigned long msk, msk2;
449 513
450 /* check active clocks to determine potential wakeup sources */ 514 /* check active clocks to determine potential wakeup sources */
451 if (sh7372_a3sm_valid(&msk, &msk2)) { 515 if (sh7372_sysc_valid(&msk, &msk2)) {
452
453 /* convert INTC mask and sense to SYSC mask and sense */ 516 /* convert INTC mask and sense to SYSC mask and sense */
454 sh7372_setup_a3sm(msk, msk2); 517 sh7372_setup_sysc(msk, msk2);
455 518
456 /* enter A3SM sleep with PLLC0 off */ 519 if (!console_suspend_enabled &&
457 pr_debug("entering A3SM\n"); 520 sh7372_a4s.genpd.status == GPD_STATE_POWER_OFF) {
458 sh7372_enter_a3sm_common(0); 521 /* enter A4S sleep with PLLC0 off */
522 pr_debug("entering A4S\n");
523 sh7372_enter_a4s_common(0);
524 } else {
525 /* enter A3SM sleep with PLLC0 off */
526 pr_debug("entering A3SM\n");
527 sh7372_enter_a3sm_common(0);
528 }
459 } else { 529 } else {
460 /* default to Core Standby that supports all wakeup sources */ 530 /* default to Core Standby that supports all wakeup sources */
461 pr_debug("entering Core Standby\n"); 531 pr_debug("entering Core Standby\n");
@@ -464,9 +534,37 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state)
464 return 0; 534 return 0;
465} 535}
466 536
537/**
538 * sh7372_pm_notifier_fn - SH7372 PM notifier routine.
539 * @notifier: Unused.
540 * @pm_event: Event being handled.
541 * @unused: Unused.
542 */
543static int sh7372_pm_notifier_fn(struct notifier_block *notifier,
544 unsigned long pm_event, void *unused)
545{
546 switch (pm_event) {
547 case PM_SUSPEND_PREPARE:
548 /*
549 * This is necessary, because the A4R domain has to be "on"
550 * when suspend_device_irqs() and resume_device_irqs() are
551 * executed during system suspend and resume, respectively, so
552 * that those functions don't crash while accessing the INTCS.
553 */
554 pm_genpd_poweron(&sh7372_a4r.genpd);
555 break;
556 case PM_POST_SUSPEND:
557 pm_genpd_poweroff_unused();
558 break;
559 }
560
561 return NOTIFY_DONE;
562}
563
467static void sh7372_suspend_init(void) 564static void sh7372_suspend_init(void)
468{ 565{
469 shmobile_suspend_ops.enter = sh7372_enter_suspend; 566 shmobile_suspend_ops.enter = sh7372_enter_suspend;
567 pm_notifier(sh7372_pm_notifier_fn, 0);
470} 568}
471#else 569#else
472static void sh7372_suspend_init(void) {} 570static void sh7372_suspend_init(void) {}
@@ -482,8 +580,6 @@ void __init sh7372_pm_init(void)
482 /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */ 580 /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
483 __raw_writel(0, PDNSEL); 581 __raw_writel(0, PDNSEL);
484 582
485 sh7372_a3sp_init();
486
487 sh7372_suspend_init(); 583 sh7372_suspend_init();
488 sh7372_cpuidle_init(); 584 sh7372_cpuidle_init();
489} 585}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 2380389e6ac5..c197f9d29d04 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -994,12 +994,16 @@ void __init sh7372_add_standard_devices(void)
994 sh7372_init_pm_domain(&sh7372_a4r); 994 sh7372_init_pm_domain(&sh7372_a4r);
995 sh7372_init_pm_domain(&sh7372_a3rv); 995 sh7372_init_pm_domain(&sh7372_a3rv);
996 sh7372_init_pm_domain(&sh7372_a3ri); 996 sh7372_init_pm_domain(&sh7372_a3ri);
997 sh7372_init_pm_domain(&sh7372_a3sg); 997 sh7372_init_pm_domain(&sh7372_a4s);
998 sh7372_init_pm_domain(&sh7372_a3sp); 998 sh7372_init_pm_domain(&sh7372_a3sp);
999 sh7372_init_pm_domain(&sh7372_a3sg);
999 1000
1000 sh7372_pm_add_subdomain(&sh7372_a4lc, &sh7372_a3rv); 1001 sh7372_pm_add_subdomain(&sh7372_a4lc, &sh7372_a3rv);
1001 sh7372_pm_add_subdomain(&sh7372_a4r, &sh7372_a4lc); 1002 sh7372_pm_add_subdomain(&sh7372_a4r, &sh7372_a4lc);
1002 1003
1004 sh7372_pm_add_subdomain(&sh7372_a4s, &sh7372_a3sg);
1005 sh7372_pm_add_subdomain(&sh7372_a4s, &sh7372_a3sp);
1006
1003 platform_add_devices(sh7372_early_devices, 1007 platform_add_devices(sh7372_early_devices,
1004 ARRAY_SIZE(sh7372_early_devices)); 1008 ARRAY_SIZE(sh7372_early_devices));
1005 1009
diff --git a/arch/arm/mach-shmobile/sleep-sh7372.S b/arch/arm/mach-shmobile/sleep-sh7372.S
index f3ab3c5810ea..1d564674451d 100644
--- a/arch/arm/mach-shmobile/sleep-sh7372.S
+++ b/arch/arm/mach-shmobile/sleep-sh7372.S
@@ -37,13 +37,18 @@
37#if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE) 37#if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE)
38 .align 12 38 .align 12
39 .text 39 .text
40 .global sh7372_resume_core_standby_a3sm 40 .global sh7372_resume_core_standby_sysc
41sh7372_resume_core_standby_a3sm: 41sh7372_resume_core_standby_sysc:
42 ldr pc, 1f 42 ldr pc, 1f
431: .long cpu_resume - PAGE_OFFSET + PLAT_PHYS_OFFSET 431: .long cpu_resume - PAGE_OFFSET + PLAT_PHYS_OFFSET
44 44
45 .global sh7372_do_idle_a3sm 45#define SPDCR 0xe6180008
46sh7372_do_idle_a3sm: 46
47 /* A3SM & A4S power down */
48 .global sh7372_do_idle_sysc
49sh7372_do_idle_sysc:
50 mov r8, r0 /* sleep mode passed in r0 */
51
47 /* 52 /*
48 * Clear the SCTLR.C bit to prevent further data cache 53 * Clear the SCTLR.C bit to prevent further data cache
49 * allocation. Clearing SCTLR.C would make all the data accesses 54 * allocation. Clearing SCTLR.C would make all the data accesses
@@ -80,13 +85,9 @@ sh7372_do_idle_a3sm:
80 dsb 85 dsb
81 dmb 86 dmb
82 87
83#define SPDCR 0xe6180008 88 /* SYSC power down */
84#define A3SM (1 << 12)
85
86 /* A3SM power down */
87 ldr r0, =SPDCR 89 ldr r0, =SPDCR
88 ldr r1, =A3SM 90 str r8, [r0]
89 str r1, [r0]
901: 911:
91 b 1b 92 b 1b
92 93