aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s5p64x0
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-s5p64x0')
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig7
-rw-r--r--arch/arm/mach-s5p64x0/Makefile11
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c96
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c84
-rw-r--r--arch/arm/mach-s5p64x0/clock.c4
-rw-r--r--arch/arm/mach-s5p64x0/common.c437
-rw-r--r--arch/arm/mach-s5p64x0/common.h57
-rw-r--r--arch/arm/mach-s5p64x0/cpu.c215
-rw-r--r--arch/arm/mach-s5p64x0/dev-spi.c224
-rw-r--r--arch/arm/mach-s5p64x0/dma.c227
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/system.h2
-rw-r--r--arch/arm/mach-s5p64x0/init.c73
-rw-r--r--arch/arm/mach-s5p64x0/irq-eint.c155
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c6
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c6
-rw-r--r--arch/arm/mach-s5p64x0/setup-spi.c55
18 files changed, 748 insertions, 915 deletions
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 18690c5f99e6..dd8c85ef6dab 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -36,6 +36,11 @@ config S5P64X0_SETUP_I2C1
36 help 36 help
37 Common setup code for i2c bus 1. 37 Common setup code for i2c bus 1.
38 38
39config S5P64X0_SETUP_SPI
40 bool
41 help
42 Common setup code for SPI GPIO configurations
43
39# machine support 44# machine support
40 45
41config MACH_SMDK6440 46config MACH_SMDK6440
@@ -45,7 +50,6 @@ config MACH_SMDK6440
45 select S3C_DEV_I2C1 50 select S3C_DEV_I2C1
46 select S3C_DEV_RTC 51 select S3C_DEV_RTC
47 select S3C_DEV_WDT 52 select S3C_DEV_WDT
48 select S3C64XX_DEV_SPI
49 select SAMSUNG_DEV_ADC 53 select SAMSUNG_DEV_ADC
50 select SAMSUNG_DEV_BACKLIGHT 54 select SAMSUNG_DEV_BACKLIGHT
51 select SAMSUNG_DEV_PWM 55 select SAMSUNG_DEV_PWM
@@ -62,7 +66,6 @@ config MACH_SMDK6450
62 select S3C_DEV_I2C1 66 select S3C_DEV_I2C1
63 select S3C_DEV_RTC 67 select S3C_DEV_RTC
64 select S3C_DEV_WDT 68 select S3C_DEV_WDT
65 select S3C64XX_DEV_SPI
66 select SAMSUNG_DEV_ADC 69 select SAMSUNG_DEV_ADC
67 select SAMSUNG_DEV_BACKLIGHT 70 select SAMSUNG_DEV_BACKLIGHT
68 select SAMSUNG_DEV_PWM 71 select SAMSUNG_DEV_PWM
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index a1324d8dc4e0..e167ca136f5d 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -10,14 +10,16 @@ obj-m :=
10obj-n := 10obj-n :=
11obj- := 11obj- :=
12 12
13# Core support for S5P64X0 system 13# Core
14 14
15obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o 15obj-y += common.o clock.o
16obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o irq-eint.o
17obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o 16obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
18obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o 17obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
18
19obj-$(CONFIG_PM) += pm.o irq-pm.o 19obj-$(CONFIG_PM) += pm.o irq-pm.o
20 20
21obj-y += dma.o
22
21# machine support 23# machine support
22 24
23obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o 25obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
@@ -26,7 +28,8 @@ obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o
26# device support 28# device support
27 29
28obj-y += dev-audio.o 30obj-y += dev-audio.o
29obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
30 31
32obj-y += setup-i2c0.o
31obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o 33obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
32obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o 34obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o
35obj-$(CONFIG_S5P64X0_SETUP_SPI) += setup-spi.o
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index c54c65d511f0..58811ba89eef 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -31,7 +31,8 @@
31#include <plat/pll.h> 31#include <plat/pll.h>
32#include <plat/s5p-clock.h> 32#include <plat/s5p-clock.h>
33#include <plat/clock-clksrc.h> 33#include <plat/clock-clksrc.h>
34#include <plat/s5p6440.h> 34
35#include "common.h"
35 36
36static u32 epll_div[][5] = { 37static u32 epll_div[][5] = {
37 { 36000000, 0, 48, 1, 4 }, 38 { 36000000, 0, 48, 1, 4 },
@@ -268,18 +269,6 @@ static struct clk init_clocks_off[] = {
268 .enable = s5p64x0_pclk_ctrl, 269 .enable = s5p64x0_pclk_ctrl,
269 .ctrlbit = (1 << 31), 270 .ctrlbit = (1 << 31),
270 }, { 271 }, {
271 .name = "sclk_spi_48",
272 .devname = "s3c64xx-spi.0",
273 .parent = &clk_48m,
274 .enable = s5p64x0_sclk_ctrl,
275 .ctrlbit = (1 << 22),
276 }, {
277 .name = "sclk_spi_48",
278 .devname = "s3c64xx-spi.1",
279 .parent = &clk_48m,
280 .enable = s5p64x0_sclk_ctrl,
281 .ctrlbit = (1 << 23),
282 }, {
283 .name = "mmc_48m", 272 .name = "mmc_48m",
284 .devname = "s3c-sdhci.0", 273 .devname = "s3c-sdhci.0",
285 .parent = &clk_48m, 274 .parent = &clk_48m,
@@ -421,35 +410,6 @@ static struct clksrc_clk clksrcs[] = {
421 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, 410 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
422 }, { 411 }, {
423 .clk = { 412 .clk = {
424 .name = "uclk1",
425 .ctrlbit = (1 << 5),
426 .enable = s5p64x0_sclk_ctrl,
427 },
428 .sources = &clkset_uart,
429 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
430 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
431 }, {
432 .clk = {
433 .name = "sclk_spi",
434 .devname = "s3c64xx-spi.0",
435 .ctrlbit = (1 << 20),
436 .enable = s5p64x0_sclk_ctrl,
437 },
438 .sources = &clkset_group1,
439 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
440 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
441 }, {
442 .clk = {
443 .name = "sclk_spi",
444 .devname = "s3c64xx-spi.1",
445 .ctrlbit = (1 << 21),
446 .enable = s5p64x0_sclk_ctrl,
447 },
448 .sources = &clkset_group1,
449 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
450 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
451 }, {
452 .clk = {
453 .name = "sclk_post", 413 .name = "sclk_post",
454 .ctrlbit = (1 << 10), 414 .ctrlbit = (1 << 10),
455 .enable = s5p64x0_sclk_ctrl, 415 .enable = s5p64x0_sclk_ctrl,
@@ -487,6 +447,41 @@ static struct clksrc_clk clksrcs[] = {
487 }, 447 },
488}; 448};
489 449
450static struct clksrc_clk clk_sclk_uclk = {
451 .clk = {
452 .name = "uclk1",
453 .ctrlbit = (1 << 5),
454 .enable = s5p64x0_sclk_ctrl,
455 },
456 .sources = &clkset_uart,
457 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
458 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
459};
460
461static struct clksrc_clk clk_sclk_spi0 = {
462 .clk = {
463 .name = "sclk_spi",
464 .devname = "s3c64xx-spi.0",
465 .ctrlbit = (1 << 20),
466 .enable = s5p64x0_sclk_ctrl,
467 },
468 .sources = &clkset_group1,
469 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
470 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
471};
472
473static struct clksrc_clk clk_sclk_spi1 = {
474 .clk = {
475 .name = "sclk_spi",
476 .devname = "s3c64xx-spi.1",
477 .ctrlbit = (1 << 21),
478 .enable = s5p64x0_sclk_ctrl,
479 },
480 .sources = &clkset_group1,
481 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
482 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
483};
484
490/* Clock initialization code */ 485/* Clock initialization code */
491static struct clksrc_clk *sysclks[] = { 486static struct clksrc_clk *sysclks[] = {
492 &clk_mout_apll, 487 &clk_mout_apll,
@@ -505,6 +500,20 @@ static struct clk dummy_apb_pclk = {
505 .id = -1, 500 .id = -1,
506}; 501};
507 502
503static struct clksrc_clk *clksrc_cdev[] = {
504 &clk_sclk_uclk,
505 &clk_sclk_spi0,
506 &clk_sclk_spi1,
507};
508
509static struct clk_lookup s5p6440_clk_lookup[] = {
510 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
511 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
512 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
513 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
514 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
515};
516
508void __init_or_cpufreq s5p6440_setup_clocks(void) 517void __init_or_cpufreq s5p6440_setup_clocks(void)
509{ 518{
510 struct clk *xtal_clk; 519 struct clk *xtal_clk;
@@ -583,9 +592,12 @@ void __init s5p6440_register_clocks(void)
583 592
584 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 593 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
585 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 594 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
595 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
596 s3c_register_clksrc(clksrc_cdev[ptr], 1);
586 597
587 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 598 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
588 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 599 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
600 clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
589 601
590 s3c24xx_register_clock(&dummy_apb_pclk); 602 s3c24xx_register_clock(&dummy_apb_pclk);
591 603
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 2d04abfba12e..bd9d1e6fc5e2 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -31,7 +31,8 @@
31#include <plat/pll.h> 31#include <plat/pll.h>
32#include <plat/s5p-clock.h> 32#include <plat/s5p-clock.h>
33#include <plat/clock-clksrc.h> 33#include <plat/clock-clksrc.h>
34#include <plat/s5p6450.h> 34
35#include "common.h"
35 36
36static struct clksrc_clk clk_mout_dpll = { 37static struct clksrc_clk clk_mout_dpll = {
37 .clk = { 38 .clk = {
@@ -443,35 +444,6 @@ static struct clksrc_clk clksrcs[] = {
443 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, 444 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
444 }, { 445 }, {
445 .clk = { 446 .clk = {
446 .name = "uclk1",
447 .ctrlbit = (1 << 5),
448 .enable = s5p64x0_sclk_ctrl,
449 },
450 .sources = &clkset_uart,
451 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
452 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
453 }, {
454 .clk = {
455 .name = "sclk_spi",
456 .devname = "s3c64xx-spi.0",
457 .ctrlbit = (1 << 20),
458 .enable = s5p64x0_sclk_ctrl,
459 },
460 .sources = &clkset_group2,
461 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
462 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
463 }, {
464 .clk = {
465 .name = "sclk_spi",
466 .devname = "s3c64xx-spi.1",
467 .ctrlbit = (1 << 21),
468 .enable = s5p64x0_sclk_ctrl,
469 },
470 .sources = &clkset_group2,
471 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
472 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
473 }, {
474 .clk = {
475 .name = "sclk_fimc", 447 .name = "sclk_fimc",
476 .ctrlbit = (1 << 10), 448 .ctrlbit = (1 << 10),
477 .enable = s5p64x0_sclk_ctrl, 449 .enable = s5p64x0_sclk_ctrl,
@@ -536,6 +508,55 @@ static struct clksrc_clk clksrcs[] = {
536 }, 508 },
537}; 509};
538 510
511static struct clksrc_clk clk_sclk_uclk = {
512 .clk = {
513 .name = "uclk1",
514 .ctrlbit = (1 << 5),
515 .enable = s5p64x0_sclk_ctrl,
516 },
517 .sources = &clkset_uart,
518 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
519 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
520};
521
522static struct clksrc_clk clk_sclk_spi0 = {
523 .clk = {
524 .name = "sclk_spi",
525 .devname = "s3c64xx-spi.0",
526 .ctrlbit = (1 << 20),
527 .enable = s5p64x0_sclk_ctrl,
528 },
529 .sources = &clkset_group2,
530 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
531 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
532};
533
534static struct clksrc_clk clk_sclk_spi1 = {
535 .clk = {
536 .name = "sclk_spi",
537 .devname = "s3c64xx-spi.1",
538 .ctrlbit = (1 << 21),
539 .enable = s5p64x0_sclk_ctrl,
540 },
541 .sources = &clkset_group2,
542 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
543 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
544};
545
546static struct clksrc_clk *clksrc_cdev[] = {
547 &clk_sclk_uclk,
548 &clk_sclk_spi0,
549 &clk_sclk_spi1,
550};
551
552static struct clk_lookup s5p6450_clk_lookup[] = {
553 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
554 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
555 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
556 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
557 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
558};
559
539/* Clock initialization code */ 560/* Clock initialization code */
540static struct clksrc_clk *sysclks[] = { 561static struct clksrc_clk *sysclks[] = {
541 &clk_mout_apll, 562 &clk_mout_apll,
@@ -634,9 +655,12 @@ void __init s5p6450_register_clocks(void)
634 655
635 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 656 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
636 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 657 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
658 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
659 s3c_register_clksrc(clksrc_cdev[ptr], 1);
637 660
638 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 661 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
639 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 662 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
663 clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
640 664
641 s3c24xx_register_clock(&dummy_apb_pclk); 665 s3c24xx_register_clock(&dummy_apb_pclk);
642 666
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
index b52c6e2f37a6..b289b726a7d6 100644
--- a/arch/arm/mach-s5p64x0/clock.c
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -30,8 +30,8 @@
30#include <plat/pll.h> 30#include <plat/pll.h>
31#include <plat/s5p-clock.h> 31#include <plat/s5p-clock.h>
32#include <plat/clock-clksrc.h> 32#include <plat/clock-clksrc.h>
33#include <plat/s5p6440.h> 33
34#include <plat/s5p6450.h> 34#include "common.h"
35 35
36struct clksrc_clk clk_mout_apll = { 36struct clksrc_clk clk_mout_apll = {
37 .clk = { 37 .clk = {
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
new file mode 100644
index 000000000000..fcf0778ae5c4
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -0,0 +1,437 @@
1/*
2 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Common Codes for S5P64X0 machines
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 version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/interrupt.h>
15#include <linux/list.h>
16#include <linux/timer.h>
17#include <linux/init.h>
18#include <linux/clk.h>
19#include <linux/io.h>
20#include <linux/sysdev.h>
21#include <linux/serial_core.h>
22#include <linux/platform_device.h>
23#include <linux/sched.h>
24#include <linux/dma-mapping.h>
25#include <linux/gpio.h>
26#include <linux/irq.h>
27
28#include <asm/irq.h>
29#include <asm/proc-fns.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/map.h>
32#include <asm/mach/irq.h>
33
34#include <mach/map.h>
35#include <mach/hardware.h>
36#include <mach/regs-clock.h>
37#include <mach/regs-gpio.h>
38
39#include <plat/cpu.h>
40#include <plat/clock.h>
41#include <plat/devs.h>
42#include <plat/pm.h>
43#include <plat/adc-core.h>
44#include <plat/fb-core.h>
45#include <plat/gpio-cfg.h>
46#include <plat/regs-irqtype.h>
47#include <plat/regs-serial.h>
48#include <plat/watchdog-reset.h>
49
50#include "common.h"
51
52static const char name_s5p6440[] = "S5P6440";
53static const char name_s5p6450[] = "S5P6450";
54
55static struct cpu_table cpu_ids[] __initdata = {
56 {
57 .idcode = S5P6440_CPU_ID,
58 .idmask = S5P64XX_CPU_MASK,
59 .map_io = s5p6440_map_io,
60 .init_clocks = s5p6440_init_clocks,
61 .init_uarts = s5p6440_init_uarts,
62 .init = s5p64x0_init,
63 .name = name_s5p6440,
64 }, {
65 .idcode = S5P6450_CPU_ID,
66 .idmask = S5P64XX_CPU_MASK,
67 .map_io = s5p6450_map_io,
68 .init_clocks = s5p6450_init_clocks,
69 .init_uarts = s5p6450_init_uarts,
70 .init = s5p64x0_init,
71 .name = name_s5p6450,
72 },
73};
74
75/* Initial IO mappings */
76
77static struct map_desc s5p64x0_iodesc[] __initdata = {
78 {
79 .virtual = (unsigned long)S5P_VA_CHIPID,
80 .pfn = __phys_to_pfn(S5P64X0_PA_CHIPID),
81 .length = SZ_4K,
82 .type = MT_DEVICE,
83 }, {
84 .virtual = (unsigned long)S3C_VA_SYS,
85 .pfn = __phys_to_pfn(S5P64X0_PA_SYSCON),
86 .length = SZ_64K,
87 .type = MT_DEVICE,
88 }, {
89 .virtual = (unsigned long)S3C_VA_TIMER,
90 .pfn = __phys_to_pfn(S5P64X0_PA_TIMER),
91 .length = SZ_16K,
92 .type = MT_DEVICE,
93 }, {
94 .virtual = (unsigned long)S3C_VA_WATCHDOG,
95 .pfn = __phys_to_pfn(S5P64X0_PA_WDT),
96 .length = SZ_4K,
97 .type = MT_DEVICE,
98 }, {
99 .virtual = (unsigned long)S5P_VA_SROMC,
100 .pfn = __phys_to_pfn(S5P64X0_PA_SROMC),
101 .length = SZ_4K,
102 .type = MT_DEVICE,
103 }, {
104 .virtual = (unsigned long)S5P_VA_GPIO,
105 .pfn = __phys_to_pfn(S5P64X0_PA_GPIO),
106 .length = SZ_4K,
107 .type = MT_DEVICE,
108 }, {
109 .virtual = (unsigned long)VA_VIC0,
110 .pfn = __phys_to_pfn(S5P64X0_PA_VIC0),
111 .length = SZ_16K,
112 .type = MT_DEVICE,
113 }, {
114 .virtual = (unsigned long)VA_VIC1,
115 .pfn = __phys_to_pfn(S5P64X0_PA_VIC1),
116 .length = SZ_16K,
117 .type = MT_DEVICE,
118 },
119};
120
121static struct map_desc s5p6440_iodesc[] __initdata = {
122 {
123 .virtual = (unsigned long)S3C_VA_UART,
124 .pfn = __phys_to_pfn(S5P6440_PA_UART(0)),
125 .length = SZ_4K,
126 .type = MT_DEVICE,
127 },
128};
129
130static struct map_desc s5p6450_iodesc[] __initdata = {
131 {
132 .virtual = (unsigned long)S3C_VA_UART,
133 .pfn = __phys_to_pfn(S5P6450_PA_UART(0)),
134 .length = SZ_512K,
135 .type = MT_DEVICE,
136 }, {
137 .virtual = (unsigned long)S3C_VA_UART + SZ_512K,
138 .pfn = __phys_to_pfn(S5P6450_PA_UART(5)),
139 .length = SZ_4K,
140 .type = MT_DEVICE,
141 },
142};
143
144static void s5p64x0_idle(void)
145{
146 unsigned long val;
147
148 if (!need_resched()) {
149 val = __raw_readl(S5P64X0_PWR_CFG);
150 val &= ~(0x3 << 5);
151 val |= (0x1 << 5);
152 __raw_writel(val, S5P64X0_PWR_CFG);
153
154 cpu_do_idle();
155 }
156 local_irq_enable();
157}
158
159/*
160 * s5p64x0_map_io
161 *
162 * register the standard CPU IO areas
163 */
164
165void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
166{
167 /* initialize the io descriptors we need for initialization */
168 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
169 if (mach_desc)
170 iotable_init(mach_desc, size);
171
172 /* detect cpu id and rev. */
173 s5p_init_cpu(S5P64X0_SYS_ID);
174
175 s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
176}
177
178void __init s5p6440_map_io(void)
179{
180 /* initialize any device information early */
181 s3c_adc_setname("s3c64xx-adc");
182 s3c_fb_setname("s5p64x0-fb");
183
184 iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
185 init_consistent_dma_size(SZ_8M);
186}
187
188void __init s5p6450_map_io(void)
189{
190 /* initialize any device information early */
191 s3c_adc_setname("s3c64xx-adc");
192 s3c_fb_setname("s5p64x0-fb");
193
194 iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
195 init_consistent_dma_size(SZ_8M);
196}
197
198/*
199 * s5p64x0_init_clocks
200 *
201 * register and setup the CPU clocks
202 */
203
204void __init s5p6440_init_clocks(int xtal)
205{
206 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
207
208 s3c24xx_register_baseclocks(xtal);
209 s5p_register_clocks(xtal);
210 s5p6440_register_clocks();
211 s5p6440_setup_clocks();
212}
213
214void __init s5p6450_init_clocks(int xtal)
215{
216 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
217
218 s3c24xx_register_baseclocks(xtal);
219 s5p_register_clocks(xtal);
220 s5p6450_register_clocks();
221 s5p6450_setup_clocks();
222}
223
224/*
225 * s5p64x0_init_irq
226 *
227 * register the CPU interrupts
228 */
229
230void __init s5p6440_init_irq(void)
231{
232 /* S5P6440 supports 2 VIC */
233 u32 vic[2];
234
235 /*
236 * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
237 * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
238 */
239 vic[0] = 0xff800ae7;
240 vic[1] = 0xffbf23e5;
241
242 s5p_init_irq(vic, ARRAY_SIZE(vic));
243}
244
245void __init s5p6450_init_irq(void)
246{
247 /* S5P6450 supports only 2 VIC */
248 u32 vic[2];
249
250 /*
251 * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
252 * VIC1 is missing IRQ VIC1[12, 14, 23]
253 */
254 vic[0] = 0xff9f1fff;
255 vic[1] = 0xff7fafff;
256
257 s5p_init_irq(vic, ARRAY_SIZE(vic));
258}
259
260struct sysdev_class s5p64x0_sysclass = {
261 .name = "s5p64x0-core",
262};
263
264static struct sys_device s5p64x0_sysdev = {
265 .cls = &s5p64x0_sysclass,
266};
267
268static int __init s5p64x0_core_init(void)
269{
270 return sysdev_class_register(&s5p64x0_sysclass);
271}
272core_initcall(s5p64x0_core_init);
273
274int __init s5p64x0_init(void)
275{
276 printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
277
278 /* set idle function */
279 pm_idle = s5p64x0_idle;
280
281 return sysdev_register(&s5p64x0_sysdev);
282}
283
284/* uart registration process */
285void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
286{
287 int uart;
288
289 for (uart = 0; uart < no; uart++) {
290 s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
291 s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
292 }
293
294 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
295}
296
297void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
298{
299 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
300}
301
302#define eint_offset(irq) ((irq) - IRQ_EINT(0))
303
304static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type)
305{
306 int offs = eint_offset(data->irq);
307 int shift;
308 u32 ctrl, mask;
309 u32 newvalue = 0;
310
311 if (offs > 15)
312 return -EINVAL;
313
314 switch (type) {
315 case IRQ_TYPE_NONE:
316 printk(KERN_WARNING "No edge setting!\n");
317 break;
318 case IRQ_TYPE_EDGE_RISING:
319 newvalue = S3C2410_EXTINT_RISEEDGE;
320 break;
321 case IRQ_TYPE_EDGE_FALLING:
322 newvalue = S3C2410_EXTINT_FALLEDGE;
323 break;
324 case IRQ_TYPE_EDGE_BOTH:
325 newvalue = S3C2410_EXTINT_BOTHEDGE;
326 break;
327 case IRQ_TYPE_LEVEL_LOW:
328 newvalue = S3C2410_EXTINT_LOWLEV;
329 break;
330 case IRQ_TYPE_LEVEL_HIGH:
331 newvalue = S3C2410_EXTINT_HILEV;
332 break;
333 default:
334 printk(KERN_ERR "No such irq type %d", type);
335 return -EINVAL;
336 }
337
338 shift = (offs / 2) * 4;
339 mask = 0x7 << shift;
340
341 ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask;
342 ctrl |= newvalue << shift;
343 __raw_writel(ctrl, S5P64X0_EINT0CON0);
344
345 /* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
346 if (soc_is_s5p6450())
347 s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
348 else
349 s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));
350
351 return 0;
352}
353
354/*
355 * s5p64x0_irq_demux_eint
356 *
357 * This function demuxes the IRQ from the group0 external interrupts,
358 * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into
359 * the specific handlers s5p64x0_irq_demux_eintX_Y.
360 */
361static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end)
362{
363 u32 status = __raw_readl(S5P64X0_EINT0PEND);
364 u32 mask = __raw_readl(S5P64X0_EINT0MASK);
365 unsigned int irq;
366
367 status &= ~mask;
368 status >>= start;
369 status &= (1 << (end - start + 1)) - 1;
370
371 for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
372 if (status & 1)
373 generic_handle_irq(irq);
374 status >>= 1;
375 }
376}
377
378static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
379{
380 s5p64x0_irq_demux_eint(0, 3);
381}
382
383static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
384{
385 s5p64x0_irq_demux_eint(4, 11);
386}
387
388static void s5p64x0_irq_demux_eint12_15(unsigned int irq,
389 struct irq_desc *desc)
390{
391 s5p64x0_irq_demux_eint(12, 15);
392}
393
394static int s5p64x0_alloc_gc(void)
395{
396 struct irq_chip_generic *gc;
397 struct irq_chip_type *ct;
398
399 gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE,
400 S5P_VA_GPIO, handle_level_irq);
401 if (!gc) {
402 printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0"
403 "external interrupts failed\n", __func__);
404 return -EINVAL;
405 }
406
407 ct = gc->chip_types;
408 ct->chip.irq_ack = irq_gc_ack_set_bit;
409 ct->chip.irq_mask = irq_gc_mask_set_bit;
410 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
411 ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
412 ct->chip.irq_set_wake = s3c_irqext_wake;
413 ct->regs.ack = EINT0PEND_OFFSET;
414 ct->regs.mask = EINT0MASK_OFFSET;
415 irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
416 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
417 return 0;
418}
419
420static int __init s5p64x0_init_irq_eint(void)
421{
422 int ret = s5p64x0_alloc_gc();
423 irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3);
424 irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11);
425 irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15);
426
427 return ret;
428}
429arch_initcall(s5p64x0_init_irq_eint);
430
431void s5p64x0_restart(char mode, const char *cmd)
432{
433 if (mode != 's')
434 arch_wdt_reset();
435
436 soft_restart(0);
437}
diff --git a/arch/arm/mach-s5p64x0/common.h b/arch/arm/mach-s5p64x0/common.h
new file mode 100644
index 000000000000..f8a60fdc5884
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/common.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Common Header for S5P64X0 machines
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 version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __ARCH_ARM_MACH_S5P64X0_COMMON_H
13#define __ARCH_ARM_MACH_S5P64X0_COMMON_H
14
15void s5p6440_init_irq(void);
16void s5p6450_init_irq(void);
17void s5p64x0_init_io(struct map_desc *mach_desc, int size);
18
19void s5p6440_register_clocks(void);
20void s5p6440_setup_clocks(void);
21
22void s5p6450_register_clocks(void);
23void s5p6450_setup_clocks(void);
24
25void s5p64x0_restart(char mode, const char *cmd);
26
27#ifdef CONFIG_CPU_S5P6440
28
29extern int s5p64x0_init(void);
30extern void s5p6440_map_io(void);
31extern void s5p6440_init_clocks(int xtal);
32
33extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
34
35#else
36#define s5p6440_init_clocks NULL
37#define s5p6440_init_uarts NULL
38#define s5p6440_map_io NULL
39#define s5p64x0_init NULL
40#endif
41
42#ifdef CONFIG_CPU_S5P6450
43
44extern int s5p64x0_init(void);
45extern void s5p6450_map_io(void);
46extern void s5p6450_init_clocks(int xtal);
47
48extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
49
50#else
51#define s5p6450_init_clocks NULL
52#define s5p6450_init_uarts NULL
53#define s5p6450_map_io NULL
54#define s5p64x0_init NULL
55#endif
56
57#endif /* __ARCH_ARM_MACH_S5P64X0_COMMON_H */
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
deleted file mode 100644
index ecab40cf19ab..000000000000
--- a/arch/arm/mach-s5p64x0/cpu.c
+++ /dev/null
@@ -1,215 +0,0 @@
1/* linux/arch/arm/mach-s5p64x0/cpu.c
2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
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 version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/interrupt.h>
14#include <linux/list.h>
15#include <linux/timer.h>
16#include <linux/init.h>
17#include <linux/clk.h>
18#include <linux/io.h>
19#include <linux/sysdev.h>
20#include <linux/serial_core.h>
21#include <linux/platform_device.h>
22#include <linux/sched.h>
23#include <linux/dma-mapping.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/irq.h>
28#include <asm/proc-fns.h>
29#include <asm/irq.h>
30
31#include <mach/hardware.h>
32#include <mach/map.h>
33#include <mach/regs-clock.h>
34
35#include <plat/regs-serial.h>
36#include <plat/cpu.h>
37#include <plat/devs.h>
38#include <plat/clock.h>
39#include <plat/s5p6440.h>
40#include <plat/s5p6450.h>
41#include <plat/adc-core.h>
42#include <plat/fb-core.h>
43
44/* Initial IO mappings */
45
46static struct map_desc s5p64x0_iodesc[] __initdata = {
47 {
48 .virtual = (unsigned long)S5P_VA_GPIO,
49 .pfn = __phys_to_pfn(S5P64X0_PA_GPIO),
50 .length = SZ_4K,
51 .type = MT_DEVICE,
52 }, {
53 .virtual = (unsigned long)VA_VIC0,
54 .pfn = __phys_to_pfn(S5P64X0_PA_VIC0),
55 .length = SZ_16K,
56 .type = MT_DEVICE,
57 }, {
58 .virtual = (unsigned long)VA_VIC1,
59 .pfn = __phys_to_pfn(S5P64X0_PA_VIC1),
60 .length = SZ_16K,
61 .type = MT_DEVICE,
62 },
63};
64
65static struct map_desc s5p6440_iodesc[] __initdata = {
66 {
67 .virtual = (unsigned long)S3C_VA_UART,
68 .pfn = __phys_to_pfn(S5P6440_PA_UART(0)),
69 .length = SZ_4K,
70 .type = MT_DEVICE,
71 },
72};
73
74static struct map_desc s5p6450_iodesc[] __initdata = {
75 {
76 .virtual = (unsigned long)S3C_VA_UART,
77 .pfn = __phys_to_pfn(S5P6450_PA_UART(0)),
78 .length = SZ_512K,
79 .type = MT_DEVICE,
80 }, {
81 .virtual = (unsigned long)S3C_VA_UART + SZ_512K,
82 .pfn = __phys_to_pfn(S5P6450_PA_UART(5)),
83 .length = SZ_4K,
84 .type = MT_DEVICE,
85 },
86};
87
88static void s5p64x0_idle(void)
89{
90 unsigned long val;
91
92 if (!need_resched()) {
93 val = __raw_readl(S5P64X0_PWR_CFG);
94 val &= ~(0x3 << 5);
95 val |= (0x1 << 5);
96 __raw_writel(val, S5P64X0_PWR_CFG);
97
98 cpu_do_idle();
99 }
100 local_irq_enable();
101}
102
103/*
104 * s5p64x0_map_io
105 *
106 * register the standard CPU IO areas
107 */
108
109void __init s5p6440_map_io(void)
110{
111 /* initialize any device information early */
112 s3c_adc_setname("s3c64xx-adc");
113 s3c_fb_setname("s5p64x0-fb");
114
115 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
116 iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
117 init_consistent_dma_size(SZ_8M);
118}
119
120void __init s5p6450_map_io(void)
121{
122 /* initialize any device information early */
123 s3c_adc_setname("s3c64xx-adc");
124 s3c_fb_setname("s5p64x0-fb");
125
126 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
127 iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
128 init_consistent_dma_size(SZ_8M);
129}
130
131/*
132 * s5p64x0_init_clocks
133 *
134 * register and setup the CPU clocks
135 */
136
137void __init s5p6440_init_clocks(int xtal)
138{
139 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
140
141 s3c24xx_register_baseclocks(xtal);
142 s5p_register_clocks(xtal);
143 s5p6440_register_clocks();
144 s5p6440_setup_clocks();
145}
146
147void __init s5p6450_init_clocks(int xtal)
148{
149 printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
150
151 s3c24xx_register_baseclocks(xtal);
152 s5p_register_clocks(xtal);
153 s5p6450_register_clocks();
154 s5p6450_setup_clocks();
155}
156
157/*
158 * s5p64x0_init_irq
159 *
160 * register the CPU interrupts
161 */
162
163void __init s5p6440_init_irq(void)
164{
165 /* S5P6440 supports 2 VIC */
166 u32 vic[2];
167
168 /*
169 * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
170 * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
171 */
172 vic[0] = 0xff800ae7;
173 vic[1] = 0xffbf23e5;
174
175 s5p_init_irq(vic, ARRAY_SIZE(vic));
176}
177
178void __init s5p6450_init_irq(void)
179{
180 /* S5P6450 supports only 2 VIC */
181 u32 vic[2];
182
183 /*
184 * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
185 * VIC1 is missing IRQ VIC1[12, 14, 23]
186 */
187 vic[0] = 0xff9f1fff;
188 vic[1] = 0xff7fafff;
189
190 s5p_init_irq(vic, ARRAY_SIZE(vic));
191}
192
193struct sysdev_class s5p64x0_sysclass = {
194 .name = "s5p64x0-core",
195};
196
197static struct sys_device s5p64x0_sysdev = {
198 .cls = &s5p64x0_sysclass,
199};
200
201static int __init s5p64x0_core_init(void)
202{
203 return sysdev_class_register(&s5p64x0_sysclass);
204}
205core_initcall(s5p64x0_core_init);
206
207int __init s5p64x0_init(void)
208{
209 printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
210
211 /* set idle function */
212 pm_idle = s5p64x0_idle;
213
214 return sysdev_register(&s5p64x0_sysdev);
215}
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
deleted file mode 100644
index 1fd9c79c7dbc..000000000000
--- a/arch/arm/mach-s5p64x0/dev-spi.c
+++ /dev/null
@@ -1,224 +0,0 @@
1/* linux/arch/arm/mach-s5p64x0/dev-spi.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
7 * Jaswinder Singh <jassi.brar@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/platform_device.h>
15#include <linux/dma-mapping.h>
16#include <linux/gpio.h>
17
18#include <mach/dma.h>
19#include <mach/map.h>
20#include <mach/irqs.h>
21#include <mach/regs-clock.h>
22#include <mach/spi-clocks.h>
23
24#include <plat/cpu.h>
25#include <plat/s3c64xx-spi.h>
26#include <plat/gpio-cfg.h>
27
28static char *s5p64x0_spi_src_clks[] = {
29 [S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
30 [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
31};
32
33/* SPI Controller platform_devices */
34
35/* Since we emulate multi-cs capability, we do not touch the CS.
36 * The emulated CS is toggled by board specific mechanism, as it can
37 * be either some immediate GPIO or some signal out of some other
38 * chip in between ... or some yet another way.
39 * We simply do not assume anything about CS.
40 */
41static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
42{
43 unsigned int base;
44
45 switch (pdev->id) {
46 case 0:
47 base = S5P6440_GPC(0);
48 break;
49
50 case 1:
51 base = S5P6440_GPC(4);
52 break;
53
54 default:
55 dev_err(&pdev->dev, "Invalid SPI Controller number!");
56 return -EINVAL;
57 }
58
59 s3c_gpio_cfgall_range(base, 3,
60 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
61
62 return 0;
63}
64
65static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
66{
67 unsigned int base;
68
69 switch (pdev->id) {
70 case 0:
71 base = S5P6450_GPC(0);
72 break;
73
74 case 1:
75 base = S5P6450_GPC(4);
76 break;
77
78 default:
79 dev_err(&pdev->dev, "Invalid SPI Controller number!");
80 return -EINVAL;
81 }
82
83 s3c_gpio_cfgall_range(base, 3,
84 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
85
86 return 0;
87}
88
89static struct resource s5p64x0_spi0_resource[] = {
90 [0] = {
91 .start = S5P64X0_PA_SPI0,
92 .end = S5P64X0_PA_SPI0 + 0x100 - 1,
93 .flags = IORESOURCE_MEM,
94 },
95 [1] = {
96 .start = DMACH_SPI0_TX,
97 .end = DMACH_SPI0_TX,
98 .flags = IORESOURCE_DMA,
99 },
100 [2] = {
101 .start = DMACH_SPI0_RX,
102 .end = DMACH_SPI0_RX,
103 .flags = IORESOURCE_DMA,
104 },
105 [3] = {
106 .start = IRQ_SPI0,
107 .end = IRQ_SPI0,
108 .flags = IORESOURCE_IRQ,
109 },
110};
111
112static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
113 .cfg_gpio = s5p6440_spi_cfg_gpio,
114 .fifo_lvl_mask = 0x1ff,
115 .rx_lvl_offset = 15,
116 .tx_st_done = 25,
117};
118
119static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
120 .cfg_gpio = s5p6450_spi_cfg_gpio,
121 .fifo_lvl_mask = 0x1ff,
122 .rx_lvl_offset = 15,
123 .tx_st_done = 25,
124};
125
126static u64 spi_dmamask = DMA_BIT_MASK(32);
127
128struct platform_device s5p64x0_device_spi0 = {
129 .name = "s3c64xx-spi",
130 .id = 0,
131 .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource),
132 .resource = s5p64x0_spi0_resource,
133 .dev = {
134 .dma_mask = &spi_dmamask,
135 .coherent_dma_mask = DMA_BIT_MASK(32),
136 },
137};
138
139static struct resource s5p64x0_spi1_resource[] = {
140 [0] = {
141 .start = S5P64X0_PA_SPI1,
142 .end = S5P64X0_PA_SPI1 + 0x100 - 1,
143 .flags = IORESOURCE_MEM,
144 },
145 [1] = {
146 .start = DMACH_SPI1_TX,
147 .end = DMACH_SPI1_TX,
148 .flags = IORESOURCE_DMA,
149 },
150 [2] = {
151 .start = DMACH_SPI1_RX,
152 .end = DMACH_SPI1_RX,
153 .flags = IORESOURCE_DMA,
154 },
155 [3] = {
156 .start = IRQ_SPI1,
157 .end = IRQ_SPI1,
158 .flags = IORESOURCE_IRQ,
159 },
160};
161
162static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
163 .cfg_gpio = s5p6440_spi_cfg_gpio,
164 .fifo_lvl_mask = 0x7f,
165 .rx_lvl_offset = 15,
166 .tx_st_done = 25,
167};
168
169static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
170 .cfg_gpio = s5p6450_spi_cfg_gpio,
171 .fifo_lvl_mask = 0x7f,
172 .rx_lvl_offset = 15,
173 .tx_st_done = 25,
174};
175
176struct platform_device s5p64x0_device_spi1 = {
177 .name = "s3c64xx-spi",
178 .id = 1,
179 .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource),
180 .resource = s5p64x0_spi1_resource,
181 .dev = {
182 .dma_mask = &spi_dmamask,
183 .coherent_dma_mask = DMA_BIT_MASK(32),
184 },
185};
186
187void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
188{
189 struct s3c64xx_spi_info *pd;
190
191 /* Reject invalid configuration */
192 if (!num_cs || src_clk_nr < 0
193 || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
194 printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
195 return;
196 }
197
198 switch (cntrlr) {
199 case 0:
200 if (soc_is_s5p6450())
201 pd = &s5p6450_spi0_pdata;
202 else
203 pd = &s5p6440_spi0_pdata;
204
205 s5p64x0_device_spi0.dev.platform_data = pd;
206 break;
207 case 1:
208 if (soc_is_s5p6450())
209 pd = &s5p6450_spi1_pdata;
210 else
211 pd = &s5p6440_spi1_pdata;
212
213 s5p64x0_device_spi1.dev.platform_data = pd;
214 break;
215 default:
216 printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
217 __func__, cntrlr);
218 return;
219 }
220
221 pd->num_cs = num_cs;
222 pd->src_clk_nr = src_clk_nr;
223 pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
224}
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index 442dd4ad12da..f820c0744405 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -38,176 +38,74 @@
38 38
39static u64 dma_dmamask = DMA_BIT_MASK(32); 39static u64 dma_dmamask = DMA_BIT_MASK(32);
40 40
41struct dma_pl330_peri s5p6440_pdma_peri[22] = { 41u8 s5p6440_pdma_peri[] = {
42 { 42 DMACH_UART0_RX,
43 .peri_id = (u8)DMACH_UART0_RX, 43 DMACH_UART0_TX,
44 .rqtype = DEVTOMEM, 44 DMACH_UART1_RX,
45 }, { 45 DMACH_UART1_TX,
46 .peri_id = (u8)DMACH_UART0_TX, 46 DMACH_UART2_RX,
47 .rqtype = MEMTODEV, 47 DMACH_UART2_TX,
48 }, { 48 DMACH_UART3_RX,
49 .peri_id = (u8)DMACH_UART1_RX, 49 DMACH_UART3_TX,
50 .rqtype = DEVTOMEM, 50 DMACH_MAX,
51 }, { 51 DMACH_MAX,
52 .peri_id = (u8)DMACH_UART1_TX, 52 DMACH_PCM0_TX,
53 .rqtype = MEMTODEV, 53 DMACH_PCM0_RX,
54 }, { 54 DMACH_I2S0_TX,
55 .peri_id = (u8)DMACH_UART2_RX, 55 DMACH_I2S0_RX,
56 .rqtype = DEVTOMEM, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI0_RX,
58 .peri_id = (u8)DMACH_UART2_TX, 58 DMACH_MAX,
59 .rqtype = MEMTODEV, 59 DMACH_MAX,
60 }, { 60 DMACH_MAX,
61 .peri_id = (u8)DMACH_UART3_RX, 61 DMACH_MAX,
62 .rqtype = DEVTOMEM, 62 DMACH_SPI1_TX,
63 }, { 63 DMACH_SPI1_RX,
64 .peri_id = (u8)DMACH_UART3_TX,
65 .rqtype = MEMTODEV,
66 }, {
67 .peri_id = DMACH_MAX,
68 }, {
69 .peri_id = DMACH_MAX,
70 }, {
71 .peri_id = (u8)DMACH_PCM0_TX,
72 .rqtype = MEMTODEV,
73 }, {
74 .peri_id = (u8)DMACH_PCM0_RX,
75 .rqtype = DEVTOMEM,
76 }, {
77 .peri_id = (u8)DMACH_I2S0_TX,
78 .rqtype = MEMTODEV,
79 }, {
80 .peri_id = (u8)DMACH_I2S0_RX,
81 .rqtype = DEVTOMEM,
82 }, {
83 .peri_id = (u8)DMACH_SPI0_TX,
84 .rqtype = MEMTODEV,
85 }, {
86 .peri_id = (u8)DMACH_SPI0_RX,
87 .rqtype = DEVTOMEM,
88 }, {
89 .peri_id = (u8)DMACH_MAX,
90 }, {
91 .peri_id = (u8)DMACH_MAX,
92 }, {
93 .peri_id = (u8)DMACH_MAX,
94 }, {
95 .peri_id = (u8)DMACH_MAX,
96 }, {
97 .peri_id = (u8)DMACH_SPI1_TX,
98 .rqtype = MEMTODEV,
99 }, {
100 .peri_id = (u8)DMACH_SPI1_RX,
101 .rqtype = DEVTOMEM,
102 },
103}; 64};
104 65
105struct dma_pl330_platdata s5p6440_pdma_pdata = { 66struct dma_pl330_platdata s5p6440_pdma_pdata = {
106 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri), 67 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
107 .peri = s5p6440_pdma_peri, 68 .peri_id = s5p6440_pdma_peri,
108}; 69};
109 70
110struct dma_pl330_peri s5p6450_pdma_peri[32] = { 71u8 s5p6450_pdma_peri[] = {
111 { 72 DMACH_UART0_RX,
112 .peri_id = (u8)DMACH_UART0_RX, 73 DMACH_UART0_TX,
113 .rqtype = DEVTOMEM, 74 DMACH_UART1_RX,
114 }, { 75 DMACH_UART1_TX,
115 .peri_id = (u8)DMACH_UART0_TX, 76 DMACH_UART2_RX,
116 .rqtype = MEMTODEV, 77 DMACH_UART2_TX,
117 }, { 78 DMACH_UART3_RX,
118 .peri_id = (u8)DMACH_UART1_RX, 79 DMACH_UART3_TX,
119 .rqtype = DEVTOMEM, 80 DMACH_UART4_RX,
120 }, { 81 DMACH_UART4_TX,
121 .peri_id = (u8)DMACH_UART1_TX, 82 DMACH_PCM0_TX,
122 .rqtype = MEMTODEV, 83 DMACH_PCM0_RX,
123 }, { 84 DMACH_I2S0_TX,
124 .peri_id = (u8)DMACH_UART2_RX, 85 DMACH_I2S0_RX,
125 .rqtype = DEVTOMEM, 86 DMACH_SPI0_TX,
126 }, { 87 DMACH_SPI0_RX,
127 .peri_id = (u8)DMACH_UART2_TX, 88 DMACH_PCM1_TX,
128 .rqtype = MEMTODEV, 89 DMACH_PCM1_RX,
129 }, { 90 DMACH_PCM2_TX,
130 .peri_id = (u8)DMACH_UART3_RX, 91 DMACH_PCM2_RX,
131 .rqtype = DEVTOMEM, 92 DMACH_SPI1_TX,
132 }, { 93 DMACH_SPI1_RX,
133 .peri_id = (u8)DMACH_UART3_TX, 94 DMACH_USI_TX,
134 .rqtype = MEMTODEV, 95 DMACH_USI_RX,
135 }, { 96 DMACH_MAX,
136 .peri_id = (u8)DMACH_UART4_RX, 97 DMACH_I2S1_TX,
137 .rqtype = DEVTOMEM, 98 DMACH_I2S1_RX,
138 }, { 99 DMACH_I2S2_TX,
139 .peri_id = (u8)DMACH_UART4_TX, 100 DMACH_I2S2_RX,
140 .rqtype = MEMTODEV, 101 DMACH_PWM,
141 }, { 102 DMACH_UART5_RX,
142 .peri_id = (u8)DMACH_PCM0_TX, 103 DMACH_UART5_TX,
143 .rqtype = MEMTODEV,
144 }, {
145 .peri_id = (u8)DMACH_PCM0_RX,
146 .rqtype = DEVTOMEM,
147 }, {
148 .peri_id = (u8)DMACH_I2S0_TX,
149 .rqtype = MEMTODEV,
150 }, {
151 .peri_id = (u8)DMACH_I2S0_RX,
152 .rqtype = DEVTOMEM,
153 }, {
154 .peri_id = (u8)DMACH_SPI0_TX,
155 .rqtype = MEMTODEV,
156 }, {
157 .peri_id = (u8)DMACH_SPI0_RX,
158 .rqtype = DEVTOMEM,
159 }, {
160 .peri_id = (u8)DMACH_PCM1_TX,
161 .rqtype = MEMTODEV,
162 }, {
163 .peri_id = (u8)DMACH_PCM1_RX,
164 .rqtype = DEVTOMEM,
165 }, {
166 .peri_id = (u8)DMACH_PCM2_TX,
167 .rqtype = MEMTODEV,
168 }, {
169 .peri_id = (u8)DMACH_PCM2_RX,
170 .rqtype = DEVTOMEM,
171 }, {
172 .peri_id = (u8)DMACH_SPI1_TX,
173 .rqtype = MEMTODEV,
174 }, {
175 .peri_id = (u8)DMACH_SPI1_RX,
176 .rqtype = DEVTOMEM,
177 }, {
178 .peri_id = (u8)DMACH_USI_TX,
179 .rqtype = MEMTODEV,
180 }, {
181 .peri_id = (u8)DMACH_USI_RX,
182 .rqtype = DEVTOMEM,
183 }, {
184 .peri_id = (u8)DMACH_MAX,
185 }, {
186 .peri_id = (u8)DMACH_I2S1_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_I2S1_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_I2S2_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_I2S2_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_PWM,
199 }, {
200 .peri_id = (u8)DMACH_UART5_RX,
201 .rqtype = DEVTOMEM,
202 }, {
203 .peri_id = (u8)DMACH_UART5_TX,
204 .rqtype = MEMTODEV,
205 },
206}; 104};
207 105
208struct dma_pl330_platdata s5p6450_pdma_pdata = { 106struct dma_pl330_platdata s5p6450_pdma_pdata = {
209 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri), 107 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
210 .peri = s5p6450_pdma_peri, 108 .peri_id = s5p6450_pdma_peri,
211}; 109};
212 110
213struct amba_device s5p64x0_device_pdma = { 111struct amba_device s5p64x0_device_pdma = {
@@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = {
227 125
228static int __init s5p64x0_dma_init(void) 126static int __init s5p64x0_dma_init(void)
229{ 127{
230 if (soc_is_s5p6450()) 128 if (soc_is_s5p6450()) {
129 dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
130 dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
231 s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; 131 s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
232 else 132 } else {
133 dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
134 dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
233 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; 135 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
136 }
234 137
235 amba_device_register(&s5p64x0_device_pdma, &iomem_resource); 138 amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
236 139
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 53982db9d259..5b845e849b30 100644
--- a/arch/arm/mach-s5p64x0/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -141,6 +141,8 @@
141 141
142#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x)) 142#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
143 143
144#define IRQ_TIMER_BASE (11)
145
144/* Set the default NR_IRQS */ 146/* Set the default NR_IRQS */
145 147
146#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) 148#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 4d3ac8a3709d..0c0175dbfa34 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -67,6 +67,8 @@
67#define S3C_PA_RTC S5P64X0_PA_RTC 67#define S3C_PA_RTC S5P64X0_PA_RTC
68#define S3C_PA_WDT S5P64X0_PA_WDT 68#define S3C_PA_WDT S5P64X0_PA_WDT
69#define S3C_PA_FB S5P64X0_PA_FB 69#define S3C_PA_FB S5P64X0_PA_FB
70#define S3C_PA_SPI0 S5P64X0_PA_SPI0
71#define S3C_PA_SPI1 S5P64X0_PA_SPI1
70 72
71#define S5P_PA_CHIPID S5P64X0_PA_CHIPID 73#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
72#define S5P_PA_SROMC S5P64X0_PA_SROMC 74#define S5P_PA_SROMC S5P64X0_PA_SROMC
diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h
index 60f57532c970..cf26e0954a2f 100644
--- a/arch/arm/mach-s5p64x0/include/mach/system.h
+++ b/arch/arm/mach-s5p64x0/include/mach/system.h
@@ -13,8 +13,6 @@
13#ifndef __ASM_ARCH_SYSTEM_H 13#ifndef __ASM_ARCH_SYSTEM_H
14#define __ASM_ARCH_SYSTEM_H __FILE__ 14#define __ASM_ARCH_SYSTEM_H __FILE__
15 15
16#include <plat/system-reset.h>
17
18static void arch_idle(void) 16static void arch_idle(void)
19{ 17{
20 /* nothing here yet */ 18 /* nothing here yet */
diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c
deleted file mode 100644
index 79833caf8165..000000000000
--- a/arch/arm/mach-s5p64x0/init.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/* linux/arch/arm/mach-s5p64x0/init.c
2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P64X0 - Init support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/init.h>
16#include <linux/serial_core.h>
17
18#include <mach/map.h>
19
20#include <plat/cpu.h>
21#include <plat/devs.h>
22#include <plat/s5p6440.h>
23#include <plat/s5p6450.h>
24#include <plat/regs-serial.h>
25
26static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
27 [0] = {
28 .name = "pclk_low",
29 .divisor = 1,
30 .min_baud = 0,
31 .max_baud = 0,
32 },
33 [1] = {
34 .name = "uclk1",
35 .divisor = 1,
36 .min_baud = 0,
37 .max_baud = 0,
38 },
39};
40
41/* uart registration process */
42
43void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
44{
45 struct s3c2410_uartcfg *tcfg = cfg;
46 u32 ucnt;
47
48 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
49 if (!tcfg->clocks) {
50 tcfg->clocks = s5p64x0_serial_clocks;
51 tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
52 }
53 }
54}
55
56void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
57{
58 int uart;
59
60 for (uart = 0; uart < no; uart++) {
61 s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
62 s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
63 }
64
65 s5p64x0_common_init_uarts(cfg, no);
66 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
67}
68
69void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
70{
71 s5p64x0_common_init_uarts(cfg, no);
72 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
73}
diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c
deleted file mode 100644
index 275dc74f4a7b..000000000000
--- a/arch/arm/mach-s5p64x0/irq-eint.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/* arch/arm/mach-s5p64x0/irq-eint.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd
4 * http://www.samsung.com/
5 *
6 * Based on linux/arch/arm/mach-s3c64xx/irq-eint.c
7 *
8 * S5P64X0 - Interrupt handling for External Interrupts.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/gpio.h>
17#include <linux/irq.h>
18#include <linux/io.h>
19
20#include <plat/cpu.h>
21#include <plat/regs-irqtype.h>
22#include <plat/gpio-cfg.h>
23#include <plat/pm.h>
24
25#include <mach/regs-gpio.h>
26#include <mach/regs-clock.h>
27
28#define eint_offset(irq) ((irq) - IRQ_EINT(0))
29
30static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type)
31{
32 int offs = eint_offset(data->irq);
33 int shift;
34 u32 ctrl, mask;
35 u32 newvalue = 0;
36
37 if (offs > 15)
38 return -EINVAL;
39
40 switch (type) {
41 case IRQ_TYPE_NONE:
42 printk(KERN_WARNING "No edge setting!\n");
43 break;
44 case IRQ_TYPE_EDGE_RISING:
45 newvalue = S3C2410_EXTINT_RISEEDGE;
46 break;
47 case IRQ_TYPE_EDGE_FALLING:
48 newvalue = S3C2410_EXTINT_FALLEDGE;
49 break;
50 case IRQ_TYPE_EDGE_BOTH:
51 newvalue = S3C2410_EXTINT_BOTHEDGE;
52 break;
53 case IRQ_TYPE_LEVEL_LOW:
54 newvalue = S3C2410_EXTINT_LOWLEV;
55 break;
56 case IRQ_TYPE_LEVEL_HIGH:
57 newvalue = S3C2410_EXTINT_HILEV;
58 break;
59 default:
60 printk(KERN_ERR "No such irq type %d", type);
61 return -EINVAL;
62 }
63
64 shift = (offs / 2) * 4;
65 mask = 0x7 << shift;
66
67 ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask;
68 ctrl |= newvalue << shift;
69 __raw_writel(ctrl, S5P64X0_EINT0CON0);
70
71 /* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
72 if (soc_is_s5p6450())
73 s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
74 else
75 s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));
76
77 return 0;
78}
79
80/*
81 * s5p64x0_irq_demux_eint
82 *
83 * This function demuxes the IRQ from the group0 external interrupts,
84 * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into
85 * the specific handlers s5p64x0_irq_demux_eintX_Y.
86 */
87static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end)
88{
89 u32 status = __raw_readl(S5P64X0_EINT0PEND);
90 u32 mask = __raw_readl(S5P64X0_EINT0MASK);
91 unsigned int irq;
92
93 status &= ~mask;
94 status >>= start;
95 status &= (1 << (end - start + 1)) - 1;
96
97 for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
98 if (status & 1)
99 generic_handle_irq(irq);
100 status >>= 1;
101 }
102}
103
104static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
105{
106 s5p64x0_irq_demux_eint(0, 3);
107}
108
109static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
110{
111 s5p64x0_irq_demux_eint(4, 11);
112}
113
114static void s5p64x0_irq_demux_eint12_15(unsigned int irq,
115 struct irq_desc *desc)
116{
117 s5p64x0_irq_demux_eint(12, 15);
118}
119
120static int s5p64x0_alloc_gc(void)
121{
122 struct irq_chip_generic *gc;
123 struct irq_chip_type *ct;
124
125 gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE,
126 S5P_VA_GPIO, handle_level_irq);
127 if (!gc) {
128 printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0"
129 "external interrupts failed\n", __func__);
130 return -EINVAL;
131 }
132
133 ct = gc->chip_types;
134 ct->chip.irq_ack = irq_gc_ack_set_bit;
135 ct->chip.irq_mask = irq_gc_mask_set_bit;
136 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
137 ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
138 ct->chip.irq_set_wake = s3c_irqext_wake;
139 ct->regs.ack = EINT0PEND_OFFSET;
140 ct->regs.mask = EINT0MASK_OFFSET;
141 irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
142 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
143 return 0;
144}
145
146static int __init s5p64x0_init_irq_eint(void)
147{
148 int ret = s5p64x0_alloc_gc();
149 irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3);
150 irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11);
151 irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15);
152
153 return ret;
154}
155arch_initcall(s5p64x0_init_irq_eint);
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index c272c3f7d6de..34d98a1dae57 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -41,7 +41,6 @@
41 41
42#include <plat/regs-serial.h> 42#include <plat/regs-serial.h>
43#include <plat/gpio-cfg.h> 43#include <plat/gpio-cfg.h>
44#include <plat/s5p6440.h>
45#include <plat/clock.h> 44#include <plat/clock.h>
46#include <plat/devs.h> 45#include <plat/devs.h>
47#include <plat/cpu.h> 46#include <plat/cpu.h>
@@ -54,6 +53,8 @@
54#include <plat/fb.h> 53#include <plat/fb.h>
55#include <plat/regs-fb.h> 54#include <plat/regs-fb.h>
56 55
56#include "common.h"
57
57#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 58#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
58 S3C2410_UCON_RXILEVEL | \ 59 S3C2410_UCON_RXILEVEL | \
59 S3C2410_UCON_TXIRQMODE | \ 60 S3C2410_UCON_TXIRQMODE | \
@@ -202,7 +203,7 @@ static struct platform_pwm_backlight_data smdk6440_bl_data = {
202 203
203static void __init smdk6440_map_io(void) 204static void __init smdk6440_map_io(void)
204{ 205{
205 s5p_init_io(NULL, 0, S5P64X0_SYS_ID); 206 s5p64x0_init_io(NULL, 0);
206 s3c24xx_init_clocks(12000000); 207 s3c24xx_init_clocks(12000000);
207 s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs)); 208 s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
208 s5p_set_timer_source(S5P_PWM3, S5P_PWM4); 209 s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
@@ -247,4 +248,5 @@ MACHINE_START(SMDK6440, "SMDK6440")
247 .map_io = smdk6440_map_io, 248 .map_io = smdk6440_map_io,
248 .init_machine = smdk6440_machine_init, 249 .init_machine = smdk6440_machine_init,
249 .timer = &s5p_timer, 250 .timer = &s5p_timer,
251 .restart = s5p64x0_restart,
250MACHINE_END 252MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 7a4700959616..135cf5d84737 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -41,7 +41,6 @@
41 41
42#include <plat/regs-serial.h> 42#include <plat/regs-serial.h>
43#include <plat/gpio-cfg.h> 43#include <plat/gpio-cfg.h>
44#include <plat/s5p6450.h>
45#include <plat/clock.h> 44#include <plat/clock.h>
46#include <plat/devs.h> 45#include <plat/devs.h>
47#include <plat/cpu.h> 46#include <plat/cpu.h>
@@ -54,6 +53,8 @@
54#include <plat/fb.h> 53#include <plat/fb.h>
55#include <plat/regs-fb.h> 54#include <plat/regs-fb.h>
56 55
56#include "common.h"
57
57#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 58#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
58 S3C2410_UCON_RXILEVEL | \ 59 S3C2410_UCON_RXILEVEL | \
59 S3C2410_UCON_TXIRQMODE | \ 60 S3C2410_UCON_TXIRQMODE | \
@@ -222,7 +223,7 @@ static struct platform_pwm_backlight_data smdk6450_bl_data = {
222 223
223static void __init smdk6450_map_io(void) 224static void __init smdk6450_map_io(void)
224{ 225{
225 s5p_init_io(NULL, 0, S5P64X0_SYS_ID); 226 s5p64x0_init_io(NULL, 0);
226 s3c24xx_init_clocks(19200000); 227 s3c24xx_init_clocks(19200000);
227 s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs)); 228 s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
228 s5p_set_timer_source(S5P_PWM3, S5P_PWM4); 229 s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
@@ -267,4 +268,5 @@ MACHINE_START(SMDK6450, "SMDK6450")
267 .map_io = smdk6450_map_io, 268 .map_io = smdk6450_map_io,
268 .init_machine = smdk6450_machine_init, 269 .init_machine = smdk6450_machine_init,
269 .timer = &s5p_timer, 270 .timer = &s5p_timer,
271 .restart = s5p64x0_restart,
270MACHINE_END 272MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/setup-spi.c b/arch/arm/mach-s5p64x0/setup-spi.c
new file mode 100644
index 000000000000..e9b841240352
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-spi.c
@@ -0,0 +1,55 @@
1/* linux/arch/arm/mach-s5p64x0/setup-spi.c
2 *
3 * Copyright (C) 2011 Samsung Electronics Ltd.
4 * http://www.samsung.com/
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13#include <linux/io.h>
14
15#include <plat/gpio-cfg.h>
16#include <plat/cpu.h>
17#include <plat/s3c64xx-spi.h>
18
19#ifdef CONFIG_S3C64XX_DEV_SPI0
20struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
21 .fifo_lvl_mask = 0x1ff,
22 .rx_lvl_offset = 15,
23 .tx_st_done = 25,
24};
25
26int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
27{
28 if (soc_is_s5p6450())
29 s3c_gpio_cfgall_range(S5P6450_GPC(0), 3,
30 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
31 else
32 s3c_gpio_cfgall_range(S5P6440_GPC(0), 3,
33 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
34 return 0;
35}
36#endif
37
38#ifdef CONFIG_S3C64XX_DEV_SPI1
39struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
40 .fifo_lvl_mask = 0x7f,
41 .rx_lvl_offset = 15,
42 .tx_st_done = 25,
43};
44
45int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
46{
47 if (soc_is_s5p6450())
48 s3c_gpio_cfgall_range(S5P6450_GPC(4), 3,
49 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
50 else
51 s3c_gpio_cfgall_range(S5P6440_GPC(4), 3,
52 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
53 return 0;
54}
55#endif