aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r--arch/arm/plat-samsung/Kconfig142
-rw-r--r--arch/arm/plat-samsung/Makefile13
-rw-r--r--arch/arm/plat-samsung/devs.c18
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h379
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c2416.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p-clock.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/sysmmu.h95
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h34
-rw-r--r--arch/arm/plat-samsung/platformdata.c2
-rw-r--r--arch/arm/plat-samsung/s5p-clock.c293
-rw-r--r--arch/arm/plat-samsung/s5p-dev-mfc.c71
-rw-r--r--arch/arm/plat-samsung/s5p-dev-uart.c89
-rw-r--r--arch/arm/plat-samsung/s5p-irq-eint.c218
-rw-r--r--arch/arm/plat-samsung/s5p-irq-gpioint.c215
-rw-r--r--arch/arm/plat-samsung/s5p-irq-pm.c102
-rw-r--r--arch/arm/plat-samsung/s5p-irq.c35
-rw-r--r--arch/arm/plat-samsung/s5p-pm.c40
-rw-r--r--arch/arm/plat-samsung/s5p-sleep.S80
-rw-r--r--arch/arm/plat-samsung/s5p-time.c405
-rw-r--r--arch/arm/plat-samsung/setup-mipiphy.c63
25 files changed, 1785 insertions, 540 deletions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index a0ffc77da809..a2fae4ea0936 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -13,6 +13,24 @@ config PLAT_SAMSUNG
help
Base platform code for all Samsung SoC based systems
+config PLAT_S5P
+ bool
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ default y
+ select ARM_VIC if !ARCH_EXYNOS
+ select ARM_GIC if ARCH_EXYNOS
+ select GIC_NON_BANKED if ARCH_EXYNOS4
+ select NO_IOPORT
+ select ARCH_REQUIRE_GPIOLIB
+ select S3C_GPIO_TRACK
+ select S5P_GPIO_DRVSTR
+ select SAMSUNG_GPIOLIB_4BIT
+ select PLAT_SAMSUNG
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_VIC_TIMER
+ help
+ Base platform code for Samsung's S5P series SoC.
+
if PLAT_SAMSUNG
# boot configurations
@@ -50,6 +68,14 @@ config S3C_LOWLEVEL_UART_PORT
this configuration should be between zero and two. The port
must have been initialised by the boot-loader before use.
+# timer options
+
+config S5P_HRT
+ bool
+ select SAMSUNG_DEV_PWM
+ help
+ Use the High Resolution timer support
+
# clock options
config SAMSUNG_CLKSRC
@@ -58,6 +84,11 @@ config SAMSUNG_CLKSRC
Select the clock code for the clksrc implementation
used by newer systems such as the S3C64XX.
+config S5P_CLOCK
+ def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ help
+ Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
+
# options for IRQ support
config SAMSUNG_IRQ_VIC_TIMER
@@ -65,6 +96,22 @@ config SAMSUNG_IRQ_VIC_TIMER
help
Internal configuration to build the VIC timer interrupt code.
+config S5P_IRQ
+ def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ help
+ Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs
+
+config S5P_EXT_INT
+ bool
+ help
+ Use the external interrupts (other than GPIO interrupts.)
+ Note: Do not choose this for S5P6440 and S5P6450.
+
+config S5P_GPIO_INT
+ bool
+ help
+ Common code for the GPIO interrupts (other than external interrupts.)
+
# options for gpio configuration support
config SAMSUNG_GPIOLIB_4BIT
@@ -117,6 +164,12 @@ config S3C_GPIO_TRACK
Internal configuration option to enable the s3c specific gpio
chip tracking if the platform requires it.
+# uart options
+
+config S5P_DEV_UART
+ def_bool y
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
+
# ADC driver
config S3C_ADC
@@ -274,6 +327,76 @@ config SAMSUNG_DEV_BACKLIGHT
help
Compile in platform device definition LCD backlight with PWM Timer
+config S5P_DEV_CSIS0
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 0
+
+config S5P_DEV_CSIS1
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 1
+
+config S5P_DEV_FIMC0
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 0
+
+config S5P_DEV_FIMC1
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 1
+
+config S5P_DEV_FIMC2
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 2
+
+config S5P_DEV_FIMC3
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 3
+
+config S5P_DEV_FIMD0
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 0
+
+config S5P_DEV_G2D
+ bool
+ help
+ Compile in platform device definitions for G2D device
+
+config S5P_DEV_I2C_HDMIPHY
+ bool
+ help
+ Compile in platform device definitions for I2C HDMIPHY controller
+
+config S5P_DEV_JPEG
+ bool
+ help
+ Compile in platform device definitions for JPEG codec
+
+config S5P_DEV_MFC
+ bool
+ help
+ Compile in setup memory (init) code for MFC
+
+config S5P_DEV_ONENAND
+ bool
+ help
+ Compile in platform device definition for OneNAND controller
+
+config S5P_DEV_TV
+ bool
+ help
+ Compile in platform device definition for TV interface
+
+config S5P_DEV_USB_EHCI
+ bool
+ help
+ Compile in platform device definition for USB EHCI
+
config S3C24XX_PWM
bool "PWM device support"
select HAVE_PWM
@@ -281,6 +404,11 @@ config S3C24XX_PWM
Support for exporting the PWM timer blocks via the pwm device
system
+config S5P_SETUP_MIPIPHY
+ bool
+ help
+ Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+
# DMA
config S3C_DMA
@@ -291,7 +419,7 @@ config S3C_DMA
config SAMSUNG_DMADEV
bool
select DMADEVICES
- select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \
+ select PL330_DMA if (ARCH_EXYNOS5 || ARCH_EXYNOS4 || CPU_S5PV210 || CPU_S5PC100 || \
CPU_S5P6450 || CPU_S5P6440)
select ARM_AMBA
help
@@ -351,6 +479,18 @@ config SAMSUNG_WAKEMASK
and above. This code allows a set of interrupt to wakeup-mask
mappings. See <plat/wakeup-mask.h>
+config S5P_PM
+ bool
+ help
+ Common code for power management support on S5P and newer SoCs
+ Note: Do not select this for S5P6440 and S5P6450.
+
+config S5P_SLEEP
+ bool
+ help
+ Internal config node to apply common S5P sleep management code.
+ Can be selected by S5P and newer SoCs with similar sleep procedure.
+
comment "Power Domain"
config SAMSUNG_PD
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 6012366f33cb..860b2db4db15 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -13,12 +13,18 @@ obj- :=
obj-y += init.o cpu.o
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
+obj-$(CONFIG_S5P_HRT) += s5p-time.o
+
obj-y += clock.o
obj-y += pwm-clock.o
obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
+obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o
obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
+obj-$(CONFIG_S5P_IRQ) += s5p-irq.o
+obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o
+obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o
# ADC
@@ -30,9 +36,13 @@ obj-y += platformdata.o
obj-y += devs.o
obj-y += dev-uart.o
+obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o
+obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o
obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
+obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
+
# DMA support
obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
@@ -47,6 +57,9 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
+obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o
+obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o
+
# PD support
obj-$(CONFIG_SAMSUNG_PD) += pd.o
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 8b928f9bc1c3..1d214cb9d770 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -30,6 +30,7 @@
#include <linux/mmc/host.h>
#include <linux/ioport.h>
#include <linux/platform_data/s3c-hsudc.h>
+#include <linux/platform_data/s3c-hsotg.h>
#include <asm/irq.h>
#include <asm/pmu.h>
@@ -57,7 +58,6 @@
#include <plat/sdhci.h>
#include <plat/ts.h>
#include <plat/udc.h>
-#include <plat/udc-hs.h>
#include <plat/usb-control.h>
#include <plat/usb-phy.h>
#include <plat/regs-iic.h>
@@ -272,16 +272,8 @@ struct platform_device s5p_device_fimc3 = {
#ifdef CONFIG_S5P_DEV_G2D
static struct resource s5p_g2d_resource[] = {
- [0] = {
- .start = S5P_PA_G2D,
- .end = S5P_PA_G2D + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_2D,
- .end = IRQ_2D,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_G2D, SZ_4K),
+ [1] = DEFINE_RES_IRQ(IRQ_2D),
};
struct platform_device s5p_device_g2d = {
@@ -370,7 +362,6 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
- .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc0 = {
@@ -401,7 +392,6 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
- .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc1 = {
@@ -434,7 +424,6 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
- .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc2 = {
@@ -465,7 +454,6 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
- .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc3 = {
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 787ceaca0be8..0721293fad63 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -202,7 +202,7 @@ extern struct bus_type s3c2443_subsys;
extern struct bus_type s3c6410_subsys;
extern struct bus_type s5p64x0_subsys;
extern struct bus_type s5pv210_subsys;
-extern struct bus_type exynos4_subsys;
+extern struct bus_type exynos_subsys;
extern void (*s5pc1xx_idle)(void);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 2155d4af62a3..61ca2f356c52 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -133,7 +133,8 @@ extern struct platform_device exynos4_device_pcm1;
extern struct platform_device exynos4_device_pcm2;
extern struct platform_device exynos4_device_pd[];
extern struct platform_device exynos4_device_spdif;
-extern struct platform_device exynos4_device_sysmmu;
+
+extern struct platform_device exynos_device_drm;
extern struct platform_device samsung_asoc_dma;
extern struct platform_device samsung_asoc_idma;
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 0670f37aaaed..d384a8016b47 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -90,6 +90,7 @@ enum dma_ch {
DMACH_MIPI_HSI5,
DMACH_MIPI_HSI6,
DMACH_MIPI_HSI7,
+ DMACH_DISP1,
DMACH_MTOM_0,
DMACH_MTOM_1,
DMACH_MTOM_2,
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index 0fedf47fa502..536002ff2ab8 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -24,15 +24,16 @@
/**
* struct s3c_fb_pd_win - per window setup data
- * @win_mode: The display parameters to initialise (not for window 0)
+ * @xres : The window X size.
+ * @yres : The window Y size.
* @virtual_x: The virtual X size.
* @virtual_y: The virtual Y size.
*/
struct s3c_fb_pd_win {
- struct fb_videomode win_mode;
-
unsigned short default_bpp;
unsigned short max_bpp;
+ unsigned short xres;
+ unsigned short yres;
unsigned short virtual_x;
unsigned short virtual_y;
};
@@ -45,6 +46,7 @@ struct s3c_fb_pd_win {
* @default_win: default window layer number to be used for UI layer.
* @vidcon0: The base vidcon0 values to control the panel data format.
* @vidcon1: The base vidcon1 values to control the panel data output.
+ * @vtiming: Video timing when connected to a RGB type panel.
* @win: The setup data for each hardware window, or NULL for unused.
* @display_mode: The LCD output display mode.
*
@@ -58,8 +60,7 @@ struct s3c_fb_platdata {
void (*setup_gpio)(void);
struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
-
- u32 default_win;
+ struct fb_videomode *vtiming;
u32 vidcon0;
u32 vidcon1;
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
deleted file mode 100644
index dc90f5ede88f..000000000000
--- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - USB2.0 Highspeed/OtG device block registers
- *
- * 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 __PLAT_S3C64XX_REGS_USB_HSOTG_H
-#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
-
-#define S3C_HSOTG_REG(x) (x)
-
-#define S3C_GOTGCTL S3C_HSOTG_REG(0x000)
-#define S3C_GOTGCTL_BSESVLD (1 << 19)
-#define S3C_GOTGCTL_ASESVLD (1 << 18)
-#define S3C_GOTGCTL_DBNC_SHORT (1 << 17)
-#define S3C_GOTGCTL_CONID_B (1 << 16)
-#define S3C_GOTGCTL_DEVHNPEN (1 << 11)
-#define S3C_GOTGCTL_HSSETHNPEN (1 << 10)
-#define S3C_GOTGCTL_HNPREQ (1 << 9)
-#define S3C_GOTGCTL_HSTNEGSCS (1 << 8)
-#define S3C_GOTGCTL_SESREQ (1 << 1)
-#define S3C_GOTGCTL_SESREQSCS (1 << 0)
-
-#define S3C_GOTGINT S3C_HSOTG_REG(0x004)
-#define S3C_GOTGINT_DbnceDone (1 << 19)
-#define S3C_GOTGINT_ADevTOUTChg (1 << 18)
-#define S3C_GOTGINT_HstNegDet (1 << 17)
-#define S3C_GOTGINT_HstnegSucStsChng (1 << 9)
-#define S3C_GOTGINT_SesReqSucStsChng (1 << 8)
-#define S3C_GOTGINT_SesEndDet (1 << 2)
-
-#define S3C_GAHBCFG S3C_HSOTG_REG(0x008)
-#define S3C_GAHBCFG_PTxFEmpLvl (1 << 8)
-#define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7)
-#define S3C_GAHBCFG_DMAEn (1 << 5)
-#define S3C_GAHBCFG_HBstLen_MASK (0xf << 1)
-#define S3C_GAHBCFG_HBstLen_SHIFT (1)
-#define S3C_GAHBCFG_HBstLen_Single (0x0 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1)
-#define S3C_GAHBCFG_GlblIntrEn (1 << 0)
-
-#define S3C_GUSBCFG S3C_HSOTG_REG(0x00C)
-#define S3C_GUSBCFG_PHYLPClkSel (1 << 15)
-#define S3C_GUSBCFG_HNPCap (1 << 9)
-#define S3C_GUSBCFG_SRPCap (1 << 8)
-#define S3C_GUSBCFG_PHYIf16 (1 << 3)
-#define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0)
-#define S3C_GUSBCFG_TOutCal_SHIFT (0)
-#define S3C_GUSBCFG_TOutCal_LIMIT (0x7)
-#define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0)
-
-#define S3C_GRSTCTL S3C_HSOTG_REG(0x010)
-
-#define S3C_GRSTCTL_AHBIdle (1 << 31)
-#define S3C_GRSTCTL_DMAReq (1 << 30)
-#define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6)
-#define S3C_GRSTCTL_TxFNum_SHIFT (6)
-#define S3C_GRSTCTL_TxFNum_LIMIT (0x1f)
-#define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6)
-#define S3C_GRSTCTL_TxFFlsh (1 << 5)
-#define S3C_GRSTCTL_RxFFlsh (1 << 4)
-#define S3C_GRSTCTL_INTknQFlsh (1 << 3)
-#define S3C_GRSTCTL_FrmCntrRst (1 << 2)
-#define S3C_GRSTCTL_HSftRst (1 << 1)
-#define S3C_GRSTCTL_CSftRst (1 << 0)
-
-#define S3C_GINTSTS S3C_HSOTG_REG(0x014)
-#define S3C_GINTMSK S3C_HSOTG_REG(0x018)
-
-#define S3C_GINTSTS_WkUpInt (1 << 31)
-#define S3C_GINTSTS_SessReqInt (1 << 30)
-#define S3C_GINTSTS_DisconnInt (1 << 29)
-#define S3C_GINTSTS_ConIDStsChng (1 << 28)
-#define S3C_GINTSTS_PTxFEmp (1 << 26)
-#define S3C_GINTSTS_HChInt (1 << 25)
-#define S3C_GINTSTS_PrtInt (1 << 24)
-#define S3C_GINTSTS_FetSusp (1 << 22)
-#define S3C_GINTSTS_incompIP (1 << 21)
-#define S3C_GINTSTS_IncomplSOIN (1 << 20)
-#define S3C_GINTSTS_OEPInt (1 << 19)
-#define S3C_GINTSTS_IEPInt (1 << 18)
-#define S3C_GINTSTS_EPMis (1 << 17)
-#define S3C_GINTSTS_EOPF (1 << 15)
-#define S3C_GINTSTS_ISOutDrop (1 << 14)
-#define S3C_GINTSTS_EnumDone (1 << 13)
-#define S3C_GINTSTS_USBRst (1 << 12)
-#define S3C_GINTSTS_USBSusp (1 << 11)
-#define S3C_GINTSTS_ErlySusp (1 << 10)
-#define S3C_GINTSTS_GOUTNakEff (1 << 7)
-#define S3C_GINTSTS_GINNakEff (1 << 6)
-#define S3C_GINTSTS_NPTxFEmp (1 << 5)
-#define S3C_GINTSTS_RxFLvl (1 << 4)
-#define S3C_GINTSTS_SOF (1 << 3)
-#define S3C_GINTSTS_OTGInt (1 << 2)
-#define S3C_GINTSTS_ModeMis (1 << 1)
-#define S3C_GINTSTS_CurMod_Host (1 << 0)
-
-#define S3C_GRXSTSR S3C_HSOTG_REG(0x01C)
-#define S3C_GRXSTSP S3C_HSOTG_REG(0x020)
-
-#define S3C_GRXSTS_FN_MASK (0x7f << 25)
-#define S3C_GRXSTS_FN_SHIFT (25)
-
-#define S3C_GRXSTS_PktSts_MASK (0xf << 17)
-#define S3C_GRXSTS_PktSts_SHIFT (17)
-#define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17)
-#define S3C_GRXSTS_PktSts_OutRX (0x2 << 17)
-#define S3C_GRXSTS_PktSts_OutDone (0x3 << 17)
-#define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17)
-#define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17)
-
-#define S3C_GRXSTS_DPID_MASK (0x3 << 15)
-#define S3C_GRXSTS_DPID_SHIFT (15)
-#define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4)
-#define S3C_GRXSTS_ByteCnt_SHIFT (4)
-#define S3C_GRXSTS_EPNum_MASK (0xf << 0)
-#define S3C_GRXSTS_EPNum_SHIFT (0)
-
-#define S3C_GRXFSIZ S3C_HSOTG_REG(0x024)
-
-#define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028)
-
-#define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16)
-#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16)
-#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff)
-#define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff)
-#define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0)
-
-#define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C)
-
-#define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24)
-#define S3C_GNPTXSTS_NPtxQTop_SHIFT (24)
-
-#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16)
-#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16)
-#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff)
-
-#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0)
-#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0)
-#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff)
-
-
-#define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100)
-
-#define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
-
-#define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16)
-#define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16)
-#define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff)
-#define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff)
-#define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16)
-
-#define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0)
-#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0)
-
-/* Device mode registers */
-#define S3C_DCFG S3C_HSOTG_REG(0x800)
-
-#define S3C_DCFG_EPMisCnt_MASK (0x1f << 18)
-#define S3C_DCFG_EPMisCnt_SHIFT (18)
-#define S3C_DCFG_EPMisCnt_LIMIT (0x1f)
-#define S3C_DCFG_EPMisCnt(_x) ((_x) << 18)
-
-#define S3C_DCFG_PerFrInt_MASK (0x3 << 11)
-#define S3C_DCFG_PerFrInt_SHIFT (11)
-#define S3C_DCFG_PerFrInt_LIMIT (0x3)
-#define S3C_DCFG_PerFrInt(_x) ((_x) << 11)
-
-#define S3C_DCFG_DevAddr_MASK (0x7f << 4)
-#define S3C_DCFG_DevAddr_SHIFT (4)
-#define S3C_DCFG_DevAddr_LIMIT (0x7f)
-#define S3C_DCFG_DevAddr(_x) ((_x) << 4)
-
-#define S3C_DCFG_NZStsOUTHShk (1 << 2)
-
-#define S3C_DCFG_DevSpd_MASK (0x3 << 0)
-#define S3C_DCFG_DevSpd_SHIFT (0)
-#define S3C_DCFG_DevSpd_HS (0x0 << 0)
-#define S3C_DCFG_DevSpd_FS (0x1 << 0)
-#define S3C_DCFG_DevSpd_LS (0x2 << 0)
-#define S3C_DCFG_DevSpd_FS48 (0x3 << 0)
-
-#define S3C_DCTL S3C_HSOTG_REG(0x804)
-
-#define S3C_DCTL_PWROnPrgDone (1 << 11)
-#define S3C_DCTL_CGOUTNak (1 << 10)
-#define S3C_DCTL_SGOUTNak (1 << 9)
-#define S3C_DCTL_CGNPInNAK (1 << 8)
-#define S3C_DCTL_SGNPInNAK (1 << 7)
-#define S3C_DCTL_TstCtl_MASK (0x7 << 4)
-#define S3C_DCTL_TstCtl_SHIFT (4)
-#define S3C_DCTL_GOUTNakSts (1 << 3)
-#define S3C_DCTL_GNPINNakSts (1 << 2)
-#define S3C_DCTL_SftDiscon (1 << 1)
-#define S3C_DCTL_RmtWkUpSig (1 << 0)
-
-#define S3C_DSTS S3C_HSOTG_REG(0x808)
-
-#define S3C_DSTS_SOFFN_MASK (0x3fff << 8)
-#define S3C_DSTS_SOFFN_SHIFT (8)
-#define S3C_DSTS_SOFFN_LIMIT (0x3fff)
-#define S3C_DSTS_SOFFN(_x) ((_x) << 8)
-#define S3C_DSTS_ErraticErr (1 << 3)
-#define S3C_DSTS_EnumSpd_MASK (0x3 << 1)
-#define S3C_DSTS_EnumSpd_SHIFT (1)
-#define S3C_DSTS_EnumSpd_HS (0x0 << 1)
-#define S3C_DSTS_EnumSpd_FS (0x1 << 1)
-#define S3C_DSTS_EnumSpd_LS (0x2 << 1)
-#define S3C_DSTS_EnumSpd_FS48 (0x3 << 1)
-
-#define S3C_DSTS_SuspSts (1 << 0)
-
-#define S3C_DIEPMSK S3C_HSOTG_REG(0x810)
-
-#define S3C_DIEPMSK_TxFIFOEmpty (1 << 7)
-#define S3C_DIEPMSK_INEPNakEffMsk (1 << 6)
-#define S3C_DIEPMSK_INTknEPMisMsk (1 << 5)
-#define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4)
-#define S3C_DIEPMSK_TimeOUTMsk (1 << 3)
-#define S3C_DIEPMSK_AHBErrMsk (1 << 2)
-#define S3C_DIEPMSK_EPDisbldMsk (1 << 1)
-#define S3C_DIEPMSK_XferComplMsk (1 << 0)
-
-#define S3C_DOEPMSK S3C_HSOTG_REG(0x814)
-
-#define S3C_DOEPMSK_Back2BackSetup (1 << 6)
-#define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4)
-#define S3C_DOEPMSK_SetupMsk (1 << 3)
-#define S3C_DOEPMSK_AHBErrMsk (1 << 2)
-#define S3C_DOEPMSK_EPDisbldMsk (1 << 1)
-#define S3C_DOEPMSK_XferComplMsk (1 << 0)
-
-#define S3C_DAINT S3C_HSOTG_REG(0x818)
-#define S3C_DAINTMSK S3C_HSOTG_REG(0x81C)
-
-#define S3C_DAINT_OutEP_SHIFT (16)
-#define S3C_DAINT_OutEP(x) (1 << ((x) + 16))
-#define S3C_DAINT_InEP(x) (1 << (x))
-
-#define S3C_DTKNQR1 S3C_HSOTG_REG(0x820)
-#define S3C_DTKNQR2 S3C_HSOTG_REG(0x824)
-#define S3C_DTKNQR3 S3C_HSOTG_REG(0x830)
-#define S3C_DTKNQR4 S3C_HSOTG_REG(0x834)
-
-#define S3C_DVBUSDIS S3C_HSOTG_REG(0x828)
-#define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C)
-
-#define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900)
-#define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00)
-#define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
-#define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
-
-/* EP0 specialness:
- * bits[29..28] - reserved (no SetD0PID, SetD1PID)
- * bits[25..22] - should always be zero, this isn't a periodic endpoint
- * bits[10..0] - MPS setting differenct for EP0
-*/
-#define S3C_D0EPCTL_MPS_MASK (0x3 << 0)
-#define S3C_D0EPCTL_MPS_SHIFT (0)
-#define S3C_D0EPCTL_MPS_64 (0x0 << 0)
-#define S3C_D0EPCTL_MPS_32 (0x1 << 0)
-#define S3C_D0EPCTL_MPS_16 (0x2 << 0)
-#define S3C_D0EPCTL_MPS_8 (0x3 << 0)
-
-#define S3C_DxEPCTL_EPEna (1 << 31)
-#define S3C_DxEPCTL_EPDis (1 << 30)
-#define S3C_DxEPCTL_SetD1PID (1 << 29)
-#define S3C_DxEPCTL_SetOddFr (1 << 29)
-#define S3C_DxEPCTL_SetD0PID (1 << 28)
-#define S3C_DxEPCTL_SetEvenFr (1 << 28)
-#define S3C_DxEPCTL_SNAK (1 << 27)
-#define S3C_DxEPCTL_CNAK (1 << 26)
-#define S3C_DxEPCTL_TxFNum_MASK (0xf << 22)
-#define S3C_DxEPCTL_TxFNum_SHIFT (22)
-#define S3C_DxEPCTL_TxFNum_LIMIT (0xf)
-#define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22)
-
-#define S3C_DxEPCTL_Stall (1 << 21)
-#define S3C_DxEPCTL_Snp (1 << 20)
-#define S3C_DxEPCTL_EPType_MASK (0x3 << 18)
-#define S3C_DxEPCTL_EPType_SHIFT (18)
-#define S3C_DxEPCTL_EPType_Control (0x0 << 18)
-#define S3C_DxEPCTL_EPType_Iso (0x1 << 18)
-#define S3C_DxEPCTL_EPType_Bulk (0x2 << 18)
-#define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18)
-
-#define S3C_DxEPCTL_NAKsts (1 << 17)
-#define S3C_DxEPCTL_DPID (1 << 16)
-#define S3C_DxEPCTL_EOFrNum (1 << 16)
-#define S3C_DxEPCTL_USBActEp (1 << 15)
-#define S3C_DxEPCTL_NextEp_MASK (0xf << 11)
-#define S3C_DxEPCTL_NextEp_SHIFT (11)
-#define S3C_DxEPCTL_NextEp_LIMIT (0xf)
-#define S3C_DxEPCTL_NextEp(_x) ((_x) << 11)
-
-#define S3C_DxEPCTL_MPS_MASK (0x7ff << 0)
-#define S3C_DxEPCTL_MPS_SHIFT (0)
-#define S3C_DxEPCTL_MPS_LIMIT (0x7ff)
-#define S3C_DxEPCTL_MPS(_x) ((_x) << 0)
-
-#define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
-#define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
-
-#define S3C_DxEPINT_INEPNakEff (1 << 6)
-#define S3C_DxEPINT_Back2BackSetup (1 << 6)
-#define S3C_DxEPINT_INTknEPMis (1 << 5)
-#define S3C_DxEPINT_INTknTXFEmp (1 << 4)
-#define S3C_DxEPINT_OUTTknEPdis (1 << 4)
-#define S3C_DxEPINT_Timeout (1 << 3)
-#define S3C_DxEPINT_Setup (1 << 3)
-#define S3C_DxEPINT_AHBErr (1 << 2)
-#define S3C_DxEPINT_EPDisbld (1 << 1)
-#define S3C_DxEPINT_XferCompl (1 << 0)
-
-#define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910)
-
-#define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19)
-#define S3C_DIEPTSIZ0_PktCnt_SHIFT (19)
-#define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3)
-#define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19)
-
-#define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0)
-#define S3C_DIEPTSIZ0_XferSize_SHIFT (0)
-#define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f)
-#define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0)
-
-
-#define DOEPTSIZ0 S3C_HSOTG_REG(0xB10)
-#define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29)
-#define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29)
-#define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3)
-#define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29)
-
-#define S3C_DOEPTSIZ0_PktCnt (1 << 19)
-#define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0)
-#define S3C_DOEPTSIZ0_XferSize_SHIFT (0)
-
-#define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
-#define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
-
-#define S3C_DxEPTSIZ_MC_MASK (0x3 << 29)
-#define S3C_DxEPTSIZ_MC_SHIFT (29)
-#define S3C_DxEPTSIZ_MC_LIMIT (0x3)
-#define S3C_DxEPTSIZ_MC(_x) ((_x) << 29)
-
-#define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19)
-#define S3C_DxEPTSIZ_PktCnt_SHIFT (19)
-#define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff)
-#define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff)
-#define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19)
-
-#define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0)
-#define S3C_DxEPTSIZ_XferSize_SHIFT (0)
-#define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff)
-#define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff)
-#define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0)
-
-
-#define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
-#define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
-#define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20))
-
-#define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
-
-#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h
index de2b5bdc5ebd..7178e338e25e 100644
--- a/arch/arm/plat-samsung/include/plat/s3c2416.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2416.h
@@ -24,6 +24,9 @@ extern void s3c2416_init_clocks(int xtal);
extern int s3c2416_baseclk_add(void);
extern void s3c2416_restart(char mode, const char *cmd);
+
+extern struct syscore_ops s3c2416_irq_syscore_ops;
+
#else
#define s3c2416_init_clocks NULL
#define s3c2416_init_uarts NULL
diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h
index 1de4b32f98e9..8364b4bea8b8 100644
--- a/arch/arm/plat-samsung/include/plat/s5p-clock.h
+++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h
@@ -32,8 +32,10 @@ extern struct clk clk_48m;
extern struct clk s5p_clk_27m;
extern struct clk clk_fout_apll;
extern struct clk clk_fout_bpll;
+extern struct clk clk_fout_bpll_div2;
extern struct clk clk_fout_cpll;
extern struct clk clk_fout_mpll;
+extern struct clk clk_fout_mpll_div2;
extern struct clk clk_fout_epll;
extern struct clk clk_fout_dpll;
extern struct clk clk_fout_vpll;
@@ -42,8 +44,10 @@ extern struct clk clk_vpll;
extern struct clksrc_sources clk_src_apll;
extern struct clksrc_sources clk_src_bpll;
+extern struct clksrc_sources clk_src_bpll_fout;
extern struct clksrc_sources clk_src_cpll;
extern struct clksrc_sources clk_src_mpll;
+extern struct clksrc_sources clk_src_mpll_fout;
extern struct clksrc_sources clk_src_epll;
extern struct clksrc_sources clk_src_dpll;
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index e834c5ef437c..151cc9195cf6 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -33,18 +33,12 @@ enum cd_types {
S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
};
-enum clk_types {
- S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */
- S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */
-};
-
/**
* struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
* @max_width: The maximum number of data bits supported.
* @host_caps: Standard MMC host capabilities bit field.
* @host_caps2: The second standard MMC host capabilities bit field.
* @cd_type: Type of Card Detection method (see cd_types enum above)
- * @clk_type: Type of clock divider method (see clk_types enum above)
* @ext_cd_init: Initialize external card detect subsystem. Called on
* sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
* notify_func argument is a callback to the sdhci-s3c driver
@@ -69,7 +63,6 @@ struct s3c_sdhci_platdata {
unsigned int host_caps2;
unsigned int pm_caps;
enum cd_types cd_type;
- enum clk_types clk_type;
int ext_cd_gpio;
bool ext_cd_gpio_invert;
diff --git a/arch/arm/plat-samsung/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h
deleted file mode 100644
index 5fe8ee01a5ba..000000000000
--- a/arch/arm/plat-samsung/include/plat/sysmmu.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung System MMU driver for S5P platform
- *
- * 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 __PLAT_SAMSUNG_SYSMMU_H
-#define __PLAT_SAMSUNG_SYSMMU_H __FILE__
-
-enum S5P_SYSMMU_INTERRUPT_TYPE {
- SYSMMU_PAGEFAULT,
- SYSMMU_AR_MULTIHIT,
- SYSMMU_AW_MULTIHIT,
- SYSMMU_BUSERROR,
- SYSMMU_AR_SECURITY,
- SYSMMU_AR_ACCESS,
- SYSMMU_AW_SECURITY,
- SYSMMU_AW_PROTECTION, /* 7 */
- SYSMMU_FAULTS_NUM
-};
-
-#ifdef CONFIG_S5P_SYSTEM_MMU
-
-#include <mach/sysmmu.h>
-
-/**
- * s5p_sysmmu_enable() - enable system mmu of ip
- * @ips: The ip connected system mmu.
- * #pgd: Base physical address of the 1st level page table
- *
- * This function enable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_disable() - disable sysmmu mmu of ip
- * @ips: The ip connected system mmu.
- *
- * This function disable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_disable(sysmmu_ips ips);
-
-/**
- * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
- * @ips: The ip connected system mmu.
- * @pgd: The page table base address.
- *
- * This function set page table base address
- * When system mmu transfer address from virtaul address to physical address,
- * system mmu refer address information from page table
- */
-void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
- * @ips: The ip connected system mmu.
- *
- * This function flush all TLB entry in system mmu
- */
-void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
-
-/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
- * @itype: type of fault.
- * @pgtable_base: the physical address of page table base. This is 0 if @ips is
- * SYSMMU_BUSERROR.
- * @fault_addr: the device (virtual) address that the System MMU tried to
- * translated. This is 0 if @ips is SYSMMU_BUSERROR.
- * Called when interrupt occurred by the System MMUs
- * The device drivers of peripheral devices that has a System MMU can implement
- * a fault handler to resolve address translation fault by System MMU.
- * The meanings of return value and parameters are described below.
-
- * return value: non-zero if the fault is correctly resolved.
- * zero if the fault is not handled.
- */
-void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
- int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr));
-#else
-#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
-#define s5p_sysmmu_disable(ips) do { } while (0)
-#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
-#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
-#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
-#endif
-#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
deleted file mode 100644
index c9e3667cb2b1..000000000000
--- a/arch/arm/plat-samsung/include/plat/udc-hs.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/udc-hs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C USB2.0 High-speed / OtG platform information
- *
- * 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.
-*/
-
-enum s3c_hsotg_dmamode {
- S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */
- S3C_HSOTG_DMA_ONLY, /* always use DMA */
- S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */
-};
-
-/**
- * struct s3c_hsotg_plat - platform data for high-speed otg/udc
- * @dma: Whether to use DMA or not.
- * @is_osc: The clock source is an oscillator, not a crystal
- */
-struct s3c_hsotg_plat {
- enum s3c_hsotg_dmamode dma;
- unsigned int is_osc : 1;
-
- int (*phy_init)(struct platform_device *pdev, int type);
- int (*phy_exit)(struct platform_device *pdev, int type);
-};
-
-extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd);
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
index fa78aa710ed1..b430e9946287 100644
--- a/arch/arm/plat-samsung/platformdata.c
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -57,6 +57,4 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
set->host_caps2 |= pd->host_caps2;
if (pd->pm_caps)
set->pm_caps |= pd->pm_caps;
- if (pd->clk_type)
- set->clk_type = pd->clk_type;
}
diff --git a/arch/arm/plat-samsung/s5p-clock.c b/arch/arm/plat-samsung/s5p-clock.c
new file mode 100644
index 000000000000..031a61899bef
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-clock.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Common clock 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p-clock.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * clk_ext_xtal_mux.
+*/
+struct clk clk_ext_xtal_mux = {
+ .name = "ext_xtal",
+ .id = -1,
+};
+
+struct clk clk_xusbxti = {
+ .name = "xusbxti",
+ .id = -1,
+};
+
+struct clk s5p_clk_27m = {
+ .name = "clk_27m",
+ .id = -1,
+ .rate = 27000000,
+};
+
+/* 48MHz USB Phy clock output */
+struct clk clk_48m = {
+ .name = "clk_48m",
+ .id = -1,
+ .rate = 48000000,
+};
+
+/* APLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_apll = {
+ .name = "fout_apll",
+ .id = -1,
+};
+
+/* BPLL clock output */
+
+struct clk clk_fout_bpll = {
+ .name = "fout_bpll",
+ .id = -1,
+};
+
+struct clk clk_fout_bpll_div2 = {
+ .name = "fout_bpll_div2",
+ .id = -1,
+};
+
+/* CPLL clock output */
+
+struct clk clk_fout_cpll = {
+ .name = "fout_cpll",
+ .id = -1,
+};
+
+/* MPLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_mpll = {
+ .name = "fout_mpll",
+ .id = -1,
+};
+
+struct clk clk_fout_mpll_div2 = {
+ .name = "fout_mpll_div2",
+ .id = -1,
+};
+
+/* EPLL clock output */
+struct clk clk_fout_epll = {
+ .name = "fout_epll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* DPLL clock output */
+struct clk clk_fout_dpll = {
+ .name = "fout_dpll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* VPLL clock output */
+struct clk clk_fout_vpll = {
+ .name = "fout_vpll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* Possible clock sources for APLL Mux */
+static struct clk *clk_src_apll_list[] = {
+ [0] = &clk_fin_apll,
+ [1] = &clk_fout_apll,
+};
+
+struct clksrc_sources clk_src_apll = {
+ .sources = clk_src_apll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_apll_list),
+};
+
+/* Possible clock sources for BPLL Mux */
+static struct clk *clk_src_bpll_list[] = {
+ [0] = &clk_fin_bpll,
+ [1] = &clk_fout_bpll,
+};
+
+struct clksrc_sources clk_src_bpll = {
+ .sources = clk_src_bpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_bpll_list),
+};
+
+static struct clk *clk_src_bpll_fout_list[] = {
+ [0] = &clk_fout_bpll_div2,
+ [1] = &clk_fout_bpll,
+};
+
+struct clksrc_sources clk_src_bpll_fout = {
+ .sources = clk_src_bpll_fout_list,
+ .nr_sources = ARRAY_SIZE(clk_src_bpll_fout_list),
+};
+
+/* Possible clock sources for CPLL Mux */
+static struct clk *clk_src_cpll_list[] = {
+ [0] = &clk_fin_cpll,
+ [1] = &clk_fout_cpll,
+};
+
+struct clksrc_sources clk_src_cpll = {
+ .sources = clk_src_cpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_cpll_list),
+};
+
+/* Possible clock sources for MPLL Mux */
+static struct clk *clk_src_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &clk_fout_mpll,
+};
+
+struct clksrc_sources clk_src_mpll = {
+ .sources = clk_src_mpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
+};
+
+static struct clk *clk_src_mpll_fout_list[] = {
+ [0] = &clk_fout_mpll_div2,
+ [1] = &clk_fout_mpll,
+};
+
+struct clksrc_sources clk_src_mpll_fout = {
+ .sources = clk_src_mpll_fout_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_fout_list),
+};
+
+/* Possible clock sources for EPLL Mux */
+static struct clk *clk_src_epll_list[] = {
+ [0] = &clk_fin_epll,
+ [1] = &clk_fout_epll,
+};
+
+struct clksrc_sources clk_src_epll = {
+ .sources = clk_src_epll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_epll_list),
+};
+
+/* Possible clock sources for DPLL Mux */
+static struct clk *clk_src_dpll_list[] = {
+ [0] = &clk_fin_dpll,
+ [1] = &clk_fout_dpll,
+};
+
+struct clksrc_sources clk_src_dpll = {
+ .sources = clk_src_dpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_dpll_list),
+};
+
+struct clk clk_vpll = {
+ .name = "vpll",
+ .id = -1,
+};
+
+int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ u32 con;
+
+ con = __raw_readl(reg);
+ con = enable ? (con | ctrlbit) : (con & ~ctrlbit);
+ __raw_writel(con, reg);
+ return 0;
+}
+
+int s5p_epll_enable(struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+ if (enable)
+ __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+ else
+ __raw_writel(epll_con, S5P_EPLL_CON);
+
+ return 0;
+}
+
+unsigned long s5p_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+int s5p_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+unsigned long s5p_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(pclk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+struct clk_ops s5p_sclk_spdif_ops = {
+ .set_rate = s5p_spdif_set_rate,
+ .get_rate = s5p_spdif_get_rate,
+};
+
+static struct clk *s5p_clks[] __initdata = {
+ &clk_ext_xtal_mux,
+ &clk_48m,
+ &s5p_clk_27m,
+ &clk_fout_apll,
+ &clk_fout_mpll,
+ &clk_fout_epll,
+ &clk_fout_dpll,
+ &clk_fout_vpll,
+ &clk_vpll,
+ &clk_xusbxti,
+};
+
+void __init s5p_register_clocks(unsigned long xtal_freq)
+{
+ int ret;
+
+ clk_ext_xtal_mux.rate = xtal_freq;
+
+ ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks));
+ if (ret > 0)
+ printk(KERN_ERR "Failed to register s5p clocks\n");
+}
diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c
new file mode 100644
index 000000000000..ad6089465e2a
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-dev-mfc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
+ *
+ * Base S5P MFC resource and device definitions
+ *
+ * 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/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/memblock.h>
+#include <linux/ioport.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/irqs.h>
+#include <plat/mfc.h>
+
+struct s5p_mfc_reserved_mem {
+ phys_addr_t base;
+ unsigned long size;
+ struct device *dev;
+};
+
+static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
+
+void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
+ phys_addr_t lbase, unsigned int lsize)
+{
+ int i;
+
+ s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev;
+ s5p_mfc_mem[0].base = rbase;
+ s5p_mfc_mem[0].size = rsize;
+
+ s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev;
+ s5p_mfc_mem[1].base = lbase;
+ s5p_mfc_mem[1].size = lsize;
+
+ for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
+ struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
+ if (memblock_remove(area->base, area->size)) {
+ printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n",
+ area->size, (unsigned long) area->base);
+ area->base = 0;
+ }
+ }
+}
+
+static int __init s5p_mfc_memory_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
+ struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
+ if (!area->base)
+ continue;
+
+ if (dma_declare_coherent_memory(area->dev, area->base,
+ area->base, area->size,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0)
+ printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n",
+ area->size, (unsigned long) area->base);
+ }
+ return 0;
+}
+device_initcall(s5p_mfc_memory_init);
diff --git a/arch/arm/plat-samsung/s5p-dev-uart.c b/arch/arm/plat-samsung/s5p-dev-uart.c
new file mode 100644
index 000000000000..cafa3deddcc1
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-dev-uart.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009,2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base S5P UART resource and device definitions
+ *
+ * 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/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+ /* Serial port registrations */
+
+static struct resource s5p_uart0_resource[] = {
+ [0] = DEFINE_RES_MEM(S5P_PA_UART0, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART0),
+};
+
+static struct resource s5p_uart1_resource[] = {
+ [0] = DEFINE_RES_MEM(S5P_PA_UART1, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART1),
+};
+
+static struct resource s5p_uart2_resource[] = {
+ [0] = DEFINE_RES_MEM(S5P_PA_UART2, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART2),
+};
+
+static struct resource s5p_uart3_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+ [0] = DEFINE_RES_MEM(S5P_PA_UART3, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART3),
+#endif
+};
+
+static struct resource s5p_uart4_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+ [0] = DEFINE_RES_MEM(S5P_PA_UART4, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART4),
+#endif
+};
+
+static struct resource s5p_uart5_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+ [0] = DEFINE_RES_MEM(S5P_PA_UART5, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART5),
+#endif
+};
+
+struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s5p_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart0_resource),
+ },
+ [1] = {
+ .resources = s5p_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart1_resource),
+ },
+ [2] = {
+ .resources = s5p_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart2_resource),
+ },
+ [3] = {
+ .resources = s5p_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart3_resource),
+ },
+ [4] = {
+ .resources = s5p_uart4_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart4_resource),
+ },
+ [5] = {
+ .resources = s5p_uart5_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart5_resource),
+ },
+};
diff --git a/arch/arm/plat-samsung/s5p-irq-eint.c b/arch/arm/plat-samsung/s5p-irq-eint.c
new file mode 100644
index 000000000000..33bd3f3d20f5
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-irq-eint.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P - IRQ EINT 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+
+#include <asm/hardware/vic.h>
+
+#include <plat/regs-irqtype.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+
+static inline void s5p_irq_eint_mask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask |= eint_irq_to_bit(data->irq);
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+}
+
+static void s5p_irq_eint_unmask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask &= ~(eint_irq_to_bit(data->irq));
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+}
+
+static inline void s5p_irq_eint_ack(struct irq_data *data)
+{
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+}
+
+static void s5p_irq_eint_maskack(struct irq_data *data)
+{
+ /* compiler should in-line these */
+ s5p_irq_eint_mask(data);
+ s5p_irq_eint_ack(data);
+}
+
+static int s5p_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;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -EINVAL;
+ }
+
+ shift = (offs & 0x7) * 4;
+ mask = 0x7 << shift;
+
+ ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
+
+ if ((0 <= offs) && (offs < 8))
+ s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
+
+ else if ((8 <= offs) && (offs < 16))
+ s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
+
+ else if ((16 <= offs) && (offs < 24))
+ s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
+
+ else if ((24 <= offs) && (offs < 32))
+ s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
+
+ else
+ printk(KERN_ERR "No such irq number %d", offs);
+
+ return 0;
+}
+
+static struct irq_chip s5p_irq_eint = {
+ .name = "s5p-eint",
+ .irq_mask = s5p_irq_eint_mask,
+ .irq_unmask = s5p_irq_eint_unmask,
+ .irq_mask_ack = s5p_irq_eint_maskack,
+ .irq_ack = s5p_irq_eint_ack,
+ .irq_set_type = s5p_irq_eint_set_type,
+#ifdef CONFIG_PM
+ .irq_set_wake = s3c_irqext_wake,
+#endif
+};
+
+/* s5p_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from EINTs 16 to 31. It is designed to be inlined into the specific
+ * handler s5p_irq_demux_eintX_Y.
+ *
+ * Each EINT pend/mask registers handle eight of them.
+ */
+static inline void s5p_irq_demux_eint(unsigned int start)
+{
+ u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
+ u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+ unsigned int irq;
+
+ status &= ~mask;
+ status &= 0xff;
+
+ while (status) {
+ irq = fls(status) - 1;
+ generic_handle_irq(irq + start);
+ status &= ~(1 << irq);
+ }
+}
+
+static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+ s5p_irq_demux_eint(IRQ_EINT(16));
+ s5p_irq_demux_eint(IRQ_EINT(24));
+}
+
+static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(data);
+
+ s5p_irq_eint_mask(data);
+ writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void s5p_irq_vic_eint_unmask(struct irq_data *data)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(data);
+
+ s5p_irq_eint_unmask(data);
+ writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE);
+}
+
+static inline void s5p_irq_vic_eint_ack(struct irq_data *data)
+{
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+}
+
+static void s5p_irq_vic_eint_maskack(struct irq_data *data)
+{
+ s5p_irq_vic_eint_mask(data);
+ s5p_irq_vic_eint_ack(data);
+}
+
+static struct irq_chip s5p_irq_vic_eint = {
+ .name = "s5p_vic_eint",
+ .irq_mask = s5p_irq_vic_eint_mask,
+ .irq_unmask = s5p_irq_vic_eint_unmask,
+ .irq_mask_ack = s5p_irq_vic_eint_maskack,
+ .irq_ack = s5p_irq_vic_eint_ack,
+ .irq_set_type = s5p_irq_eint_set_type,
+#ifdef CONFIG_PM
+ .irq_set_wake = s3c_irqext_wake,
+#endif
+};
+
+static int __init s5p_init_irq_eint(void)
+{
+ int irq;
+
+ for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++)
+ irq_set_chip(irq, &s5p_irq_vic_eint);
+
+ for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
+ irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31);
+ return 0;
+}
+
+arch_initcall(s5p_init_irq_eint);
diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c
new file mode 100644
index 000000000000..f9431fe5b06e
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include <mach/map.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+
+#include <asm/mach/irq.h>
+
+#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u)
+
+#define CON_OFFSET 0x700
+#define MASK_OFFSET 0x900
+#define PEND_OFFSET 0xA00
+#define REG_OFFSET(x) ((x) << 2)
+
+struct s5p_gpioint_bank {
+ struct list_head list;
+ int start;
+ int nr_groups;
+ int irq;
+ struct samsung_gpio_chip **chips;
+ void (*handler)(unsigned int, struct irq_desc *);
+};
+
+static LIST_HEAD(banks);
+
+static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = gc->chip_types;
+ unsigned int shift = (d->irq - gc->irq_base) << 2;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ type = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ type = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ type = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ type = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ type = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+ case IRQ_TYPE_NONE:
+ default:
+ printk(KERN_WARNING "No irq type\n");
+ return -EINVAL;
+ }
+
+ gc->type_cache &= ~(0x7 << shift);
+ gc->type_cache |= type << shift;
+ writel(gc->type_cache, gc->reg_base + ct->regs.type);
+ return 0;
+}
+
+static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
+ int group, pend_offset, mask_offset;
+ unsigned int pend, mask;
+
+ struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
+
+ for (group = 0; group < bank->nr_groups; group++) {
+ struct samsung_gpio_chip *chip = bank->chips[group];
+ if (!chip)
+ continue;
+
+ pend_offset = REG_OFFSET(group);
+ pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
+ if (!pend)
+ continue;
+
+ mask_offset = REG_OFFSET(group);
+ mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+ pend &= ~mask;
+
+ while (pend) {
+ int offset = fls(pend) - 1;
+ int real_irq = chip->irq_base + offset;
+ generic_handle_irq(real_irq);
+ pend &= ~BIT(offset);
+ }
+ }
+ chained_irq_exit(chip, desc);
+}
+
+static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip)
+{
+ static int used_gpioint_groups = 0;
+ int group = chip->group;
+ struct s5p_gpioint_bank *b, *bank = NULL;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
+ return -ENOMEM;
+
+ list_for_each_entry(b, &banks, list) {
+ if (group >= b->start && group < b->start + b->nr_groups) {
+ bank = b;
+ break;
+ }
+ }
+ if (!bank)
+ return -EINVAL;
+
+ if (!bank->handler) {
+ bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) *
+ bank->nr_groups, GFP_KERNEL);
+ if (!bank->chips)
+ return -ENOMEM;
+
+ irq_set_chained_handler(bank->irq, s5p_gpioint_handler);
+ irq_set_handler_data(bank->irq, bank);
+ bank->handler = s5p_gpioint_handler;
+ printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
+ bank->irq);
+ }
+
+ /*
+ * chained GPIO irq has been successfully registered, allocate new gpio
+ * int group and assign irq nubmers
+ */
+ chip->irq_base = S5P_GPIOINT_BASE +
+ used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
+ used_gpioint_groups++;
+
+ bank->chips[group - bank->start] = chip;
+
+ gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
+ (void __iomem *)GPIO_BASE(chip),
+ handle_level_irq);
+ if (!gc)
+ return -ENOMEM;
+ 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 = s5p_gpioint_set_type,
+ ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start);
+ ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start);
+ ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start);
+ irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
+ IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+ return 0;
+}
+
+int __init s5p_register_gpio_interrupt(int pin)
+{
+ struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin);
+ int offset, group;
+ int ret;
+
+ if (!my_chip)
+ return -EINVAL;
+
+ offset = pin - my_chip->chip.base;
+ group = my_chip->group;
+
+ /* check if the group has been already registered */
+ if (my_chip->irq_base)
+ return my_chip->irq_base + offset;
+
+ /* register gpio group */
+ ret = s5p_gpioint_add(my_chip);
+ if (ret == 0) {
+ my_chip->chip.to_irq = samsung_gpiolib_to_irq;
+ printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
+ group);
+ return my_chip->irq_base + offset;
+ }
+ return ret;
+}
+
+int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
+{
+ struct s5p_gpioint_bank *bank;
+
+ bank = kzalloc(sizeof(*bank), GFP_KERNEL);
+ if (!bank)
+ return -ENOMEM;
+
+ bank->start = start;
+ bank->nr_groups = nr_groups;
+ bank->irq = chain_irq;
+
+ list_add_tail(&bank->list, &banks);
+ return 0;
+}
diff --git a/arch/arm/plat-samsung/s5p-irq-pm.c b/arch/arm/plat-samsung/s5p-irq-pm.c
new file mode 100644
index 000000000000..7c1e3b7072fc
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-irq-pm.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/plat-s3c24xx/irq-pm.c,
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include <plat/cpu.h>
+#include <plat/irqs.h>
+#include <plat/pm.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
+ * as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow = 0x00000006L;
+unsigned long s3c_irqwake_eintallow = 0xffffffffL;
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long irqbit;
+ unsigned int irq_rtc_tic, irq_rtc_alarm;
+
+#ifdef CONFIG_ARCH_EXYNOS
+ if (soc_is_exynos5250()) {
+ irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC;
+ irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM;
+ } else {
+ irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC;
+ irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM;
+ }
+#else
+ irq_rtc_tic = IRQ_RTC_TIC;
+ irq_rtc_alarm = IRQ_RTC_ALARM;
+#endif
+
+ if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) {
+ irqbit = 1 << (data->irq + 1 - irq_rtc_alarm);
+
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+ } else {
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+static struct sleep_save eint_save[] = {
+ SAVE_ITEM(S5P_EINT_CON(0)),
+ SAVE_ITEM(S5P_EINT_CON(1)),
+ SAVE_ITEM(S5P_EINT_CON(2)),
+ SAVE_ITEM(S5P_EINT_CON(3)),
+
+ SAVE_ITEM(S5P_EINT_FLTCON(0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(1)),
+ SAVE_ITEM(S5P_EINT_FLTCON(2)),
+ SAVE_ITEM(S5P_EINT_FLTCON(3)),
+ SAVE_ITEM(S5P_EINT_FLTCON(4)),
+ SAVE_ITEM(S5P_EINT_FLTCON(5)),
+ SAVE_ITEM(S5P_EINT_FLTCON(6)),
+ SAVE_ITEM(S5P_EINT_FLTCON(7)),
+
+ SAVE_ITEM(S5P_EINT_MASK(0)),
+ SAVE_ITEM(S5P_EINT_MASK(1)),
+ SAVE_ITEM(S5P_EINT_MASK(2)),
+ SAVE_ITEM(S5P_EINT_MASK(3)),
+};
+
+int s3c24xx_irq_suspend(void)
+{
+ s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
+
+ return 0;
+}
+
+void s3c24xx_irq_resume(void)
+{
+ s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
+}
+
diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
new file mode 100644
index 000000000000..dfb47d638f03
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Interrupt handling
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/cpu.h>
+#include <plat/irq-vic-timer.h>
+
+void __init s5p_init_irq(u32 *vic, u32 num_vic)
+{
+#ifdef CONFIG_ARM_VIC
+ int irq;
+
+ /* initialize the VICs */
+ for (irq = 0; irq < num_vic; irq++)
+ vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
+#endif
+
+ s3c_init_vic_timer_irq(5, IRQ_TIMER0);
+}
diff --git a/arch/arm/plat-samsung/s5p-pm.c b/arch/arm/plat-samsung/s5p-pm.c
new file mode 100644
index 000000000000..0747468f0936
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-pm.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P Power Manager (Suspend-To-RAM) support
+ *
+ * Based on arch/arm/plat-s3c24xx/pm.c
+ * Copyright (c) 2004,2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/suspend.h>
+#include <plat/pm.h>
+
+#define PFX "s5p pm: "
+
+/* s3c_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+void s3c_pm_configure_extint(void)
+{
+ /* nothing here yet */
+}
+
+void s3c_pm_restore_core(void)
+{
+ /* nothing here yet */
+}
+
+void s3c_pm_save_core(void)
+{
+ /* nothing here yet */
+}
+
diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
new file mode 100644
index 000000000000..bdf6dadf8790
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-sleep.S
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common S5P Sleep Code
+ * Based on S3C64XX sleep code by:
+ * Ben Dooks, (c) 2008 Simtec Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*
+ * The following code is located into the .data section. This is to
+ * allow l2x0_regs_phys to be accessed with a relative load while we
+ * can't rely on any MMU translation. We could have put l2x0_regs_phys
+ * in the .text section as well, but some setups might insist on it to
+ * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
+ */
+ .data
+ .align
+
+ /*
+ * sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+ /*
+ * s3c_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ */
+
+ENTRY(s3c_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+ adr r0, l2x0_regs_phys
+ ldr r0, [r0]
+ ldr r1, [r0, #L2X0_R_PHY_BASE]
+ ldr r2, [r1, #L2X0_CTRL]
+ tst r2, #0x1
+ bne resume_l2on
+ ldr r2, [r0, #L2X0_R_AUX_CTRL]
+ str r2, [r1, #L2X0_AUX_CTRL]
+ ldr r2, [r0, #L2X0_R_TAG_LATENCY]
+ str r2, [r1, #L2X0_TAG_LATENCY_CTRL]
+ ldr r2, [r0, #L2X0_R_DATA_LATENCY]
+ str r2, [r1, #L2X0_DATA_LATENCY_CTRL]
+ ldr r2, [r0, #L2X0_R_PREFETCH_CTRL]
+ str r2, [r1, #L2X0_PREFETCH_CTRL]
+ ldr r2, [r0, #L2X0_R_PWR_CTRL]
+ str r2, [r1, #L2X0_POWER_CTRL]
+ mov r2, #1
+ str r2, [r1, #L2X0_CTRL]
+resume_l2on:
+#endif
+ b cpu_resume
+ENDPROC(s3c_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+ .globl l2x0_regs_phys
+l2x0_regs_phys:
+ .long 0
+#endif
diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/s5p-time.c
new file mode 100644
index 000000000000..028b6e877eb9
--- /dev/null
+++ b/arch/arm/plat-samsung/s5p-time.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Common hr-timer 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+
+#include <asm/smp_twd.h>
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/sched_clock.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
+#include <plat/s5p-time.h>
+
+static struct clk *tin_event;
+static struct clk *tin_source;
+static struct clk *tdiv_event;
+static struct clk *tdiv_source;
+static struct clk *timerclk;
+static struct s5p_timer_source timer_source;
+static unsigned long clock_count_per_tick;
+static void s5p_timer_resume(void);
+
+static void s5p_time_stop(enum s5p_timer_mode mode)
+{
+ unsigned long tcon;
+
+ tcon = __raw_readl(S3C2410_TCON);
+
+ switch (mode) {
+ case S5P_PWM0:
+ tcon &= ~S3C2410_TCON_T0START;
+ break;
+
+ case S5P_PWM1:
+ tcon &= ~S3C2410_TCON_T1START;
+ break;
+
+ case S5P_PWM2:
+ tcon &= ~S3C2410_TCON_T2START;
+ break;
+
+ case S5P_PWM3:
+ tcon &= ~S3C2410_TCON_T3START;
+ break;
+
+ case S5P_PWM4:
+ tcon &= ~S3C2410_TCON_T4START;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", mode);
+ break;
+ }
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
+{
+ unsigned long tcon;
+
+ tcon = __raw_readl(S3C2410_TCON);
+
+ tcnt--;
+
+ switch (mode) {
+ case S5P_PWM0:
+ tcon &= ~(0x0f << 0);
+ tcon |= S3C2410_TCON_T0MANUALUPD;
+ break;
+
+ case S5P_PWM1:
+ tcon &= ~(0x0f << 8);
+ tcon |= S3C2410_TCON_T1MANUALUPD;
+ break;
+
+ case S5P_PWM2:
+ tcon &= ~(0x0f << 12);
+ tcon |= S3C2410_TCON_T2MANUALUPD;
+ break;
+
+ case S5P_PWM3:
+ tcon &= ~(0x0f << 16);
+ tcon |= S3C2410_TCON_T3MANUALUPD;
+ break;
+
+ case S5P_PWM4:
+ tcon &= ~(0x07 << 20);
+ tcon |= S3C2410_TCON_T4MANUALUPD;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", mode);
+ break;
+ }
+
+ __raw_writel(tcnt, S3C2410_TCNTB(mode));
+ __raw_writel(tcnt, S3C2410_TCMPB(mode));
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
+{
+ unsigned long tcon;
+
+ tcon = __raw_readl(S3C2410_TCON);
+
+ switch (mode) {
+ case S5P_PWM0:
+ tcon |= S3C2410_TCON_T0START;
+ tcon &= ~S3C2410_TCON_T0MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T0RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T0RELOAD;
+ break;
+
+ case S5P_PWM1:
+ tcon |= S3C2410_TCON_T1START;
+ tcon &= ~S3C2410_TCON_T1MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T1RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T1RELOAD;
+ break;
+
+ case S5P_PWM2:
+ tcon |= S3C2410_TCON_T2START;
+ tcon &= ~S3C2410_TCON_T2MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T2RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T2RELOAD;
+ break;
+
+ case S5P_PWM3:
+ tcon |= S3C2410_TCON_T3START;
+ tcon &= ~S3C2410_TCON_T3MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T3RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T3RELOAD;
+ break;
+
+ case S5P_PWM4:
+ tcon |= S3C2410_TCON_T4START;
+ tcon &= ~S3C2410_TCON_T4MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T4RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T4RELOAD;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", mode);
+ break;
+ }
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static int s5p_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ s5p_time_setup(timer_source.event_id, cycles);
+ s5p_time_start(timer_source.event_id, NON_PERIODIC);
+
+ return 0;
+}
+
+static void s5p_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ s5p_time_stop(timer_source.event_id);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+ s5p_time_start(timer_source.event_id, PERIODIC);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ s5p_timer_resume();
+ break;
+ }
+}
+
+static void s5p_timer_resume(void)
+{
+ /* event timer restart */
+ s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+ s5p_time_start(timer_source.event_id, PERIODIC);
+
+ /* source timer restart */
+ s5p_time_setup(timer_source.source_id, TCNT_MAX);
+ s5p_time_start(timer_source.source_id, PERIODIC);
+}
+
+void __init s5p_set_timer_source(enum s5p_timer_mode event,
+ enum s5p_timer_mode source)
+{
+ s3c_device_timer[event].dev.bus = &platform_bus_type;
+ s3c_device_timer[source].dev.bus = &platform_bus_type;
+
+ timer_source.event_id = event;
+ timer_source.source_id = source;
+}
+
+static struct clock_event_device time_event_device = {
+ .name = "s5p_event_timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = s5p_set_next_event,
+ .set_mode = s5p_set_mode,
+};
+
+static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction s5p_clock_event_irq = {
+ .name = "s5p_time_irq",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = s5p_clock_event_isr,
+ .dev_id = &time_event_device,
+};
+
+static void __init s5p_clockevent_init(void)
+{
+ unsigned long pclk;
+ unsigned long clock_rate;
+ unsigned int irq_number;
+ struct clk *tscaler;
+
+ pclk = clk_get_rate(timerclk);
+
+ tscaler = clk_get_parent(tdiv_event);
+
+ clk_set_rate(tscaler, pclk / 2);
+ clk_set_rate(tdiv_event, pclk / 2);
+ clk_set_parent(tin_event, tdiv_event);
+
+ clock_rate = clk_get_rate(tin_event);
+ clock_count_per_tick = clock_rate / HZ;
+
+ clockevents_calc_mult_shift(&time_event_device,
+ clock_rate, S5PTIMER_MIN_RANGE);
+ time_event_device.max_delta_ns =
+ clockevent_delta2ns(-1, &time_event_device);
+ time_event_device.min_delta_ns =
+ clockevent_delta2ns(1, &time_event_device);
+
+ time_event_device.cpumask = cpumask_of(0);
+ clockevents_register_device(&time_event_device);
+
+ irq_number = timer_source.event_id + IRQ_TIMER0;
+ setup_irq(irq_number, &s5p_clock_event_irq);
+}
+
+static void __iomem *s5p_timer_reg(void)
+{
+ unsigned long offset = 0;
+
+ switch (timer_source.source_id) {
+ case S5P_PWM0:
+ case S5P_PWM1:
+ case S5P_PWM2:
+ case S5P_PWM3:
+ offset = (timer_source.source_id * 0x0c) + 0x14;
+ break;
+
+ case S5P_PWM4:
+ offset = 0x40;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+ return NULL;
+ }
+
+ return S3C_TIMERREG(offset);
+}
+
+/*
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel. We accept that
+ * this wraps around for now, since it is just a relative time
+ * stamp. (Inspired by U300 implementation.)
+ */
+static u32 notrace s5p_read_sched_clock(void)
+{
+ void __iomem *reg = s5p_timer_reg();
+
+ if (!reg)
+ return 0;
+
+ return ~__raw_readl(reg);
+}
+
+static void __init s5p_clocksource_init(void)
+{
+ unsigned long pclk;
+ unsigned long clock_rate;
+
+ pclk = clk_get_rate(timerclk);
+
+ clk_set_rate(tdiv_source, pclk / 2);
+ clk_set_parent(tin_source, tdiv_source);
+
+ clock_rate = clk_get_rate(tin_source);
+
+ s5p_time_setup(timer_source.source_id, TCNT_MAX);
+ s5p_time_start(timer_source.source_id, PERIODIC);
+
+ setup_sched_clock(s5p_read_sched_clock, 32, clock_rate);
+
+ if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer",
+ clock_rate, 250, 32, clocksource_mmio_readl_down))
+ panic("s5p_clocksource_timer: can't register clocksource\n");
+}
+
+static void __init s5p_timer_resources(void)
+{
+
+ unsigned long event_id = timer_source.event_id;
+ unsigned long source_id = timer_source.source_id;
+ char devname[15];
+
+ timerclk = clk_get(NULL, "timers");
+ if (IS_ERR(timerclk))
+ panic("failed to get timers clock for timer");
+
+ clk_enable(timerclk);
+
+ sprintf(devname, "s3c24xx-pwm.%lu", event_id);
+ s3c_device_timer[event_id].id = event_id;
+ s3c_device_timer[event_id].dev.init_name = devname;
+
+ tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
+ if (IS_ERR(tin_event))
+ panic("failed to get pwm-tin clock for event timer");
+
+ tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
+ if (IS_ERR(tdiv_event))
+ panic("failed to get pwm-tdiv clock for event timer");
+
+ clk_enable(tin_event);
+
+ sprintf(devname, "s3c24xx-pwm.%lu", source_id);
+ s3c_device_timer[source_id].id = source_id;
+ s3c_device_timer[source_id].dev.init_name = devname;
+
+ tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
+ if (IS_ERR(tin_source))
+ panic("failed to get pwm-tin clock for source timer");
+
+ tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
+ if (IS_ERR(tdiv_source))
+ panic("failed to get pwm-tdiv clock for source timer");
+
+ clk_enable(tin_source);
+}
+
+static void __init s5p_timer_init(void)
+{
+ s5p_timer_resources();
+ s5p_clockevent_init();
+ s5p_clocksource_init();
+}
+
+struct sys_timer s5p_timer = {
+ .init = s5p_timer_init,
+};
diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
new file mode 100644
index 000000000000..683c466c0e6a
--- /dev/null
+++ b/arch/arm/plat-samsung/setup-mipiphy.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control
+ *
+ * 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <mach/regs-clock.h>
+
+static int __s5p_mipi_phy_control(struct platform_device *pdev,
+ bool on, u32 reset)
+{
+ static DEFINE_SPINLOCK(lock);
+ void __iomem *addr;
+ unsigned long flags;
+ int pid;
+ u32 cfg;
+
+ if (!pdev)
+ return -EINVAL;
+
+ pid = (pdev->id == -1) ? 0 : pdev->id;
+
+ if (pid != 0 && pid != 1)
+ return -EINVAL;
+
+ addr = S5P_MIPI_DPHY_CONTROL(pid);
+
+ spin_lock_irqsave(&lock, flags);
+
+ cfg = __raw_readl(addr);
+ cfg = on ? (cfg | reset) : (cfg & ~reset);
+ __raw_writel(cfg, addr);
+
+ if (on) {
+ cfg |= S5P_MIPI_DPHY_ENABLE;
+ } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN |
+ S5P_MIPI_DPHY_MRESETN) & ~reset)) {
+ cfg &= ~S5P_MIPI_DPHY_ENABLE;
+ }
+
+ __raw_writel(cfg, addr);
+ spin_unlock_irqrestore(&lock, flags);
+
+ return 0;
+}
+
+int s5p_csis_phy_enable(struct platform_device *pdev, bool on)
+{
+ return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN);
+}
+
+int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
+{
+ return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN);
+}