summaryrefslogtreecommitdiffstats
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/Kconfig31
-rw-r--r--arch/arm/mach-s5p64x0/Makefile12
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c170
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c158
-rw-r--r--arch/arm/mach-s5p64x0/clock.c6
-rw-r--r--arch/arm/mach-s5p64x0/common.c447
-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/entry-macro.S7
-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/include/mach/vmalloc.h20
-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.c33
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c34
-rw-r--r--arch/arm/mach-s5p64x0/pm.c10
-rw-r--r--arch/arm/mach-s5p64x0/setup-sdhci-gpio.c104
-rw-r--r--arch/arm/mach-s5p64x0/setup-spi.c55
22 files changed, 1038 insertions, 1006 deletions
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 18690c5f99e6..c87f6108eeb1 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -36,6 +36,16 @@ config S5P64X0_SETUP_I2C1
help
Common setup code for i2c bus 1.
+config S5P64X0_SETUP_SPI
+ bool
+ help
+ Common setup code for SPI GPIO configurations
+
+config S5P64X0_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for SDHCI gpio.
+
# machine support
config MACH_SMDK6440
@@ -45,13 +55,16 @@ config MACH_SMDK6440
select S3C_DEV_I2C1
select S3C_DEV_RTC
select S3C_DEV_WDT
- select S3C64XX_DEV_SPI
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
select S5P64X0_SETUP_FB_24BPP
select S5P64X0_SETUP_I2C1
+ select S5P64X0_SETUP_SDHCI_GPIO
help
Machine support for the Samsung SMDK6440
@@ -62,14 +75,28 @@ config MACH_SMDK6450
select S3C_DEV_I2C1
select S3C_DEV_RTC
select S3C_DEV_WDT
- select S3C64XX_DEV_SPI
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
select S5P64X0_SETUP_FB_24BPP
select S5P64X0_SETUP_I2C1
+ select S5P64X0_SETUP_SDHCI_GPIO
help
Machine support for the Samsung SMDK6450
+menu "Use 8-bit SDHCI bus width"
+
+config S5P64X0_SD_CH1_8BIT
+ bool "SDHCI Channel 1 (Slot 1)"
+ depends on MACH_SMDK6450 || MACH_SMDK6440
+ help
+ Support SDHCI Channel 1 8-bit bus.
+ If selected, Channel 2 is disabled.
+
+endmenu
+
endif
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index a1324d8dc4e0..12bb951187a4 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -10,14 +10,16 @@ obj-m :=
obj-n :=
obj- :=
-# Core support for S5P64X0 system
+# Core
-obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o
-obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o irq-eint.o
+obj-y += common.o clock.o
obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
+
obj-$(CONFIG_PM) += pm.o irq-pm.o
+obj-y += dma.o
+
# machine support
obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
@@ -26,7 +28,9 @@ obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o
# device support
obj-y += dev-audio.o
-obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+obj-y += setup-i2c0.o
obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S5P64X0_SETUP_SPI) += setup-spi.o
+obj-$(CONFIG_S5P64X0_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index c54c65d511f0..ee1e8e7f5631 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -17,7 +17,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
-#include <linux/sysdev.h>
+#include <linux/device.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -31,7 +31,8 @@
#include <plat/pll.h>
#include <plat/s5p-clock.h>
#include <plat/clock-clksrc.h>
-#include <plat/s5p6440.h>
+
+#include "common.h"
static u32 epll_div[][5] = {
{ 36000000, 0, 48, 1, 4 },
@@ -268,18 +269,6 @@ static struct clk init_clocks_off[] = {
.enable = s5p64x0_pclk_ctrl,
.ctrlbit = (1 << 31),
}, {
- .name = "sclk_spi_48",
- .devname = "s3c64xx-spi.0",
- .parent = &clk_48m,
- .enable = s5p64x0_sclk_ctrl,
- .ctrlbit = (1 << 22),
- }, {
- .name = "sclk_spi_48",
- .devname = "s3c64xx-spi.1",
- .parent = &clk_48m,
- .enable = s5p64x0_sclk_ctrl,
- .ctrlbit = (1 << 23),
- }, {
.name = "mmc_48m",
.devname = "s3c-sdhci.0",
.parent = &clk_48m,
@@ -391,65 +380,6 @@ static struct clksrc_sources clkset_audio = {
static struct clksrc_clk clksrcs[] = {
{
.clk = {
- .name = "sclk_mmc",
- .devname = "s3c-sdhci.0",
- .ctrlbit = (1 << 24),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .devname = "s3c-sdhci.1",
- .ctrlbit = (1 << 25),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .devname = "s3c-sdhci.2",
- .ctrlbit = (1 << 26),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .ctrlbit = (1 << 5),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .devname = "s3c64xx-spi.0",
- .ctrlbit = (1 << 20),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .devname = "s3c64xx-spi.1",
- .ctrlbit = (1 << 21),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group1,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
- }, {
- .clk = {
.name = "sclk_post",
.ctrlbit = (1 << 10),
.enable = s5p64x0_sclk_ctrl,
@@ -487,6 +417,77 @@ static struct clksrc_clk clksrcs[] = {
},
};
+static struct clksrc_clk clk_sclk_mmc0 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.0",
+ .ctrlbit = (1 << 24),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_mmc1 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.1",
+ .ctrlbit = (1 << 25),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_mmc2 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.2",
+ .ctrlbit = (1 << 26),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uclk = {
+ .clk = {
+ .name = "uclk1",
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_spi0 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.0",
+ .ctrlbit = (1 << 20),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_spi1 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.1",
+ .ctrlbit = (1 << 21),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+};
+
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -505,6 +506,26 @@ static struct clk dummy_apb_pclk = {
.id = -1,
};
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uclk,
+ &clk_sclk_spi0,
+ &clk_sclk_spi1,
+ &clk_sclk_mmc0,
+ &clk_sclk_mmc1,
+ &clk_sclk_mmc2
+};
+
+static struct clk_lookup s5p6440_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
+ CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
+ CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
+ CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
+ CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
+ CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
+ CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
+};
+
void __init_or_cpufreq s5p6440_setup_clocks(void)
{
struct clk *xtal_clk;
@@ -583,9 +604,12 @@ void __init s5p6440_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 2d04abfba12e..dae6a13f43bb 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -17,7 +17,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
-#include <linux/sysdev.h>
+#include <linux/device.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -31,7 +31,8 @@
#include <plat/pll.h>
#include <plat/s5p-clock.h>
#include <plat/clock-clksrc.h>
-#include <plat/s5p6450.h>
+
+#include "common.h"
static struct clksrc_clk clk_mout_dpll = {
.clk = {
@@ -413,65 +414,6 @@ static struct clksrc_clk clk_sclk_audio0 = {
static struct clksrc_clk clksrcs[] = {
{
.clk = {
- .name = "sclk_mmc",
- .devname = "s3c-sdhci.0",
- .ctrlbit = (1 << 24),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group2,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .devname = "s3c-sdhci.1",
- .ctrlbit = (1 << 25),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group2,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .devname = "s3c-sdhci.2",
- .ctrlbit = (1 << 26),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group2,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .ctrlbit = (1 << 5),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_uart,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .devname = "s3c64xx-spi.0",
- .ctrlbit = (1 << 20),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group2,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .devname = "s3c64xx-spi.1",
- .ctrlbit = (1 << 21),
- .enable = s5p64x0_sclk_ctrl,
- },
- .sources = &clkset_group2,
- .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
- .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
- }, {
- .clk = {
.name = "sclk_fimc",
.ctrlbit = (1 << 10),
.enable = s5p64x0_sclk_ctrl,
@@ -536,6 +478,97 @@ static struct clksrc_clk clksrcs[] = {
},
};
+static struct clksrc_clk clk_sclk_mmc0 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.0",
+ .ctrlbit = (1 << 24),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_mmc1 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.1",
+ .ctrlbit = (1 << 25),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_mmc2 = {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.2",
+ .ctrlbit = (1 << 26),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_uclk = {
+ .clk = {
+ .name = "uclk1",
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_spi0 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.0",
+ .ctrlbit = (1 << 20),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_spi1 = {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.1",
+ .ctrlbit = (1 << 21),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk *clksrc_cdev[] = {
+ &clk_sclk_uclk,
+ &clk_sclk_spi0,
+ &clk_sclk_spi1,
+ &clk_sclk_mmc0,
+ &clk_sclk_mmc1,
+ &clk_sclk_mmc2,
+};
+
+static struct clk_lookup s5p6450_clk_lookup[] = {
+ CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
+ CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
+ CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
+ CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
+ CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
+ CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
+ CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
+ CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
+};
+
/* Clock initialization code */
static struct clksrc_clk *sysclks[] = {
&clk_mout_apll,
@@ -634,9 +667,12 @@ void __init s5p6450_register_clocks(void)
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
+ s3c_register_clksrc(clksrc_cdev[ptr], 1);
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
index b52c6e2f37a6..241d0e645c85 100644
--- a/arch/arm/mach-s5p64x0/clock.c
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -17,7 +17,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
-#include <linux/sysdev.h>
+#include <linux/device.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -30,8 +30,8 @@
#include <plat/pll.h>
#include <plat/s5p-clock.h>
#include <plat/clock-clksrc.h>
-#include <plat/s5p6440.h>
-#include <plat/s5p6450.h>
+
+#include "common.h"
struct clksrc_clk clk_mout_apll = {
.clk = {
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
new file mode 100644
index 000000000000..52b89a376447
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common Codes for S5P64X0 machines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/irq.h>
+#include <asm/proc-fns.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/map.h>
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/sdhci.h>
+#include <plat/adc-core.h>
+#include <plat/fb-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-irqtype.h>
+#include <plat/regs-serial.h>
+#include <plat/watchdog-reset.h>
+
+#include "common.h"
+
+static const char name_s5p6440[] = "S5P6440";
+static const char name_s5p6450[] = "S5P6450";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = S5P6440_CPU_ID,
+ .idmask = S5P64XX_CPU_MASK,
+ .map_io = s5p6440_map_io,
+ .init_clocks = s5p6440_init_clocks,
+ .init_uarts = s5p6440_init_uarts,
+ .init = s5p64x0_init,
+ .name = name_s5p6440,
+ }, {
+ .idcode = S5P6450_CPU_ID,
+ .idmask = S5P64XX_CPU_MASK,
+ .map_io = s5p6450_map_io,
+ .init_clocks = s5p6450_init_clocks,
+ .init_uarts = s5p6450_init_uarts,
+ .init = s5p64x0_init,
+ .name = name_s5p6450,
+ },
+};
+
+/* Initial IO mappings */
+
+static struct map_desc s5p64x0_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_CHIPID,
+ .pfn = __phys_to_pfn(S5P64X0_PA_CHIPID),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S5P64X0_PA_SYSCON),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(S5P64X0_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_WATCHDOG,
+ .pfn = __phys_to_pfn(S5P64X0_PA_WDT),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(S5P64X0_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5P64X0_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5P64X0_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5P64X0_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc s5p6440_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S5P6440_PA_UART(0)),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc s5p6450_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S5P6450_PA_UART(0)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART + SZ_512K,
+ .pfn = __phys_to_pfn(S5P6450_PA_UART(5)),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void s5p64x0_idle(void)
+{
+ unsigned long val;
+
+ if (!need_resched()) {
+ val = __raw_readl(S5P64X0_PWR_CFG);
+ val &= ~(0x3 << 5);
+ val |= (0x1 << 5);
+ __raw_writel(val, S5P64X0_PWR_CFG);
+
+ cpu_do_idle();
+ }
+ local_irq_enable();
+}
+
+/*
+ * s5p64x0_map_io
+ *
+ * register the standard CPU IO areas
+ */
+
+void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
+{
+ /* initialize the io descriptors we need for initialization */
+ iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+ if (mach_desc)
+ iotable_init(mach_desc, size);
+
+ /* detect cpu id and rev. */
+ s5p_init_cpu(S5P64X0_SYS_ID);
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
+
+void __init s5p6440_map_io(void)
+{
+ /* initialize any device information early */
+ s3c_adc_setname("s3c64xx-adc");
+ s3c_fb_setname("s5p64x0-fb");
+
+ s5p64x0_default_sdhci0();
+ s5p64x0_default_sdhci1();
+ s5p6440_default_sdhci2();
+
+ iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+ init_consistent_dma_size(SZ_8M);
+}
+
+void __init s5p6450_map_io(void)
+{
+ /* initialize any device information early */
+ s3c_adc_setname("s3c64xx-adc");
+ s3c_fb_setname("s5p64x0-fb");
+
+ s5p64x0_default_sdhci0();
+ s5p64x0_default_sdhci1();
+ s5p6450_default_sdhci2();
+
+ iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
+ init_consistent_dma_size(SZ_8M);
+}
+
+/*
+ * s5p64x0_init_clocks
+ *
+ * register and setup the CPU clocks
+ */
+
+void __init s5p6440_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6440_register_clocks();
+ s5p6440_setup_clocks();
+}
+
+void __init s5p6450_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6450_register_clocks();
+ s5p6450_setup_clocks();
+}
+
+/*
+ * s5p64x0_init_irq
+ *
+ * register the CPU interrupts
+ */
+
+void __init s5p6440_init_irq(void)
+{
+ /* S5P6440 supports 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
+ * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
+ */
+ vic[0] = 0xff800ae7;
+ vic[1] = 0xffbf23e5;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+void __init s5p6450_init_irq(void)
+{
+ /* S5P6450 supports only 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
+ * VIC1 is missing IRQ VIC1[12, 14, 23]
+ */
+ vic[0] = 0xff9f1fff;
+ vic[1] = 0xff7fafff;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+struct bus_type s5p64x0_subsys = {
+ .name = "s5p64x0-core",
+ .dev_name = "s5p64x0-core",
+};
+
+static struct device s5p64x0_dev = {
+ .bus = &s5p64x0_subsys,
+};
+
+static int __init s5p64x0_core_init(void)
+{
+ return subsys_system_register(&s5p64x0_subsys, NULL);
+}
+core_initcall(s5p64x0_core_init);
+
+int __init s5p64x0_init(void)
+{
+ printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5p64x0_idle;
+
+ return device_register(&s5p64x0_dev);
+}
+
+/* uart registration process */
+void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ int uart;
+
+ for (uart = 0; uart < no; uart++) {
+ s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
+ s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
+ }
+
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
+
+void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
+
+#define eint_offset(irq) ((irq) - IRQ_EINT(0))
+
+static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type)
+{
+ int offs = eint_offset(data->irq);
+ int shift;
+ u32 ctrl, mask;
+ u32 newvalue = 0;
+
+ if (offs > 15)
+ return -EINVAL;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S3C2410_EXTINT_RISEEDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S3C2410_EXTINT_FALLEDGE;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S3C2410_EXTINT_BOTHEDGE;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S3C2410_EXTINT_LOWLEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S3C2410_EXTINT_HILEV;
+ break;
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -EINVAL;
+ }
+
+ shift = (offs / 2) * 4;
+ mask = 0x7 << shift;
+
+ ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, S5P64X0_EINT0CON0);
+
+ /* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
+ else
+ s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));
+
+ return 0;
+}
+
+/*
+ * s5p64x0_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into
+ * the specific handlers s5p64x0_irq_demux_eintX_Y.
+ */
+static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end)
+{
+ u32 status = __raw_readl(S5P64X0_EINT0PEND);
+ u32 mask = __raw_readl(S5P64X0_EINT0MASK);
+ unsigned int irq;
+
+ status &= ~mask;
+ status >>= start;
+ status &= (1 << (end - start + 1)) - 1;
+
+ for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+ if (status & 1)
+ generic_handle_irq(irq);
+ status >>= 1;
+ }
+}
+
+static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+ s5p64x0_irq_demux_eint(0, 3);
+}
+
+static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+ s5p64x0_irq_demux_eint(4, 11);
+}
+
+static void s5p64x0_irq_demux_eint12_15(unsigned int irq,
+ struct irq_desc *desc)
+{
+ s5p64x0_irq_demux_eint(12, 15);
+}
+
+static int s5p64x0_alloc_gc(void)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE,
+ S5P_VA_GPIO, handle_level_irq);
+ if (!gc) {
+ printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0"
+ "external interrupts failed\n", __func__);
+ return -EINVAL;
+ }
+
+ ct = gc->chip_types;
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
+ ct->chip.irq_mask = irq_gc_mask_set_bit;
+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
+ ct->chip.irq_set_wake = s3c_irqext_wake;
+ ct->regs.ack = EINT0PEND_OFFSET;
+ ct->regs.mask = EINT0MASK_OFFSET;
+ irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+ return 0;
+}
+
+static int __init s5p64x0_init_irq_eint(void)
+{
+ int ret = s5p64x0_alloc_gc();
+ irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3);
+ irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11);
+ irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15);
+
+ return ret;
+}
+arch_initcall(s5p64x0_init_irq_eint);
+
+void s5p64x0_restart(char mode, const char *cmd)
+{
+ if (mode != 's')
+ arch_wdt_reset();
+
+ soft_restart(0);
+}
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 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common Header for S5P64X0 machines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_S5P64X0_COMMON_H
+#define __ARCH_ARM_MACH_S5P64X0_COMMON_H
+
+void s5p6440_init_irq(void);
+void s5p6450_init_irq(void);
+void s5p64x0_init_io(struct map_desc *mach_desc, int size);
+
+void s5p6440_register_clocks(void);
+void s5p6440_setup_clocks(void);
+
+void s5p6450_register_clocks(void);
+void s5p6450_setup_clocks(void);
+
+void s5p64x0_restart(char mode, const char *cmd);
+
+#ifdef CONFIG_CPU_S5P6440
+
+extern int s5p64x0_init(void);
+extern void s5p6440_map_io(void);
+extern void s5p6440_init_clocks(int xtal);
+
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6440_init_clocks NULL
+#define s5p6440_init_uarts NULL
+#define s5p6440_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S5P6450
+
+extern int s5p64x0_init(void);
+extern void s5p6450_map_io(void);
+extern void s5p6450_init_clocks(int xtal);
+
+extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6450_init_clocks NULL
+#define s5p6450_init_uarts NULL
+#define s5p6450_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+#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 @@
-/* linux/arch/arm/mach-s5p64x0/cpu.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/proc-fns.h>
-#include <asm/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-
-#include <plat/regs-serial.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/s5p6440.h>
-#include <plat/s5p6450.h>
-#include <plat/adc-core.h>
-#include <plat/fb-core.h>
-
-/* Initial IO mappings */
-
-static struct map_desc s5p64x0_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_GPIO,
- .pfn = __phys_to_pfn(S5P64X0_PA_GPIO),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)VA_VIC0,
- .pfn = __phys_to_pfn(S5P64X0_PA_VIC0),
- .length = SZ_16K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)VA_VIC1,
- .pfn = __phys_to_pfn(S5P64X0_PA_VIC1),
- .length = SZ_16K,
- .type = MT_DEVICE,
- },
-};
-
-static struct map_desc s5p6440_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S3C_VA_UART,
- .pfn = __phys_to_pfn(S5P6440_PA_UART(0)),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
-static struct map_desc s5p6450_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S3C_VA_UART,
- .pfn = __phys_to_pfn(S5P6450_PA_UART(0)),
- .length = SZ_512K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_UART + SZ_512K,
- .pfn = __phys_to_pfn(S5P6450_PA_UART(5)),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
-static void s5p64x0_idle(void)
-{
- unsigned long val;
-
- if (!need_resched()) {
- val = __raw_readl(S5P64X0_PWR_CFG);
- val &= ~(0x3 << 5);
- val |= (0x1 << 5);
- __raw_writel(val, S5P64X0_PWR_CFG);
-
- cpu_do_idle();
- }
- local_irq_enable();
-}
-
-/*
- * s5p64x0_map_io
- *
- * register the standard CPU IO areas
- */
-
-void __init s5p6440_map_io(void)
-{
- /* initialize any device information early */
- s3c_adc_setname("s3c64xx-adc");
- s3c_fb_setname("s5p64x0-fb");
-
- iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
- iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
- init_consistent_dma_size(SZ_8M);
-}
-
-void __init s5p6450_map_io(void)
-{
- /* initialize any device information early */
- s3c_adc_setname("s3c64xx-adc");
- s3c_fb_setname("s5p64x0-fb");
-
- iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
- iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
- init_consistent_dma_size(SZ_8M);
-}
-
-/*
- * s5p64x0_init_clocks
- *
- * register and setup the CPU clocks
- */
-
-void __init s5p6440_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
- s3c24xx_register_baseclocks(xtal);
- s5p_register_clocks(xtal);
- s5p6440_register_clocks();
- s5p6440_setup_clocks();
-}
-
-void __init s5p6450_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
- s3c24xx_register_baseclocks(xtal);
- s5p_register_clocks(xtal);
- s5p6450_register_clocks();
- s5p6450_setup_clocks();
-}
-
-/*
- * s5p64x0_init_irq
- *
- * register the CPU interrupts
- */
-
-void __init s5p6440_init_irq(void)
-{
- /* S5P6440 supports 2 VIC */
- u32 vic[2];
-
- /*
- * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
- * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
- */
- vic[0] = 0xff800ae7;
- vic[1] = 0xffbf23e5;
-
- s5p_init_irq(vic, ARRAY_SIZE(vic));
-}
-
-void __init s5p6450_init_irq(void)
-{
- /* S5P6450 supports only 2 VIC */
- u32 vic[2];
-
- /*
- * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
- * VIC1 is missing IRQ VIC1[12, 14, 23]
- */
- vic[0] = 0xff9f1fff;
- vic[1] = 0xff7fafff;
-
- s5p_init_irq(vic, ARRAY_SIZE(vic));
-}
-
-struct sysdev_class s5p64x0_sysclass = {
- .name = "s5p64x0-core",
-};
-
-static struct sys_device s5p64x0_sysdev = {
- .cls = &s5p64x0_sysclass,
-};
-
-static int __init s5p64x0_core_init(void)
-{
- return sysdev_class_register(&s5p64x0_sysclass);
-}
-core_initcall(s5p64x0_core_init);
-
-int __init s5p64x0_init(void)
-{
- printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
-
- /* set idle function */
- pm_idle = s5p64x0_idle;
-
- return sysdev_register(&s5p64x0_sysdev);
-}
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 @@
-/* linux/arch/arm/mach-s5p64x0/dev-spi.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <mach/dma.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/regs-clock.h>
-#include <mach/spi-clocks.h>
-
-#include <plat/cpu.h>
-#include <plat/s3c64xx-spi.h>
-#include <plat/gpio-cfg.h>
-
-static char *s5p64x0_spi_src_clks[] = {
- [S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
- [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
-};
-
-/* SPI Controller platform_devices */
-
-/* Since we emulate multi-cs capability, we do not touch the CS.
- * The emulated CS is toggled by board specific mechanism, as it can
- * be either some immediate GPIO or some signal out of some other
- * chip in between ... or some yet another way.
- * We simply do not assume anything about CS.
- */
-static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
-{
- unsigned int base;
-
- switch (pdev->id) {
- case 0:
- base = S5P6440_GPC(0);
- break;
-
- case 1:
- base = S5P6440_GPC(4);
- break;
-
- default:
- dev_err(&pdev->dev, "Invalid SPI Controller number!");
- return -EINVAL;
- }
-
- s3c_gpio_cfgall_range(base, 3,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-
- return 0;
-}
-
-static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
-{
- unsigned int base;
-
- switch (pdev->id) {
- case 0:
- base = S5P6450_GPC(0);
- break;
-
- case 1:
- base = S5P6450_GPC(4);
- break;
-
- default:
- dev_err(&pdev->dev, "Invalid SPI Controller number!");
- return -EINVAL;
- }
-
- s3c_gpio_cfgall_range(base, 3,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-
- return 0;
-}
-
-static struct resource s5p64x0_spi0_resource[] = {
- [0] = {
- .start = S5P64X0_PA_SPI0,
- .end = S5P64X0_PA_SPI0 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_SPI0_TX,
- .end = DMACH_SPI0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_SPI0_RX,
- .end = DMACH_SPI0_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = IRQ_SPI0,
- .end = IRQ_SPI0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
- .cfg_gpio = s5p6440_spi_cfg_gpio,
- .fifo_lvl_mask = 0x1ff,
- .rx_lvl_offset = 15,
- .tx_st_done = 25,
-};
-
-static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
- .cfg_gpio = s5p6450_spi_cfg_gpio,
- .fifo_lvl_mask = 0x1ff,
- .rx_lvl_offset = 15,
- .tx_st_done = 25,
-};
-
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s5p64x0_device_spi0 = {
- .name = "s3c64xx-spi",
- .id = 0,
- .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource),
- .resource = s5p64x0_spi0_resource,
- .dev = {
- .dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-static struct resource s5p64x0_spi1_resource[] = {
- [0] = {
- .start = S5P64X0_PA_SPI1,
- .end = S5P64X0_PA_SPI1 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_SPI1_TX,
- .end = DMACH_SPI1_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_SPI1_RX,
- .end = DMACH_SPI1_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = IRQ_SPI1,
- .end = IRQ_SPI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
- .cfg_gpio = s5p6440_spi_cfg_gpio,
- .fifo_lvl_mask = 0x7f,
- .rx_lvl_offset = 15,
- .tx_st_done = 25,
-};
-
-static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
- .cfg_gpio = s5p6450_spi_cfg_gpio,
- .fifo_lvl_mask = 0x7f,
- .rx_lvl_offset = 15,
- .tx_st_done = 25,
-};
-
-struct platform_device s5p64x0_device_spi1 = {
- .name = "s3c64xx-spi",
- .id = 1,
- .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource),
- .resource = s5p64x0_spi1_resource,
- .dev = {
- .dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
-{
- struct s3c64xx_spi_info *pd;
-
- /* Reject invalid configuration */
- if (!num_cs || src_clk_nr < 0
- || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
- printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
- return;
- }
-
- switch (cntrlr) {
- case 0:
- if (soc_is_s5p6450())
- pd = &s5p6450_spi0_pdata;
- else
- pd = &s5p6440_spi0_pdata;
-
- s5p64x0_device_spi0.dev.platform_data = pd;
- break;
- case 1:
- if (soc_is_s5p6450())
- pd = &s5p6450_spi1_pdata;
- else
- pd = &s5p6440_spi1_pdata;
-
- s5p64x0_device_spi1.dev.platform_data = pd;
- break;
- default:
- printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
- __func__, cntrlr);
- return;
- }
-
- pd->num_cs = num_cs;
- pd->src_clk_nr = src_clk_nr;
- pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
-}
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 @@
static u64 dma_dmamask = DMA_BIT_MASK(32);
-struct dma_pl330_peri s5p6440_pdma_peri[22] = {
- {
- .peri_id = (u8)DMACH_UART0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART3_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART3_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = DMACH_MAX,
- }, {
- .peri_id = DMACH_MAX,
- }, {
- .peri_id = (u8)DMACH_PCM0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_I2S0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SPI0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SPI0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_MAX,
- }, {
- .peri_id = (u8)DMACH_MAX,
- }, {
- .peri_id = (u8)DMACH_MAX,
- }, {
- .peri_id = (u8)DMACH_MAX,
- }, {
- .peri_id = (u8)DMACH_SPI1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SPI1_RX,
- .rqtype = DEVTOMEM,
- },
+u8 s5p6440_pdma_peri[] = {
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART1_RX,
+ DMACH_UART1_TX,
+ DMACH_UART2_RX,
+ DMACH_UART2_TX,
+ DMACH_UART3_RX,
+ DMACH_UART3_TX,
+ DMACH_MAX,
+ DMACH_MAX,
+ DMACH_PCM0_TX,
+ DMACH_PCM0_RX,
+ DMACH_I2S0_TX,
+ DMACH_I2S0_RX,
+ DMACH_SPI0_TX,
+ DMACH_SPI0_RX,
+ DMACH_MAX,
+ DMACH_MAX,
+ DMACH_MAX,
+ DMACH_MAX,
+ DMACH_SPI1_TX,
+ DMACH_SPI1_RX,
};
struct dma_pl330_platdata s5p6440_pdma_pdata = {
.nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
- .peri = s5p6440_pdma_peri,
+ .peri_id = s5p6440_pdma_peri,
};
-struct dma_pl330_peri s5p6450_pdma_peri[32] = {
- {
- .peri_id = (u8)DMACH_UART0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART3_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART3_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_UART4_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART4_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_I2S0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SPI0_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SPI0_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PCM1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PCM2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_PCM2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_SPI1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_SPI1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_USI_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_USI_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_MAX,
- }, {
- .peri_id = (u8)DMACH_I2S1_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S1_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_I2S2_TX,
- .rqtype = MEMTODEV,
- }, {
- .peri_id = (u8)DMACH_I2S2_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_PWM,
- }, {
- .peri_id = (u8)DMACH_UART5_RX,
- .rqtype = DEVTOMEM,
- }, {
- .peri_id = (u8)DMACH_UART5_TX,
- .rqtype = MEMTODEV,
- },
+u8 s5p6450_pdma_peri[] = {
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART1_RX,
+ DMACH_UART1_TX,
+ DMACH_UART2_RX,
+ DMACH_UART2_TX,
+ DMACH_UART3_RX,
+ DMACH_UART3_TX,
+ DMACH_UART4_RX,
+ DMACH_UART4_TX,
+ DMACH_PCM0_TX,
+ DMACH_PCM0_RX,
+ DMACH_I2S0_TX,
+ DMACH_I2S0_RX,
+ DMACH_SPI0_TX,
+ DMACH_SPI0_RX,
+ DMACH_PCM1_TX,
+ DMACH_PCM1_RX,
+ DMACH_PCM2_TX,
+ DMACH_PCM2_RX,
+ DMACH_SPI1_TX,
+ DMACH_SPI1_RX,
+ DMACH_USI_TX,
+ DMACH_USI_RX,
+ DMACH_MAX,
+ DMACH_I2S1_TX,
+ DMACH_I2S1_RX,
+ DMACH_I2S2_TX,
+ DMACH_I2S2_RX,
+ DMACH_PWM,
+ DMACH_UART5_RX,
+ DMACH_UART5_TX,
};
struct dma_pl330_platdata s5p6450_pdma_pdata = {
.nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
- .peri = s5p6450_pdma_peri,
+ .peri_id = s5p6450_pdma_peri,
};
struct amba_device s5p64x0_device_pdma = {
@@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = {
static int __init s5p64x0_dma_init(void)
{
- if (soc_is_s5p6450())
+ if (soc_is_s5p6450()) {
+ dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
+ dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
- else
+ } else {
+ dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
+ dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
+ }
amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
diff --git a/arch/arm/mach-s5p64x0/include/mach/entry-macro.S b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
index 10b62b4f8211..fbb246d0a3df 100644
--- a/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
+++ b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
@@ -10,7 +10,8 @@
* published by the Free Software Foundation.
*/
-#include <mach/map.h>
-#include <plat/irqs.h>
+ .macro disable_fiq
+ .endm
-#include <asm/entry-macro-vic2.S>
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
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 @@
#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
+#define IRQ_TIMER_BASE (11)
+
/* Set the default NR_IRQS */
#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 @@
#define S3C_PA_RTC S5P64X0_PA_RTC
#define S3C_PA_WDT S5P64X0_PA_WDT
#define S3C_PA_FB S5P64X0_PA_FB
+#define S3C_PA_SPI0 S5P64X0_PA_SPI0
+#define S3C_PA_SPI1 S5P64X0_PA_SPI1
#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
#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 @@
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H __FILE__
-#include <plat/system-reset.h>
-
static void arch_idle(void)
{
/* nothing here yet */
diff --git a/arch/arm/mach-s5p64x0/include/mach/vmalloc.h b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
deleted file mode 100644
index 38dcc71a03cc..000000000000
--- a/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* linux/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C6400 vmalloc definition
-*/
-
-#ifndef __ASM_ARCH_VMALLOC_H
-#define __ASM_ARCH_VMALLOC_H
-
-#define VMALLOC_END 0xF6000000UL
-
-#endif /* __ASM_ARCH_VMALLOC_H */
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 @@
-/* linux/arch/arm/mach-s5p64x0/init.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * S5P64X0 - Init support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-
-#include <mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s5p6440.h>
-#include <plat/s5p6450.h>
-#include <plat/regs-serial.h>
-
-static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
- [0] = {
- .name = "pclk_low",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
- [1] = {
- .name = "uclk1",
- .divisor = 1,
- .min_baud = 0,
- .max_baud = 0,
- },
-};
-
-/* uart registration process */
-
-void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- struct s3c2410_uartcfg *tcfg = cfg;
- u32 ucnt;
-
- for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
- if (!tcfg->clocks) {
- tcfg->clocks = s5p64x0_serial_clocks;
- tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
- }
- }
-}
-
-void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- int uart;
-
- for (uart = 0; uart < no; uart++) {
- s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
- s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
- }
-
- s5p64x0_common_init_uarts(cfg, no);
- s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
-}
-
-void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- s5p64x0_common_init_uarts(cfg, no);
- s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
-}
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 @@
-/* arch/arm/mach-s5p64x0/irq-eint.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
- * http://www.samsung.com/
- *
- * Based on linux/arch/arm/mach-s3c64xx/irq-eint.c
- *
- * S5P64X0 - Interrupt handling for External Interrupts.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <plat/cpu.h>
-#include <plat/regs-irqtype.h>
-#include <plat/gpio-cfg.h>
-#include <plat/pm.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/regs-clock.h>
-
-#define eint_offset(irq) ((irq) - IRQ_EINT(0))
-
-static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type)
-{
- int offs = eint_offset(data->irq);
- int shift;
- u32 ctrl, mask;
- u32 newvalue = 0;
-
- if (offs > 15)
- return -EINVAL;
-
- switch (type) {
- case IRQ_TYPE_NONE:
- printk(KERN_WARNING "No edge setting!\n");
- break;
- case IRQ_TYPE_EDGE_RISING:
- newvalue = S3C2410_EXTINT_RISEEDGE;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- newvalue = S3C2410_EXTINT_FALLEDGE;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- newvalue = S3C2410_EXTINT_BOTHEDGE;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- newvalue = S3C2410_EXTINT_LOWLEV;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- newvalue = S3C2410_EXTINT_HILEV;
- break;
- default:
- printk(KERN_ERR "No such irq type %d", type);
- return -EINVAL;
- }
-
- shift = (offs / 2) * 4;
- mask = 0x7 << shift;
-
- ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask;
- ctrl |= newvalue << shift;
- __raw_writel(ctrl, S5P64X0_EINT0CON0);
-
- /* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
- if (soc_is_s5p6450())
- s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
- else
- s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-/*
- * s5p64x0_irq_demux_eint
- *
- * This function demuxes the IRQ from the group0 external interrupts,
- * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into
- * the specific handlers s5p64x0_irq_demux_eintX_Y.
- */
-static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end)
-{
- u32 status = __raw_readl(S5P64X0_EINT0PEND);
- u32 mask = __raw_readl(S5P64X0_EINT0MASK);
- unsigned int irq;
-
- status &= ~mask;
- status >>= start;
- status &= (1 << (end - start + 1)) - 1;
-
- for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
- if (status & 1)
- generic_handle_irq(irq);
- status >>= 1;
- }
-}
-
-static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
-{
- s5p64x0_irq_demux_eint(0, 3);
-}
-
-static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
-{
- s5p64x0_irq_demux_eint(4, 11);
-}
-
-static void s5p64x0_irq_demux_eint12_15(unsigned int irq,
- struct irq_desc *desc)
-{
- s5p64x0_irq_demux_eint(12, 15);
-}
-
-static int s5p64x0_alloc_gc(void)
-{
- struct irq_chip_generic *gc;
- struct irq_chip_type *ct;
-
- gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE,
- S5P_VA_GPIO, handle_level_irq);
- if (!gc) {
- printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0"
- "external interrupts failed\n", __func__);
- return -EINVAL;
- }
-
- ct = gc->chip_types;
- ct->chip.irq_ack = irq_gc_ack_set_bit;
- ct->chip.irq_mask = irq_gc_mask_set_bit;
- ct->chip.irq_unmask = irq_gc_mask_clr_bit;
- ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
- ct->chip.irq_set_wake = s3c_irqext_wake;
- ct->regs.ack = EINT0PEND_OFFSET;
- ct->regs.mask = EINT0MASK_OFFSET;
- irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
- IRQ_NOREQUEST | IRQ_NOPROBE, 0);
- return 0;
-}
-
-static int __init s5p64x0_init_irq_eint(void)
-{
- int ret = s5p64x0_alloc_gc();
- irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3);
- irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11);
- irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15);
-
- return ret;
-}
-arch_initcall(s5p64x0_init_irq_eint);
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 4a1250cd1356..a40e325d62c8 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -24,9 +24,11 @@
#include <linux/gpio.h>
#include <linux/pwm_backlight.h>
#include <linux/fb.h>
+#include <linux/mmc/host.h>
#include <video/platform_lcd.h>
+#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/irq.h>
@@ -40,7 +42,6 @@
#include <plat/regs-serial.h>
#include <plat/gpio-cfg.h>
-#include <plat/s5p6440.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -52,6 +53,9 @@
#include <plat/backlight.h>
#include <plat/fb.h>
#include <plat/regs-fb.h>
+#include <plat/sdhci.h>
+
+#include "common.h"
#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -161,6 +165,25 @@ static struct platform_device *smdk6440_devices[] __initdata = {
&s5p6440_device_iis,
&s3c_device_fb,
&smdk6440_lcd_lte480wv,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+};
+
+static struct s3c_sdhci_platdata smdk6440_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_NONE,
+};
+
+static struct s3c_sdhci_platdata smdk6440_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+#if defined(CONFIG_S5P64X0_SD_CH1_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdk6440_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_NONE,
};
static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
@@ -201,7 +224,7 @@ static struct platform_pwm_backlight_data smdk6440_bl_data = {
static void __init smdk6440_map_io(void)
{
- s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
+ s5p64x0_init_io(NULL, 0);
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
@@ -234,6 +257,10 @@ static void __init smdk6440_machine_init(void)
s5p6440_set_lcd_interface();
s3c_fb_set_platdata(&smdk6440_lcd_pdata);
+ s3c_sdhci0_set_platdata(&smdk6440_hsmmc0_pdata);
+ s3c_sdhci1_set_platdata(&smdk6440_hsmmc1_pdata);
+ s3c_sdhci2_set_platdata(&smdk6440_hsmmc2_pdata);
+
platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
}
@@ -242,7 +269,9 @@ MACHINE_START(SMDK6440, "SMDK6440")
.atag_offset = 0x100,
.init_irq = s5p6440_init_irq,
+ .handle_irq = vic_handle_irq,
.map_io = smdk6440_map_io,
.init_machine = smdk6440_machine_init,
.timer = &s5p_timer,
+ .restart = s5p64x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 0ab129ecf009..efb69e2f2afe 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -24,9 +24,11 @@
#include <linux/gpio.h>
#include <linux/pwm_backlight.h>
#include <linux/fb.h>
+#include <linux/mmc/host.h>
#include <video/platform_lcd.h>
+#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/irq.h>
@@ -40,7 +42,6 @@
#include <plat/regs-serial.h>
#include <plat/gpio-cfg.h>
-#include <plat/s5p6450.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -52,6 +53,9 @@
#include <plat/backlight.h>
#include <plat/fb.h>
#include <plat/regs-fb.h>
+#include <plat/sdhci.h>
+
+#include "common.h"
#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -179,10 +183,28 @@ static struct platform_device *smdk6450_devices[] __initdata = {
&s5p6450_device_iis0,
&s3c_device_fb,
&smdk6450_lcd_lte480wv,
-
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
/* s5p6450_device_spi0 will be added */
};
+static struct s3c_sdhci_platdata smdk6450_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_NONE,
+};
+
+static struct s3c_sdhci_platdata smdk6450_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_NONE,
+#if defined(CONFIG_S5P64X0_SD_CH1_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdk6450_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_NONE,
+};
+
static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = {
.flags = 0,
.slave_addr = 0x10,
@@ -221,7 +243,7 @@ static struct platform_pwm_backlight_data smdk6450_bl_data = {
static void __init smdk6450_map_io(void)
{
- s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
+ s5p64x0_init_io(NULL, 0);
s3c24xx_init_clocks(19200000);
s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
@@ -254,6 +276,10 @@ static void __init smdk6450_machine_init(void)
s5p6450_set_lcd_interface();
s3c_fb_set_platdata(&smdk6450_lcd_pdata);
+ s3c_sdhci0_set_platdata(&smdk6450_hsmmc0_pdata);
+ s3c_sdhci1_set_platdata(&smdk6450_hsmmc1_pdata);
+ s3c_sdhci2_set_platdata(&smdk6450_hsmmc2_pdata);
+
platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
}
@@ -262,7 +288,9 @@ MACHINE_START(SMDK6450, "SMDK6450")
.atag_offset = 0x100,
.init_irq = s5p6450_init_irq,
+ .handle_irq = vic_handle_irq,
.map_io = smdk6450_map_io,
.init_machine = smdk6450_machine_init,
.timer = &s5p_timer,
+ .restart = s5p64x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
index 69927243d25f..23f9b22439c9 100644
--- a/arch/arm/mach-s5p64x0/pm.c
+++ b/arch/arm/mach-s5p64x0/pm.c
@@ -160,7 +160,7 @@ static void s5p64x0_pm_prepare(void)
}
-static int s5p64x0_pm_add(struct sys_device *sysdev)
+static int s5p64x0_pm_add(struct device *dev)
{
pm_cpu_prep = s5p64x0_pm_prepare;
pm_cpu_sleep = s5p64x0_cpu_suspend;
@@ -169,15 +169,17 @@ static int s5p64x0_pm_add(struct sys_device *sysdev)
return 0;
}
-static struct sysdev_driver s5p64x0_pm_driver = {
- .add = s5p64x0_pm_add,
+static struct subsys_interface s5p64x0_pm_interface = {
+ .name = "s5p64x0_pm",
+ .subsys = &s5p64x0_subsys,
+ .add_dev = s5p64x0_pm_add,
};
static __init int s5p64x0_pm_drvinit(void)
{
s3c_pm_init();
- return sysdev_driver_register(&s5p64x0_sysclass, &s5p64x0_pm_driver);
+ return subsys_interface_register(&s5p64x0_pm_interface);
}
arch_initcall(s5p64x0_pm_drvinit);
diff --git a/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c b/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c
new file mode 100644
index 000000000000..8410af0d12bf
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c
@@ -0,0 +1,104 @@
+/* linux/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P64X0 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/sdhci.h>
+#include <plat/cpu.h>
+
+void s5p64x0_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG pins to special-function 2 */
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgrange_nopull(S5P6450_GPG(0), 2 + width,
+ S3C_GPIO_SFN(2));
+ else
+ s3c_gpio_cfgrange_nopull(S5P6440_GPG(0), 2 + width,
+ S3C_GPIO_SFN(2));
+
+ /* Set GPG[6] pin to special-function 2 - MMC0 CDn */
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ if (soc_is_s5p6450()) {
+ s3c_gpio_setpull(S5P6450_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5P6450_GPG(6), S3C_GPIO_SFN(2));
+ } else {
+ s3c_gpio_setpull(S5P6440_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5P6440_GPG(6), S3C_GPIO_SFN(2));
+ }
+ }
+}
+
+void s5p64x0_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set GPH[0:1] pins to special-function 2 - CLK and CMD */
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgrange_nopull(S5P6450_GPH(0), 2, S3C_GPIO_SFN(2));
+ else
+ s3c_gpio_cfgrange_nopull(S5P6440_GPH(0), 2 , S3C_GPIO_SFN(2));
+
+ switch (width) {
+ case 8:
+ /* Set data pins GPH[6:9] special-function 2 */
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgrange_nopull(S5P6450_GPH(6), 4,
+ S3C_GPIO_SFN(2));
+ else
+ s3c_gpio_cfgrange_nopull(S5P6440_GPH(6), 4,
+ S3C_GPIO_SFN(2));
+ case 4:
+ /* set data pins GPH[2:5] special-function 2 */
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgrange_nopull(S5P6450_GPH(2), 4,
+ S3C_GPIO_SFN(2));
+ else
+ s3c_gpio_cfgrange_nopull(S5P6440_GPH(2), 4,
+ S3C_GPIO_SFN(2));
+ default:
+ break;
+ }
+
+ /* Set GPG[6] pin to special-funtion 3 : MMC1 CDn */
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ if (soc_is_s5p6450()) {
+ s3c_gpio_setpull(S5P6450_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5P6450_GPG(6), S3C_GPIO_SFN(3));
+ } else {
+ s3c_gpio_setpull(S5P6440_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5P6440_GPG(6), S3C_GPIO_SFN(3));
+ }
+ }
+}
+
+void s5p6440_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ /* Set GPC[4:5] pins to special-function 3 - CLK and CMD */
+ s3c_gpio_cfgrange_nopull(S5P6440_GPC(4), 2, S3C_GPIO_SFN(3));
+
+ /* Set data pins GPH[6:9] pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S5P6440_GPH(6), 4, S3C_GPIO_SFN(3));
+}
+
+void s5p6450_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ /* Set all the necessary GPG pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S5P6450_GPG(7), 2 + width, S3C_GPIO_SFN(3));
+}
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 @@
+/* linux/arch/arm/mach-s5p64x0/setup-spi.c
+ *
+ * Copyright (C) 2011 Samsung Electronics Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/s3c64xx-spi.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+};
+
+int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
+{
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgall_range(S5P6450_GPC(0), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(S5P6440_GPC(0), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+};
+
+int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
+{
+ if (soc_is_s5p6450())
+ s3c_gpio_cfgall_range(S5P6450_GPC(4), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(S5P6440_GPC(4), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+#endif