From 6c41106f177e1e3e198604f42adedc8be97c482a Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 13 Jun 2020 10:21:37 +0200 Subject: soc: bcm: add BCM63xx power domain driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM6318, BCM6328, BCM6362 and BCM63268 SoCs have a power domain controller to enable/disable certain components in order to save power. Signed-off-by: Álvaro Fernández Rojas Reviewed-by: Florian Fainelli Signed-off-by: Florian Fainelli --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index deaafb617361..c742864ab699 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3491,6 +3491,7 @@ F: arch/mips/bmips/* F: arch/mips/boot/dts/brcm/bcm*.dts* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* +F: drivers/soc/bcm/bcm63xx F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* -- cgit v1.2.3 From 177f71f18ee595c508fdede140177765c4a4a779 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 29 Jul 2020 21:21:54 +0200 Subject: MAINTAINERS: drop Vincent Sanders from Simtec S3C boards Vincent Sanders' email bounces with code 550 (user does not exist) so remove the entry from Simtec S3C24xx boards. Cc: Simtec Linux Team Cc: linux-samsung-soc@vger.kernel.org Signed-off-by: Krzysztof Kozlowski --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index deaafb617361..d369f15730cb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15825,13 +15825,11 @@ F: drivers/video/fbdev/simplefb.c F: include/linux/platform_data/simplefb.h SIMTEC EB110ATX (Chalice CATS) -M: Vincent Sanders M: Simtec Linux Team S: Supported W: http://www.simtec.co.uk/products/EB110ATX/ SIMTEC EB2410ITX (BAST) -M: Vincent Sanders M: Simtec Linux Team S: Supported W: http://www.simtec.co.uk/products/EB2410ITX/ -- cgit v1.2.3 From 351367bb05bd64f24ff0d610b98585b1e9e3bce4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 6 Aug 2020 20:06:22 +0200 Subject: MAINTAINERS: add more name matches for Samsung SoC entries The Samsung SoC maintainer entry covers drivers and headers matching "exynos" name but except that there are also files for S3C24xx, S3C64xx and S5Pv210 SoCs. These sometimes do not have a separate entry for a driver maintainer thus might miss review. Add them to the Samsung SoC maintainer entry to cover all SoCs with name matches. Signed-off-by: Krzysztof Kozlowski Acked-by: Arnd Bergmann --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index d369f15730cb..11860c5e15fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2424,6 +2424,9 @@ F: drivers/soc/samsung/ F: drivers/tty/serial/samsung* F: include/linux/soc/samsung/ N: exynos +N: s3c2410 +N: s3c64xx +N: s5pv210 ARM/SAMSUNG MOBILE MACHINE SUPPORT M: Kyungmin Park -- cgit v1.2.3 From c2fe8ebb332eefb3d0543b248e28dd2992c04793 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Aug 2020 21:26:42 +0200 Subject: clk: samsung: s3c64xx: declare s3c64xx_clk_init() in shared header The s3c64xx_clk_init() is defined and used by the clk-s3c64xx driver and also used in the mach-s3c64xx machine code. Move the declaration to a header to fix W=1 build warning: drivers/clk/samsung/clk-s3c64xx.c:391:13: warning: no previous prototype for 's3c64xx_clk_init' [-Wmissing-prototypes] 391 | void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, Signed-off-by: Krzysztof Kozlowski Reviewed-by: Tomasz Figa Acked-by: Chanwoo Choi Reviewed-by: Stephen Boyd --- MAINTAINERS | 1 + arch/arm/mach-s3c64xx/common.c | 1 + arch/arm/mach-s3c64xx/common.h | 2 -- drivers/clk/samsung/clk-s3c64xx.c | 1 + include/linux/clk/samsung.h | 24 ++++++++++++++++++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 include/linux/clk/samsung.h (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index 11860c5e15fb..d6abe0cc1a5d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15304,6 +15304,7 @@ F: Documentation/devicetree/bindings/clock/samsung,s3c* F: Documentation/devicetree/bindings/clock/samsung,s5p* F: drivers/clk/samsung/ F: include/dt-bindings/clock/exynos*.h +F: include/linux/clk/samsung.h SAMSUNG SPI DRIVERS M: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index 13e91074308a..a655bf0c7802 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index 03670887a764..f4eca42cdc86 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -22,8 +22,6 @@ void s3c64xx_init_io(struct map_desc *mach_desc, int size); void s3c64xx_restart(enum reboot_mode mode, const char *cmd); struct device_node; -void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, - unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base); void s3c64xx_set_xtal_freq(unsigned long freq); void s3c64xx_set_xusbxti_freq(unsigned long freq); diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index b96d33e5eb45..56f95b63f71f 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -7,6 +7,7 @@ #include #include +#include #include #include diff --git a/include/linux/clk/samsung.h b/include/linux/clk/samsung.h new file mode 100644 index 000000000000..7a0824b22eed --- /dev/null +++ b/include/linux/clk/samsung.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Krzysztof Kozlowski + */ + +#ifndef __LINUX_CLK_SAMSUNG_H_ +#define __LINUX_CLK_SAMSUNG_H_ + +#include + +struct device_node; + +#ifdef CONFIG_ARCH_S3C64XX +void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, + unsigned long xusbxti_f, bool s3c6400, + void __iomem *base); +#else +static inline void s3c64xx_clk_init(struct device_node *np, + unsigned long xtal_f, + unsigned long xusbxti_f, + bool s3c6400, void __iomem *base) { } +#endif /* CONFIG_ARCH_S3C64XX */ + +#endif /* __LINUX_CLK_SAMSUNG_H_ */ -- cgit v1.2.3 From b84e23f5135103c45022b0e4a4ed2459d5398a7e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 6 Aug 2020 20:20:23 +0200 Subject: ARM: s3c24xx: pass pointer to clk driver via platform data Passing pointers directly as platform data is fragile and undocumented. Better to create a platform data structure which explicitly documents what is passed to the driver. Suggested-by: Tomasz Figa Signed-off-by: Krzysztof Kozlowski Acked-by: Arnd Bergmann Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20200806182059.2431-6-krzk@kernel.org --- MAINTAINERS | 1 + arch/arm/mach-s3c24xx/common.c | 7 ++++++- drivers/clk/samsung/clk-s3c2410-dclk.c | 7 ++++++- include/linux/platform_data/clk-s3c2410.h | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 include/linux/platform_data/clk-s3c2410.h (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index d6abe0cc1a5d..45906c58ff4a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15305,6 +15305,7 @@ F: Documentation/devicetree/bindings/clock/samsung,s5p* F: drivers/clk/samsung/ F: include/dt-bindings/clock/exynos*.h F: include/linux/clk/samsung.h +F: include/linux/platform_data/clk-s3c2410.h SAMSUNG SPI DRIVERS M: Kukjin Kim diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index 222238e8acbb..c476a673d07f 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -663,13 +664,17 @@ static struct resource s3c2410_dclk_resource[] = { [0] = DEFINE_RES_MEM(0x56000084, 0x4), }; +static struct s3c2410_clk_platform_data s3c_clk_platform_data = { + .modify_misccr = s3c2410_modify_misccr, +}; + struct platform_device s3c2410_device_dclk = { .name = "s3c2410-dclk", .id = 0, .num_resources = ARRAY_SIZE(s3c2410_dclk_resource), .resource = s3c2410_dclk_resource, .dev = { - .platform_data = s3c2410_modify_misccr, + .platform_data = &s3c_clk_platform_data, }, }; #endif diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c index 3e0f23e8ec21..f5e0a6ba2d12 100644 --- a/drivers/clk/samsung/clk-s3c2410-dclk.c +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "clk.h" @@ -89,10 +90,14 @@ static struct clk_hw *s3c24xx_register_clkout(struct device *dev, const char *name, const char **parent_names, u8 num_parents, u8 shift, u32 mask) { + struct s3c2410_clk_platform_data *pdata = dev_get_platdata(dev); struct s3c24xx_clkout *clkout; struct clk_init_data init; int ret; + if (!pdata) + return ERR_PTR(-EINVAL); + /* allocate the clkout */ clkout = kzalloc(sizeof(*clkout), GFP_KERNEL); if (!clkout) @@ -107,7 +112,7 @@ static struct clk_hw *s3c24xx_register_clkout(struct device *dev, clkout->shift = shift; clkout->mask = mask; clkout->hw.init = &init; - clkout->modify_misccr = dev->platform_data; + clkout->modify_misccr = pdata->modify_misccr; ret = clk_hw_register(dev, &clkout->hw); if (ret) diff --git a/include/linux/platform_data/clk-s3c2410.h b/include/linux/platform_data/clk-s3c2410.h new file mode 100644 index 000000000000..7eb1cfa5409b --- /dev/null +++ b/include/linux/platform_data/clk-s3c2410.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Krzysztof Kozlowski + */ + +#ifndef __LINUX_PLATFORM_DATA_CLK_S3C2410_H_ +#define __LINUX_PLATFORM_DATA_CLK_S3C2410_H_ + +/** + * struct s3c2410_clk_platform_data - platform data for S3C2410 clock driver + * + * @modify_misccr: Function to modify the MISCCR and return the new value + */ +struct s3c2410_clk_platform_data { + unsigned int (*modify_misccr)(unsigned int clr, unsigned int chg); +}; + +#endif /* __LINUX_PLATFORM_DATA_CLK_S3C2410_H_ */ + -- cgit v1.2.3 From f131a4443ea468cd532410c271c229bb39caab08 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 3 Sep 2019 11:31:09 +0200 Subject: ARM: s3c24xx: move spi fiq handler into platform The fiq handler needs access to some register definitions that should not be used directly by device drivers. Since this is closely related to the irqchip driver anyway, move it into the same place. Signed-off-by: Arnd Bergmann [krzk: Add a header guard in include/linux/spi/s3c24xx-fiq.h, fix SPDX comment style, update maintainer's entry] Co-developed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20200806182059.2431-23-krzk%40kernel.org Acked-by: Mark Brown --- MAINTAINERS | 1 + arch/arm/mach-s3c24xx/Makefile | 2 + arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c | 9 ++ arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S | 115 ++++++++++++++++++++++++ drivers/spi/Makefile | 1 - drivers/spi/spi-s3c24xx-fiq.S | 115 ------------------------ drivers/spi/spi-s3c24xx-fiq.h | 23 ----- drivers/spi/spi-s3c24xx.c | 7 +- include/linux/spi/s3c24xx-fiq.h | 33 +++++++ 9 files changed, 161 insertions(+), 145 deletions(-) create mode 100644 arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c create mode 100644 arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S delete mode 100644 drivers/spi/spi-s3c24xx-fiq.S delete mode 100644 drivers/spi/spi-s3c24xx-fiq.h create mode 100644 include/linux/spi/s3c24xx-fiq.h (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index 45906c58ff4a..a14144691ca5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15317,6 +15317,7 @@ S: Maintained F: Documentation/devicetree/bindings/spi/spi-samsung.txt F: drivers/spi/spi-s3c* F: include/linux/platform_data/spi-s3c64xx.h +F: include/linux/spi/s3c24xx-fiq.h SAMSUNG SXGBE DRIVERS M: Byungho An diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index 3ad297bd6b4a..b69eee24940b 100644 --- a/arch/arm/mach-s3c24xx/Makefile +++ b/arch/arm/mach-s3c24xx/Makefile @@ -9,6 +9,8 @@ obj-y += common.o obj-y += irq-s3c24xx.o +obj-$(CONFIG_SPI_S3C24XX_FIQ) += irq-s3c24xx-fiq.o +obj-$(CONFIG_SPI_S3C24XX_FIQ) += irq-s3c24xx-fiq-exports.o obj-$(CONFIG_CPU_S3C2410) += s3c2410.o obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o diff --git a/arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c b/arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c new file mode 100644 index 000000000000..84cf86376ded --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include + +EXPORT_SYMBOL(s3c24xx_spi_fiq_rx); +EXPORT_SYMBOL(s3c24xx_spi_fiq_txrx); +EXPORT_SYMBOL(s3c24xx_spi_fiq_tx); diff --git a/arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S b/arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S new file mode 100644 index 000000000000..2a84535a14fd --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* linux/drivers/spi/spi_s3c24xx_fiq.S + * + * Copyright 2009 Simtec Electronics + * Ben Dooks + * + * S3C24XX SPI - FIQ pseudo-DMA transfer code +*/ + +#include +#include + +#include +#include + +#include + +#define S3C2410_SPTDAT (0x10) +#define S3C2410_SPRDAT (0x14) + + .text + + @ entry to these routines is as follows, with the register names + @ defined in fiq.h so that they can be shared with the C files which + @ setup the calling registers. + @ + @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND + @ fiq_rtmp Temporary register to hold tx/rx data + @ fiq_rspi The base of the SPI register block + @ fiq_rtx The tx buffer pointer + @ fiq_rrx The rx buffer pointer + @ fiq_rcount The number of bytes to move + + @ each entry starts with a word entry of how long it is + @ and an offset to the irq acknowledgment word + +ENTRY(s3c24xx_spi_fiq_rx) +s3c24xx_spi_fix_rx: + .word fiq_rx_end - fiq_rx_start + .word fiq_rx_irq_ack - fiq_rx_start +fiq_rx_start: + ldr fiq_rtmp, fiq_rx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + mov fiq_rtmp, #0xff + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + @@ set IRQ controller so that next op will trigger IRQ + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_rx_irq_ack: + .word 0 +fiq_rx_end: + +ENTRY(s3c24xx_spi_fiq_txrx) +s3c24xx_spi_fiq_txrx: + .word fiq_txrx_end - fiq_txrx_start + .word fiq_txrx_irq_ack - fiq_txrx_start +fiq_txrx_start: + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + ldr fiq_rtmp, fiq_txrx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_txrx_irq_ack: + .word 0 + +fiq_txrx_end: + +ENTRY(s3c24xx_spi_fiq_tx) +s3c24xx_spi_fix_tx: + .word fiq_tx_end - fiq_tx_start + .word fiq_tx_irq_ack - fiq_tx_start +fiq_tx_start: + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + + ldr fiq_rtmp, fiq_tx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_tx_irq_ack: + .word 0 + +fiq_tx_end: + + .end diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index cf955ea803cd..eba6fb607aa2 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -97,7 +97,6 @@ obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o obj-$(CONFIG_SPI_RSPI) += spi-rspi.o obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o spi-s3c24xx-hw-y := spi-s3c24xx.o -spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o obj-$(CONFIG_SPI_SH) += spi-sh.o diff --git a/drivers/spi/spi-s3c24xx-fiq.S b/drivers/spi/spi-s3c24xx-fiq.S deleted file mode 100644 index 9d5f8f1e5e81..000000000000 --- a/drivers/spi/spi-s3c24xx-fiq.S +++ /dev/null @@ -1,115 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* linux/drivers/spi/spi_s3c24xx_fiq.S - * - * Copyright 2009 Simtec Electronics - * Ben Dooks - * - * S3C24XX SPI - FIQ pseudo-DMA transfer code -*/ - -#include -#include - -#include -#include - -#include "spi-s3c24xx-fiq.h" - -#define S3C2410_SPTDAT (0x10) -#define S3C2410_SPRDAT (0x14) - - .text - - @ entry to these routines is as follows, with the register names - @ defined in fiq.h so that they can be shared with the C files which - @ setup the calling registers. - @ - @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND - @ fiq_rtmp Temporary register to hold tx/rx data - @ fiq_rspi The base of the SPI register block - @ fiq_rtx The tx buffer pointer - @ fiq_rrx The rx buffer pointer - @ fiq_rcount The number of bytes to move - - @ each entry starts with a word entry of how long it is - @ and an offset to the irq acknowledgment word - -ENTRY(s3c24xx_spi_fiq_rx) -s3c24xx_spi_fix_rx: - .word fiq_rx_end - fiq_rx_start - .word fiq_rx_irq_ack - fiq_rx_start -fiq_rx_start: - ldr fiq_rtmp, fiq_rx_irq_ack - str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] - - ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] - strb fiq_rtmp, [ fiq_rrx ], #1 - - mov fiq_rtmp, #0xff - strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] - - subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do - - @@ set IRQ controller so that next op will trigger IRQ - mov fiq_rtmp, #0 - str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] - subs pc, lr, #4 - -fiq_rx_irq_ack: - .word 0 -fiq_rx_end: - -ENTRY(s3c24xx_spi_fiq_txrx) -s3c24xx_spi_fiq_txrx: - .word fiq_txrx_end - fiq_txrx_start - .word fiq_txrx_irq_ack - fiq_txrx_start -fiq_txrx_start: - - ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] - strb fiq_rtmp, [ fiq_rrx ], #1 - - ldr fiq_rtmp, fiq_txrx_irq_ack - str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] - - ldrb fiq_rtmp, [ fiq_rtx ], #1 - strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] - - subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do - - mov fiq_rtmp, #0 - str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] - subs pc, lr, #4 - -fiq_txrx_irq_ack: - .word 0 - -fiq_txrx_end: - -ENTRY(s3c24xx_spi_fiq_tx) -s3c24xx_spi_fix_tx: - .word fiq_tx_end - fiq_tx_start - .word fiq_tx_irq_ack - fiq_tx_start -fiq_tx_start: - ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] - - ldr fiq_rtmp, fiq_tx_irq_ack - str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] - - ldrb fiq_rtmp, [ fiq_rtx ], #1 - strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] - - subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do - - mov fiq_rtmp, #0 - str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] - subs pc, lr, #4 - -fiq_tx_irq_ack: - .word 0 - -fiq_tx_end: - - .end diff --git a/drivers/spi/spi-s3c24xx-fiq.h b/drivers/spi/spi-s3c24xx-fiq.h deleted file mode 100644 index 7786b0ea56ec..000000000000 --- a/drivers/spi/spi-s3c24xx-fiq.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* linux/drivers/spi/spi_s3c24xx_fiq.h - * - * Copyright 2009 Simtec Electronics - * Ben Dooks - * - * S3C24XX SPI - FIQ pseudo-DMA transfer support -*/ - -/* We have R8 through R13 to play with */ - -#ifdef __ASSEMBLY__ -#define __REG_NR(x) r##x -#else -#define __REG_NR(x) (x) -#endif - -#define fiq_rspi __REG_NR(8) -#define fiq_rtmp __REG_NR(9) -#define fiq_rrx __REG_NR(10) -#define fiq_rtx __REG_NR(11) -#define fiq_rcount __REG_NR(12) -#define fiq_rirq __REG_NR(13) diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index 0691248c7c0d..6ac6f0b6f237 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -19,12 +19,12 @@ #include #include #include +#include #include #include #include "spi-s3c24xx-regs.h" -#include "spi-s3c24xx-fiq.h" /** * s3c24xx_spi_devstate - per device data @@ -229,10 +229,6 @@ struct spi_fiq_code { u8 data[]; }; -extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; -extern struct spi_fiq_code s3c24xx_spi_fiq_tx; -extern struct spi_fiq_code s3c24xx_spi_fiq_rx; - /** * ack_bit - turn IRQ into IRQ acknowledgement bit * @irq: The interrupt number @@ -282,7 +278,6 @@ static void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) regs.uregs[fiq_rrx] = (long)hw->rx; regs.uregs[fiq_rtx] = (long)hw->tx + 1; regs.uregs[fiq_rcount] = hw->len - 1; - regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ; set_fiq_regs(®s); diff --git a/include/linux/spi/s3c24xx-fiq.h b/include/linux/spi/s3c24xx-fiq.h new file mode 100644 index 000000000000..d2842ac1de27 --- /dev/null +++ b/include/linux/spi/s3c24xx-fiq.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* linux/drivers/spi/spi_s3c24xx_fiq.h + * + * Copyright 2009 Simtec Electronics + * Ben Dooks + * + * S3C24XX SPI - FIQ pseudo-DMA transfer support +*/ + +#ifndef __LINUX_SPI_S3C24XX_FIQ_H +#define __LINUX_SPI_S3C24XX_FIQ_H __FILE__ + +/* We have R8 through R13 to play with */ + +#ifdef __ASSEMBLY__ +#define __REG_NR(x) r##x +#else + +extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; +extern struct spi_fiq_code s3c24xx_spi_fiq_tx; +extern struct spi_fiq_code s3c24xx_spi_fiq_rx; + +#define __REG_NR(x) (x) +#endif + +#define fiq_rspi __REG_NR(8) +#define fiq_rtmp __REG_NR(9) +#define fiq_rrx __REG_NR(10) +#define fiq_rtx __REG_NR(11) +#define fiq_rcount __REG_NR(12) +#define fiq_rirq __REG_NR(13) + +#endif /* __LINUX_SPI_S3C24XX_FIQ_H */ -- cgit v1.2.3 From 71b9114d2c13a648fbe6523dd859e611c316ad90 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 2 Sep 2019 17:47:55 +0200 Subject: ARM: s3c: move into a common directory s3c24xx and s3c64xx have a lot in common, but are split across three separate directories, which makes the interaction of the header files more complicated than necessary. Move all three directories into a new mach-s3c, with a minimal set of changes to each file. Signed-off-by: Arnd Bergmann [krzk: Rebase, add s3c24xx and s3c64xx suffix to several files, add SPDX headers to new files, remove plat-samsung from MAINTAINERS] Co-developed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski https://lore.kernel.org/r/20200806182059.2431-39-krzk@kernel.org --- MAINTAINERS | 16 +- arch/arm/Kconfig | 5 +- arch/arm/Makefile | 5 +- arch/arm/mach-s3c/Kconfig | 250 ++++ arch/arm/mach-s3c/Kconfig.s3c24xx | 583 +++++++++ arch/arm/mach-s3c/Kconfig.s3c64xx | 350 +++++ arch/arm/mach-s3c/Makefile | 37 + arch/arm/mach-s3c/Makefile.boot | 9 + arch/arm/mach-s3c/Makefile.s3c24xx | 102 ++ arch/arm/mach-s3c/Makefile.s3c64xx | 62 + arch/arm/mach-s3c/adc.c | 510 ++++++++ arch/arm/mach-s3c/anubis.h | 50 + arch/arm/mach-s3c/ata-core-s3c64xx.h | 24 + arch/arm/mach-s3c/backlight-s3c64xx.h | 22 + arch/arm/mach-s3c/bast-ide.c | 82 ++ arch/arm/mach-s3c/bast-irq.c | 137 ++ arch/arm/mach-s3c/bast.h | 194 +++ arch/arm/mach-s3c/common-smdk-s3c24xx.c | 228 ++++ arch/arm/mach-s3c/common-smdk-s3c24xx.h | 11 + arch/arm/mach-s3c/cpu.c | 31 + arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c | 94 ++ arch/arm/mach-s3c/cpuidle-s3c64xx.c | 60 + arch/arm/mach-s3c/crag6410.h | 22 + arch/arm/mach-s3c/dev-audio-s3c64xx.c | 212 ++++ arch/arm/mach-s3c/dev-backlight-s3c64xx.c | 137 ++ arch/arm/mach-s3c/dev-uart-s3c64xx.c | 65 + arch/arm/mach-s3c/dev-uart.c | 41 + arch/arm/mach-s3c/devs.c | 1199 ++++++++++++++++++ arch/arm/mach-s3c/fb-core-s3c24xx.h | 24 + arch/arm/mach-s3c/gpio-samsung.c | 1324 +++++++++++++++++++ arch/arm/mach-s3c/gta02.h | 20 + arch/arm/mach-s3c/h1940-bluetooth.c | 140 ++ arch/arm/mach-s3c/h1940.h | 52 + arch/arm/mach-s3c/include/mach/dma-s3c24xx.h | 51 + arch/arm/mach-s3c/include/mach/dma-s3c64xx.h | 57 + arch/arm/mach-s3c/include/mach/dma.h | 9 + .../mach-s3c/include/mach/gpio-samsung-s3c24xx.h | 103 ++ .../mach-s3c/include/mach/gpio-samsung-s3c64xx.h | 94 ++ arch/arm/mach-s3c/include/mach/gpio-samsung.h | 9 + arch/arm/mach-s3c/include/mach/hardware-s3c24xx.h | 14 + arch/arm/mach-s3c/include/mach/io-s3c24xx.h | 50 + arch/arm/mach-s3c/include/mach/io.h | 8 + arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h | 213 ++++ arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h | 172 +++ arch/arm/mach-s3c/include/mach/irqs.h | 9 + arch/arm/mach-s3c/include/mach/map-s3c24xx.h | 159 +++ arch/arm/mach-s3c/include/mach/map-s3c64xx.h | 122 ++ arch/arm/mach-s3c/include/mach/map.h | 9 + arch/arm/mach-s3c/include/mach/pm-core-s3c24xx.h | 96 ++ arch/arm/mach-s3c/include/mach/pm-core-s3c64xx.h | 84 ++ arch/arm/mach-s3c/include/mach/pm-core.h | 9 + .../arm/mach-s3c/include/mach/regs-clock-s3c24xx.h | 146 +++ .../arm/mach-s3c/include/mach/regs-clock-s3c64xx.h | 34 + arch/arm/mach-s3c/include/mach/regs-clock.h | 9 + arch/arm/mach-s3c/include/mach/regs-gpio-s3c24xx.h | 608 +++++++++ arch/arm/mach-s3c/include/mach/regs-gpio-s3c64xx.h | 188 +++ arch/arm/mach-s3c/include/mach/regs-gpio.h | 9 + arch/arm/mach-s3c/include/mach/regs-irq-s3c24xx.h | 51 + arch/arm/mach-s3c/include/mach/regs-irq-s3c64xx.h | 15 + arch/arm/mach-s3c/include/mach/regs-irq.h | 9 + .../arm/mach-s3c/include/mach/regs-s3c2443-clock.h | 238 ++++ arch/arm/mach-s3c/include/mach/rtc-core-s3c24xx.h | 23 + arch/arm/mach-s3c/include/mach/s3c2412.h | 25 + arch/arm/mach-s3c/include/plat/adc-core.h | 24 + arch/arm/mach-s3c/include/plat/cpu.h | 128 ++ arch/arm/mach-s3c/include/plat/devs.h | 96 ++ arch/arm/mach-s3c/include/plat/fb.h | 31 + arch/arm/mach-s3c/include/plat/gpio-cfg-helpers.h | 159 +++ arch/arm/mach-s3c/include/plat/gpio-cfg.h | 178 +++ arch/arm/mach-s3c/include/plat/gpio-core.h | 142 +++ arch/arm/mach-s3c/include/plat/iic-core.h | 38 + arch/arm/mach-s3c/include/plat/keypad.h | 27 + arch/arm/mach-s3c/include/plat/map-base.h | 42 + arch/arm/mach-s3c/include/plat/map-s3c.h | 70 + arch/arm/mach-s3c/include/plat/map-s5p.h | 20 + arch/arm/mach-s3c/include/plat/pm-common.h | 40 + arch/arm/mach-s3c/include/plat/pm.h | 109 ++ arch/arm/mach-s3c/include/plat/pwm-core.h | 19 + arch/arm/mach-s3c/include/plat/regs-adc.h | 64 + arch/arm/mach-s3c/include/plat/regs-irqtype.h | 17 + arch/arm/mach-s3c/include/plat/sdhci.h | 162 +++ arch/arm/mach-s3c/include/plat/usb-phy.h | 13 + arch/arm/mach-s3c/include/plat/wakeup-mask.h | 39 + arch/arm/mach-s3c/init.c | 173 +++ arch/arm/mach-s3c/iotiming-s3c2410.c | 472 +++++++ arch/arm/mach-s3c/iotiming-s3c2412.c | 278 ++++ arch/arm/mach-s3c/irq-pm-s3c24xx.c | 115 ++ arch/arm/mach-s3c/irq-pm-s3c64xx.c | 119 ++ arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c | 9 + arch/arm/mach-s3c/irq-s3c24xx-fiq.S | 115 ++ arch/arm/mach-s3c/irq-s3c24xx.c | 1337 ++++++++++++++++++++ arch/arm/mach-s3c/irq-uart-s3c64xx.h | 16 + arch/arm/mach-s3c/mach-amlm5900.c | 246 ++++ arch/arm/mach-s3c/mach-anubis.c | 426 +++++++ arch/arm/mach-s3c/mach-anw6410.c | 230 ++++ arch/arm/mach-s3c/mach-at2440evb.c | 232 ++++ arch/arm/mach-s3c/mach-bast.c | 587 +++++++++ arch/arm/mach-s3c/mach-crag6410-module.c | 445 +++++++ arch/arm/mach-s3c/mach-crag6410.c | 879 +++++++++++++ arch/arm/mach-s3c/mach-gta02.c | 580 +++++++++ arch/arm/mach-s3c/mach-h1940.c | 793 ++++++++++++ arch/arm/mach-s3c/mach-hmt.c | 282 +++++ arch/arm/mach-s3c/mach-jive.c | 684 ++++++++++ arch/arm/mach-s3c/mach-mini2440.c | 792 ++++++++++++ arch/arm/mach-s3c/mach-mini6410.c | 365 ++++++ arch/arm/mach-s3c/mach-n30.c | 674 ++++++++++ arch/arm/mach-s3c/mach-ncp.c | 100 ++ arch/arm/mach-s3c/mach-nexcoder.c | 161 +++ arch/arm/mach-s3c/mach-osiris-dvs.c | 178 +++ arch/arm/mach-s3c/mach-osiris.c | 409 ++++++ arch/arm/mach-s3c/mach-otom.c | 124 ++ arch/arm/mach-s3c/mach-qt2410.c | 374 ++++++ arch/arm/mach-s3c/mach-real6410.c | 333 +++++ arch/arm/mach-s3c/mach-rx1950.c | 867 +++++++++++++ arch/arm/mach-s3c/mach-rx3715.c | 218 ++++ arch/arm/mach-s3c/mach-s3c2416-dt.c | 48 + arch/arm/mach-s3c/mach-s3c64xx-dt.c | 51 + arch/arm/mach-s3c/mach-smartq.c | 424 +++++++ arch/arm/mach-s3c/mach-smartq.h | 16 + arch/arm/mach-s3c/mach-smartq5.c | 154 +++ arch/arm/mach-s3c/mach-smartq7.c | 170 +++ arch/arm/mach-s3c/mach-smdk2410.c | 111 ++ arch/arm/mach-s3c/mach-smdk2413.c | 160 +++ arch/arm/mach-s3c/mach-smdk2416.c | 257 ++++ arch/arm/mach-s3c/mach-smdk2440.c | 189 +++ arch/arm/mach-s3c/mach-smdk2443.c | 136 ++ arch/arm/mach-s3c/mach-smdk6400.c | 90 ++ arch/arm/mach-s3c/mach-smdk6410.c | 706 +++++++++++ arch/arm/mach-s3c/mach-tct_hammer.c | 156 +++ arch/arm/mach-s3c/mach-vr1000.c | 368 ++++++ arch/arm/mach-s3c/mach-vstms.c | 165 +++ arch/arm/mach-s3c/nand-core-s3c24xx.h | 24 + arch/arm/mach-s3c/onenand-core-s3c64xx.h | 32 + arch/arm/mach-s3c/osiris.h | 50 + arch/arm/mach-s3c/otom.h | 25 + arch/arm/mach-s3c/pl080.c | 264 ++++ arch/arm/mach-s3c/platformdata.c | 53 + arch/arm/mach-s3c/pll-s3c2410.c | 83 ++ arch/arm/mach-s3c/pll-s3c2440-12000000.c | 95 ++ arch/arm/mach-s3c/pll-s3c2440-16934400.c | 122 ++ arch/arm/mach-s3c/pm-common.c | 73 ++ arch/arm/mach-s3c/pm-gpio.c | 380 ++++++ arch/arm/mach-s3c/pm-h1940.S | 19 + arch/arm/mach-s3c/pm-s3c2410.c | 170 +++ arch/arm/mach-s3c/pm-s3c2412.c | 126 ++ arch/arm/mach-s3c/pm-s3c2416.c | 81 ++ arch/arm/mach-s3c/pm-s3c24xx.c | 121 ++ arch/arm/mach-s3c/pm-s3c64xx.c | 400 ++++++ arch/arm/mach-s3c/pm.c | 199 +++ arch/arm/mach-s3c/regs-dsc-s3c24xx.h | 22 + arch/arm/mach-s3c/regs-gpio-memport-s3c64xx.h | 25 + arch/arm/mach-s3c/regs-mem-s3c24xx.h | 53 + arch/arm/mach-s3c/regs-modem-s3c64xx.h | 27 + arch/arm/mach-s3c/regs-srom-s3c64xx.h | 55 + arch/arm/mach-s3c/regs-sys-s3c64xx.h | 27 + arch/arm/mach-s3c/regs-syscon-power-s3c64xx.h | 112 ++ arch/arm/mach-s3c/regs-usb-hsotg-phy-s3c64xx.h | 47 + arch/arm/mach-s3c/s3c2410.c | 130 ++ arch/arm/mach-s3c/s3c2412-power.h | 34 + arch/arm/mach-s3c/s3c2412.c | 175 +++ arch/arm/mach-s3c/s3c2416.c | 132 ++ arch/arm/mach-s3c/s3c2440.c | 71 ++ arch/arm/mach-s3c/s3c2442.c | 62 + arch/arm/mach-s3c/s3c2443.c | 112 ++ arch/arm/mach-s3c/s3c244x.c | 128 ++ arch/arm/mach-s3c/s3c24xx.c | 680 ++++++++++ arch/arm/mach-s3c/s3c24xx.h | 124 ++ arch/arm/mach-s3c/s3c6400.c | 90 ++ arch/arm/mach-s3c/s3c6410.c | 94 ++ arch/arm/mach-s3c/s3c64xx.c | 423 +++++++ arch/arm/mach-s3c/s3c64xx.h | 66 + arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c | 23 + arch/arm/mach-s3c/setup-i2c-s3c24xx.c | 22 + arch/arm/mach-s3c/setup-i2c0-s3c64xx.c | 24 + arch/arm/mach-s3c/setup-i2c1-s3c64xx.c | 24 + arch/arm/mach-s3c/setup-ide-s3c64xx.c | 39 + arch/arm/mach-s3c/setup-keypad-s3c64xx.c | 20 + arch/arm/mach-s3c/setup-sdhci-gpio-s3c24xx.c | 31 + arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c | 53 + arch/arm/mach-s3c/setup-spi-s3c24xx.c | 27 + arch/arm/mach-s3c/setup-spi-s3c64xx.c | 27 + arch/arm/mach-s3c/setup-ts-s3c24xx.c | 29 + arch/arm/mach-s3c/setup-usb-phy-s3c64xx.c | 90 ++ arch/arm/mach-s3c/simtec-audio.c | 76 ++ arch/arm/mach-s3c/simtec-nor.c | 74 ++ arch/arm/mach-s3c/simtec-pm.c | 60 + arch/arm/mach-s3c/simtec-usb.c | 125 ++ arch/arm/mach-s3c/simtec.h | 17 + arch/arm/mach-s3c/sleep-s3c2410.S | 54 + arch/arm/mach-s3c/sleep-s3c2412.S | 53 + arch/arm/mach-s3c/sleep-s3c24xx.S | 69 + arch/arm/mach-s3c/sleep-s3c64xx.S | 69 + arch/arm/mach-s3c/spi-core-s3c24xx.h | 27 + arch/arm/mach-s3c/vr1000.h | 113 ++ arch/arm/mach-s3c/wakeup-mask.c | 42 + arch/arm/mach-s3c24xx/Kconfig | 583 --------- arch/arm/mach-s3c24xx/Makefile | 102 -- arch/arm/mach-s3c24xx/Makefile.boot | 9 - arch/arm/mach-s3c24xx/anubis.h | 50 - arch/arm/mach-s3c24xx/bast-ide.c | 82 -- arch/arm/mach-s3c24xx/bast-irq.c | 137 -- arch/arm/mach-s3c24xx/bast.h | 194 --- arch/arm/mach-s3c24xx/common-smdk.c | 228 ---- arch/arm/mach-s3c24xx/common-smdk.h | 11 - arch/arm/mach-s3c24xx/common.c | 680 ---------- arch/arm/mach-s3c24xx/common.h | 124 -- arch/arm/mach-s3c24xx/cpufreq-utils.c | 94 -- arch/arm/mach-s3c24xx/fb-core.h | 24 - arch/arm/mach-s3c24xx/gta02.h | 20 - arch/arm/mach-s3c24xx/h1940-bluetooth.c | 140 -- arch/arm/mach-s3c24xx/h1940.h | 52 - arch/arm/mach-s3c24xx/include/mach/dma.h | 51 - arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h | 103 -- arch/arm/mach-s3c24xx/include/mach/hardware.h | 14 - arch/arm/mach-s3c24xx/include/mach/io.h | 50 - arch/arm/mach-s3c24xx/include/mach/irqs.h | 213 ---- arch/arm/mach-s3c24xx/include/mach/map.h | 159 --- arch/arm/mach-s3c24xx/include/mach/pm-core.h | 96 -- arch/arm/mach-s3c24xx/include/mach/regs-clock.h | 146 --- arch/arm/mach-s3c24xx/include/mach/regs-gpio.h | 608 --------- arch/arm/mach-s3c24xx/include/mach/regs-irq.h | 51 - .../mach-s3c24xx/include/mach/regs-s3c2443-clock.h | 238 ---- arch/arm/mach-s3c24xx/include/mach/rtc-core.h | 23 - arch/arm/mach-s3c24xx/include/mach/s3c2412.h | 25 - arch/arm/mach-s3c24xx/iotiming-s3c2410.c | 472 ------- arch/arm/mach-s3c24xx/iotiming-s3c2412.c | 278 ---- arch/arm/mach-s3c24xx/irq-pm.c | 115 -- arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c | 9 - arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S | 115 -- arch/arm/mach-s3c24xx/irq-s3c24xx.c | 1337 -------------------- arch/arm/mach-s3c24xx/mach-amlm5900.c | 246 ---- arch/arm/mach-s3c24xx/mach-anubis.c | 426 ------- arch/arm/mach-s3c24xx/mach-at2440evb.c | 232 ---- arch/arm/mach-s3c24xx/mach-bast.c | 587 --------- arch/arm/mach-s3c24xx/mach-gta02.c | 580 --------- arch/arm/mach-s3c24xx/mach-h1940.c | 793 ------------ arch/arm/mach-s3c24xx/mach-jive.c | 684 ---------- arch/arm/mach-s3c24xx/mach-mini2440.c | 792 ------------ arch/arm/mach-s3c24xx/mach-n30.c | 674 ---------- arch/arm/mach-s3c24xx/mach-nexcoder.c | 161 --- arch/arm/mach-s3c24xx/mach-osiris-dvs.c | 178 --- arch/arm/mach-s3c24xx/mach-osiris.c | 409 ------ arch/arm/mach-s3c24xx/mach-otom.c | 124 -- arch/arm/mach-s3c24xx/mach-qt2410.c | 374 ------ arch/arm/mach-s3c24xx/mach-rx1950.c | 867 ------------- arch/arm/mach-s3c24xx/mach-rx3715.c | 218 ---- arch/arm/mach-s3c24xx/mach-s3c2416-dt.c | 48 - arch/arm/mach-s3c24xx/mach-smdk2410.c | 111 -- arch/arm/mach-s3c24xx/mach-smdk2413.c | 160 --- arch/arm/mach-s3c24xx/mach-smdk2416.c | 257 ---- arch/arm/mach-s3c24xx/mach-smdk2440.c | 189 --- arch/arm/mach-s3c24xx/mach-smdk2443.c | 136 -- arch/arm/mach-s3c24xx/mach-tct_hammer.c | 156 --- arch/arm/mach-s3c24xx/mach-vr1000.c | 368 ------ arch/arm/mach-s3c24xx/mach-vstms.c | 165 --- arch/arm/mach-s3c24xx/nand-core.h | 24 - arch/arm/mach-s3c24xx/osiris.h | 50 - arch/arm/mach-s3c24xx/otom.h | 25 - arch/arm/mach-s3c24xx/pll-s3c2410.c | 83 -- arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c | 95 -- arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c | 122 -- arch/arm/mach-s3c24xx/pm-h1940.S | 19 - arch/arm/mach-s3c24xx/pm-s3c2410.c | 170 --- arch/arm/mach-s3c24xx/pm-s3c2412.c | 126 -- arch/arm/mach-s3c24xx/pm-s3c2416.c | 81 -- arch/arm/mach-s3c24xx/pm.c | 121 -- arch/arm/mach-s3c24xx/regs-dsc.h | 22 - arch/arm/mach-s3c24xx/regs-mem.h | 53 - arch/arm/mach-s3c24xx/s3c2410.c | 130 -- arch/arm/mach-s3c24xx/s3c2412-power.h | 34 - arch/arm/mach-s3c24xx/s3c2412.c | 175 --- arch/arm/mach-s3c24xx/s3c2416.c | 132 -- arch/arm/mach-s3c24xx/s3c2440.c | 71 -- arch/arm/mach-s3c24xx/s3c2442.c | 62 - arch/arm/mach-s3c24xx/s3c2443.c | 112 -- arch/arm/mach-s3c24xx/s3c244x.c | 128 -- arch/arm/mach-s3c24xx/setup-i2c.c | 22 - arch/arm/mach-s3c24xx/setup-sdhci-gpio.c | 31 - arch/arm/mach-s3c24xx/setup-spi.c | 27 - arch/arm/mach-s3c24xx/setup-ts.c | 29 - arch/arm/mach-s3c24xx/simtec-audio.c | 76 -- arch/arm/mach-s3c24xx/simtec-nor.c | 74 -- arch/arm/mach-s3c24xx/simtec-pm.c | 60 - arch/arm/mach-s3c24xx/simtec-usb.c | 125 -- arch/arm/mach-s3c24xx/simtec.h | 17 - arch/arm/mach-s3c24xx/sleep-s3c2410.S | 54 - arch/arm/mach-s3c24xx/sleep-s3c2412.S | 53 - arch/arm/mach-s3c24xx/sleep.S | 69 - arch/arm/mach-s3c24xx/spi-core.h | 27 - arch/arm/mach-s3c24xx/vr1000.h | 113 -- arch/arm/mach-s3c64xx/Kconfig | 350 ----- arch/arm/mach-s3c64xx/Makefile | 62 - arch/arm/mach-s3c64xx/ata-core.h | 24 - arch/arm/mach-s3c64xx/backlight.h | 22 - arch/arm/mach-s3c64xx/common.c | 423 ------- arch/arm/mach-s3c64xx/common.h | 66 - arch/arm/mach-s3c64xx/cpuidle.c | 60 - arch/arm/mach-s3c64xx/crag6410.h | 22 - arch/arm/mach-s3c64xx/dev-audio.c | 212 ---- arch/arm/mach-s3c64xx/dev-backlight.c | 137 -- arch/arm/mach-s3c64xx/dev-uart.c | 65 - arch/arm/mach-s3c64xx/include/mach/dma.h | 57 - arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h | 94 -- arch/arm/mach-s3c64xx/include/mach/irqs.h | 172 --- arch/arm/mach-s3c64xx/include/mach/map.h | 122 -- arch/arm/mach-s3c64xx/include/mach/pm-core.h | 84 -- arch/arm/mach-s3c64xx/include/mach/regs-clock.h | 34 - arch/arm/mach-s3c64xx/include/mach/regs-gpio.h | 188 --- arch/arm/mach-s3c64xx/include/mach/regs-irq.h | 15 - arch/arm/mach-s3c64xx/irq-pm.c | 119 -- arch/arm/mach-s3c64xx/irq-uart.h | 16 - arch/arm/mach-s3c64xx/mach-anw6410.c | 230 ---- arch/arm/mach-s3c64xx/mach-crag6410-module.c | 445 ------- arch/arm/mach-s3c64xx/mach-crag6410.c | 879 ------------- arch/arm/mach-s3c64xx/mach-hmt.c | 282 ----- arch/arm/mach-s3c64xx/mach-mini6410.c | 365 ------ arch/arm/mach-s3c64xx/mach-ncp.c | 100 -- arch/arm/mach-s3c64xx/mach-real6410.c | 333 ----- arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c | 51 - arch/arm/mach-s3c64xx/mach-smartq.c | 424 ------- arch/arm/mach-s3c64xx/mach-smartq.h | 16 - arch/arm/mach-s3c64xx/mach-smartq5.c | 154 --- arch/arm/mach-s3c64xx/mach-smartq7.c | 170 --- arch/arm/mach-s3c64xx/mach-smdk6400.c | 90 -- arch/arm/mach-s3c64xx/mach-smdk6410.c | 706 ----------- arch/arm/mach-s3c64xx/onenand-core.h | 32 - arch/arm/mach-s3c64xx/pl080.c | 264 ---- arch/arm/mach-s3c64xx/pm.c | 400 ------ arch/arm/mach-s3c64xx/regs-gpio-memport.h | 25 - arch/arm/mach-s3c64xx/regs-modem.h | 27 - arch/arm/mach-s3c64xx/regs-srom.h | 55 - arch/arm/mach-s3c64xx/regs-sys.h | 27 - arch/arm/mach-s3c64xx/regs-syscon-power.h | 112 -- arch/arm/mach-s3c64xx/regs-usb-hsotg-phy.h | 47 - arch/arm/mach-s3c64xx/s3c6400.c | 90 -- arch/arm/mach-s3c64xx/s3c6410.c | 94 -- arch/arm/mach-s3c64xx/setup-fb-24bpp.c | 23 - arch/arm/mach-s3c64xx/setup-i2c0.c | 24 - arch/arm/mach-s3c64xx/setup-i2c1.c | 24 - arch/arm/mach-s3c64xx/setup-ide.c | 39 - arch/arm/mach-s3c64xx/setup-keypad.c | 20 - arch/arm/mach-s3c64xx/setup-sdhci-gpio.c | 53 - arch/arm/mach-s3c64xx/setup-spi.c | 27 - arch/arm/mach-s3c64xx/setup-usb-phy.c | 90 -- arch/arm/mach-s3c64xx/sleep.S | 69 - arch/arm/plat-samsung/Kconfig | 247 ---- arch/arm/plat-samsung/Makefile | 30 - arch/arm/plat-samsung/adc.c | 510 -------- arch/arm/plat-samsung/cpu.c | 31 - arch/arm/plat-samsung/dev-uart.c | 41 - arch/arm/plat-samsung/devs.c | 1199 ------------------ arch/arm/plat-samsung/gpio-samsung.c | 1324 ------------------- arch/arm/plat-samsung/include/plat/adc-core.h | 24 - arch/arm/plat-samsung/include/plat/cpu.h | 128 -- arch/arm/plat-samsung/include/plat/devs.h | 96 -- arch/arm/plat-samsung/include/plat/fb.h | 31 - .../plat-samsung/include/plat/gpio-cfg-helpers.h | 159 --- arch/arm/plat-samsung/include/plat/gpio-cfg.h | 178 --- arch/arm/plat-samsung/include/plat/gpio-core.h | 142 --- arch/arm/plat-samsung/include/plat/iic-core.h | 38 - arch/arm/plat-samsung/include/plat/keypad.h | 27 - arch/arm/plat-samsung/include/plat/map-base.h | 42 - arch/arm/plat-samsung/include/plat/map-s3c.h | 70 - arch/arm/plat-samsung/include/plat/map-s5p.h | 20 - arch/arm/plat-samsung/include/plat/pm-common.h | 40 - arch/arm/plat-samsung/include/plat/pm.h | 109 -- arch/arm/plat-samsung/include/plat/pwm-core.h | 19 - arch/arm/plat-samsung/include/plat/regs-adc.h | 64 - arch/arm/plat-samsung/include/plat/regs-irqtype.h | 17 - arch/arm/plat-samsung/include/plat/sdhci.h | 162 --- arch/arm/plat-samsung/include/plat/usb-phy.h | 13 - arch/arm/plat-samsung/include/plat/wakeup-mask.h | 39 - arch/arm/plat-samsung/init.c | 173 --- arch/arm/plat-samsung/platformdata.c | 53 - arch/arm/plat-samsung/pm-common.c | 73 -- arch/arm/plat-samsung/pm-gpio.c | 380 ------ arch/arm/plat-samsung/pm.c | 199 --- arch/arm/plat-samsung/wakeup-mask.c | 42 - 378 files changed, 32130 insertions(+), 32048 deletions(-) create mode 100644 arch/arm/mach-s3c/Kconfig create mode 100644 arch/arm/mach-s3c/Kconfig.s3c24xx create mode 100644 arch/arm/mach-s3c/Kconfig.s3c64xx create mode 100644 arch/arm/mach-s3c/Makefile create mode 100644 arch/arm/mach-s3c/Makefile.boot create mode 100644 arch/arm/mach-s3c/Makefile.s3c24xx create mode 100644 arch/arm/mach-s3c/Makefile.s3c64xx create mode 100644 arch/arm/mach-s3c/adc.c create mode 100644 arch/arm/mach-s3c/anubis.h create mode 100644 arch/arm/mach-s3c/ata-core-s3c64xx.h create mode 100644 arch/arm/mach-s3c/backlight-s3c64xx.h create mode 100644 arch/arm/mach-s3c/bast-ide.c create mode 100644 arch/arm/mach-s3c/bast-irq.c create mode 100644 arch/arm/mach-s3c/bast.h create mode 100644 arch/arm/mach-s3c/common-smdk-s3c24xx.c create mode 100644 arch/arm/mach-s3c/common-smdk-s3c24xx.h create mode 100644 arch/arm/mach-s3c/cpu.c create mode 100644 arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c create mode 100644 arch/arm/mach-s3c/cpuidle-s3c64xx.c create mode 100644 arch/arm/mach-s3c/crag6410.h create mode 100644 arch/arm/mach-s3c/dev-audio-s3c64xx.c create mode 100644 arch/arm/mach-s3c/dev-backlight-s3c64xx.c create mode 100644 arch/arm/mach-s3c/dev-uart-s3c64xx.c create mode 100644 arch/arm/mach-s3c/dev-uart.c create mode 100644 arch/arm/mach-s3c/devs.c create mode 100644 arch/arm/mach-s3c/fb-core-s3c24xx.h create mode 100644 arch/arm/mach-s3c/gpio-samsung.c create mode 100644 arch/arm/mach-s3c/gta02.h create mode 100644 arch/arm/mach-s3c/h1940-bluetooth.c create mode 100644 arch/arm/mach-s3c/h1940.h create mode 100644 arch/arm/mach-s3c/include/mach/dma-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/dma-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/dma.h create mode 100644 arch/arm/mach-s3c/include/mach/gpio-samsung-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/gpio-samsung-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/gpio-samsung.h create mode 100644 arch/arm/mach-s3c/include/mach/hardware-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/io-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/io.h create mode 100644 arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/irqs.h create mode 100644 arch/arm/mach-s3c/include/mach/map-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/map-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/map.h create mode 100644 arch/arm/mach-s3c/include/mach/pm-core-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/pm-core-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/pm-core.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-clock-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-clock-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-clock.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-gpio-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-gpio-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-gpio.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-irq-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-irq-s3c64xx.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-irq.h create mode 100644 arch/arm/mach-s3c/include/mach/regs-s3c2443-clock.h create mode 100644 arch/arm/mach-s3c/include/mach/rtc-core-s3c24xx.h create mode 100644 arch/arm/mach-s3c/include/mach/s3c2412.h create mode 100644 arch/arm/mach-s3c/include/plat/adc-core.h create mode 100644 arch/arm/mach-s3c/include/plat/cpu.h create mode 100644 arch/arm/mach-s3c/include/plat/devs.h create mode 100644 arch/arm/mach-s3c/include/plat/fb.h create mode 100644 arch/arm/mach-s3c/include/plat/gpio-cfg-helpers.h create mode 100644 arch/arm/mach-s3c/include/plat/gpio-cfg.h create mode 100644 arch/arm/mach-s3c/include/plat/gpio-core.h create mode 100644 arch/arm/mach-s3c/include/plat/iic-core.h create mode 100644 arch/arm/mach-s3c/include/plat/keypad.h create mode 100644 arch/arm/mach-s3c/include/plat/map-base.h create mode 100644 arch/arm/mach-s3c/include/plat/map-s3c.h create mode 100644 arch/arm/mach-s3c/include/plat/map-s5p.h create mode 100644 arch/arm/mach-s3c/include/plat/pm-common.h create mode 100644 arch/arm/mach-s3c/include/plat/pm.h create mode 100644 arch/arm/mach-s3c/include/plat/pwm-core.h create mode 100644 arch/arm/mach-s3c/include/plat/regs-adc.h create mode 100644 arch/arm/mach-s3c/include/plat/regs-irqtype.h create mode 100644 arch/arm/mach-s3c/include/plat/sdhci.h create mode 100644 arch/arm/mach-s3c/include/plat/usb-phy.h create mode 100644 arch/arm/mach-s3c/include/plat/wakeup-mask.h create mode 100644 arch/arm/mach-s3c/init.c create mode 100644 arch/arm/mach-s3c/iotiming-s3c2410.c create mode 100644 arch/arm/mach-s3c/iotiming-s3c2412.c create mode 100644 arch/arm/mach-s3c/irq-pm-s3c24xx.c create mode 100644 arch/arm/mach-s3c/irq-pm-s3c64xx.c create mode 100644 arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c create mode 100644 arch/arm/mach-s3c/irq-s3c24xx-fiq.S create mode 100644 arch/arm/mach-s3c/irq-s3c24xx.c create mode 100644 arch/arm/mach-s3c/irq-uart-s3c64xx.h create mode 100644 arch/arm/mach-s3c/mach-amlm5900.c create mode 100644 arch/arm/mach-s3c/mach-anubis.c create mode 100644 arch/arm/mach-s3c/mach-anw6410.c create mode 100644 arch/arm/mach-s3c/mach-at2440evb.c create mode 100644 arch/arm/mach-s3c/mach-bast.c create mode 100644 arch/arm/mach-s3c/mach-crag6410-module.c create mode 100644 arch/arm/mach-s3c/mach-crag6410.c create mode 100644 arch/arm/mach-s3c/mach-gta02.c create mode 100644 arch/arm/mach-s3c/mach-h1940.c create mode 100644 arch/arm/mach-s3c/mach-hmt.c create mode 100644 arch/arm/mach-s3c/mach-jive.c create mode 100644 arch/arm/mach-s3c/mach-mini2440.c create mode 100644 arch/arm/mach-s3c/mach-mini6410.c create mode 100644 arch/arm/mach-s3c/mach-n30.c create mode 100644 arch/arm/mach-s3c/mach-ncp.c create mode 100644 arch/arm/mach-s3c/mach-nexcoder.c create mode 100644 arch/arm/mach-s3c/mach-osiris-dvs.c create mode 100644 arch/arm/mach-s3c/mach-osiris.c create mode 100644 arch/arm/mach-s3c/mach-otom.c create mode 100644 arch/arm/mach-s3c/mach-qt2410.c create mode 100644 arch/arm/mach-s3c/mach-real6410.c create mode 100644 arch/arm/mach-s3c/mach-rx1950.c create mode 100644 arch/arm/mach-s3c/mach-rx3715.c create mode 100644 arch/arm/mach-s3c/mach-s3c2416-dt.c create mode 100644 arch/arm/mach-s3c/mach-s3c64xx-dt.c create mode 100644 arch/arm/mach-s3c/mach-smartq.c create mode 100644 arch/arm/mach-s3c/mach-smartq.h create mode 100644 arch/arm/mach-s3c/mach-smartq5.c create mode 100644 arch/arm/mach-s3c/mach-smartq7.c create mode 100644 arch/arm/mach-s3c/mach-smdk2410.c create mode 100644 arch/arm/mach-s3c/mach-smdk2413.c create mode 100644 arch/arm/mach-s3c/mach-smdk2416.c create mode 100644 arch/arm/mach-s3c/mach-smdk2440.c create mode 100644 arch/arm/mach-s3c/mach-smdk2443.c create mode 100644 arch/arm/mach-s3c/mach-smdk6400.c create mode 100644 arch/arm/mach-s3c/mach-smdk6410.c create mode 100644 arch/arm/mach-s3c/mach-tct_hammer.c create mode 100644 arch/arm/mach-s3c/mach-vr1000.c create mode 100644 arch/arm/mach-s3c/mach-vstms.c create mode 100644 arch/arm/mach-s3c/nand-core-s3c24xx.h create mode 100644 arch/arm/mach-s3c/onenand-core-s3c64xx.h create mode 100644 arch/arm/mach-s3c/osiris.h create mode 100644 arch/arm/mach-s3c/otom.h create mode 100644 arch/arm/mach-s3c/pl080.c create mode 100644 arch/arm/mach-s3c/platformdata.c create mode 100644 arch/arm/mach-s3c/pll-s3c2410.c create mode 100644 arch/arm/mach-s3c/pll-s3c2440-12000000.c create mode 100644 arch/arm/mach-s3c/pll-s3c2440-16934400.c create mode 100644 arch/arm/mach-s3c/pm-common.c create mode 100644 arch/arm/mach-s3c/pm-gpio.c create mode 100644 arch/arm/mach-s3c/pm-h1940.S create mode 100644 arch/arm/mach-s3c/pm-s3c2410.c create mode 100644 arch/arm/mach-s3c/pm-s3c2412.c create mode 100644 arch/arm/mach-s3c/pm-s3c2416.c create mode 100644 arch/arm/mach-s3c/pm-s3c24xx.c create mode 100644 arch/arm/mach-s3c/pm-s3c64xx.c create mode 100644 arch/arm/mach-s3c/pm.c create mode 100644 arch/arm/mach-s3c/regs-dsc-s3c24xx.h create mode 100644 arch/arm/mach-s3c/regs-gpio-memport-s3c64xx.h create mode 100644 arch/arm/mach-s3c/regs-mem-s3c24xx.h create mode 100644 arch/arm/mach-s3c/regs-modem-s3c64xx.h create mode 100644 arch/arm/mach-s3c/regs-srom-s3c64xx.h create mode 100644 arch/arm/mach-s3c/regs-sys-s3c64xx.h create mode 100644 arch/arm/mach-s3c/regs-syscon-power-s3c64xx.h create mode 100644 arch/arm/mach-s3c/regs-usb-hsotg-phy-s3c64xx.h create mode 100644 arch/arm/mach-s3c/s3c2410.c create mode 100644 arch/arm/mach-s3c/s3c2412-power.h create mode 100644 arch/arm/mach-s3c/s3c2412.c create mode 100644 arch/arm/mach-s3c/s3c2416.c create mode 100644 arch/arm/mach-s3c/s3c2440.c create mode 100644 arch/arm/mach-s3c/s3c2442.c create mode 100644 arch/arm/mach-s3c/s3c2443.c create mode 100644 arch/arm/mach-s3c/s3c244x.c create mode 100644 arch/arm/mach-s3c/s3c24xx.c create mode 100644 arch/arm/mach-s3c/s3c24xx.h create mode 100644 arch/arm/mach-s3c/s3c6400.c create mode 100644 arch/arm/mach-s3c/s3c6410.c create mode 100644 arch/arm/mach-s3c/s3c64xx.c create mode 100644 arch/arm/mach-s3c/s3c64xx.h create mode 100644 arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-i2c-s3c24xx.c create mode 100644 arch/arm/mach-s3c/setup-i2c0-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-i2c1-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-ide-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-keypad-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-sdhci-gpio-s3c24xx.c create mode 100644 arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-spi-s3c24xx.c create mode 100644 arch/arm/mach-s3c/setup-spi-s3c64xx.c create mode 100644 arch/arm/mach-s3c/setup-ts-s3c24xx.c create mode 100644 arch/arm/mach-s3c/setup-usb-phy-s3c64xx.c create mode 100644 arch/arm/mach-s3c/simtec-audio.c create mode 100644 arch/arm/mach-s3c/simtec-nor.c create mode 100644 arch/arm/mach-s3c/simtec-pm.c create mode 100644 arch/arm/mach-s3c/simtec-usb.c create mode 100644 arch/arm/mach-s3c/simtec.h create mode 100644 arch/arm/mach-s3c/sleep-s3c2410.S create mode 100644 arch/arm/mach-s3c/sleep-s3c2412.S create mode 100644 arch/arm/mach-s3c/sleep-s3c24xx.S create mode 100644 arch/arm/mach-s3c/sleep-s3c64xx.S create mode 100644 arch/arm/mach-s3c/spi-core-s3c24xx.h create mode 100644 arch/arm/mach-s3c/vr1000.h create mode 100644 arch/arm/mach-s3c/wakeup-mask.c delete mode 100644 arch/arm/mach-s3c24xx/Kconfig delete mode 100644 arch/arm/mach-s3c24xx/Makefile delete mode 100644 arch/arm/mach-s3c24xx/Makefile.boot delete mode 100644 arch/arm/mach-s3c24xx/anubis.h delete mode 100644 arch/arm/mach-s3c24xx/bast-ide.c delete mode 100644 arch/arm/mach-s3c24xx/bast-irq.c delete mode 100644 arch/arm/mach-s3c24xx/bast.h delete mode 100644 arch/arm/mach-s3c24xx/common-smdk.c delete mode 100644 arch/arm/mach-s3c24xx/common-smdk.h delete mode 100644 arch/arm/mach-s3c24xx/common.c delete mode 100644 arch/arm/mach-s3c24xx/common.h delete mode 100644 arch/arm/mach-s3c24xx/cpufreq-utils.c delete mode 100644 arch/arm/mach-s3c24xx/fb-core.h delete mode 100644 arch/arm/mach-s3c24xx/gta02.h delete mode 100644 arch/arm/mach-s3c24xx/h1940-bluetooth.c delete mode 100644 arch/arm/mach-s3c24xx/h1940.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/dma.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/hardware.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/io.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/irqs.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/map.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/pm-core.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-clock.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-gpio.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-irq.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/rtc-core.h delete mode 100644 arch/arm/mach-s3c24xx/include/mach/s3c2412.h delete mode 100644 arch/arm/mach-s3c24xx/iotiming-s3c2410.c delete mode 100644 arch/arm/mach-s3c24xx/iotiming-s3c2412.c delete mode 100644 arch/arm/mach-s3c24xx/irq-pm.c delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c24xx-fiq-exports.c delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c24xx-fiq.S delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c24xx.c delete mode 100644 arch/arm/mach-s3c24xx/mach-amlm5900.c delete mode 100644 arch/arm/mach-s3c24xx/mach-anubis.c delete mode 100644 arch/arm/mach-s3c24xx/mach-at2440evb.c delete mode 100644 arch/arm/mach-s3c24xx/mach-bast.c delete mode 100644 arch/arm/mach-s3c24xx/mach-gta02.c delete mode 100644 arch/arm/mach-s3c24xx/mach-h1940.c delete mode 100644 arch/arm/mach-s3c24xx/mach-jive.c delete mode 100644 arch/arm/mach-s3c24xx/mach-mini2440.c delete mode 100644 arch/arm/mach-s3c24xx/mach-n30.c delete mode 100644 arch/arm/mach-s3c24xx/mach-nexcoder.c delete mode 100644 arch/arm/mach-s3c24xx/mach-osiris-dvs.c delete mode 100644 arch/arm/mach-s3c24xx/mach-osiris.c delete mode 100644 arch/arm/mach-s3c24xx/mach-otom.c delete mode 100644 arch/arm/mach-s3c24xx/mach-qt2410.c delete mode 100644 arch/arm/mach-s3c24xx/mach-rx1950.c delete mode 100644 arch/arm/mach-s3c24xx/mach-rx3715.c delete mode 100644 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c delete mode 100644 arch/arm/mach-s3c24xx/mach-smdk2410.c delete mode 100644 arch/arm/mach-s3c24xx/mach-smdk2413.c delete mode 100644 arch/arm/mach-s3c24xx/mach-smdk2416.c delete mode 100644 arch/arm/mach-s3c24xx/mach-smdk2440.c delete mode 100644 arch/arm/mach-s3c24xx/mach-smdk2443.c delete mode 100644 arch/arm/mach-s3c24xx/mach-tct_hammer.c delete mode 100644 arch/arm/mach-s3c24xx/mach-vr1000.c delete mode 100644 arch/arm/mach-s3c24xx/mach-vstms.c delete mode 100644 arch/arm/mach-s3c24xx/nand-core.h delete mode 100644 arch/arm/mach-s3c24xx/osiris.h delete mode 100644 arch/arm/mach-s3c24xx/otom.h delete mode 100644 arch/arm/mach-s3c24xx/pll-s3c2410.c delete mode 100644 arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c delete mode 100644 arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c delete mode 100644 arch/arm/mach-s3c24xx/pm-h1940.S delete mode 100644 arch/arm/mach-s3c24xx/pm-s3c2410.c delete mode 100644 arch/arm/mach-s3c24xx/pm-s3c2412.c delete mode 100644 arch/arm/mach-s3c24xx/pm-s3c2416.c delete mode 100644 arch/arm/mach-s3c24xx/pm.c delete mode 100644 arch/arm/mach-s3c24xx/regs-dsc.h delete mode 100644 arch/arm/mach-s3c24xx/regs-mem.h delete mode 100644 arch/arm/mach-s3c24xx/s3c2410.c delete mode 100644 arch/arm/mach-s3c24xx/s3c2412-power.h delete mode 100644 arch/arm/mach-s3c24xx/s3c2412.c delete mode 100644 arch/arm/mach-s3c24xx/s3c2416.c delete mode 100644 arch/arm/mach-s3c24xx/s3c2440.c delete mode 100644 arch/arm/mach-s3c24xx/s3c2442.c delete mode 100644 arch/arm/mach-s3c24xx/s3c2443.c delete mode 100644 arch/arm/mach-s3c24xx/s3c244x.c delete mode 100644 arch/arm/mach-s3c24xx/setup-i2c.c delete mode 100644 arch/arm/mach-s3c24xx/setup-sdhci-gpio.c delete mode 100644 arch/arm/mach-s3c24xx/setup-spi.c delete mode 100644 arch/arm/mach-s3c24xx/setup-ts.c delete mode 100644 arch/arm/mach-s3c24xx/simtec-audio.c delete mode 100644 arch/arm/mach-s3c24xx/simtec-nor.c delete mode 100644 arch/arm/mach-s3c24xx/simtec-pm.c delete mode 100644 arch/arm/mach-s3c24xx/simtec-usb.c delete mode 100644 arch/arm/mach-s3c24xx/simtec.h delete mode 100644 arch/arm/mach-s3c24xx/sleep-s3c2410.S delete mode 100644 arch/arm/mach-s3c24xx/sleep-s3c2412.S delete mode 100644 arch/arm/mach-s3c24xx/sleep.S delete mode 100644 arch/arm/mach-s3c24xx/spi-core.h delete mode 100644 arch/arm/mach-s3c24xx/vr1000.h delete mode 100644 arch/arm/mach-s3c64xx/Kconfig delete mode 100644 arch/arm/mach-s3c64xx/Makefile delete mode 100644 arch/arm/mach-s3c64xx/ata-core.h delete mode 100644 arch/arm/mach-s3c64xx/backlight.h delete mode 100644 arch/arm/mach-s3c64xx/common.c delete mode 100644 arch/arm/mach-s3c64xx/common.h delete mode 100644 arch/arm/mach-s3c64xx/cpuidle.c delete mode 100644 arch/arm/mach-s3c64xx/crag6410.h delete mode 100644 arch/arm/mach-s3c64xx/dev-audio.c delete mode 100644 arch/arm/mach-s3c64xx/dev-backlight.c delete mode 100644 arch/arm/mach-s3c64xx/dev-uart.c delete mode 100644 arch/arm/mach-s3c64xx/include/mach/dma.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/irqs.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/map.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/pm-core.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/regs-clock.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/regs-gpio.h delete mode 100644 arch/arm/mach-s3c64xx/include/mach/regs-irq.h delete mode 100644 arch/arm/mach-s3c64xx/irq-pm.c delete mode 100644 arch/arm/mach-s3c64xx/irq-uart.h delete mode 100644 arch/arm/mach-s3c64xx/mach-anw6410.c delete mode 100644 arch/arm/mach-s3c64xx/mach-crag6410-module.c delete mode 100644 arch/arm/mach-s3c64xx/mach-crag6410.c delete mode 100644 arch/arm/mach-s3c64xx/mach-hmt.c delete mode 100644 arch/arm/mach-s3c64xx/mach-mini6410.c delete mode 100644 arch/arm/mach-s3c64xx/mach-ncp.c delete mode 100644 arch/arm/mach-s3c64xx/mach-real6410.c delete mode 100644 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c delete mode 100644 arch/arm/mach-s3c64xx/mach-smartq.c delete mode 100644 arch/arm/mach-s3c64xx/mach-smartq.h delete mode 100644 arch/arm/mach-s3c64xx/mach-smartq5.c delete mode 100644 arch/arm/mach-s3c64xx/mach-smartq7.c delete mode 100644 arch/arm/mach-s3c64xx/mach-smdk6400.c delete mode 100644 arch/arm/mach-s3c64xx/mach-smdk6410.c delete mode 100644 arch/arm/mach-s3c64xx/onenand-core.h delete mode 100644 arch/arm/mach-s3c64xx/pl080.c delete mode 100644 arch/arm/mach-s3c64xx/pm.c delete mode 100644 arch/arm/mach-s3c64xx/regs-gpio-memport.h delete mode 100644 arch/arm/mach-s3c64xx/regs-modem.h delete mode 100644 arch/arm/mach-s3c64xx/regs-srom.h delete mode 100644 arch/arm/mach-s3c64xx/regs-sys.h delete mode 100644 arch/arm/mach-s3c64xx/regs-syscon-power.h delete mode 100644 arch/arm/mach-s3c64xx/regs-usb-hsotg-phy.h delete mode 100644 arch/arm/mach-s3c64xx/s3c6400.c delete mode 100644 arch/arm/mach-s3c64xx/s3c6410.c delete mode 100644 arch/arm/mach-s3c64xx/setup-fb-24bpp.c delete mode 100644 arch/arm/mach-s3c64xx/setup-i2c0.c delete mode 100644 arch/arm/mach-s3c64xx/setup-i2c1.c delete mode 100644 arch/arm/mach-s3c64xx/setup-ide.c delete mode 100644 arch/arm/mach-s3c64xx/setup-keypad.c delete mode 100644 arch/arm/mach-s3c64xx/setup-sdhci-gpio.c delete mode 100644 arch/arm/mach-s3c64xx/setup-spi.c delete mode 100644 arch/arm/mach-s3c64xx/setup-usb-phy.c delete mode 100644 arch/arm/mach-s3c64xx/sleep.S delete mode 100644 arch/arm/plat-samsung/Kconfig delete mode 100644 arch/arm/plat-samsung/Makefile delete mode 100644 arch/arm/plat-samsung/adc.c delete mode 100644 arch/arm/plat-samsung/cpu.c delete mode 100644 arch/arm/plat-samsung/dev-uart.c delete mode 100644 arch/arm/plat-samsung/devs.c delete mode 100644 arch/arm/plat-samsung/gpio-samsung.c delete mode 100644 arch/arm/plat-samsung/include/plat/adc-core.h delete mode 100644 arch/arm/plat-samsung/include/plat/cpu.h delete mode 100644 arch/arm/plat-samsung/include/plat/devs.h delete mode 100644 arch/arm/plat-samsung/include/plat/fb.h delete mode 100644 arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h delete mode 100644 arch/arm/plat-samsung/include/plat/gpio-cfg.h delete mode 100644 arch/arm/plat-samsung/include/plat/gpio-core.h delete mode 100644 arch/arm/plat-samsung/include/plat/iic-core.h delete mode 100644 arch/arm/plat-samsung/include/plat/keypad.h delete mode 100644 arch/arm/plat-samsung/include/plat/map-base.h delete mode 100644 arch/arm/plat-samsung/include/plat/map-s3c.h delete mode 100644 arch/arm/plat-samsung/include/plat/map-s5p.h delete mode 100644 arch/arm/plat-samsung/include/plat/pm-common.h delete mode 100644 arch/arm/plat-samsung/include/plat/pm.h delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h delete mode 100644 arch/arm/plat-samsung/include/plat/regs-adc.h delete mode 100644 arch/arm/plat-samsung/include/plat/regs-irqtype.h delete mode 100644 arch/arm/plat-samsung/include/plat/sdhci.h delete mode 100644 arch/arm/plat-samsung/include/plat/usb-phy.h delete mode 100644 arch/arm/plat-samsung/include/plat/wakeup-mask.h delete mode 100644 arch/arm/plat-samsung/init.c delete mode 100644 arch/arm/plat-samsung/platformdata.c delete mode 100644 arch/arm/plat-samsung/pm-common.c delete mode 100644 arch/arm/plat-samsung/pm-gpio.c delete mode 100644 arch/arm/plat-samsung/pm.c delete mode 100644 arch/arm/plat-samsung/wakeup-mask.c (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index a14144691ca5..a1e5be8f9f09 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2220,8 +2220,8 @@ ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT L: openmoko-kernel@lists.openmoko.org (subscribers-only) S: Orphan W: http://wiki.openmoko.org/wiki/Neo_FreeRunner -F: arch/arm/mach-s3c24xx/gta02.h -F: arch/arm/mach-s3c24xx/mach-gta02.c +F: arch/arm/mach-s3c/gta02.h +F: arch/arm/mach-s3c/mach-gta02.c ARM/Orion SoC/Technologic Systems TS-78xx platform support M: Alexander Clouter @@ -2410,10 +2410,8 @@ F: arch/arm/boot/dts/exynos* F: arch/arm/boot/dts/s3c* F: arch/arm/boot/dts/s5p* F: arch/arm/mach-exynos*/ -F: arch/arm/mach-s3c24*/ -F: arch/arm/mach-s3c64xx/ +F: arch/arm/mach-s3c/ F: arch/arm/mach-s5p*/ -F: arch/arm/plat-samsung/ F: arch/arm64/boot/dts/exynos/ F: drivers/*/*/*s3c24* F: drivers/*/*s3c24* @@ -15839,9 +15837,9 @@ SIMTEC EB2410ITX (BAST) M: Simtec Linux Team S: Supported W: http://www.simtec.co.uk/products/EB2410ITX/ -F: arch/arm/mach-s3c24xx/bast-ide.c -F: arch/arm/mach-s3c24xx/bast-irq.c -F: arch/arm/mach-s3c24xx/mach-bast.c +F: arch/arm/mach-s3c/bast-ide.c +F: arch/arm/mach-s3c/bast-irq.c +F: arch/arm/mach-s3c/mach-bast.c SIOX M: Thorsten Scherer @@ -18760,7 +18758,7 @@ F: Documentation/devicetree/bindings/mfd/wm831x.txt F: Documentation/devicetree/bindings/regulator/wlf,arizona.yaml F: Documentation/devicetree/bindings/sound/wlf,arizona.yaml F: Documentation/hwmon/wm83??.rst -F: arch/arm/mach-s3c64xx/mach-crag6410* +F: arch/arm/mach-s3c/mach-crag6410* F: drivers/clk/clk-wm83*.c F: drivers/extcon/extcon-arizona.c F: drivers/gpio/gpio-*wm*.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 97aedb9a73eb..82c197a248dd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -637,7 +637,6 @@ source "arch/arm/mach-dove/Kconfig" source "arch/arm/mach-ep93xx/Kconfig" source "arch/arm/mach-exynos/Kconfig" -source "arch/arm/plat-samsung/Kconfig" source "arch/arm/mach-footbridge/Kconfig" @@ -710,9 +709,7 @@ source "arch/arm/mach-realview/Kconfig" source "arch/arm/mach-rockchip/Kconfig" -source "arch/arm/mach-s3c24xx/Kconfig" - -source "arch/arm/mach-s3c64xx/Kconfig" +source "arch/arm/mach-s3c/Kconfig" source "arch/arm/mach-s5pv210/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 3997cec8848e..d3a447a856ce 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -209,8 +209,7 @@ machine-$(CONFIG_ARCH_REALTEK) += realtek machine-$(CONFIG_ARCH_REALVIEW) += realview machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_ARCH_RPC) += rpc -machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx -machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx +machine-$(CONFIG_PLAT_SAMSUNG) += s3c machine-$(CONFIG_ARCH_S5PV210) += s5pv210 machine-$(CONFIG_ARCH_SA1100) += sa1100 machine-$(CONFIG_ARCH_RENESAS) += shmobile @@ -233,10 +232,8 @@ machine-$(CONFIG_PLAT_SPEAR) += spear # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. plat-$(CONFIG_ARCH_OMAP) += omap -plat-$(CONFIG_ARCH_S3C64XX) += samsung plat-$(CONFIG_PLAT_ORION) += orion plat-$(CONFIG_PLAT_PXA) += pxa -plat-$(CONFIG_PLAT_S3C24XX) += samsung plat-$(CONFIG_PLAT_VERSATILE) += versatile ifeq ($(CONFIG_ARCH_EBSA110),y) diff --git a/arch/arm/mach-s3c/Kconfig b/arch/arm/mach-s3c/Kconfig new file mode 100644 index 000000000000..25606e668cf9 --- /dev/null +++ b/arch/arm/mach-s3c/Kconfig @@ -0,0 +1,250 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2009 Simtec Electronics + +source "arch/arm/mach-s3c/Kconfig.s3c24xx" +source "arch/arm/mach-s3c/Kconfig.s3c64xx" + +config PLAT_SAMSUNG + bool + depends on PLAT_S3C24XX || ARCH_S3C64XX + default y + select GENERIC_IRQ_CHIP + select NO_IOPORT_MAP + select SOC_SAMSUNG + help + Base platform code for all Samsung SoC based systems + +config SAMSUNG_PM + bool + depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX) + default y + help + Base platform power management code for samsung code + +if PLAT_SAMSUNG +menu "Samsung Common options" + +# boot configurations + +comment "Boot options" + +config S3C_LOWLEVEL_UART_PORT + int "S3C UART to use for low-level messages" + depends on ARCH_S3C64XX + default 0 + help + Choice of which UART port to use for the low-level messages, + such as the `Uncompressing...` at start time. The value of + this configuration should be between zero and two. The port + must have been initialised by the boot-loader before use. + +config SAMSUNG_ATAGS + def_bool n + depends on ATAGS + help + This option enables ATAGS based boot support code for + Samsung platforms, including static platform devices, legacy + clock, timer and interrupt initialization, etc. + + Platforms that support only DT based boot need not to select + this option. + +if SAMSUNG_ATAGS + +config S3C_GPIO_SPACE + int "Space between gpio banks" + default 0 + help + Add a number of spare GPIO entries between each bank for debugging + purposes. This allows any problems where an counter overflows from + one bank to another to be caught, at the expense of using a little + more memory. + +config S3C_GPIO_TRACK + bool + help + Internal configuration option to enable the s3c specific gpio + chip tracking if the platform requires it. + +# ADC driver + +config S3C_ADC + bool "ADC common driver support" + depends on !ARCH_MULTIPLATFORM + help + Core support for the ADC block found in the Samsung SoC systems + for drivers such as the touchscreen and hwmon to use to share + this resource. + +# device definitions to compile in + +config S3C_DEV_HSMMC + bool + help + Compile in platform device definitions for HSMMC code + +config S3C_DEV_HSMMC1 + bool + help + Compile in platform device definitions for HSMMC channel 1 + +config S3C_DEV_HSMMC2 + bool + help + Compile in platform device definitions for HSMMC channel 2 + +config S3C_DEV_HSMMC3 + bool + help + Compile in platform device definitions for HSMMC channel 3 + +config S3C_DEV_HWMON + bool + help + Compile in platform device definitions for HWMON + +config S3C_DEV_I2C1 + bool + help + Compile in platform device definitions for I2C channel 1 + +config S3C_DEV_I2C2 + bool + help + Compile in platform device definitions for I2C channel 2 + +config S3C_DEV_I2C3 + bool + help + Compile in platform device definition for I2C controller 3 + +config S3C_DEV_I2C4 + bool + help + Compile in platform device definition for I2C controller 4 + +config S3C_DEV_I2C5 + bool + help + Compile in platform device definition for I2C controller 5 + +config S3C_DEV_I2C6 + bool + help + Compile in platform device definition for I2C controller 6 + +config S3C_DEV_I2C7 + bool + help + Compile in platform device definition for I2C controller 7 + +config S3C_DEV_FB + bool + help + Compile in platform device definition for framebuffer + +config S3C_DEV_USB_HOST + bool + help + Compile in platform device definition for USB host. + +config S3C_DEV_USB_HSOTG + bool + help + Compile in platform device definition for USB high-speed OtG + +config S3C_DEV_WDT + bool + default y if ARCH_S3C24XX + help + Compile in platform device definition for Watchdog Timer + +config S3C_DEV_NAND + bool + help + Compile in platform device definition for NAND controller + +config S3C_DEV_ONENAND + bool + help + Compile in platform device definition for OneNAND controller + +config S3C_DEV_RTC + bool + help + Compile in platform device definition for RTC + +config SAMSUNG_DEV_ADC + bool + help + Compile in platform device definition for ADC controller + +config SAMSUNG_DEV_IDE + bool + help + Compile in platform device definitions for IDE + +config S3C64XX_DEV_SPI0 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 0 + +config S3C64XX_DEV_SPI1 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 1 + +config S3C64XX_DEV_SPI2 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 2 + +config SAMSUNG_DEV_TS + bool + help + Common in platform device definitions for touchscreen device + +config SAMSUNG_DEV_KEYPAD + bool + help + Compile in platform device definitions for keypad + +config SAMSUNG_DEV_PWM + bool + default y if ARCH_S3C24XX + help + Compile in platform device definition for PWM Timer + +config S3C24XX_PWM + bool "PWM device support" + select PWM + select PWM_SAMSUNG + help + Support for exporting the PWM timer blocks via the pwm device + system + +config GPIO_SAMSUNG + def_bool y + +config SAMSUNG_PM_GPIO + bool + default y if GPIO_SAMSUNG && PM + help + Include legacy GPIO power management code for platforms not using + pinctrl-samsung driver. +endif + +config SAMSUNG_WAKEMASK + bool + depends on PM + help + Compile support for wakeup-mask controls found on the S3C6400 + and above. This code allows a set of interrupt to wakeup-mask + mappings. See + +endmenu +endif diff --git a/arch/arm/mach-s3c/Kconfig.s3c24xx b/arch/arm/mach-s3c/Kconfig.s3c24xx new file mode 100644 index 000000000000..000e3e234f71 --- /dev/null +++ b/arch/arm/mach-s3c/Kconfig.s3c24xx @@ -0,0 +1,583 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2012 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Copyright 2007 Simtec Electronics + +if ARCH_S3C24XX + +config PLAT_S3C24XX + def_bool y + select GPIOLIB + select NO_IOPORT_MAP + select S3C_DEV_NAND + select IRQ_DOMAIN + select COMMON_CLK + help + Base platform code for any Samsung S3C24XX device + + + +menu "Samsung S3C24XX SoCs Support" + +comment "S3C24XX SoCs" + +config CPU_S3C2410 + bool "Samsung S3C2410" + default y + select CPU_ARM920T + select S3C2410_COMMON_CLK + select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ + select S3C2410_PM if PM + help + Support for S3C2410 and S3C2410A family from the S3C24XX line + of Samsung Mobile CPUs. + +config CPU_S3C2412 + bool "Samsung S3C2412" + select CPU_ARM926T + select S3C2412_COMMON_CLK + select S3C2412_PM if PM_SLEEP + help + Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line + +config CPU_S3C2416 + bool "Samsung S3C2416/S3C2450" + select CPU_ARM926T + select S3C2416_PM if PM_SLEEP + select S3C2443_COMMON_CLK + help + Support for the S3C2416 SoC from the S3C24XX line + +config CPU_S3C2440 + bool "Samsung S3C2440" + select CPU_ARM920T + select S3C2410_COMMON_CLK + select S3C2410_PM if PM_SLEEP + help + Support for S3C2440 Samsung Mobile CPU based systems. + +config CPU_S3C2442 + bool "Samsung S3C2442" + select CPU_ARM920T + select S3C2410_COMMON_CLK + select S3C2410_PM if PM_SLEEP + help + Support for S3C2442 Samsung Mobile CPU based systems. + +config CPU_S3C244X + def_bool y + depends on CPU_S3C2440 || CPU_S3C2442 + +config CPU_S3C2443 + bool "Samsung S3C2443" + select CPU_ARM920T + select S3C2443_COMMON_CLK + help + Support for the S3C2443 SoC from the S3C24XX line + +# common code + +config S3C24XX_SMDK + bool + help + Common machine code for SMDK2410 and SMDK2440 + +config S3C24XX_SIMTEC_AUDIO + bool + depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS) + default y + help + Add audio devices for common Simtec S3C24XX boards + +config S3C24XX_SIMTEC_PM + bool + help + Common power management code for systems that are + compatible with the Simtec style of power management + +config S3C24XX_SIMTEC_USB + bool + help + USB management code for common Simtec S3C24XX boards + +config S3C24XX_SETUP_TS + bool + help + Compile in platform device definition for Samsung TouchScreen. + +config S3C2410_PM + bool + help + Power Management code common to S3C2410 and better + +config S3C24XX_PLL + bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)" + depends on ARM_S3C24XX_CPUFREQ + help + Compile in support for changing the PLL frequency from the + S3C24XX series CPUfreq driver. The PLL takes time to settle + after a frequency change, so by default it is not enabled. + + This also means that the PLL tables for the selected CPU(s) will + be built which may increase the size of the kernel image. + +# cpu frequency items common between s3c2410 and s3c2440/s3c2442 + +config S3C2410_IOTIMING + bool + depends on ARM_S3C24XX_CPUFREQ + help + Internal node to select io timing code that is common to the s3c2410 + and s3c2440/s3c2442 cpu frequency support. + +# cpu frequency support common to s3c2412, s3c2413 and s3c2442 + +config S3C2412_IOTIMING + bool + depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443) + help + Intel node to select io timing code that is common to the s3c2412 + and the s3c2443. + +# cpu-specific sections + +if CPU_S3C2410 + +config S3C2410_PLL + bool + depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL + default y + help + Select the PLL table for the S3C2410 + +config S3C24XX_SIMTEC_NOR + bool + help + Internal node to specify machine has simtec NOR mapping + +config MACH_BAST_IDE + bool + select HAVE_PATA_PLATFORM + help + Internal node for machines with an BAST style IDE + interface + +comment "S3C2410 Boards" + +# +# The "S3C2410 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_AML_M5900 + bool "AML M5900 Series" + select S3C24XX_SIMTEC_PM if PM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the American Microsystems M5900 Series + + +config ARCH_BAST + bool "Simtec Electronics BAST (EB2410ITX)" + select ISA + select MACH_BAST_IDE + select S3C2410_COMMON_DCLK + select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ + select S3C24XX_SIMTEC_NOR + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_SIMTEC_USB + select S3C_DEV_HWMON + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec Electronics EB2410ITX + development board (also known as BAST) + +config BAST_PC104_IRQ + bool "BAST PC104 IRQ support" + depends on ARCH_BAST + default y + help + Say Y here to enable the PC104 IRQ routing on the + Simtec BAST (EB2410ITX) + +config ARCH_H1940 + bool "IPAQ H1940" + select PM_H1940 if PM + select S3C24XX_SETUP_TS + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the HP IPAQ H1940 + +config H1940BT + tristate "Control the state of H1940 bluetooth chip" + depends on ARCH_H1940 + depends on RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on h1940. + +config MACH_N30 + bool "Acer N30 family" + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you want suppt for the Acer N30, Acer N35, + Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. + +config MACH_OTOM + bool "NexVision OTOM Board" + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Nex Vision OTOM board + +config MACH_QT2410 + bool "QT2410" + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Armzone QT2410 + +config ARCH_SMDK2410 + bool "SMDK2410/A9M2410" + select S3C24XX_SMDK + select S3C_DEV_USB_HOST + help + Say Y here if you are using the SMDK2410 or the derived module A9M2410 + + +config MACH_TCT_HAMMER + bool "TCT Hammer Board" + select S3C_DEV_USB_HOST + help + Say Y here if you are using the TinCanTools Hammer Board + + +config MACH_VR1000 + bool "Thorcom VR1000" + select MACH_BAST_IDE + select S3C2410_COMMON_DCLK + select S3C24XX_SIMTEC_NOR + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_SIMTEC_USB + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Thorcom VR1000 board. + +endif # CPU_S3C2410 + +config S3C2412_PM_SLEEP + bool + help + Internal config node to apply sleep for S3C2412 power management. + Can be selected by another SoCs such as S3C2416 with similar + sleep procedure. + +if CPU_S3C2412 + +config CPU_S3C2412_ONLY + bool + depends on !CPU_S3C2410 && !CPU_S3C2416 && !CPU_S3C2440 && \ + !CPU_S3C2442 && !CPU_S3C2443 + default y + +config S3C2412_PM + bool + select S3C2412_PM_SLEEP + select SAMSUNG_WAKEMASK + help + Internal config node to apply S3C2412 power management + +comment "S3C2412 Boards" + +# +# The "S3C2412 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_JIVE + bool "Logitech Jive" + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Logitech Jive. + +config MACH_JIVE_SHOW_BOOTLOADER + bool "Allow access to bootloader partitions in MTD" + depends on MACH_JIVE + +config MACH_S3C2413 + bool + help + Internal node for S3C2413 version of SMDK2413, so that + machine_is_s3c2413() will work when MACH_SMDK2413 is + selected + +config MACH_SMDK2412 + bool "SMDK2412" + select MACH_SMDK2413 + help + Say Y here if you are using an SMDK2412 + + Note, this shares support with SMDK2413, so will automatically + select MACH_SMDK2413. + +config MACH_SMDK2413 + bool "SMDK2413" + select MACH_S3C2413 + select S3C24XX_SMDK + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using an SMDK2413 + +config MACH_VSTMS + bool "VMSTMS" + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using an VSTMS board + +endif # CPU_S3C2412 + +if CPU_S3C2416 + +config S3C2416_PM + bool + select S3C2412_PM_SLEEP + select SAMSUNG_WAKEMASK + help + Internal config node to apply S3C2416 power management + +config S3C2416_SETUP_SDHCI + bool + select S3C2416_SETUP_SDHCI_GPIO + help + Internal helper functions for S3C2416 based SDHCI systems + +config S3C2416_SETUP_SDHCI_GPIO + bool + help + Common setup code for SDHCI gpio. + +comment "S3C2416 Boards" + +config MACH_SMDK2416 + bool "SMDK2416" + select S3C2416_SETUP_SDHCI + select S3C24XX_SMDK + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using an SMDK2416 + +config MACH_S3C2416_DT + bool "Samsung S3C2416 machine using devicetree" + select TIMER_OF + select USE_OF + select PINCTRL + select PINCTRL_S3C24XX + help + Machine support for Samsung S3C2416 machines with device tree enabled. + Select this if a fdt blob is available for the S3C2416 SoC based board. + Note: This is under development and not all peripherals can be supported + with this machine file. + +endif # CPU_S3C2416 + +if CPU_S3C2440 || CPU_S3C2442 + +config S3C2440_XTAL_12000000 + bool + help + Indicate that the build needs to support 12MHz system + crystal. + +config S3C2440_XTAL_16934400 + bool + help + Indicate that the build needs to support 16.9344MHz system + crystal. + +config S3C2440_PLL_12000000 + bool + depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000 + default y if S3C24XX_PLL + help + PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals. + +config S3C2440_PLL_16934400 + bool + depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400 + default y if S3C24XX_PLL + help + PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. +endif + +if CPU_S3C2440 + +comment "S3C2440 Boards" + +# +# The "S3C2440 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_ANUBIS + bool "Simtec Electronics ANUBIS" + select HAVE_PATA_PLATFORM + select S3C2410_COMMON_DCLK + select S3C2440_XTAL_12000000 + select S3C24XX_SIMTEC_PM if PM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec Electronics ANUBIS + development system + +config MACH_AT2440EVB + bool "Avantech AT2440EVB development board" + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the AT2440EVB development board + +config MACH_MINI2440 + bool "MINI2440 development board" + select LEDS_CLASS + select LEDS_TRIGGERS + select LEDS_TRIGGER_BACKLIGHT + select NEW_LEDS + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here to select support for the MINI2440. Is a 10cm x 10cm board + available via various sources. It can come with a 3.5" or 7" touch LCD. + +config MACH_NEXCODER_2440 + bool "NexVision NEXCODER 2440 Light Board" + select S3C2440_XTAL_12000000 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board + +config MACH_OSIRIS + bool "Simtec IM2440D20 (OSIRIS) module" + select S3C2410_COMMON_DCLK + select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ + select S3C2440_XTAL_12000000 + select S3C24XX_SIMTEC_PM if PM + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec IM2440D20 module, also + known as the Osiris. + +config MACH_OSIRIS_DVS + tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver" + depends on MACH_OSIRIS + depends on TPS65010 + help + Say Y/M here if you want to have dynamic voltage scaling support + on the Simtec IM2440D20 (OSIRIS) module via the TPS65011. + + The DVS driver alters the voltage supplied to the ARM core + depending on the frequency it is running at. The driver itself + does not do any of the frequency alteration, which is left up + to the cpufreq driver. + +config MACH_RX3715 + bool "HP iPAQ rx3715" + select PM_H1940 if PM + select S3C2440_XTAL_16934400 + select S3C_DEV_NAND + help + Say Y here if you are using the HP iPAQ rx3715. + +config ARCH_S3C2440 + bool "SMDK2440" + select S3C2440_XTAL_16934400 + select S3C24XX_SMDK + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here if you are using the SMDK2440. + +config SMDK2440_CPU2440 + bool "SMDK2440 with S3C2440 CPU module" + default y if ARCH_S3C2440 + select S3C2440_XTAL_16934400 + +endif # CPU_S3C2440 + +if CPU_S3C2442 + +comment "S3C2442 Boards" + +# +# The "S3C2442 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_NEO1973_GTA02 + bool "Openmoko GTA02 / Freerunner phone" + select I2C + select MFD_PCF50633 + select PCF50633_GPIO + select POWER_SUPPLY + select S3C24XX_PWM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone + +config MACH_RX1950 + bool "HP iPAQ rx1950" + select I2C + select PM_H1940 if PM + select S3C2410_COMMON_DCLK + select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ + select S3C2440_XTAL_16934400 + select S3C24XX_PWM + select S3C_DEV_NAND + help + Say Y here if you're using HP iPAQ rx1950 + +endif # CPU_S3C2442 + +if CPU_S3C2443 || CPU_S3C2416 + +config S3C2443_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations + +endif # CPU_S3C2443 || CPU_S3C2416 + +if CPU_S3C2443 + +comment "S3C2443 Boards" + +config MACH_SMDK2443 + bool "SMDK2443" + select S3C24XX_SMDK + select S3C_DEV_HSMMC1 + help + Say Y here if you are using an SMDK2443 + +endif # CPU_S3C2443 + +config PM_H1940 + bool + help + Internal node for H1940 and related PM + +endmenu # Samsung S3C24XX SoCs Support + +endif # ARCH_S3C24XX diff --git a/arch/arm/mach-s3c/Kconfig.s3c64xx b/arch/arm/mach-s3c/Kconfig.s3c64xx new file mode 100644 index 000000000000..f3fcb570edf5 --- /dev/null +++ b/arch/arm/mach-s3c/Kconfig.s3c64xx @@ -0,0 +1,350 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2008 Openmoko, Inc. +# Simtec Electronics, Ben Dooks + +menuconfig ARCH_S3C64XX + bool "Samsung S3C64XX" + depends on ARCH_MULTI_V6 + select ARM_AMBA + select ARM_VIC + select CLKSRC_SAMSUNG_PWM + select COMMON_CLK_SAMSUNG + select GPIO_SAMSUNG if ATAGS + select GPIOLIB + select HAVE_S3C2410_I2C if I2C + select HAVE_TCM + select PLAT_SAMSUNG + select PM_GENERIC_DOMAINS if PM + select S3C_DEV_NAND if ATAGS + select S3C_GPIO_TRACK if ATAGS + select S3C2410_WATCHDOG + select SAMSUNG_ATAGS if ATAGS + select SAMSUNG_WAKEMASK if PM + select WATCHDOG + help + Samsung S3C64XX series based systems + +if ARCH_S3C64XX + +# Configuration options for the S3C6410 CPU + +config CPU_S3C6400 + bool + help + Enable S3C6400 CPU support + +config CPU_S3C6410 + bool + help + Enable S3C6410 CPU support + +config S3C64XX_PL080 + def_bool DMADEVICES + select AMBA_PL08X + +config S3C64XX_SETUP_SDHCI + bool + select S3C64XX_SETUP_SDHCI_GPIO + help + Internal configuration for default SDHCI setup for S3C6400 and + S3C6410 SoCs. + +config S3C64XX_DEV_ONENAND1 + bool + help + Compile in platform device definition for OneNAND1 controller + +config SAMSUNG_DEV_BACKLIGHT + bool + depends on SAMSUNG_DEV_PWM + help + Compile in platform device definition LCD backlight with PWM Timer + +# platform specific device setup + +config S3C64XX_SETUP_I2C0 + bool + default y + help + Common setup code for i2c bus 0. + + Note, currently since i2c0 is always compiled, this setup helper + is always compiled with it. + +config S3C64XX_SETUP_I2C1 + bool + help + Common setup code for i2c bus 1. + +config S3C64XX_SETUP_IDE + bool + help + Common setup code for S3C64XX IDE. + +config S3C64XX_SETUP_FB_24BPP + bool + help + Common setup code for S3C64XX with an 24bpp RGB display helper. + +config S3C64XX_SETUP_KEYPAD + bool + help + Common setup code for S3C64XX KEYPAD GPIO configurations + +config S3C64XX_SETUP_SDHCI_GPIO + bool + help + Common setup code for S3C64XX SDHCI GPIO configurations + +config S3C64XX_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations + +config S3C64XX_SETUP_USB_PHY + bool + help + Common setup code for USB PHY controller + +# S36400 Macchine support + +config MACH_SMDK6400 + bool "SMDK6400" + depends on ATAGS + select CPU_S3C6400 + select S3C64XX_SETUP_SDHCI + select S3C_DEV_HSMMC1 + help + Machine support for the Samsung SMDK6400 + +# S3C6410 machine support + +config MACH_ANW6410 + bool "A&W6410" + depends on ATAGS + select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C_DEV_FB + help + Machine support for the A&W6410 + +config MACH_MINI6410 + bool "MINI6410" + depends on ATAGS + select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_SDHCI + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_TS + help + Machine support for the FriendlyARM MINI6410 + +config MACH_REAL6410 + bool "REAL6410" + depends on ATAGS + select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_SDHCI + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_TS + help + Machine support for the CoreWind REAL6410 + +config MACH_SMDK6410 + bool "SMDK6410" + depends on ATAGS + select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_I2C1 + select S3C64XX_SETUP_IDE + select S3C64XX_SETUP_KEYPAD + select S3C64XX_SETUP_SDHCI + select S3C64XX_SETUP_USB_PHY + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_I2C1 + select S3C_DEV_RTC + select S3C_DEV_USB_HOST + select S3C_DEV_USB_HSOTG + select S3C_DEV_WDT + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_BACKLIGHT + select SAMSUNG_DEV_IDE + select SAMSUNG_DEV_KEYPAD + select SAMSUNG_DEV_PWM + select SAMSUNG_DEV_TS + help + Machine support for the Samsung SMDK6410 + +# At least some of the SMDK6410s were shipped with the card detect +# for the MMC/SD slots connected to the same input. This means that +# either the boards need to be altered to have channel0 to an alternate +# configuration or that only one slot can be used. + +choice + prompt "SMDK6410 MMC/SD slot setup" + depends on MACH_SMDK6410 + +config SMDK6410_SD_CH0 + bool "Use channel 0 only" + depends on MACH_SMDK6410 + help + Select CON7 (channel 0) as the MMC/SD slot, as + at least some SMDK6410 boards come with the + resistors fitted so that the card detects for + channels 0 and 1 are the same. + +config SMDK6410_SD_CH1 + bool "Use channel 1 only" + depends on MACH_SMDK6410 + help + Select CON6 (channel 1) as the MMC/SD slot, as + at least some SMDK6410 boards come with the + resistors fitted so that the card detects for + channels 0 and 1 are the same. + +endchoice + +config SMDK6410_WM1190_EV1 + bool "Support Wolfson Microelectronics 1190-EV1 PMIC card" + depends on MACH_SMDK6410 + depends on I2C=y + select MFD_WM8350_I2C + select REGULATOR + select REGULATOR_WM8350 + help + The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC + and audio daughtercard for the Samsung SMDK6410 reference + platform. Enabling this option will build support for this + module into the kernel. The presence of the module will be + detected at runtime so the resulting kernel can be used + with or without the 1190-EV1 fitted. + +config SMDK6410_WM1192_EV1 + bool "Support Wolfson Microelectronics 1192-EV1 PMIC card" + depends on MACH_SMDK6410 + depends on I2C=y + select MFD_WM831X + select MFD_WM831X_I2C + select REGULATOR + select REGULATOR_WM831X + help + The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC + daughtercard for the Samsung SMDK6410 reference platform. + Enabling this option will build support for this module into + the kernel. The presence of the daughtercard will be + detected at runtime so the resulting kernel can be used + with or without the 1192-EV1 fitted. + +config MACH_NCP + bool "NCP" + depends on ATAGS + select CPU_S3C6410 + select S3C64XX_SETUP_I2C1 + select S3C_DEV_HSMMC1 + select S3C_DEV_I2C1 + help + Machine support for the Samsung NCP + +config MACH_HMT + bool "Airgoo HMT" + depends on ATAGS + select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C_DEV_FB + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + select SAMSUNG_DEV_PWM + help + Machine support for the Airgoo HMT + +config MACH_SMARTQ + bool + select CPU_S3C6410 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_SDHCI + select S3C64XX_SETUP_USB_PHY + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_HSMMC2 + select S3C_DEV_HWMON + select S3C_DEV_RTC + select S3C_DEV_USB_HOST + select S3C_DEV_USB_HSOTG + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_PWM + select SAMSUNG_DEV_TS + help + Shared machine support for SmartQ 5/7 + +config MACH_SMARTQ5 + bool "SmartQ 5" + depends on ATAGS + select MACH_SMARTQ + help + Machine support for the SmartQ 5 + +config MACH_SMARTQ7 + bool "SmartQ 7" + depends on ATAGS + select MACH_SMARTQ + help + Machine support for the SmartQ 7 + +config MACH_WLF_CRAGG_6410 + bool "Wolfson Cragganmore 6410" + depends on ATAGS + depends on I2C=y + select CPU_S3C6410 + select LEDS_GPIO_REGISTER + select S3C64XX_DEV_SPI0 + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_I2C1 + select S3C64XX_SETUP_IDE + select S3C64XX_SETUP_KEYPAD + select S3C64XX_SETUP_SDHCI + select S3C64XX_SETUP_SPI + select S3C64XX_SETUP_USB_PHY + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_HSMMC2 + select S3C_DEV_I2C1 + select S3C_DEV_RTC + select S3C_DEV_USB_HOST + select S3C_DEV_USB_HSOTG + select S3C_DEV_WDT + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_KEYPAD + select SAMSUNG_DEV_PWM + help + Machine support for the Wolfson Cragganmore S3C6410 variant. + +config MACH_S3C64XX_DT + bool "Samsung S3C6400/S3C6410 machine using Device Tree" + select CPU_S3C6400 + select CPU_S3C6410 + select PINCTRL + select PINCTRL_S3C64XX + help + Machine support for Samsung S3C6400/S3C6410 machines with Device Tree + enabled. + Select this if a fdt blob is available for your S3C64XX SoC based + board. + Note: This is under development and not all peripherals can be + supported with this machine file. + +endif diff --git a/arch/arm/mach-s3c/Makefile b/arch/arm/mach-s3c/Makefile new file mode 100644 index 000000000000..54188d10ab2e --- /dev/null +++ b/arch/arm/mach-s3c/Makefile @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2009 Simtec Electronics + +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include + +ifdef CONFIG_ARCH_S3C24XX +include $(src)/Makefile.s3c24xx +endif + +ifdef CONFIG_ARCH_S3C64XX +include $(src)/Makefile.s3c64xx +endif + +# Objects we always build independent of SoC choice + +obj-y += init.o cpu.o + +# ADC + +obj-$(CONFIG_S3C_ADC) += adc.o + +# devices + +obj-$(CONFIG_SAMSUNG_ATAGS) += platformdata.o + +obj-$(CONFIG_SAMSUNG_ATAGS) += devs.o +obj-$(CONFIG_SAMSUNG_ATAGS) += dev-uart.o + +obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o + +# PM support + +obj-$(CONFIG_SAMSUNG_PM) += pm.o pm-common.o +obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o + +obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o diff --git a/arch/arm/mach-s3c/Makefile.boot b/arch/arm/mach-s3c/Makefile.boot new file mode 100644 index 000000000000..7f19e226035e --- /dev/null +++ b/arch/arm/mach-s3c/Makefile.boot @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifeq ($(CONFIG_PM_H1940),y) + zreladdr-y += 0x30108000 + params_phys-y := 0x30100100 +else + zreladdr-y += 0x30008000 + params_phys-y := 0x30000100 +endif diff --git a/arch/arm/mach-s3c/Makefile.s3c24xx b/arch/arm/mach-s3c/Makefile.s3c24xx new file mode 100644 index 000000000000..3483ab3a2b81 --- /dev/null +++ b/arch/arm/mach-s3c/Makefile.s3c24xx @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2012 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Copyright 2007 Simtec Electronics + +# core + +obj-y += s3c24xx.o +obj-y += irq-s3c24xx.o +obj-$(CONFIG_SPI_S3C24XX_FIQ) += irq-s3c24xx-fiq.o +obj-$(CONFIG_SPI_S3C24XX_FIQ) += irq-s3c24xx-fiq-exports.o + +obj-$(CONFIG_CPU_S3C2410) += s3c2410.o +obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o +obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o + +obj-$(CONFIG_CPU_S3C2412) += s3c2412.o +obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o +obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o + +obj-$(CONFIG_CPU_S3C2416) += s3c2416.o +obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o + +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o +obj-$(CONFIG_CPU_S3C2442) += s3c2442.o +obj-$(CONFIG_CPU_S3C244X) += s3c244x.o +obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o +obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o + +obj-$(CONFIG_CPU_S3C2443) += s3c2443.o + +# PM + +obj-$(CONFIG_PM) += pm-s3c24xx.o +obj-$(CONFIG_PM_SLEEP) += irq-pm-s3c24xx.o sleep-s3c24xx.o + +# common code + +obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += cpufreq-utils-s3c24xx.o + +obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o +obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o + +# +# machine support +# following is ordered alphabetically by option text. +# + +obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o +obj-$(CONFIG_ARCH_BAST) += mach-bast.o +obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_H1940BT) += h1940-bluetooth.o +obj-$(CONFIG_PM_H1940) += pm-h1940.o +obj-$(CONFIG_MACH_N30) += mach-n30.o +obj-$(CONFIG_MACH_OTOM) += mach-otom.o +obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o +obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o +obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o +obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o + +obj-$(CONFIG_MACH_JIVE) += mach-jive.o +obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o +obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o + +obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o +obj-$(CONFIG_MACH_S3C2416_DT) += mach-s3c2416-dt.o + +obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o +obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o +obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o +obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o +obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o +obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o +obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o + +obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o +obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o + +obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o + +# common bits of machine support + +obj-$(CONFIG_S3C24XX_SMDK) += common-smdk-s3c24xx.o +obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o +obj-$(CONFIG_S3C24XX_SIMTEC_NOR) += simtec-nor.o +obj-$(CONFIG_S3C24XX_SIMTEC_PM) += simtec-pm.o +obj-$(CONFIG_S3C24XX_SIMTEC_USB) += simtec-usb.o + +# machine additions + +obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o +obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o + +# device setup + +obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio-s3c24xx.o +obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi-s3c24xx.o +obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c-s3c24xx.o +obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts-s3c24xx.o diff --git a/arch/arm/mach-s3c/Makefile.s3c64xx b/arch/arm/mach-s3c/Makefile.s3c64xx new file mode 100644 index 000000000000..e06e5356da9b --- /dev/null +++ b/arch/arm/mach-s3c/Makefile.s3c64xx @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2008 Openmoko, Inc. +# Copyright 2008 Simtec Electronics + +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include +asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include + +# PM + +obj-$(CONFIG_PM) += pm-s3c64xx.o +obj-$(CONFIG_PM_SLEEP) += sleep-s3c64xx.o +obj-$(CONFIG_CPU_IDLE) += cpuidle-s3c64xx.o + +ifdef CONFIG_SAMSUNG_ATAGS + +obj-$(CONFIG_PM_SLEEP) += irq-pm-s3c64xx.o + +# Core + +obj-y += s3c64xx.o +obj-$(CONFIG_CPU_S3C6400) += s3c6400.o +obj-$(CONFIG_CPU_S3C6410) += s3c6410.o + +# DMA support + +obj-$(CONFIG_S3C64XX_PL080) += pl080.o + +# Device support + +obj-y += dev-uart-s3c64xx.o +obj-y += dev-audio-s3c64xx.o + +# Device setup + +obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy-s3c64xx.o + +obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight-s3c64xx.o + +# Machine support + +obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o +obj-$(CONFIG_MACH_HMT) += mach-hmt.o +obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o +obj-$(CONFIG_MACH_NCP) += mach-ncp.o +obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o +obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o +obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o +obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o +obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o +obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o +obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o +endif + +obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o diff --git a/arch/arm/mach-s3c/adc.c b/arch/arm/mach-s3c/adc.c new file mode 100644 index 000000000000..e35e04417cce --- /dev/null +++ b/arch/arm/mach-s3c/adc.c @@ -0,0 +1,510 @@ +// SPDX-License-Identifier: GPL-1.0+ +// +// Copyright (c) 2008 Simtec Electronics +// http://armlinux.simtec.co.uk/ +// Ben Dooks , +// +// Samsung ADC device core + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* This driver is designed to control the usage of the ADC block between + * the touchscreen and any other drivers that may need to use it, such as + * the hwmon driver. + * + * Priority will be given to the touchscreen driver, but as this itself is + * rate limited it should not starve other requests which are processed in + * order that they are received. + * + * Each user registers to get a client block which uniquely identifies it + * and stores information such as the necessary functions to callback when + * action is required. + */ + +enum s3c_cpu_type { + TYPE_ADCV1, /* S3C24XX */ + TYPE_ADCV11, /* S3C2443 */ + TYPE_ADCV12, /* S3C2416, S3C2450 */ + TYPE_ADCV2, /* S3C64XX */ + TYPE_ADCV3, /* S5PV210, S5PC110, Exynos4210 */ +}; + +struct s3c_adc_client { + struct platform_device *pdev; + struct list_head pend; + wait_queue_head_t *wait; + + unsigned int nr_samples; + int result; + unsigned char is_ts; + unsigned char channel; + + void (*select_cb)(struct s3c_adc_client *c, unsigned selected); + void (*convert_cb)(struct s3c_adc_client *c, + unsigned val1, unsigned val2, + unsigned *samples_left); +}; + +struct adc_device { + struct platform_device *pdev; + struct platform_device *owner; + struct clk *clk; + struct s3c_adc_client *cur; + struct s3c_adc_client *ts_pend; + void __iomem *regs; + spinlock_t lock; + + unsigned int prescale; + + int irq; + struct regulator *vdd; +}; + +static struct adc_device *adc_dev; + +static LIST_HEAD(adc_pending); /* protected by adc_device.lock */ + +#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg) + +static inline void s3c_adc_convert(struct adc_device *adc) +{ + unsigned con = readl(adc->regs + S3C2410_ADCCON); + + con |= S3C2410_ADCCON_ENABLE_START; + writel(con, adc->regs + S3C2410_ADCCON); +} + +static inline void s3c_adc_select(struct adc_device *adc, + struct s3c_adc_client *client) +{ + unsigned con = readl(adc->regs + S3C2410_ADCCON); + enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data; + + client->select_cb(client, 1); + + if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2) + con &= ~S3C2410_ADCCON_MUXMASK; + con &= ~S3C2410_ADCCON_STDBM; + con &= ~S3C2410_ADCCON_STARTMASK; + + if (!client->is_ts) { + if (cpu == TYPE_ADCV3) + writel(client->channel & 0xf, adc->regs + S5P_ADCMUX); + else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12) + writel(client->channel & 0xf, + adc->regs + S3C2443_ADCMUX); + else + con |= S3C2410_ADCCON_SELMUX(client->channel); + } + + writel(con, adc->regs + S3C2410_ADCCON); +} + +static void s3c_adc_dbgshow(struct adc_device *adc) +{ + adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n", + readl(adc->regs + S3C2410_ADCCON), + readl(adc->regs + S3C2410_ADCTSC), + readl(adc->regs + S3C2410_ADCDLY)); +} + +static void s3c_adc_try(struct adc_device *adc) +{ + struct s3c_adc_client *next = adc->ts_pend; + + if (!next && !list_empty(&adc_pending)) { + next = list_first_entry(&adc_pending, + struct s3c_adc_client, pend); + list_del(&next->pend); + } else + adc->ts_pend = NULL; + + if (next) { + adc_dbg(adc, "new client is %p\n", next); + adc->cur = next; + s3c_adc_select(adc, next); + s3c_adc_convert(adc); + s3c_adc_dbgshow(adc); + } +} + +int s3c_adc_start(struct s3c_adc_client *client, + unsigned int channel, unsigned int nr_samples) +{ + struct adc_device *adc = adc_dev; + unsigned long flags; + + if (!adc) { + printk(KERN_ERR "%s: failed to find adc\n", __func__); + return -EINVAL; + } + + spin_lock_irqsave(&adc->lock, flags); + + if (client->is_ts && adc->ts_pend) { + spin_unlock_irqrestore(&adc->lock, flags); + return -EAGAIN; + } + + client->channel = channel; + client->nr_samples = nr_samples; + + if (client->is_ts) + adc->ts_pend = client; + else + list_add_tail(&client->pend, &adc_pending); + + if (!adc->cur) + s3c_adc_try(adc); + + spin_unlock_irqrestore(&adc->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c_adc_start); + +static void s3c_convert_done(struct s3c_adc_client *client, + unsigned v, unsigned u, unsigned *left) +{ + client->result = v; + wake_up(client->wait); +} + +int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch) +{ + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake); + int ret; + + client->convert_cb = s3c_convert_done; + client->wait = &wake; + client->result = -1; + + ret = s3c_adc_start(client, ch, 1); + if (ret < 0) + goto err; + + ret = wait_event_timeout(wake, client->result >= 0, HZ / 2); + if (client->result < 0) { + ret = -ETIMEDOUT; + goto err; + } + + client->convert_cb = NULL; + return client->result; + +err: + return ret; +} +EXPORT_SYMBOL_GPL(s3c_adc_read); + +static void s3c_adc_default_select(struct s3c_adc_client *client, + unsigned select) +{ +} + +struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, + void (*select)(struct s3c_adc_client *client, + unsigned int selected), + void (*conv)(struct s3c_adc_client *client, + unsigned d0, unsigned d1, + unsigned *samples_left), + unsigned int is_ts) +{ + struct s3c_adc_client *client; + + WARN_ON(!pdev); + + if (!select) + select = s3c_adc_default_select; + + if (!pdev) + return ERR_PTR(-EINVAL); + + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return ERR_PTR(-ENOMEM); + + client->pdev = pdev; + client->is_ts = is_ts; + client->select_cb = select; + client->convert_cb = conv; + + return client; +} +EXPORT_SYMBOL_GPL(s3c_adc_register); + +void s3c_adc_release(struct s3c_adc_client *client) +{ + unsigned long flags; + + spin_lock_irqsave(&adc_dev->lock, flags); + + /* We should really check that nothing is in progress. */ + if (adc_dev->cur == client) + adc_dev->cur = NULL; + if (adc_dev->ts_pend == client) + adc_dev->ts_pend = NULL; + else { + struct list_head *p, *n; + struct s3c_adc_client *tmp; + + list_for_each_safe(p, n, &adc_pending) { + tmp = list_entry(p, struct s3c_adc_client, pend); + if (tmp == client) + list_del(&tmp->pend); + } + } + + if (adc_dev->cur == NULL) + s3c_adc_try(adc_dev); + + spin_unlock_irqrestore(&adc_dev->lock, flags); + kfree(client); +} +EXPORT_SYMBOL_GPL(s3c_adc_release); + +static irqreturn_t s3c_adc_irq(int irq, void *pw) +{ + struct adc_device *adc = pw; + struct s3c_adc_client *client = adc->cur; + enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data; + unsigned data0, data1; + + if (!client) { + dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__); + goto exit; + } + + data0 = readl(adc->regs + S3C2410_ADCDAT0); + data1 = readl(adc->regs + S3C2410_ADCDAT1); + adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); + + client->nr_samples--; + + if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV11) { + data0 &= 0x3ff; + data1 &= 0x3ff; + } else { + /* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */ + data0 &= 0xfff; + data1 &= 0xfff; + } + + if (client->convert_cb) + (client->convert_cb)(client, data0, data1, &client->nr_samples); + + if (client->nr_samples > 0) { + /* fire another conversion for this */ + + client->select_cb(client, 1); + s3c_adc_convert(adc); + } else { + spin_lock(&adc->lock); + (client->select_cb)(client, 0); + adc->cur = NULL; + + s3c_adc_try(adc); + spin_unlock(&adc->lock); + } + +exit: + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) { + /* Clear ADC interrupt */ + writel(0, adc->regs + S3C64XX_ADCCLRINT); + } + return IRQ_HANDLED; +} + +static int s3c_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct adc_device *adc; + enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; + int ret; + unsigned tmp; + + adc = devm_kzalloc(dev, sizeof(*adc), GFP_KERNEL); + if (!adc) + return -ENOMEM; + + spin_lock_init(&adc->lock); + + adc->pdev = pdev; + adc->prescale = S3C2410_ADCCON_PRSCVL(49); + + adc->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(adc->vdd)) { + dev_err(dev, "operating without regulator \"vdd\" .\n"); + return PTR_ERR(adc->vdd); + } + + adc->irq = platform_get_irq(pdev, 1); + if (adc->irq <= 0) + return -ENOENT; + + ret = devm_request_irq(dev, adc->irq, s3c_adc_irq, 0, dev_name(dev), + adc); + if (ret < 0) { + dev_err(dev, "failed to attach adc irq\n"); + return ret; + } + + adc->clk = devm_clk_get(dev, "adc"); + if (IS_ERR(adc->clk)) { + dev_err(dev, "failed to get adc clock\n"); + return PTR_ERR(adc->clk); + } + + adc->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(adc->regs)) + return PTR_ERR(adc->regs); + + ret = regulator_enable(adc->vdd); + if (ret) + return ret; + + clk_prepare_enable(adc->clk); + + tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; + + /* Enable 12-bit ADC resolution */ + if (cpu == TYPE_ADCV12) + tmp |= S3C2416_ADCCON_RESSEL; + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) + tmp |= S3C64XX_ADCCON_RESSEL; + + writel(tmp, adc->regs + S3C2410_ADCCON); + + dev_info(dev, "attached adc driver\n"); + + platform_set_drvdata(pdev, adc); + adc_dev = adc; + + return 0; +} + +static int s3c_adc_remove(struct platform_device *pdev) +{ + struct adc_device *adc = platform_get_drvdata(pdev); + + clk_disable_unprepare(adc->clk); + regulator_disable(adc->vdd); + + return 0; +} + +#ifdef CONFIG_PM +static int s3c_adc_suspend(struct device *dev) +{ + struct adc_device *adc = dev_get_drvdata(dev); + unsigned long flags; + u32 con; + + spin_lock_irqsave(&adc->lock, flags); + + con = readl(adc->regs + S3C2410_ADCCON); + con |= S3C2410_ADCCON_STDBM; + writel(con, adc->regs + S3C2410_ADCCON); + + disable_irq(adc->irq); + spin_unlock_irqrestore(&adc->lock, flags); + clk_disable(adc->clk); + regulator_disable(adc->vdd); + + return 0; +} + +static int s3c_adc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct adc_device *adc = platform_get_drvdata(pdev); + enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; + int ret; + unsigned long tmp; + + ret = regulator_enable(adc->vdd); + if (ret) + return ret; + clk_enable(adc->clk); + enable_irq(adc->irq); + + tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; + + /* Enable 12-bit ADC resolution */ + if (cpu == TYPE_ADCV12) + tmp |= S3C2416_ADCCON_RESSEL; + if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) + tmp |= S3C64XX_ADCCON_RESSEL; + + writel(tmp, adc->regs + S3C2410_ADCCON); + + return 0; +} + +#else +#define s3c_adc_suspend NULL +#define s3c_adc_resume NULL +#endif + +static const struct platform_device_id s3c_adc_driver_ids[] = { + { + .name = "s3c24xx-adc", + .driver_data = TYPE_ADCV1, + }, { + .name = "s3c2443-adc", + .driver_data = TYPE_ADCV11, + }, { + .name = "s3c2416-adc", + .driver_data = TYPE_ADCV12, + }, { + .name = "s3c64xx-adc", + .driver_data = TYPE_ADCV2, + }, { + .name = "samsung-adc-v3", + .driver_data = TYPE_ADCV3, + }, + { } +}; +MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids); + +static const struct dev_pm_ops adc_pm_ops = { + .suspend = s3c_adc_suspend, + .resume = s3c_adc_resume, +}; + +static struct platform_driver s3c_adc_driver = { + .id_table = s3c_adc_driver_ids, + .driver = { + .name = "s3c-adc", + .pm = &adc_pm_ops, + }, + .probe = s3c_adc_probe, + .remove = s3c_adc_remove, +}; + +static int __init adc_init(void) +{ + int ret; + + ret = platform_driver_register(&s3c_adc_driver); + if (ret) + printk(KERN_ERR "%s: failed to add adc driver\n", __func__); + + return ret; +} + +module_init(adc_init); diff --git a/arch/arm/mach-s3c/anubis.h b/arch/arm/mach-s3c/anubis.h new file mode 100644 index 000000000000..13847292e6c7 --- /dev/null +++ b/arch/arm/mach-s3c/anubis.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - CPLD control constants + * ANUBIS - IRQ Number definitions + * ANUBIS - Memory map definitions + */ + +#ifndef __MACH_S3C24XX_ANUBIS_H +#define __MACH_S3C24XX_ANUBIS_H __FILE__ + +/* CTRL2 - NAND WP control, IDE Reset assert/check */ + +#define ANUBIS_CTRL1_NANDSEL (0x3) + +/* IDREG - revision */ + +#define ANUBIS_IDREG_REVMASK (0x7) + +/* irq */ + +#define ANUBIS_IRQ_IDE0 IRQ_EINT2 +#define ANUBIS_IRQ_IDE1 IRQ_EINT3 +#define ANUBIS_IRQ_ASIX IRQ_EINT1 + +/* map */ + +/* start peripherals off after the S3C2410 */ + +#define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x01800000)) + +#define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26)) + +/* we put the CPLD registers next, to get them out of the way */ + +#define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) +#define ANUBIS_PA_CTRL1 ANUBIS_PA_CPLD + +#define ANUBIS_VA_IDREG ANUBIS_IOADDR(0x00300000) +#define ANUBIS_PA_IDREG (ANUBIS_PA_CPLD + (3 << 23)) + +#define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000) +#define ANUBIS_IDEPRIAUX ANUBIS_IOADDR(0x01100000) +#define ANUBIS_IDESEC ANUBIS_IOADDR(0x01200000) +#define ANUBIS_IDESECAUX ANUBIS_IOADDR(0x01300000) + +#endif /* __MACH_S3C24XX_ANUBIS_H */ diff --git a/arch/arm/mach-s3c/ata-core-s3c64xx.h b/arch/arm/mach-s3c/ata-core-s3c64xx.h new file mode 100644 index 000000000000..4863ad9d3a42 --- /dev/null +++ b/arch/arm/mach-s3c/ata-core-s3c64xx.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung CF-ATA Controller core functions + */ + +#ifndef __ASM_PLAT_ATA_CORE_S3C64XX_H +#define __ASM_PLAT_ATA_CORE_S3C64XX_H __FILE__ + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code +*/ + +/* re-define device name depending on support. */ +static inline void s3c_cfcon_setname(char *name) +{ +#ifdef CONFIG_SAMSUNG_DEV_IDE + s3c_device_cfcon.name = name; +#endif +} + +#endif /* __ASM_PLAT_ATA_CORE_S3C64XX_H */ diff --git a/arch/arm/mach-s3c/backlight-s3c64xx.h b/arch/arm/mach-s3c/backlight-s3c64xx.h new file mode 100644 index 000000000000..2a2b35821d58 --- /dev/null +++ b/arch/arm/mach-s3c/backlight-s3c64xx.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + */ + +#ifndef __ASM_PLAT_BACKLIGHT_S3C64XX_H +#define __ASM_PLAT_BACKLIGHT_S3C64XX_H __FILE__ + +/* samsung_bl_gpio_info - GPIO info for PWM Backlight control + * @no: GPIO number for PWM timer out + * @func: Special function of GPIO line for PWM timer + */ +struct samsung_bl_gpio_info { + int no; + int func; +}; + +extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, + struct platform_pwm_backlight_data *bl_data); + +#endif /* __ASM_PLAT_BACKLIGHT_S3C64XX_H */ diff --git a/arch/arm/mach-s3c/bast-ide.c b/arch/arm/mach-s3c/bast-ide.c new file mode 100644 index 000000000000..ee6fbb407640 --- /dev/null +++ b/arch/arm/mach-s3c/bast-ide.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2007 Simtec Electronics +// http://www.simtec.co.uk/products/EB2410ITX/ +// http://armlinux.simtec.co.uk/ +// Ben Dooks + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include "bast.h" + +/* IDE ports */ + +static struct pata_platform_info bast_ide_platdata = { + .ioport_shift = 5, +}; + +static struct resource bast_ide0_resource[] = { + [0] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRI, 8 * 0x20), + [1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20), 0x20), + [2] = DEFINE_RES_IRQ(BAST_IRQ_IDE0), +}; + +static struct platform_device bast_device_ide0 = { + .name = "pata_platform", + .id = 0, + .num_resources = ARRAY_SIZE(bast_ide0_resource), + .resource = bast_ide0_resource, + .dev = { + .platform_data = &bast_ide_platdata, + .coherent_dma_mask = ~0, + } + +}; + +static struct resource bast_ide1_resource[] = { + [0] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESEC, 8 * 0x20), + [1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20), 0x20), + [2] = DEFINE_RES_IRQ(BAST_IRQ_IDE1), +}; + +static struct platform_device bast_device_ide1 = { + .name = "pata_platform", + .id = 1, + .num_resources = ARRAY_SIZE(bast_ide1_resource), + .resource = bast_ide1_resource, + .dev = { + .platform_data = &bast_ide_platdata, + .coherent_dma_mask = ~0, + } +}; + +static struct platform_device *bast_ide_devices[] __initdata = { + &bast_device_ide0, + &bast_device_ide1, +}; + +static __init int bast_ide_init(void) +{ + if (machine_is_bast() || machine_is_vr1000()) + return platform_add_devices(bast_ide_devices, + ARRAY_SIZE(bast_ide_devices)); + + return 0; +} + +fs_initcall(bast_ide_init); diff --git a/arch/arm/mach-s3c/bast-irq.c b/arch/arm/mach-s3c/bast-irq.c new file mode 100644 index 000000000000..141a35d58dd7 --- /dev/null +++ b/arch/arm/mach-s3c/bast-irq.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright 2003-2005 Simtec Electronics +// Ben Dooks +// +// http://www.simtec.co.uk/products/EB2410ITX/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "bast.h" + +#define irqdbf(x...) +#define irqdbf2(x...) + +/* handle PC104 ISA interrupts from the system CPLD */ + +/* table of ISA irq nos to the relevant mask... zero means + * the irq is not implemented +*/ +static const unsigned char bast_pc104_irqmasks[] = { + 0, /* 0 */ + 0, /* 1 */ + 0, /* 2 */ + 1, /* 3 */ + 0, /* 4 */ + 2, /* 5 */ + 0, /* 6 */ + 4, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 8, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ +}; + +static const unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 }; + +static void +bast_pc104_mask(struct irq_data *data) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp &= ~bast_pc104_irqmasks[data->irq]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); +} + +static void +bast_pc104_maskack(struct irq_data *data) +{ + struct irq_desc *desc = irq_to_desc(BAST_IRQ_ISA); + + bast_pc104_mask(data); + desc->irq_data.chip->irq_ack(&desc->irq_data); +} + +static void +bast_pc104_unmask(struct irq_data *data) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp |= bast_pc104_irqmasks[data->irq]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); +} + +static struct irq_chip bast_pc104_chip = { + .irq_mask = bast_pc104_mask, + .irq_unmask = bast_pc104_unmask, + .irq_ack = bast_pc104_maskack +}; + +static void bast_irq_pc104_demux(struct irq_desc *desc) +{ + unsigned int stat; + unsigned int irqno; + int i; + + stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf; + + if (unlikely(stat == 0)) { + /* ack if we get an irq with nothing (ie, startup) */ + desc->irq_data.chip->irq_ack(&desc->irq_data); + } else { + /* handle the IRQ */ + + for (i = 0; stat != 0; i++, stat >>= 1) { + if (stat & 1) { + irqno = bast_pc104_irqs[i]; + generic_handle_irq(irqno); + } + } + } +} + +static __init int bast_irq_init(void) +{ + unsigned int i; + + if (machine_is_bast()) { + printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n"); + + /* zap all the IRQs */ + + __raw_writeb(0x0, BAST_VA_PC104_IRQMASK); + + irq_set_chained_handler(BAST_IRQ_ISA, bast_irq_pc104_demux); + + /* register our IRQs */ + + for (i = 0; i < 4; i++) { + unsigned int irqno = bast_pc104_irqs[i]; + + irq_set_chip_and_handler(irqno, &bast_pc104_chip, + handle_level_irq); + irq_clear_status_flags(irqno, IRQ_NOREQUEST); + } + } + + return 0; +} + +arch_initcall(bast_irq_init); diff --git a/arch/arm/mach-s3c/bast.h b/arch/arm/mach-s3c/bast.h new file mode 100644 index 000000000000..a7726f93f5eb --- /dev/null +++ b/arch/arm/mach-s3c/bast.h @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * BAST - CPLD control constants + * BAST - IRQ Number definitions + * BAST - Memory map definitions + */ + +#ifndef __MACH_S3C24XX_BAST_H +#define __MACH_S3C24XX_BAST_H __FILE__ + +/* CTRL1 - Audio LR routing */ + +#define BAST_CPLD_CTRL1_LRCOFF (0x00) +#define BAST_CPLD_CTRL1_LRCADC (0x01) +#define BAST_CPLD_CTRL1_LRCDAC (0x02) +#define BAST_CPLD_CTRL1_LRCARM (0x03) +#define BAST_CPLD_CTRL1_LRMASK (0x03) + +/* CTRL2 - NAND WP control, IDE Reset assert/check */ + +#define BAST_CPLD_CTRL2_WNAND (0x04) +#define BAST_CPLD_CTLR2_IDERST (0x08) + +/* CTRL3 - rom write control, CPLD identity */ + +#define BAST_CPLD_CTRL3_IDMASK (0x0e) +#define BAST_CPLD_CTRL3_ROMWEN (0x01) + +/* CTRL4 - 8bit LCD interface control/status */ + +#define BAST_CPLD_CTRL4_LLAT (0x01) +#define BAST_CPLD_CTRL4_LCDRW (0x02) +#define BAST_CPLD_CTRL4_LCDCMD (0x04) +#define BAST_CPLD_CTRL4_LCDE2 (0x01) + +/* CTRL5 - DMA routing */ + +#define BAST_CPLD_DMA0_PRIIDE (0) +#define BAST_CPLD_DMA0_SECIDE (1) +#define BAST_CPLD_DMA0_ISA15 (2) +#define BAST_CPLD_DMA0_ISA36 (3) + +#define BAST_CPLD_DMA1_PRIIDE (0 << 2) +#define BAST_CPLD_DMA1_SECIDE (1 << 2) +#define BAST_CPLD_DMA1_ISA15 (2 << 2) +#define BAST_CPLD_DMA1_ISA36 (3 << 2) + +/* irq numbers to onboard peripherals */ + +#define BAST_IRQ_USBOC IRQ_EINT18 +#define BAST_IRQ_IDE0 IRQ_EINT16 +#define BAST_IRQ_IDE1 IRQ_EINT17 +#define BAST_IRQ_PCSERIAL1 IRQ_EINT15 +#define BAST_IRQ_PCSERIAL2 IRQ_EINT14 +#define BAST_IRQ_PCPARALLEL IRQ_EINT13 +#define BAST_IRQ_ASIX IRQ_EINT11 +#define BAST_IRQ_DM9000 IRQ_EINT10 +#define BAST_IRQ_ISA IRQ_EINT9 +#define BAST_IRQ_SMALERT IRQ_EINT8 + +/* map */ + +/* + * ok, we've used up to 0x13000000, now we need to find space for the + * peripherals that live in the nGCS[x] areas, which are quite numerous + * in their space. We also have the board's CPLD to find register space + * for. + */ + +#define BAST_IOADDR(x) (S3C2410_ADDR((x) + 0x01300000)) + +/* we put the CPLD registers next, to get them out of the way */ + +#define BAST_VA_CTRL1 BAST_IOADDR(0x00000000) +#define BAST_PA_CTRL1 (S3C2410_CS5 | 0x7800000) + +#define BAST_VA_CTRL2 BAST_IOADDR(0x00100000) +#define BAST_PA_CTRL2 (S3C2410_CS1 | 0x6000000) + +#define BAST_VA_CTRL3 BAST_IOADDR(0x00200000) +#define BAST_PA_CTRL3 (S3C2410_CS1 | 0x6800000) + +#define BAST_VA_CTRL4 BAST_IOADDR(0x00300000) +#define BAST_PA_CTRL4 (S3C2410_CS1 | 0x7000000) + +/* next, we have the PC104 ISA interrupt registers */ + +#define BAST_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000) +#define BAST_VA_PC104_IRQREQ BAST_IOADDR(0x00400000) + +#define BAST_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000) +#define BAST_VA_PC104_IRQRAW BAST_IOADDR(0x00500000) + +#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) +#define BAST_VA_PC104_IRQMASK BAST_IOADDR(0x00600000) + +#define BAST_PA_LCD_RCMD1 (0x8800000) +#define BAST_VA_LCD_RCMD1 BAST_IOADDR(0x00700000) + +#define BAST_PA_LCD_WCMD1 (0x8000000) +#define BAST_VA_LCD_WCMD1 BAST_IOADDR(0x00800000) + +#define BAST_PA_LCD_RDATA1 (0x9800000) +#define BAST_VA_LCD_RDATA1 BAST_IOADDR(0x00900000) + +#define BAST_PA_LCD_WDATA1 (0x9000000) +#define BAST_VA_LCD_WDATA1 BAST_IOADDR(0x00A00000) + +#define BAST_PA_LCD_RCMD2 (0xA800000) +#define BAST_VA_LCD_RCMD2 BAST_IOADDR(0x00B00000) + +#define BAST_PA_LCD_WCMD2 (0xA000000) +#define BAST_VA_LCD_WCMD2 BAST_IOADDR(0x00C00000) + +#define BAST_PA_LCD_RDATA2 (0xB800000) +#define BAST_VA_LCD_RDATA2 BAST_IOADDR(0x00D00000) + +#define BAST_PA_LCD_WDATA2 (0xB000000) +#define BAST_VA_LCD_WDATA2 BAST_IOADDR(0x00E00000) + + +/* + * 0xE0000000 contains the IO space that is split by speed and + * whether the access is for 8 or 16bit IO... this ensures that + * the correct access is made + * + * 0x10000000 of space, partitioned as so: + * + * 0x00000000 to 0x04000000 8bit, slow + * 0x04000000 to 0x08000000 16bit, slow + * 0x08000000 to 0x0C000000 16bit, net + * 0x0C000000 to 0x10000000 16bit, fast + * + * each of these spaces has the following in: + * + * 0x00000000 to 0x01000000 16MB ISA IO space + * 0x01000000 to 0x02000000 16MB ISA memory space + * 0x02000000 to 0x02100000 1MB IDE primary channel + * 0x02100000 to 0x02200000 1MB IDE primary channel aux + * 0x02200000 to 0x02400000 1MB IDE secondary channel + * 0x02300000 to 0x02400000 1MB IDE secondary channel aux + * 0x02400000 to 0x02500000 1MB ASIX ethernet controller + * 0x02500000 to 0x02600000 1MB Davicom DM9000 ethernet controller + * 0x02600000 to 0x02700000 1MB PC SuperIO controller + * + * the phyiscal layout of the zones are: + * nGCS2 - 8bit, slow + * nGCS3 - 16bit, slow + * nGCS4 - 16bit, net + * nGCS5 - 16bit, fast + */ + +#define BAST_VA_MULTISPACE (0xE0000000) + +#define BAST_VA_ISAIO (BAST_VA_MULTISPACE + 0x00000000) +#define BAST_VA_ISAMEM (BAST_VA_MULTISPACE + 0x01000000) +#define BAST_VA_IDEPRI (BAST_VA_MULTISPACE + 0x02000000) +#define BAST_VA_IDEPRIAUX (BAST_VA_MULTISPACE + 0x02100000) +#define BAST_VA_IDESEC (BAST_VA_MULTISPACE + 0x02200000) +#define BAST_VA_IDESECAUX (BAST_VA_MULTISPACE + 0x02300000) +#define BAST_VA_ASIXNET (BAST_VA_MULTISPACE + 0x02400000) +#define BAST_VA_DM9000 (BAST_VA_MULTISPACE + 0x02500000) +#define BAST_VA_SUPERIO (BAST_VA_MULTISPACE + 0x02600000) + +#define BAST_VAM_CS2 (0x00000000) +#define BAST_VAM_CS3 (0x04000000) +#define BAST_VAM_CS4 (0x08000000) +#define BAST_VAM_CS5 (0x0C000000) + +/* physical offset addresses for the peripherals */ + +#define BAST_PA_ISAIO (0x00000000) +#define BAST_PA_ASIXNET (0x01000000) +#define BAST_PA_SUPERIO (0x01800000) +#define BAST_PA_IDEPRI (0x02000000) +#define BAST_PA_IDEPRIAUX (0x02800000) +#define BAST_PA_IDESEC (0x03000000) +#define BAST_PA_IDESECAUX (0x03800000) +#define BAST_PA_ISAMEM (0x04000000) +#define BAST_PA_DM9000 (0x05000000) + +/* some configurations for the peripherals */ + +#define BAST_PCSIO (BAST_VA_SUPERIO + BAST_VAM_CS2) + +#define BAST_ASIXNET_CS BAST_VAM_CS5 +#define BAST_DM9000_CS BAST_VAM_CS4 + +#define BAST_IDE_CS S3C2410_CS5 + +#endif /* __MACH_S3C24XX_BAST_H */ diff --git a/arch/arm/mach-s3c/common-smdk-s3c24xx.c b/arch/arm/mach-s3c/common-smdk-s3c24xx.c new file mode 100644 index 000000000000..e3281dc3af13 --- /dev/null +++ b/arch/arm/mach-s3c/common-smdk-s3c24xx.c @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2006 Simtec Electronics +// Ben Dooks +// +// Common code for SMDK2410 and SMDK2440 boards +// +// http://www.fluff.org/ben/smdk2440/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "common-smdk-s3c24xx.h" + +/* LED devices */ + +static struct gpiod_lookup_table smdk_led4_gpio_table = { + .dev_id = "s3c24xx_led.0", + .table = { + GPIO_LOOKUP("GPF", 4, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN), + { }, + }, +}; + +static struct gpiod_lookup_table smdk_led5_gpio_table = { + .dev_id = "s3c24xx_led.1", + .table = { + GPIO_LOOKUP("GPF", 5, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN), + { }, + }, +}; + +static struct gpiod_lookup_table smdk_led6_gpio_table = { + .dev_id = "s3c24xx_led.2", + .table = { + GPIO_LOOKUP("GPF", 6, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN), + { }, + }, +}; + +static struct gpiod_lookup_table smdk_led7_gpio_table = { + .dev_id = "s3c24xx_led.3", + .table = { + GPIO_LOOKUP("GPF", 7, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN), + { }, + }, +}; + +static struct s3c24xx_led_platdata smdk_pdata_led4 = { + .name = "led4", + .def_trigger = "timer", +}; + +static struct s3c24xx_led_platdata smdk_pdata_led5 = { + .name = "led5", + .def_trigger = "nand-disk", +}; + +static struct s3c24xx_led_platdata smdk_pdata_led6 = { + .name = "led6", +}; + +static struct s3c24xx_led_platdata smdk_pdata_led7 = { + .name = "led7", +}; + +static struct platform_device smdk_led4 = { + .name = "s3c24xx_led", + .id = 0, + .dev = { + .platform_data = &smdk_pdata_led4, + }, +}; + +static struct platform_device smdk_led5 = { + .name = "s3c24xx_led", + .id = 1, + .dev = { + .platform_data = &smdk_pdata_led5, + }, +}; + +static struct platform_device smdk_led6 = { + .name = "s3c24xx_led", + .id = 2, + .dev = { + .platform_data = &smdk_pdata_led6, + }, +}; + +static struct platform_device smdk_led7 = { + .name = "s3c24xx_led", + .id = 3, + .dev = { + .platform_data = &smdk_pdata_led7, + }, +}; + +/* NAND parititon from 2.4.18-swl5 */ + +static struct mtd_partition smdk_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0, + }, + [1] = { + .name = "S3C2410 flash partition 1", + .offset = 0, + .size = SZ_2M, + }, + [2] = { + .name = "S3C2410 flash partition 2", + .offset = SZ_4M, + .size = SZ_4M, + }, + [3] = { + .name = "S3C2410 flash partition 3", + .offset = SZ_8M, + .size = SZ_2M, + }, + [4] = { + .name = "S3C2410 flash partition 4", + .offset = SZ_1M * 10, + .size = SZ_4M, + }, + [5] = { + .name = "S3C2410 flash partition 5", + .offset = SZ_1M * 14, + .size = SZ_1M * 10, + }, + [6] = { + .name = "S3C2410 flash partition 6", + .offset = SZ_1M * 24, + .size = SZ_1M * 24, + }, + [7] = { + .name = "S3C2410 flash partition 7", + .offset = SZ_1M * 48, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct s3c2410_nand_set smdk_nand_sets[] = { + [0] = { + .name = "NAND", + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(smdk_default_nand_part), + .partitions = smdk_default_nand_part, + }, +}; + +/* choose a set of timings which should suit most 512Mbit + * chips and beyond. +*/ + +static struct s3c2410_platform_nand smdk_nand_info = { + .tacls = 20, + .twrph0 = 60, + .twrph1 = 20, + .nr_sets = ARRAY_SIZE(smdk_nand_sets), + .sets = smdk_nand_sets, + .ecc_mode = NAND_ECC_SOFT, +}; + +/* devices we initialise */ + +static struct platform_device __initdata *smdk_devs[] = { + &s3c_device_nand, + &smdk_led4, + &smdk_led5, + &smdk_led6, + &smdk_led7, +}; + +void __init smdk_machine_init(void) +{ + if (machine_is_smdk2443()) + smdk_nand_info.twrph0 = 50; + + s3c_nand_set_platdata(&smdk_nand_info); + + /* Disable pull-up on the LED lines */ + s3c_gpio_setpull(S3C2410_GPF(4), S3C_GPIO_PULL_NONE); + s3c_gpio_setpull(S3C2410_GPF(5), S3C_GPIO_PULL_NONE); + s3c_gpio_setpull(S3C2410_GPF(6), S3C_GPIO_PULL_NONE); + s3c_gpio_setpull(S3C2410_GPF(7), S3C_GPIO_PULL_NONE); + + /* Add lookups for the lines */ + gpiod_add_lookup_table(&smdk_led4_gpio_table); + gpiod_add_lookup_table(&smdk_led5_gpio_table); + gpiod_add_lookup_table(&smdk_led6_gpio_table); + gpiod_add_lookup_table(&smdk_led7_gpio_table); + + platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); + + s3c_pm_init(); +} diff --git a/arch/arm/mach-s3c/common-smdk-s3c24xx.h b/arch/arm/mach-s3c/common-smdk-s3c24xx.h new file mode 100644 index 000000000000..c0352b06e435 --- /dev/null +++ b/arch/arm/mach-s3c/common-smdk-s3c24xx.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * Common code for SMDK2410 and SMDK2440 boards + * + * http://www.fluff.org/ben/smdk2440/ + */ + +extern void smdk_machine_init(void); diff --git a/arch/arm/mach-s3c/cpu.c b/arch/arm/mach-s3c/cpu.c new file mode 100644 index 000000000000..8acba21bbf4b --- /dev/null +++ b/arch/arm/mach-s3c/cpu.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. +// http://www.samsung.com +// +// Samsung CPU Support + +#include +#include +#include +#include + +#include +#include + +unsigned long samsung_cpu_id; + +void __init s3c64xx_init_cpu(void) +{ + samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0x118); + if (!samsung_cpu_id) { + /* + * S3C6400 has the ID register in a different place, + * and needs a write before it can be read. + */ + writel_relaxed(0x0, S3C_VA_SYS + 0xA1C); + samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0xA1C); + } + + pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id); +} diff --git a/arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c b/arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c new file mode 100644 index 000000000000..17b70d635236 --- /dev/null +++ b/arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2009 Simtec Electronics +// http://armlinux.simtec.co.uk/ +// Ben Dooks +// +// S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "regs-mem-s3c24xx.h" + +/** + * s3c2410_cpufreq_setrefresh - set SDRAM refresh value + * @cfg: The frequency configuration + * + * Set the SDRAM refresh value appropriately for the configured + * frequency. + */ +void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) +{ + struct s3c_cpufreq_board *board = cfg->board; + unsigned long refresh; + unsigned long refval; + + /* Reduce both the refresh time (in ns) and the frequency (in MHz) + * down to ensure that we do not overflow 32 bit numbers. + * + * This should work for HCLK up to 133MHz and refresh period up + * to 30usec. + */ + + refresh = (cfg->freq.hclk / 100) * (board->refresh / 10); + refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */ + refresh = (1 << 11) + 1 - refresh; + + s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh); + + refval = __raw_readl(S3C2410_REFRESH); + refval &= ~((1 << 12) - 1); + refval |= refresh; + __raw_writel(refval, S3C2410_REFRESH); +} + +/** + * s3c2410_set_fvco - set the PLL value + * @cfg: The frequency configuration + */ +void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg) +{ + if (!IS_ERR(cfg->mpll)) + clk_set_rate(cfg->mpll, cfg->pll.frequency); +} + +#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) +u32 s3c2440_read_camdivn(void) +{ + return __raw_readl(S3C2440_CAMDIVN); +} + +void s3c2440_write_camdivn(u32 camdiv) +{ + __raw_writel(camdiv, S3C2440_CAMDIVN); +} +#endif + +u32 s3c24xx_read_clkdivn(void) +{ + return __raw_readl(S3C2410_CLKDIVN); +} + +void s3c24xx_write_clkdivn(u32 clkdiv) +{ + __raw_writel(clkdiv, S3C2410_CLKDIVN); +} + +u32 s3c24xx_read_mpllcon(void) +{ + return __raw_readl(S3C2410_MPLLCON); +} + +void s3c24xx_write_locktime(u32 locktime) +{ + return __raw_writel(locktime, S3C2410_LOCKTIME); +} diff --git a/arch/arm/mach-s3c/cpuidle-s3c64xx.c b/arch/arm/mach-s3c/cpuidle-s3c64xx.c new file mode 100644 index 000000000000..a629f4d2fa3b --- /dev/null +++ b/arch/arm/mach-s3c/cpuidle-s3c64xx.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2011 Wolfson Microelectronics, plc +// Copyright (c) 2011 Samsung Electronics Co., Ltd. +// http://www.samsung.com + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "regs-sys-s3c64xx.h" +#include "regs-syscon-power-s3c64xx.h" + +static int s3c64xx_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + unsigned long tmp; + + /* Setup PWRCFG to enter idle mode */ + tmp = __raw_readl(S3C64XX_PWR_CFG); + tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK; + tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE; + __raw_writel(tmp, S3C64XX_PWR_CFG); + + cpu_do_idle(); + + return index; +} + +static struct cpuidle_driver s3c64xx_cpuidle_driver = { + .name = "s3c64xx_cpuidle", + .owner = THIS_MODULE, + .states = { + { + .enter = s3c64xx_enter_idle, + .exit_latency = 1, + .target_residency = 1, + .name = "IDLE", + .desc = "System active, ARM gated", + }, + }, + .state_count = 1, +}; + +static int __init s3c64xx_init_cpuidle(void) +{ + if (soc_is_s3c64xx()) + return cpuidle_register(&s3c64xx_cpuidle_driver, NULL); + return 0; +} +device_initcall(s3c64xx_init_cpuidle); diff --git a/arch/arm/mach-s3c/crag6410.h b/arch/arm/mach-s3c/crag6410.h new file mode 100644 index 000000000000..00d9aa114aa7 --- /dev/null +++ b/arch/arm/mach-s3c/crag6410.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Cragganmore 6410 shared definitions + * + * Copyright 2011 Wolfson Microelectronics plc + * Mark Brown + */ + +#ifndef MACH_CRAG6410_H +#define MACH_CRAG6410_H + +#include + +#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START +#define BANFF_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) + +#define PCA935X_GPIO_BASE GPIO_BOARD_START +#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) +#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 32) +#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 64) +#define MMGPIO_GPIO_BASE (GPIO_BOARD_START + 96) + +#endif diff --git a/arch/arm/mach-s3c/dev-audio-s3c64xx.c b/arch/arm/mach-s3c/dev-audio-s3c64xx.c new file mode 100644 index 000000000000..1d3124db6afc --- /dev/null +++ b/arch/arm/mach-s3c/dev-audio-s3c64xx.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2009 Wolfson Microelectronics +// Mark Brown + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) +{ + unsigned int base; + + switch (pdev->id) { + case 0: + base = S3C64XX_GPD(0); + break; + case 1: + base = S3C64XX_GPE(0); + break; + case 2: + s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5)); + return 0; + default: + printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", + pdev->id); + return -EINVAL; + } + + s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3)); + + return 0; +} + +static struct resource s3c64xx_iis0_resource[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256), +}; + +static struct s3c_audio_pdata i2s0_pdata = { + .cfg_gpio = s3c64xx_i2s_cfg_gpio, +}; + +struct platform_device s3c64xx_device_iis0 = { + .name = "samsung-i2s", + .id = 0, + .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), + .resource = s3c64xx_iis0_resource, + .dev = { + .platform_data = &i2s0_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_iis0); + +static struct resource s3c64xx_iis1_resource[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256), +}; + +static struct s3c_audio_pdata i2s1_pdata = { + .cfg_gpio = s3c64xx_i2s_cfg_gpio, +}; + +struct platform_device s3c64xx_device_iis1 = { + .name = "samsung-i2s", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), + .resource = s3c64xx_iis1_resource, + .dev = { + .platform_data = &i2s1_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_iis1); + +static struct resource s3c64xx_iisv4_resource[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256), +}; + +static struct s3c_audio_pdata i2sv4_pdata = { + .cfg_gpio = s3c64xx_i2s_cfg_gpio, + .type = { + .quirks = QUIRK_PRI_6CHAN, + }, +}; + +struct platform_device s3c64xx_device_iisv4 = { + .name = "samsung-i2s", + .id = 2, + .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), + .resource = s3c64xx_iisv4_resource, + .dev = { + .platform_data = &i2sv4_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_iisv4); + + +/* PCM Controller platform_devices */ + +static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) +{ + unsigned int base; + + switch (pdev->id) { + case 0: + base = S3C64XX_GPD(0); + break; + case 1: + base = S3C64XX_GPE(0); + break; + default: + printk(KERN_DEBUG "Invalid PCM Controller number: %d\n", + pdev->id); + return -EINVAL; + } + + s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2)); + return 0; +} + +static struct resource s3c64xx_pcm0_resource[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256), +}; + +static struct s3c_audio_pdata s3c_pcm0_pdata = { + .cfg_gpio = s3c64xx_pcm_cfg_gpio, +}; + +struct platform_device s3c64xx_device_pcm0 = { + .name = "samsung-pcm", + .id = 0, + .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource), + .resource = s3c64xx_pcm0_resource, + .dev = { + .platform_data = &s3c_pcm0_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_pcm0); + +static struct resource s3c64xx_pcm1_resource[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256), +}; + +static struct s3c_audio_pdata s3c_pcm1_pdata = { + .cfg_gpio = s3c64xx_pcm_cfg_gpio, +}; + +struct platform_device s3c64xx_device_pcm1 = { + .name = "samsung-pcm", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource), + .resource = s3c64xx_pcm1_resource, + .dev = { + .platform_data = &s3c_pcm1_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_pcm1); + +/* AC97 Controller platform devices */ + +static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev) +{ + return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4)); +} + +static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev) +{ + return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4)); +} + +static struct resource s3c64xx_ac97_resource[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_AC97), +}; + +static struct s3c_audio_pdata s3c_ac97_pdata = { +}; + +static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32); + +struct platform_device s3c64xx_device_ac97 = { + .name = "samsung-ac97", + .id = -1, + .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource), + .resource = s3c64xx_ac97_resource, + .dev = { + .platform_data = &s3c_ac97_pdata, + .dma_mask = &s3c64xx_ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +EXPORT_SYMBOL(s3c64xx_device_ac97); + +void __init s3c64xx_ac97_setup_gpio(int num) +{ + if (num == S3C64XX_AC97_GPD) + s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd; + else + s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe; +} diff --git a/arch/arm/mach-s3c/dev-backlight-s3c64xx.c b/arch/arm/mach-s3c/dev-backlight-s3c64xx.c new file mode 100644 index 000000000000..53bf14f5467f --- /dev/null +++ b/arch/arm/mach-s3c/dev-backlight-s3c64xx.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2011 Samsung Electronics Co., Ltd. +// http://www.samsung.com +// +// Common infrastructure for PWM Backlight for Samsung boards + +#include +#include +#include +#include +#include + +#include +#include + +#include "backlight-s3c64xx.h" + +struct samsung_bl_drvdata { + struct platform_pwm_backlight_data plat_data; + struct samsung_bl_gpio_info *gpio_info; +}; + +static int samsung_bl_init(struct device *dev) +{ + int ret = 0; + struct platform_pwm_backlight_data *pdata = dev->platform_data; + struct samsung_bl_drvdata *drvdata = container_of(pdata, + struct samsung_bl_drvdata, plat_data); + struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info; + + ret = gpio_request(bl_gpio_info->no, "Backlight"); + if (ret) { + printk(KERN_ERR "failed to request GPIO for LCD Backlight\n"); + return ret; + } + + /* Configure GPIO pin with specific GPIO function for PWM timer */ + s3c_gpio_cfgpin(bl_gpio_info->no, bl_gpio_info->func); + + return 0; +} + +static void samsung_bl_exit(struct device *dev) +{ + struct platform_pwm_backlight_data *pdata = dev->platform_data; + struct samsung_bl_drvdata *drvdata = container_of(pdata, + struct samsung_bl_drvdata, plat_data); + struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info; + + s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT); + gpio_free(bl_gpio_info->no); +} + +/* Initialize few important fields of platform_pwm_backlight_data + * structure with default values. These fields can be overridden by + * board-specific values sent from machine file. + * For ease of operation, these fields are initialized with values + * used by most samsung boards. + * Users has the option of sending info about other parameters + * for their specific boards + */ + +static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = { + .plat_data = { + .max_brightness = 255, + .dft_brightness = 255, + .init = samsung_bl_init, + .exit = samsung_bl_exit, + }, +}; + +static struct platform_device samsung_dfl_bl_device __initdata = { + .name = "pwm-backlight", +}; + +/* samsung_bl_set - Set board specific data (if any) provided by user for + * PWM Backlight control and register specific PWM and backlight device. + * @gpio_info: structure containing GPIO info for PWM timer + * @bl_data: structure containing Backlight control data + */ +void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, + struct platform_pwm_backlight_data *bl_data) +{ + int ret = 0; + struct platform_device *samsung_bl_device; + struct samsung_bl_drvdata *samsung_bl_drvdata; + struct platform_pwm_backlight_data *samsung_bl_data; + + samsung_bl_device = kmemdup(&samsung_dfl_bl_device, + sizeof(struct platform_device), GFP_KERNEL); + if (!samsung_bl_device) + return; + + samsung_bl_drvdata = kmemdup(&samsung_dfl_bl_data, + sizeof(samsung_dfl_bl_data), GFP_KERNEL); + if (!samsung_bl_drvdata) + goto err_data; + + samsung_bl_device->dev.platform_data = &samsung_bl_drvdata->plat_data; + samsung_bl_drvdata->gpio_info = gpio_info; + samsung_bl_data = &samsung_bl_drvdata->plat_data; + + /* Copy board specific data provided by user */ + samsung_bl_device->dev.parent = &samsung_device_pwm.dev; + + if (bl_data->max_brightness) + samsung_bl_data->max_brightness = bl_data->max_brightness; + if (bl_data->dft_brightness) + samsung_bl_data->dft_brightness = bl_data->dft_brightness; + if (bl_data->lth_brightness) + samsung_bl_data->lth_brightness = bl_data->lth_brightness; + if (bl_data->init) + samsung_bl_data->init = bl_data->init; + if (bl_data->notify) + samsung_bl_data->notify = bl_data->notify; + if (bl_data->notify_after) + samsung_bl_data->notify_after = bl_data->notify_after; + if (bl_data->exit) + samsung_bl_data->exit = bl_data->exit; + if (bl_data->check_fb) + samsung_bl_data->check_fb = bl_data->check_fb; + + /* Register the Backlight dev */ + ret = platform_device_register(samsung_bl_device); + if (ret) { + printk(KERN_ERR "failed to register backlight device: %d\n", ret); + goto err_plat_reg2; + } + + return; + +err_plat_reg2: + kfree(samsung_bl_data); +err_data: + kfree(samsung_bl_device); +} diff --git a/arch/arm/mach-s3c/dev-uart-s3c64xx.c b/arch/arm/mach-s3c/dev-uart-s3c64xx.c new file mode 100644 index 000000000000..021a2b7926fa --- /dev/null +++ b/arch/arm/mach-s3c/dev-uart-s3c64xx.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2008 Openmoko, Inc. +// Copyright 2008 Simtec Electronics +// Ben Dooks +// http://armlinux.simtec.co.uk/ +// +// Base S3C64XX UART resource and device definitions + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* Serial port registrations */ + +/* 64xx uarts are closer together */ + +static struct resource s3c64xx_uart0_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_UART0, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART0), +}; + +static struct resource s3c64xx_uart1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_UART1, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART1), +}; + +static struct resource s3c6xx_uart2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_UART2, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART2), +}; + +static struct resource s3c64xx_uart3_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_UART3, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_UART3), +}; + + +struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = { + [0] = { + .resources = s3c64xx_uart0_resource, + .nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource), + }, + [1] = { + .resources = s3c64xx_uart1_resource, + .nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource), + }, + [2] = { + .resources = s3c6xx_uart2_resource, + .nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource), + }, + [3] = { + .resources = s3c64xx_uart3_resource, + .nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource), + }, +}; diff --git a/arch/arm/mach-s3c/dev-uart.c b/arch/arm/mach-s3c/dev-uart.c new file mode 100644 index 000000000000..7476a5dbae77 --- /dev/null +++ b/arch/arm/mach-s3c/dev-uart.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// originally from arch/arm/plat-s3c24xx/devs.c +// +// Copyright (c) 2004 Simtec Electronics +// Ben Dooks +// +// Base S3C24XX platform device definitions + +#include +#include + +#include + +/* uart devices */ + +static struct platform_device s3c24xx_uart_device0 = { + .id = 0, +}; + +static struct platform_device s3c24xx_uart_device1 = { + .id = 1, +}; + +static struct platform_device s3c24xx_uart_device2 = { + .id = 2, +}; + +static struct platform_device s3c24xx_uart_device3 = { + .id = 3, +}; + +struct platform_device *s3c24xx_uart_src[4] = { + &s3c24xx_uart_device0, + &s3c24xx_uart_device1, + &s3c24xx_uart_device2, + &s3c24xx_uart_device3, +}; + +struct platform_device *s3c24xx_uart_devs[4] = { +}; diff --git a/arch/arm/mach-s3c/devs.c b/arch/arm/mach-s3c/devs.c new file mode 100644 index 000000000000..e23204132b27 --- /dev/null +++ b/arch/arm/mach-s3c/devs.c @@ -0,0 +1,1199 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2011 Samsung Electronics Co., Ltd. +// http://www.samsung.com +// +// Base Samsung platform device definitions + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_PLAT_S3C24XX +#include +#endif /* CONFIG_PLAT_S3C24XX */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define samsung_device_dma_mask (*((u64[]) { DMA_BIT_MASK(32) })) + +/* AC97 */ +#ifdef CONFIG_CPU_S3C2440 +static struct resource s3c_ac97_resource[] = { + [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97), + [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97), +}; + +struct platform_device s3c_device_ac97 = { + .name = "samsung-ac97", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_ac97_resource), + .resource = s3c_ac97_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_CPU_S3C2440 */ + +/* ADC */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_adc_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC), + [1] = DEFINE_RES_IRQ(IRQ_TC), + [2] = DEFINE_RES_IRQ(IRQ_ADC), +}; + +struct platform_device s3c_device_adc = { + .name = "s3c24xx-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +#if defined(CONFIG_SAMSUNG_DEV_ADC) +static struct resource s3c_adc_resource[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_ADC), + [2] = DEFINE_RES_IRQ(IRQ_TC), +}; + +struct platform_device s3c_device_adc = { + .name = "exynos-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; +#endif /* CONFIG_SAMSUNG_DEV_ADC */ + +/* Camif Controller */ + +#ifdef CONFIG_CPU_S3C2440 +static struct resource s3c_camif_resource[] = { + [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF), + [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C), + [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P), +}; + +struct platform_device s3c_device_camif = { + .name = "s3c2440-camif", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_camif_resource), + .resource = s3c_camif_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_CPU_S3C2440 */ + +/* FB */ + +#ifdef CONFIG_S3C_DEV_FB +static struct resource s3c_fb_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K), + [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC), + [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO), + [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM), +}; + +struct platform_device s3c_device_fb = { + .name = "s3c-fb", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_fb_resource), + .resource = s3c_fb_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), + &s3c_device_fb); +} +#endif /* CONFIG_S3C_DEV_FB */ + +/* HWMON */ + +#ifdef CONFIG_S3C_DEV_HWMON +struct platform_device s3c_device_hwmon = { + .name = "s3c-hwmon", + .id = -1, + .dev.parent = &s3c_device_adc.dev, +}; + +void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata), + &s3c_device_hwmon); +} +#endif /* CONFIG_S3C_DEV_HWMON */ + +/* HSMMC */ + +#ifdef CONFIG_S3C_DEV_HSMMC +static struct resource s3c_hsmmc_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC0), +}; + +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), +}; + +struct platform_device s3c_device_hsmmc0 = { + .name = "s3c-sdhci", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), + .resource = s3c_hsmmc_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc0_def_platdata, + }, +}; + +void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC */ + +#ifdef CONFIG_S3C_DEV_HSMMC1 +static struct resource s3c_hsmmc1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC1), +}; + +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), +}; + +struct platform_device s3c_device_hsmmc1 = { + .name = "s3c-sdhci", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), + .resource = s3c_hsmmc1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc1_def_platdata, + }, +}; + +void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC1 */ + +/* HSMMC2 */ + +#ifdef CONFIG_S3C_DEV_HSMMC2 +static struct resource s3c_hsmmc2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC2), +}; + +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), +}; + +struct platform_device s3c_device_hsmmc2 = { + .name = "s3c-sdhci", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource), + .resource = s3c_hsmmc2_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc2_def_platdata, + }, +}; + +void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC2 */ + +#ifdef CONFIG_S3C_DEV_HSMMC3 +static struct resource s3c_hsmmc3_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_HSMMC3), +}; + +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), +}; + +struct platform_device s3c_device_hsmmc3 = { + .name = "s3c-sdhci", + .id = 3, + .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource), + .resource = s3c_hsmmc3_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c_hsmmc3_def_platdata, + }, +}; + +void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) +{ + s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata); +} +#endif /* CONFIG_S3C_DEV_HSMMC3 */ + +/* I2C */ + +static struct resource s3c_i2c0_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC), +}; + +struct platform_device s3c_device_i2c0 = { + .name = "s3c2410-i2c", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_i2c0_resource), + .resource = s3c_i2c0_resource, +}; + +struct s3c2410_platform_i2c default_i2c_data __initdata = { + .flags = 0, + .slave_addr = 0x10, + .frequency = 100*1000, + .sda_delay = 100, +}; + +void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 0; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c0); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c0_cfg_gpio; +} + +#ifdef CONFIG_S3C_DEV_I2C1 +static struct resource s3c_i2c1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC1), +}; + +struct platform_device s3c_device_i2c1 = { + .name = "s3c2410-i2c", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_i2c1_resource), + .resource = s3c_i2c1_resource, +}; + +void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 1; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c1); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c1_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C1 */ + +#ifdef CONFIG_S3C_DEV_I2C2 +static struct resource s3c_i2c2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC2), +}; + +struct platform_device s3c_device_i2c2 = { + .name = "s3c2410-i2c", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_i2c2_resource), + .resource = s3c_i2c2_resource, +}; + +void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 2; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c2); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c2_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C2 */ + +#ifdef CONFIG_S3C_DEV_I2C3 +static struct resource s3c_i2c3_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC3), +}; + +struct platform_device s3c_device_i2c3 = { + .name = "s3c2440-i2c", + .id = 3, + .num_resources = ARRAY_SIZE(s3c_i2c3_resource), + .resource = s3c_i2c3_resource, +}; + +void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 3; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c3); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c3_cfg_gpio; +} +#endif /*CONFIG_S3C_DEV_I2C3 */ + +#ifdef CONFIG_S3C_DEV_I2C4 +static struct resource s3c_i2c4_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC4), +}; + +struct platform_device s3c_device_i2c4 = { + .name = "s3c2440-i2c", + .id = 4, + .num_resources = ARRAY_SIZE(s3c_i2c4_resource), + .resource = s3c_i2c4_resource, +}; + +void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 4; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c4); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c4_cfg_gpio; +} +#endif /*CONFIG_S3C_DEV_I2C4 */ + +#ifdef CONFIG_S3C_DEV_I2C5 +static struct resource s3c_i2c5_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC5), +}; + +struct platform_device s3c_device_i2c5 = { + .name = "s3c2440-i2c", + .id = 5, + .num_resources = ARRAY_SIZE(s3c_i2c5_resource), + .resource = s3c_i2c5_resource, +}; + +void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 5; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c5); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c5_cfg_gpio; +} +#endif /*CONFIG_S3C_DEV_I2C5 */ + +#ifdef CONFIG_S3C_DEV_I2C6 +static struct resource s3c_i2c6_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC6), +}; + +struct platform_device s3c_device_i2c6 = { + .name = "s3c2440-i2c", + .id = 6, + .num_resources = ARRAY_SIZE(s3c_i2c6_resource), + .resource = s3c_i2c6_resource, +}; + +void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 6; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c6); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c6_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C6 */ + +#ifdef CONFIG_S3C_DEV_I2C7 +static struct resource s3c_i2c7_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_IIC7), +}; + +struct platform_device s3c_device_i2c7 = { + .name = "s3c2440-i2c", + .id = 7, + .num_resources = ARRAY_SIZE(s3c_i2c7_resource), + .resource = s3c_i2c7_resource, +}; + +void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) { + pd = &default_i2c_data; + pd->bus_num = 7; + } + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c7); + + if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c7_cfg_gpio; +} +#endif /* CONFIG_S3C_DEV_I2C7 */ + +/* I2S */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_iis_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS), +}; + +struct platform_device s3c_device_iis = { + .name = "s3c24xx-iis", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_iis_resource), + .resource = s3c_iis_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +/* IDE CFCON */ + +#ifdef CONFIG_SAMSUNG_DEV_IDE +static struct resource s3c_cfcon_resource[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K), + [1] = DEFINE_RES_IRQ(IRQ_CFCON), +}; + +struct platform_device s3c_device_cfcon = { + .id = 0, + .num_resources = ARRAY_SIZE(s3c_cfcon_resource), + .resource = s3c_cfcon_resource, +}; + +void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) +{ + s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), + &s3c_device_cfcon); +} +#endif /* CONFIG_SAMSUNG_DEV_IDE */ + +/* KEYPAD */ + +#ifdef CONFIG_SAMSUNG_DEV_KEYPAD +static struct resource samsung_keypad_resources[] = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_KEYPAD), +}; + +struct platform_device samsung_device_keypad = { + .name = "samsung-keypad", + .id = -1, + .num_resources = ARRAY_SIZE(samsung_keypad_resources), + .resource = samsung_keypad_resources, +}; + +void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) +{ + struct samsung_keypad_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(*npd), &samsung_device_keypad); + + if (!npd->cfg_gpio) + npd->cfg_gpio = samsung_keypad_cfg_gpio; +} +#endif /* CONFIG_SAMSUNG_DEV_KEYPAD */ + +/* LCD Controller */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_lcd_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD), + [1] = DEFINE_RES_IRQ(IRQ_LCD), +}; + +struct platform_device s3c_device_lcd = { + .name = "s3c2410-lcd", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_lcd_resource), + .resource = s3c_lcd_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) +{ + struct s3c2410fb_mach_info *npd; + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd); + if (npd) { + npd->displays = kmemdup(pd->displays, + sizeof(struct s3c2410fb_display) * npd->num_displays, + GFP_KERNEL); + if (!npd->displays) + printk(KERN_ERR "no memory for LCD display data\n"); + } else { + printk(KERN_ERR "no memory for LCD platform data\n"); + } +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* NAND */ + +#ifdef CONFIG_S3C_DEV_NAND +static struct resource s3c_nand_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M), +}; + +struct platform_device s3c_device_nand = { + .name = "s3c2410-nand", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_nand_resource), + .resource = s3c_nand_resource, +}; + +/* + * s3c_nand_copy_set() - copy nand set data + * @set: The new structure, directly copied from the old. + * + * Copy all the fields from the NAND set field from what is probably __initdata + * to new kernel memory. The code returns 0 if the copy happened correctly or + * an error code for the calling function to display. + * + * Note, we currently do not try and look to see if we've already copied the + * data in a previous set. + */ +static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) +{ + void *ptr; + int size; + + size = sizeof(struct mtd_partition) * set->nr_partitions; + if (size) { + ptr = kmemdup(set->partitions, size, GFP_KERNEL); + set->partitions = ptr; + + if (!ptr) + return -ENOMEM; + } + + if (set->nr_map && set->nr_chips) { + size = sizeof(int) * set->nr_chips; + ptr = kmemdup(set->nr_map, size, GFP_KERNEL); + set->nr_map = ptr; + + if (!ptr) + return -ENOMEM; + } + + return 0; +} + +void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) +{ + struct s3c2410_platform_nand *npd; + int size; + int ret; + + /* note, if we get a failure in allocation, we simply drop out of the + * function. If there is so little memory available at initialisation + * time then there is little chance the system is going to run. + */ + + npd = s3c_set_platdata(nand, sizeof(*npd), &s3c_device_nand); + if (!npd) + return; + + /* now see if we need to copy any of the nand set data */ + + size = sizeof(struct s3c2410_nand_set) * npd->nr_sets; + if (size) { + struct s3c2410_nand_set *from = npd->sets; + struct s3c2410_nand_set *to; + int i; + + to = kmemdup(from, size, GFP_KERNEL); + npd->sets = to; /* set, even if we failed */ + + if (!to) { + printk(KERN_ERR "%s: no memory for sets\n", __func__); + return; + } + + for (i = 0; i < npd->nr_sets; i++) { + ret = s3c_nand_copy_set(to); + if (ret) { + printk(KERN_ERR "%s: failed to copy set %d\n", + __func__, i); + return; + } + to++; + } + } +} +#endif /* CONFIG_S3C_DEV_NAND */ + +/* ONENAND */ + +#ifdef CONFIG_S3C_DEV_ONENAND +static struct resource s3c_onenand_resources[] = { + [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K), + [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF), + [2] = DEFINE_RES_IRQ(IRQ_ONENAND), +}; + +struct platform_device s3c_device_onenand = { + .name = "samsung-onenand", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_onenand_resources), + .resource = s3c_onenand_resources, +}; +#endif /* CONFIG_S3C_DEV_ONENAND */ + +#ifdef CONFIG_S3C64XX_DEV_ONENAND1 +static struct resource s3c64xx_onenand1_resources[] = { + [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K), + [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF), + [2] = DEFINE_RES_IRQ(IRQ_ONENAND1), +}; + +struct platform_device s3c64xx_device_onenand1 = { + .name = "samsung-onenand", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources), + .resource = s3c64xx_onenand1_resources, +}; + +void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) +{ + s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), + &s3c64xx_device_onenand1); +} +#endif /* CONFIG_S3C64XX_DEV_ONENAND1 */ + +/* PWM Timer */ + +#ifdef CONFIG_SAMSUNG_DEV_PWM +static struct resource samsung_pwm_resource[] = { + DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K), +}; + +struct platform_device samsung_device_pwm = { + .name = "samsung-pwm", + .id = -1, + .num_resources = ARRAY_SIZE(samsung_pwm_resource), + .resource = samsung_pwm_resource, +}; + +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) +{ + samsung_device_pwm.dev.platform_data = pd; +} +#endif /* CONFIG_SAMSUNG_DEV_PWM */ + +/* RTC */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_rtc_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_RTC), + [2] = DEFINE_RES_IRQ(IRQ_TICK), +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c2410-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +#ifdef CONFIG_S3C_DEV_RTC +static struct resource s3c_rtc_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM), + [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC), +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c64xx-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; +#endif /* CONFIG_S3C_DEV_RTC */ + +/* SDI */ + +#ifdef CONFIG_PLAT_S3C24XX +void s3c24xx_mci_def_set_power(unsigned char power_mode, unsigned short vdd) +{ + switch (power_mode) { + case MMC_POWER_ON: + case MMC_POWER_UP: + /* Configure GPE5...GPE10 pins in SD mode */ + s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2), + S3C_GPIO_PULL_NONE); + break; + + case MMC_POWER_OFF: + default: + gpio_direction_output(S3C2410_GPE(5), 0); + break; + } +} + +static struct resource s3c_sdi_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI), + [1] = DEFINE_RES_IRQ(IRQ_SDI), +}; + +static struct s3c24xx_mci_pdata s3cmci_def_pdata = { + /* This is currently here to avoid a number of if (host->pdata) + * checks. Any zero fields to ensure reasonable defaults are picked. */ + .no_wprotect = 1, + .no_detect = 1, + .set_power = s3c24xx_mci_def_set_power, +}; + +struct platform_device s3c_device_sdi = { + .name = "s3c2410-sdi", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_sdi_resource), + .resource = s3c_sdi_resource, + .dev.platform_data = &s3cmci_def_pdata, +}; + +void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) +{ + s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata), + &s3c_device_sdi); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* SPI */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_spi0_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_SPI0), +}; + +struct platform_device s3c_device_spi0 = { + .name = "s3c2410-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_spi0_resource), + .resource = s3c_spi0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +static struct resource s3c_spi1_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_SPI1), +}; + +struct platform_device s3c_device_spi1 = { + .name = "s3c2410-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_spi1_resource), + .resource = s3c_spi1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +#endif /* CONFIG_PLAT_S3C24XX */ + +/* Touchscreen */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_ts_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC), + [1] = DEFINE_RES_IRQ(IRQ_TC), +}; + +struct platform_device s3c_device_ts = { + .name = "s3c2410-ts", + .id = -1, + .dev.parent = &s3c_device_adc.dev, + .num_resources = ARRAY_SIZE(s3c_ts_resource), + .resource = s3c_ts_resource, +}; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) +{ + s3c_set_platdata(hard_s3c2410ts_info, + sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +#ifdef CONFIG_SAMSUNG_DEV_TS +static struct s3c2410_ts_mach_info default_ts_data __initdata = { + .delay = 10000, + .presc = 49, + .oversampling_shift = 2, +}; + +void __init s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) +{ + if (!pd) + pd = &default_ts_data; + + s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info), + &s3c_device_adc); +} +#endif /* CONFIG_SAMSUNG_DEV_TS */ + +/* USB */ + +#ifdef CONFIG_S3C_DEV_USB_HOST +static struct resource s3c_usb_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_USBH), +}; + +struct platform_device s3c_device_ohci = { + .name = "s3c2410-ohci", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usb_resource), + .resource = s3c_usb_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +/* + * s3c_ohci_set_platdata - initialise OHCI device platform data + * @info: The platform data. + * + * This call copies the @info passed in and sets the device .platform_data + * field to that copy. The @info is copied so that the original can be marked + * __initdata. + */ + +void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info) +{ + s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info), + &s3c_device_ohci); +} +#endif /* CONFIG_S3C_DEV_USB_HOST */ + +/* USB Device (Gadget) */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_usbgadget_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV), + [1] = DEFINE_RES_IRQ(IRQ_USBD), +}; + +struct platform_device s3c_device_usbgadget = { + .name = "s3c2410-usbgadget", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), + .resource = s3c_usbgadget_resource, +}; + +void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd) +{ + s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget); +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* USB HSOTG */ + +#ifdef CONFIG_S3C_DEV_USB_HSOTG +static struct resource s3c_usb_hsotg_resources[] = { + [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K), + [1] = DEFINE_RES_IRQ(IRQ_OTG), +}; + +struct platform_device s3c_device_usb_hsotg = { + .name = "s3c-hsotg", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources), + .resource = s3c_usb_hsotg_resources, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd) +{ + struct dwc2_hsotg_plat *npd; + + npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_usb_hsotg); + + if (!npd->phy_init) + npd->phy_init = s3c_usb_phy_init; + if (!npd->phy_exit) + npd->phy_exit = s3c_usb_phy_exit; +} +#endif /* CONFIG_S3C_DEV_USB_HSOTG */ + +/* USB High Spped 2.0 Device (Gadget) */ + +#ifdef CONFIG_PLAT_S3C24XX +static struct resource s3c_hsudc_resource[] = { + [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC), + [1] = DEFINE_RES_IRQ(IRQ_USBD), +}; + +struct platform_device s3c_device_usb_hsudc = { + .name = "s3c-hsudc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_hsudc_resource), + .resource = s3c_hsudc_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc); + pd->phy_init = s3c_hsudc_init_phy; + pd->phy_uninit = s3c_hsudc_uninit_phy; +} +#endif /* CONFIG_PLAT_S3C24XX */ + +/* WDT */ + +#ifdef CONFIG_S3C_DEV_WDT +static struct resource s3c_wdt_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K), + [1] = DEFINE_RES_IRQ(IRQ_WDT), +}; + +struct platform_device s3c_device_wdt = { + .name = "s3c2410-wdt", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_wdt_resource), + .resource = s3c_wdt_resource, +}; +#endif /* CONFIG_S3C_DEV_WDT */ + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +static struct resource s3c64xx_spi0_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_SPI0), +}; + +struct platform_device s3c64xx_device_spi0 = { + .name = "s3c6410-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), + .resource = s3c64xx_spi0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, + int num_cs) +{ + struct s3c64xx_spi_info pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd.num_cs = num_cs; + pd.src_clk_nr = src_clk_nr; + pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; + + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); +} +#endif /* CONFIG_S3C64XX_DEV_SPI0 */ + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +static struct resource s3c64xx_spi1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_SPI1), +}; + +struct platform_device s3c64xx_device_spi1 = { + .name = "s3c6410-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), + .resource = s3c64xx_spi1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, + int num_cs) +{ + struct s3c64xx_spi_info pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd.num_cs = num_cs; + pd.src_clk_nr = src_clk_nr; + pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; + + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); +} +#endif /* CONFIG_S3C64XX_DEV_SPI1 */ + +#ifdef CONFIG_S3C64XX_DEV_SPI2 +static struct resource s3c64xx_spi2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256), + [1] = DEFINE_RES_IRQ(IRQ_SPI2), +}; + +struct platform_device s3c64xx_device_spi2 = { + .name = "s3c6410-spi", + .id = 2, + .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource), + .resource = s3c64xx_spi2_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, + int num_cs) +{ + struct s3c64xx_spi_info pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd.num_cs = num_cs; + pd.src_clk_nr = src_clk_nr; + pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; + + s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); +} +#endif /* CONFIG_S3C64XX_DEV_SPI2 */ diff --git a/arch/arm/mach-s3c/fb-core-s3c24xx.h b/arch/arm/mach-s3c/fb-core-s3c24xx.h new file mode 100644 index 000000000000..0e07f3ba4aef --- /dev/null +++ b/arch/arm/mach-s3c/fb-core-s3c24xx.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2010 Samsung Electronics Co., Ltd. + * Pawel Osciak + * + * Samsung framebuffer driver core functions + */ +#ifndef __ASM_PLAT_FB_CORE_S3C24XX_H +#define __ASM_PLAT_FB_CORE_S3C24XX_H __FILE__ + +/* + * These functions are only for use with the core support code, such as + * the CPU-specific initialization code. + */ + +/* Re-define device name depending on support. */ +static inline void s3c_fb_setname(char *name) +{ +#ifdef CONFIG_S3C_DEV_FB + s3c_device_fb.name = name; +#endif +} + +#endif /* __ASM_PLAT_FB_CORE_S3C24XX_H */ diff --git a/arch/arm/mach-s3c/gpio-samsung.c b/arch/arm/mach-s3c/gpio-samsung.c new file mode 100644 index 000000000000..8955fd675265 --- /dev/null +++ b/arch/arm/mach-s3c/gpio-samsung.c @@ -0,0 +1,1324 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. +// http://www.samsung.com/ +// +// Copyright 2008 Openmoko, Inc. +// Copyright 2008 Simtec Electronics +// Ben Dooks +// http://armlinux.simtec.co.uk/ +// +// Samsung - GPIOlib support + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull) +{ + void __iomem *reg = chip->base + 0x08; + int shift = off * 2; + u32 pup; + + pup = __raw_readl(reg); + pup &= ~(3 << shift); + pup |= pull << shift; + __raw_writel(pup, reg); + + return 0; +} + +samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip, + unsigned int off) +{ + void __iomem *reg = chip->base + 0x08; + int shift = off * 2; + u32 pup = __raw_readl(reg); + + pup >>= shift; + pup &= 0x3; + + return (__force samsung_gpio_pull_t)pup; +} + +int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull) +{ + switch (pull) { + case S3C_GPIO_PULL_NONE: + pull = 0x01; + break; + case S3C_GPIO_PULL_UP: + pull = 0x00; + break; + case S3C_GPIO_PULL_DOWN: + pull = 0x02; + break; + } + return samsung_gpio_setpull_updown(chip, off, pull); +} + +samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip, + unsigned int off) +{ + samsung_gpio_pull_t pull; + + pull = samsung_gpio_getpull_updown(chip, off); + + switch (pull) { + case 0x00: + pull = S3C_GPIO_PULL_UP; + break; + case 0x01: + case 0x03: + pull = S3C_GPIO_PULL_NONE; + break; + case 0x02: + pull = S3C_GPIO_PULL_DOWN; + break; + } + + return pull; +} + +static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull, + samsung_gpio_pull_t updown) +{ + void __iomem *reg = chip->base + 0x08; + u32 pup = __raw_readl(reg); + + if (pull == updown) + pup &= ~(1 << off); + else if (pull == S3C_GPIO_PULL_NONE) + pup |= (1 << off); + else + return -EINVAL; + + __raw_writel(pup, reg); + return 0; +} + +static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip, + unsigned int off, + samsung_gpio_pull_t updown) +{ + void __iomem *reg = chip->base + 0x08; + u32 pup = __raw_readl(reg); + + pup &= (1 << off); + return pup ? S3C_GPIO_PULL_NONE : updown; +} + +samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip, + unsigned int off) +{ + return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); +} + +int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull) +{ + return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); +} + +samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip, + unsigned int off) +{ + return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); +} + +int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull) +{ + return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); +} + +/* + * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @cfg: The configuration value to set. + * + * This helper deal with the GPIO cases where the control register + * has two bits of configuration per gpio, which have the following + * functions: + * 00 = input + * 01 = output + * 1x = special function + */ + +static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift = off * 2; + u32 con; + + if (samsung_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + if (cfg > 3) + return -EINVAL; + + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0x3 << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} + +/* + * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * + * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which + * could be directly passed back to samsung_gpio_setcfg_2bit(), from the + * S3C_GPIO_SPECIAL() macro. + */ + +static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip, + unsigned int off) +{ + u32 con; + + con = __raw_readl(chip->base); + con >>= off * 2; + con &= 3; + + /* this conversion works for IN and OUT as well as special mode */ + return S3C_GPIO_SPECIAL(con); +} + +/* + * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @cfg: The configuration value to set. + * + * This helper deal with the GPIO cases where the control register has 4 bits + * of control per GPIO, generally in the form of: + * 0000 = Input + * 0001 = Output + * others = Special functions (dependent on bank) + * + * Note, since the code to deal with the case where there are two control + * registers instead of one, we do not have a separate set of functions for + * each case. + */ + +static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift = (off & 7) * 4; + u32 con; + + if (off < 8 && chip->chip.ngpio > 8) + reg -= 4; + + if (samsung_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0xf << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} + +/* + * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * + * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration + * register setting into a value the software can use, such as could be passed + * to samsung_gpio_setcfg_4bit(). + * + * @sa samsung_gpio_getcfg_2bit + */ + +static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip, + unsigned int off) +{ + void __iomem *reg = chip->base; + unsigned int shift = (off & 7) * 4; + u32 con; + + if (off < 8 && chip->chip.ngpio > 8) + reg -= 4; + + con = __raw_readl(reg); + con >>= shift; + con &= 0xf; + + /* this conversion works for IN and OUT as well as special mode */ + return S3C_GPIO_SPECIAL(con); +} + +#ifdef CONFIG_PLAT_S3C24XX +/* + * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A) + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @cfg: The configuration value to set. + * + * This helper deal with the GPIO cases where the control register + * has one bit of configuration for the gpio, where setting the bit + * means the pin is in special function mode and unset means output. + */ + +static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift = off; + u32 con; + + if (samsung_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + + /* Map output to 0, and SFN2 to 1 */ + cfg -= 1; + if (cfg > 1) + return -EINVAL; + + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0x1 << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} + +/* + * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A) + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * + * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable + * GPIO configuration value. + * + * @sa samsung_gpio_getcfg_2bit + * @sa samsung_gpio_getcfg_4bit + */ + +static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip, + unsigned int off) +{ + u32 con; + + con = __raw_readl(chip->base); + con >>= off; + con &= 1; + con++; + + return S3C_GPIO_SFN(con); +} +#endif + +static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg, + int nr_chips) +{ + for (; nr_chips > 0; nr_chips--, chipcfg++) { + if (!chipcfg->set_config) + chipcfg->set_config = samsung_gpio_setcfg_4bit; + if (!chipcfg->get_config) + chipcfg->get_config = samsung_gpio_getcfg_4bit; + if (!chipcfg->set_pull) + chipcfg->set_pull = samsung_gpio_setpull_updown; + if (!chipcfg->get_pull) + chipcfg->get_pull = samsung_gpio_getpull_updown; + } +} + +struct samsung_gpio_cfg s3c24xx_gpiocfg_default = { + .set_config = samsung_gpio_setcfg_2bit, + .get_config = samsung_gpio_getcfg_2bit, +}; + +#ifdef CONFIG_PLAT_S3C24XX +static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { + .set_config = s3c24xx_gpio_setcfg_abank, + .get_config = s3c24xx_gpio_getcfg_abank, +}; +#endif + +static struct samsung_gpio_cfg samsung_gpio_cfgs[] = { + [0] = { + .cfg_eint = 0x0, + }, + [1] = { + .cfg_eint = 0x3, + }, + [2] = { + .cfg_eint = 0x7, + }, + [3] = { + .cfg_eint = 0xF, + }, + [4] = { + .cfg_eint = 0x0, + .set_config = samsung_gpio_setcfg_2bit, + .get_config = samsung_gpio_getcfg_2bit, + }, + [5] = { + .cfg_eint = 0x2, + .set_config = samsung_gpio_setcfg_2bit, + .get_config = samsung_gpio_getcfg_2bit, + }, + [6] = { + .cfg_eint = 0x3, + .set_config = samsung_gpio_setcfg_2bit, + .get_config = samsung_gpio_getcfg_2bit, + }, + [7] = { + .set_config = samsung_gpio_setcfg_2bit, + .get_config = samsung_gpio_getcfg_2bit, + }, +}; + +/* + * Default routines for controlling GPIO, based on the original S3C24XX + * GPIO functions which deal with the case where each gpio bank of the + * chip is as following: + * + * base + 0x00: Control register, 2 bits per gpio + * gpio n: 2 bits starting at (2*n) + * 00 = input, 01 = output, others mean special-function + * base + 0x04: Data register, 1 bit per gpio + * bit n: data bit n +*/ + +static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long con; + + samsung_gpio_lock(ourchip, flags); + + con = __raw_readl(base + 0x00); + con &= ~(3 << (offset * 2)); + + __raw_writel(con, base + 0x00); + + samsung_gpio_unlock(ourchip, flags); + return 0; +} + +static int samsung_gpiolib_2bit_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long dat; + unsigned long con; + + samsung_gpio_lock(ourchip, flags); + + dat = __raw_readl(base + 0x04); + dat &= ~(1 << offset); + if (value) + dat |= 1 << offset; + __raw_writel(dat, base + 0x04); + + con = __raw_readl(base + 0x00); + con &= ~(3 << (offset * 2)); + con |= 1 << (offset * 2); + + __raw_writel(con, base + 0x00); + __raw_writel(dat, base + 0x04); + + samsung_gpio_unlock(ourchip, flags); + return 0; +} + +/* + * The samsung_gpiolib_4bit routines are to control the gpio banks where + * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the + * following example: + * + * base + 0x00: Control register, 4 bits per gpio + * gpio n: 4 bits starting at (4*n) + * 0000 = input, 0001 = output, others mean special-function + * base + 0x04: Data register, 1 bit per gpio + * bit n: data bit n + * + * Note, since the data register is one bit per gpio and is at base + 0x4 + * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the + * state of the output. + */ + +static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long con; + + con = __raw_readl(base + GPIOCON_OFF); + if (ourchip->bitmap_gpio_int & BIT(offset)) + con |= 0xf << con_4bit_shift(offset); + else + con &= ~(0xf << con_4bit_shift(offset)); + __raw_writel(con, base + GPIOCON_OFF); + + pr_debug("%s: %p: CON now %08lx\n", __func__, base, con); + + return 0; +} + +static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long con; + unsigned long dat; + + con = __raw_readl(base + GPIOCON_OFF); + con &= ~(0xf << con_4bit_shift(offset)); + con |= 0x1 << con_4bit_shift(offset); + + dat = __raw_readl(base + GPIODAT_OFF); + + if (value) + dat |= 1 << offset; + else + dat &= ~(1 << offset); + + __raw_writel(dat, base + GPIODAT_OFF); + __raw_writel(con, base + GPIOCON_OFF); + __raw_writel(dat, base + GPIODAT_OFF); + + pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); + + return 0; +} + +/* + * The next set of routines are for the case where the GPIO configuration + * registers are 4 bits per GPIO but there is more than one register (the + * bank has more than 8 GPIOs. + * + * This case is the similar to the 4 bit case, but the registers are as + * follows: + * + * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) + * gpio n: 4 bits starting at (4*n) + * 0000 = input, 0001 = output, others mean special-function + * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) + * gpio n: 4 bits starting at (4*n) + * 0000 = input, 0001 = output, others mean special-function + * base + 0x08: Data register, 1 bit per gpio + * bit n: data bit n + * + * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set + * routines we store the 'base + 0x4' address so that these routines see + * the data register at ourchip->base + 0x04. + */ + +static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + void __iomem *regcon = base; + unsigned long con; + + if (offset > 7) + offset -= 8; + else + regcon -= 4; + + con = __raw_readl(regcon); + con &= ~(0xf << con_4bit_shift(offset)); + __raw_writel(con, regcon); + + pr_debug("%s: %p: CON %08lx\n", __func__, base, con); + + return 0; +} + +static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + void __iomem *regcon = base; + unsigned long con; + unsigned long dat; + unsigned con_offset = offset; + + if (con_offset > 7) + con_offset -= 8; + else + regcon -= 4; + + con = __raw_readl(regcon); + con &= ~(0xf << con_4bit_shift(con_offset)); + con |= 0x1 << con_4bit_shift(con_offset); + + dat = __raw_readl(base + GPIODAT_OFF); + + if (value) + dat |= 1 << offset; + else + dat &= ~(1 << offset); + + __raw_writel(dat, base + GPIODAT_OFF); + __raw_writel(con, regcon); + __raw_writel(dat, base + GPIODAT_OFF); + + pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); + + return 0; +} + +#ifdef CONFIG_PLAT_S3C24XX +/* The next set of routines are for the case of s3c24xx bank a */ + +static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) +{ + return -EINVAL; +} + +static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long dat; + unsigned long con; + + local_irq_save(flags); + + con = __raw_readl(base + 0x00); + dat = __raw_readl(base + 0x04); + + dat &= ~(1 << offset); + if (value) + dat |= 1 << offset; + + __raw_writel(dat, base + 0x04); + + con &= ~(1 << offset); + + __raw_writel(con, base + 0x00); + __raw_writel(dat, base + 0x04); + + local_irq_restore(flags); + return 0; +} +#endif + +static void samsung_gpiolib_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long dat; + + samsung_gpio_lock(ourchip, flags); + + dat = __raw_readl(base + 0x04); + dat &= ~(1 << offset); + if (value) + dat |= 1 << offset; + __raw_writel(dat, base + 0x04); + + samsung_gpio_unlock(ourchip, flags); +} + +static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset) +{ + struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); + unsigned long val; + + val = __raw_readl(ourchip->base + 0x04); + val >>= offset; + val &= 1; + + return val; +} + +/* + * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios + * for use with the configuration calls, and other parts of the s3c gpiolib + * support code. + * + * Not all s3c support code will need this, as some configurations of cpu + * may only support one or two different configuration options and have an + * easy gpio to samsung_gpio_chip mapping function. If this is the case, then + * the machine support file should provide its own samsung_gpiolib_getchip() + * and any other necessary functions. + */ + +#ifdef CONFIG_S3C_GPIO_TRACK +struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END]; + +static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip) +{ + unsigned int gpn; + int i; + + gpn = chip->chip.base; + for (i = 0; i < chip->chip.ngpio; i++, gpn++) { + BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios)); + s3c_gpios[gpn] = chip; + } +} +#endif /* CONFIG_S3C_GPIO_TRACK */ + +/* + * samsung_gpiolib_add() - add the Samsung gpio_chip. + * @chip: The chip to register + * + * This is a wrapper to gpiochip_add() that takes our specific gpio chip + * information and makes the necessary alterations for the platform and + * notes the information for use with the configuration systems and any + * other parts of the system. + */ + +static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) +{ + struct gpio_chip *gc = &chip->chip; + int ret; + + BUG_ON(!chip->base); + BUG_ON(!gc->label); + BUG_ON(!gc->ngpio); + + spin_lock_init(&chip->lock); + + if (!gc->direction_input) + gc->direction_input = samsung_gpiolib_2bit_input; + if (!gc->direction_output) + gc->direction_output = samsung_gpiolib_2bit_output; + if (!gc->set) + gc->set = samsung_gpiolib_set; + if (!gc->get) + gc->get = samsung_gpiolib_get; + +#ifdef CONFIG_PM + if (chip->pm != NULL) { + if (!chip->pm->save || !chip->pm->resume) + pr_err("gpio: %s has missing PM functions\n", + gc->label); + } else + pr_err("gpio: %s has no PM function\n", gc->label); +#endif + + /* gpiochip_add() prints own failure message on error. */ + ret = gpiochip_add_data(gc, chip); + if (ret >= 0) + s3c_gpiolib_track(chip); +} + +static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, + int nr_chips, void __iomem *base) +{ + int i; + struct gpio_chip *gc = &chip->chip; + + for (i = 0 ; i < nr_chips; i++, chip++) { + /* skip banks not present on SoC */ + if (chip->chip.base >= S3C_GPIO_END) + continue; + + if (!chip->config) + chip->config = &s3c24xx_gpiocfg_default; + if (!chip->pm) + chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); + if ((base != NULL) && (chip->base == NULL)) + chip->base = base + ((i) * 0x10); + + if (!gc->direction_input) + gc->direction_input = samsung_gpiolib_2bit_input; + if (!gc->direction_output) + gc->direction_output = samsung_gpiolib_2bit_output; + + samsung_gpiolib_add(chip); + } +} + +static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip, + int nr_chips, void __iomem *base, + unsigned int offset) +{ + int i; + + for (i = 0 ; i < nr_chips; i++, chip++) { + chip->chip.direction_input = samsung_gpiolib_2bit_input; + chip->chip.direction_output = samsung_gpiolib_2bit_output; + + if (!chip->config) + chip->config = &samsung_gpio_cfgs[7]; + if (!chip->pm) + chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); + if ((base != NULL) && (chip->base == NULL)) + chip->base = base + ((i) * offset); + + samsung_gpiolib_add(chip); + } +} + +/* + * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config. + * @chip: The gpio chip that is being configured. + * @nr_chips: The no of chips (gpio ports) for the GPIO being configured. + * + * This helper deal with the GPIO cases where the control register has 4 bits + * of control per GPIO, generally in the form of: + * 0000 = Input + * 0001 = Output + * others = Special functions (dependent on bank) + * + * Note, since the code to deal with the case where there are two control + * registers instead of one, we do not have a separate set of function + * (samsung_gpiolib_add_4bit2_chips)for each case. + */ + +static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip, + int nr_chips, void __iomem *base) +{ + int i; + + for (i = 0 ; i < nr_chips; i++, chip++) { + chip->chip.direction_input = samsung_gpiolib_4bit_input; + chip->chip.direction_output = samsung_gpiolib_4bit_output; + + if (!chip->config) + chip->config = &samsung_gpio_cfgs[2]; + if (!chip->pm) + chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); + if ((base != NULL) && (chip->base == NULL)) + chip->base = base + ((i) * 0x20); + + chip->bitmap_gpio_int = 0; + + samsung_gpiolib_add(chip); + } +} + +static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip, + int nr_chips) +{ + for (; nr_chips > 0; nr_chips--, chip++) { + chip->chip.direction_input = samsung_gpiolib_4bit2_input; + chip->chip.direction_output = samsung_gpiolib_4bit2_output; + + if (!chip->config) + chip->config = &samsung_gpio_cfgs[2]; + if (!chip->pm) + chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); + + samsung_gpiolib_add(chip); + } +} + +int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip); + + return samsung_chip->irq_base + offset; +} + +#ifdef CONFIG_PLAT_S3C24XX +static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) +{ + if (offset < 4) { + if (soc_is_s3c2412()) + return IRQ_EINT0_2412 + offset; + else + return IRQ_EINT0 + offset; + } + + if (offset < 8) + return IRQ_EINT4 + offset - 4; + + return -EINVAL; +} +#endif + +#ifdef CONFIG_ARCH_S3C64XX +static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin) +{ + return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO; +} + +static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin) +{ + return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO; +} +#endif + +struct samsung_gpio_chip s3c24xx_gpios[] = { +#ifdef CONFIG_PLAT_S3C24XX + { + .config = &s3c24xx_gpiocfg_banka, + .chip = { + .base = S3C2410_GPA(0), + .owner = THIS_MODULE, + .label = "GPIOA", + .ngpio = 27, + .direction_input = s3c24xx_gpiolib_banka_input, + .direction_output = s3c24xx_gpiolib_banka_output, + }, + }, { + .chip = { + .base = S3C2410_GPB(0), + .owner = THIS_MODULE, + .label = "GPIOB", + .ngpio = 11, + }, + }, { + .chip = { + .base = S3C2410_GPC(0), + .owner = THIS_MODULE, + .label = "GPIOC", + .ngpio = 16, + }, + }, { + .chip = { + .base = S3C2410_GPD(0), + .owner = THIS_MODULE, + .label = "GPIOD", + .ngpio = 16, + }, + }, { + .chip = { + .base = S3C2410_GPE(0), + .label = "GPIOE", + .owner = THIS_MODULE, + .ngpio = 16, + }, + }, { + .chip = { + .base = S3C2410_GPF(0), + .owner = THIS_MODULE, + .label = "GPIOF", + .ngpio = 8, + .to_irq = s3c24xx_gpiolib_fbank_to_irq, + }, + }, { + .irq_base = IRQ_EINT8, + .chip = { + .base = S3C2410_GPG(0), + .owner = THIS_MODULE, + .label = "GPIOG", + .ngpio = 16, + .to_irq = samsung_gpiolib_to_irq, + }, + }, { + .chip = { + .base = S3C2410_GPH(0), + .owner = THIS_MODULE, + .label = "GPIOH", + .ngpio = 15, + }, + }, + /* GPIOS for the S3C2443 and later devices. */ + { + .base = S3C2440_GPJCON, + .chip = { + .base = S3C2410_GPJ(0), + .owner = THIS_MODULE, + .label = "GPIOJ", + .ngpio = 16, + }, + }, { + .base = S3C2443_GPKCON, + .chip = { + .base = S3C2410_GPK(0), + .owner = THIS_MODULE, + .label = "GPIOK", + .ngpio = 16, + }, + }, { + .base = S3C2443_GPLCON, + .chip = { + .base = S3C2410_GPL(0), + .owner = THIS_MODULE, + .label = "GPIOL", + .ngpio = 15, + }, + }, { + .base = S3C2443_GPMCON, + .chip = { + .base = S3C2410_GPM(0), + .owner = THIS_MODULE, + .label = "GPIOM", + .ngpio = 2, + }, + }, +#endif +}; + +/* + * GPIO bank summary: + * + * Bank GPIOs Style SlpCon ExtInt Group + * A 8 4Bit Yes 1 + * B 7 4Bit Yes 1 + * C 8 4Bit Yes 2 + * D 5 4Bit Yes 3 + * E 5 4Bit Yes None + * F 16 2Bit Yes 4 [1] + * G 7 4Bit Yes 5 + * H 10 4Bit[2] Yes 6 + * I 16 2Bit Yes None + * J 12 2Bit Yes None + * K 16 4Bit[2] No None + * L 15 4Bit[2] No None + * M 6 4Bit No IRQ_EINT + * N 16 2Bit No IRQ_EINT + * O 16 2Bit Yes 7 + * P 15 2Bit Yes 8 + * Q 9 2Bit Yes 9 + * + * [1] BANKF pins 14,15 do not form part of the external interrupt sources + * [2] BANK has two control registers, GPxCON0 and GPxCON1 + */ + +static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = { +#ifdef CONFIG_ARCH_S3C64XX + { + .chip = { + .base = S3C64XX_GPA(0), + .ngpio = S3C64XX_GPIO_A_NR, + .label = "GPA", + }, + }, { + .chip = { + .base = S3C64XX_GPB(0), + .ngpio = S3C64XX_GPIO_B_NR, + .label = "GPB", + }, + }, { + .chip = { + .base = S3C64XX_GPC(0), + .ngpio = S3C64XX_GPIO_C_NR, + .label = "GPC", + }, + }, { + .chip = { + .base = S3C64XX_GPD(0), + .ngpio = S3C64XX_GPIO_D_NR, + .label = "GPD", + }, + }, { + .config = &samsung_gpio_cfgs[0], + .chip = { + .base = S3C64XX_GPE(0), + .ngpio = S3C64XX_GPIO_E_NR, + .label = "GPE", + }, + }, { + .base = S3C64XX_GPG_BASE, + .chip = { + .base = S3C64XX_GPG(0), + .ngpio = S3C64XX_GPIO_G_NR, + .label = "GPG", + }, + }, { + .base = S3C64XX_GPM_BASE, + .config = &samsung_gpio_cfgs[1], + .chip = { + .base = S3C64XX_GPM(0), + .ngpio = S3C64XX_GPIO_M_NR, + .label = "GPM", + .to_irq = s3c64xx_gpiolib_mbank_to_irq, + }, + }, +#endif +}; + +static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = { +#ifdef CONFIG_ARCH_S3C64XX + { + .base = S3C64XX_GPH_BASE + 0x4, + .chip = { + .base = S3C64XX_GPH(0), + .ngpio = S3C64XX_GPIO_H_NR, + .label = "GPH", + }, + }, { + .base = S3C64XX_GPK_BASE + 0x4, + .config = &samsung_gpio_cfgs[0], + .chip = { + .base = S3C64XX_GPK(0), + .ngpio = S3C64XX_GPIO_K_NR, + .label = "GPK", + }, + }, { + .base = S3C64XX_GPL_BASE + 0x4, + .config = &samsung_gpio_cfgs[1], + .chip = { + .base = S3C64XX_GPL(0), + .ngpio = S3C64XX_GPIO_L_NR, + .label = "GPL", + .to_irq = s3c64xx_gpiolib_lbank_to_irq, + }, + }, +#endif +}; + +static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { +#ifdef CONFIG_ARCH_S3C64XX + { + .base = S3C64XX_GPF_BASE, + .config = &samsung_gpio_cfgs[6], + .chip = { + .base = S3C64XX_GPF(0), + .ngpio = S3C64XX_GPIO_F_NR, + .label = "GPF", + }, + }, { + .config = &samsung_gpio_cfgs[7], + .chip = { + .base = S3C64XX_GPI(0), + .ngpio = S3C64XX_GPIO_I_NR, + .label = "GPI", + }, + }, { + .config = &samsung_gpio_cfgs[7], + .chip = { + .base = S3C64XX_GPJ(0), + .ngpio = S3C64XX_GPIO_J_NR, + .label = "GPJ", + }, + }, { + .config = &samsung_gpio_cfgs[6], + .chip = { + .base = S3C64XX_GPO(0), + .ngpio = S3C64XX_GPIO_O_NR, + .label = "GPO", + }, + }, { + .config = &samsung_gpio_cfgs[6], + .chip = { + .base = S3C64XX_GPP(0), + .ngpio = S3C64XX_GPIO_P_NR, + .label = "GPP", + }, + }, { + .config = &samsung_gpio_cfgs[6], + .chip = { + .base = S3C64XX_GPQ(0), + .ngpio = S3C64XX_GPIO_Q_NR, + .label = "GPQ", + }, + }, { + .base = S3C64XX_GPN_BASE, + .irq_base = IRQ_EINT(0), + .config = &samsung_gpio_cfgs[5], + .chip = { + .base = S3C64XX_GPN(0), + .ngpio = S3C64XX_GPIO_N_NR, + .label = "GPN", + .to_irq = samsung_gpiolib_to_irq, + }, + }, +#endif +}; + +/* TODO: cleanup soc_is_* */ +static __init int samsung_gpiolib_init(void) +{ + /* + * Currently there are two drivers that can provide GPIO support for + * Samsung SoCs. For device tree enabled platforms, the new + * pinctrl-samsung driver is used, providing both GPIO and pin control + * interfaces. For legacy (non-DT) platforms this driver is used. + */ + if (of_have_populated_dt()) + return 0; + + if (soc_is_s3c24xx()) { + samsung_gpiolib_set_cfg(samsung_gpio_cfgs, + ARRAY_SIZE(samsung_gpio_cfgs)); + s3c24xx_gpiolib_add_chips(s3c24xx_gpios, + ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO); + } else if (soc_is_s3c64xx()) { + samsung_gpiolib_set_cfg(samsung_gpio_cfgs, + ARRAY_SIZE(samsung_gpio_cfgs)); + samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit, + ARRAY_SIZE(s3c64xx_gpios_2bit), + S3C64XX_VA_GPIO + 0xE0, 0x20); + samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit, + ARRAY_SIZE(s3c64xx_gpios_4bit), + S3C64XX_VA_GPIO); + samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2, + ARRAY_SIZE(s3c64xx_gpios_4bit2)); + } + + return 0; +} +core_initcall(samsung_gpiolib_init); + +int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) +{ + struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); + unsigned long flags; + int offset; + int ret; + + if (!chip) + return -EINVAL; + + offset = pin - chip->chip.base; + + samsung_gpio_lock(chip, flags); + ret = samsung_gpio_do_setcfg(chip, offset, config); + samsung_gpio_unlock(chip, flags); + + return ret; +} +EXPORT_SYMBOL(s3c_gpio_cfgpin); + +int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, + unsigned int cfg) +{ + int ret; + + for (; nr > 0; nr--, start++) { + ret = s3c_gpio_cfgpin(start, cfg); + if (ret != 0) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); + +int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, + unsigned int cfg, samsung_gpio_pull_t pull) +{ + int ret; + + for (; nr > 0; nr--, start++) { + s3c_gpio_setpull(start, pull); + ret = s3c_gpio_cfgpin(start, cfg); + if (ret != 0) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); + +unsigned s3c_gpio_getcfg(unsigned int pin) +{ + struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); + unsigned long flags; + unsigned ret = 0; + int offset; + + if (chip) { + offset = pin - chip->chip.base; + + samsung_gpio_lock(chip, flags); + ret = samsung_gpio_do_getcfg(chip, offset); + samsung_gpio_unlock(chip, flags); + } + + return ret; +} +EXPORT_SYMBOL(s3c_gpio_getcfg); + +int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull) +{ + struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); + unsigned long flags; + int offset, ret; + + if (!chip) + return -EINVAL; + + offset = pin - chip->chip.base; + + samsung_gpio_lock(chip, flags); + ret = samsung_gpio_do_setpull(chip, offset, pull); + samsung_gpio_unlock(chip, flags); + + return ret; +} +EXPORT_SYMBOL(s3c_gpio_setpull); + +samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin) +{ + struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); + unsigned long flags; + int offset; + u32 pup = 0; + + if (chip) { + offset = pin - chip->chip.base; + + samsung_gpio_lock(chip, flags); + pup = samsung_gpio_do_getpull(chip, offset); + samsung_gpio_unlock(chip, flags); + } + + return (__force samsung_gpio_pull_t)pup; +} +EXPORT_SYMBOL(s3c_gpio_getpull); + +#ifdef CONFIG_PLAT_S3C24XX +unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) +{ + unsigned long flags; + unsigned long misccr; + + local_irq_save(flags); + misccr = __raw_readl(S3C24XX_MISCCR); + misccr &= ~clear; + misccr ^= change; + __raw_writel(misccr, S3C24XX_MISCCR); + local_irq_restore(flags); + + return misccr; +} +EXPORT_SYMBOL(s3c2410_modify_misccr); +#endif diff --git a/arch/arm/mach-s3c/gta02.h b/arch/arm/mach-s3c/gta02.h new file mode 100644 index 000000000000..d5610ba829a4 --- /dev/null +++ b/arch/arm/mach-s3c/gta02.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * GTA02 header + */ + +#ifndef __MACH_S3C24XX_GTA02_H +#define __MACH_S3C24XX_GTA02_H __FILE__ + +#include + +#define GTA02_GPIO_AUX_LED S3C2410_GPB(2) +#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9) +#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6) +#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7) +#define GTA02_GPIO_AMP_SHUT S3C2410_GPJ(1) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_HP_IN S3C2410_GPJ(2) /* v2 + v3 + v4 only */ + +#define GTA02_IRQ_PCF50633 IRQ_EINT9 + +#endif /* __MACH_S3C24XX_GTA02_H */ diff --git a/arch/arm/mach-s3c/h1940-bluetooth.c b/arch/arm/mach-s3c/h1940-bluetooth.c new file mode 100644 index 000000000000..8533e7521b50 --- /dev/null +++ b/arch/arm/mach-s3c/h1940-bluetooth.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-1.0+ +// +// Copyright (c) Arnaud Patard +// +// S3C2410 bluetooth "driver" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "h1940.h" + +#define DRV_NAME "h1940-bt" + +/* Bluetooth control */ +static void h1940bt_enable(int on) +{ + if (on) { + /* Power on the chip */ + gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1); + /* Reset the chip */ + mdelay(10); + + gpio_set_value(S3C2410_GPH(1), 1); + mdelay(10); + gpio_set_value(S3C2410_GPH(1), 0); + + h1940_led_blink_set(NULL, GPIO_LED_BLINK, NULL, NULL); + } + else { + gpio_set_value(S3C2410_GPH(1), 1); + mdelay(10); + gpio_set_value(S3C2410_GPH(1), 0); + mdelay(10); + gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0); + + h1940_led_blink_set(NULL, GPIO_LED_NO_BLINK_LOW, NULL, NULL); + } +} + +static int h1940bt_set_block(void *data, bool blocked) +{ + h1940bt_enable(!blocked); + return 0; +} + +static const struct rfkill_ops h1940bt_rfkill_ops = { + .set_block = h1940bt_set_block, +}; + +static int h1940bt_probe(struct platform_device *pdev) +{ + struct rfkill *rfk; + int ret = 0; + + ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev)); + if (ret) { + dev_err(&pdev->dev, "could not get GPH1\n"); + return ret; + } + + ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev)); + if (ret) { + gpio_free(S3C2410_GPH(1)); + dev_err(&pdev->dev, "could not get BT_POWER\n"); + return ret; + } + + /* Configures BT serial port GPIOs */ + s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); + s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); + s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); + s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); + s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); + + rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, + &h1940bt_rfkill_ops, NULL); + if (!rfk) { + ret = -ENOMEM; + goto err_rfk_alloc; + } + + ret = rfkill_register(rfk); + if (ret) + goto err_rfkill; + + platform_set_drvdata(pdev, rfk); + + return 0; + +err_rfkill: + rfkill_destroy(rfk); +err_rfk_alloc: + return ret; +} + +static int h1940bt_remove(struct platform_device *pdev) +{ + struct rfkill *rfk = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + gpio_free(S3C2410_GPH(1)); + + if (rfk) { + rfkill_unregister(rfk); + rfkill_destroy(rfk); + } + rfk = NULL; + + h1940bt_enable(0); + + return 0; +} + + +static struct platform_driver h1940bt_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = h1940bt_probe, + .remove = h1940bt_remove, +}; + +module_platform_driver(h1940bt_driver); + +MODULE_AUTHOR("Arnaud Patard "); +MODULE_DESCRIPTION("Driver for the iPAQ H1940 bluetooth chip"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-s3c/h1940.h b/arch/arm/mach-s3c/h1940.h new file mode 100644 index 000000000000..5dfe9d10cd15 --- /dev/null +++ b/arch/arm/mach-s3c/h1940.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2006 Ben Dooks + * + * Copyright (c) 2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * iPAQ H1940 series definitions + */ + +#ifndef __MACH_S3C24XX_H1940_H +#define __MACH_S3C24XX_H1940_H __FILE__ + +#define H1940_SUSPEND_CHECKSUM (0x30003ff8) +#define H1940_SUSPEND_RESUMEAT (0x30081000) +#define H1940_SUSPEND_CHECK (0x30080000) + +struct gpio_desc; + +extern void h1940_pm_return(void); +extern int h1940_led_blink_set(struct gpio_desc *desc, int state, + unsigned long *delay_on, + unsigned long *delay_off); + +#include + +#define H1940_LATCH_GPIO(x) (S3C_GPIO_END + (x)) + +/* SD layer latch */ + +#define H1940_LATCH_LCD_P0 H1940_LATCH_GPIO(0) +#define H1940_LATCH_LCD_P1 H1940_LATCH_GPIO(1) +#define H1940_LATCH_LCD_P2 H1940_LATCH_GPIO(2) +#define H1940_LATCH_LCD_P3 H1940_LATCH_GPIO(3) +#define H1940_LATCH_MAX1698_nSHUTDOWN H1940_LATCH_GPIO(4) +#define H1940_LATCH_LED_RED H1940_LATCH_GPIO(5) +#define H1940_LATCH_SDQ7 H1940_LATCH_GPIO(6) +#define H1940_LATCH_USB_DP H1940_LATCH_GPIO(7) + +/* CPU layer latch */ + +#define H1940_LATCH_UDA_POWER H1940_LATCH_GPIO(8) +#define H1940_LATCH_AUDIO_POWER H1940_LATCH_GPIO(9) +#define H1940_LATCH_SM803_ENABLE H1940_LATCH_GPIO(10) +#define H1940_LATCH_LCD_P4 H1940_LATCH_GPIO(11) +#define H1940_LATCH_SD_POWER H1940_LATCH_GPIO(12) +#define H1940_LATCH_BLUETOOTH_POWER H1940_LATCH_GPIO(13) +#define H1940_LATCH_LED_GREEN H1940_LATCH_GPIO(14) +#define H1940_LATCH_LED_FLASH H1940_LATCH_GPIO(15) + +#endif /* __MACH_S3C24XX_H1940_H */ diff --git a/arch/arm/mach-s3c/include/mach/dma-s3c24xx.h b/arch/arm/mach-s3c/include/mach/dma-s3c24xx.h new file mode 100644 index 000000000000..25fc9c258fc1 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/dma-s3c24xx.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2003-2006 Simtec Electronics + * Ben Dooks + * + * Samsung S3C24XX DMA support + */ + +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H __FILE__ + +#include + +/* We use `virtual` dma channels to hide the fact we have only a limited + * number of DMA channels, and not of all of them (dependent on the device) + * can be attached to any DMA source. We therefore let the DMA core handle + * the allocation of hardware channels to clients. +*/ + +enum dma_ch { + DMACH_XD0 = 0, + DMACH_XD1, + DMACH_SDI, + DMACH_SPI0, + DMACH_SPI1, + DMACH_UART0, + DMACH_UART1, + DMACH_UART2, + DMACH_TIMER, + DMACH_I2S_IN, + DMACH_I2S_OUT, + DMACH_PCM_IN, + DMACH_PCM_OUT, + DMACH_MIC_IN, + DMACH_USB_EP1, + DMACH_USB_EP2, + DMACH_USB_EP3, + DMACH_USB_EP4, + DMACH_UART0_SRC2, /* s3c2412 second uart sources */ + DMACH_UART1_SRC2, + DMACH_UART2_SRC2, + DMACH_UART3, /* s3c2443 has extra uart */ + DMACH_UART3_SRC2, + DMACH_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */ + DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */ + DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */ + DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */ + DMACH_MAX, /* the end entry */ +}; + +#endif /* __ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-s3c/include/mach/dma-s3c64xx.h b/arch/arm/mach-s3c/include/mach/dma-s3c64xx.h new file mode 100644 index 000000000000..40ca8de21096 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/dma-s3c64xx.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* linux/arch/arm/mach-s3c6400/include/mach/dma.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C6400 - DMA support + */ + +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H __FILE__ + +#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name)) + +/* DMA0/SDMA0 */ +#define DMACH_UART0 "uart0_tx" +#define DMACH_UART0_SRC2 "uart0_rx" +#define DMACH_UART1 "uart1_tx" +#define DMACH_UART1_SRC2 "uart1_rx" +#define DMACH_UART2 "uart2_tx" +#define DMACH_UART2_SRC2 "uart2_rx" +#define DMACH_UART3 "uart3_tx" +#define DMACH_UART3_SRC2 "uart3_rx" +#define DMACH_PCM0_TX "pcm0_tx" +#define DMACH_PCM0_RX "pcm0_rx" +#define DMACH_I2S0_OUT "i2s0_tx" +#define DMACH_I2S0_IN "i2s0_rx" +#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx") +#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx") +#define DMACH_HSI_I2SV40_TX "i2s2_tx" +#define DMACH_HSI_I2SV40_RX "i2s2_rx" + +/* DMA1/SDMA1 */ +#define DMACH_PCM1_TX "pcm1_tx" +#define DMACH_PCM1_RX "pcm1_rx" +#define DMACH_I2S1_OUT "i2s1_tx" +#define DMACH_I2S1_IN "i2s1_rx" +#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx") +#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx") +#define DMACH_AC97_PCMOUT "ac97_out" +#define DMACH_AC97_PCMIN "ac97_in" +#define DMACH_AC97_MICIN "ac97_mic" +#define DMACH_PWM "pwm" +#define DMACH_IRDA "irda" +#define DMACH_EXTERNAL "external" +#define DMACH_SECURITY_RX "sec_rx" +#define DMACH_SECURITY_TX "sec_tx" + +enum dma_ch { + DMACH_MAX = 32 +}; + +#include + +#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c/include/mach/dma.h b/arch/arm/mach-s3c/include/mach/dma.h new file mode 100644 index 000000000000..59a4578c5f00 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/dma.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "dma-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "dma-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/gpio-samsung-s3c24xx.h b/arch/arm/mach-s3c/include/mach/gpio-samsung-s3c24xx.h new file mode 100644 index 000000000000..f8a114891f16 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/gpio-samsung-s3c24xx.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2410 - GPIO lib support + */ + +/* some boards require extra gpio capacity to support external + * devices that need GPIO. + */ + +#ifndef GPIO_SAMSUNG_S3C24XX_H +#define GPIO_SAMSUNG_S3C24XX_H + +#include + +/* + * GPIO sizes for various SoCs: + * + * 2410 2412 2440 2443 2416 + * 2442 + * ---- ---- ---- ---- ---- + * A 23 22 25 16 27 + * B 11 11 11 11 11 + * C 16 16 16 16 16 + * D 16 16 16 16 16 + * E 16 16 16 16 16 + * F 8 8 8 8 8 + * G 16 16 16 16 8 + * H 11 11 11 15 15 + * J -- -- 13 16 -- + * K -- -- -- -- 16 + * L -- -- -- 15 14 + * M -- -- -- 2 2 + */ + +/* GPIO bank sizes */ + +#define S3C2410_GPIO_A_NR (32) +#define S3C2410_GPIO_B_NR (32) +#define S3C2410_GPIO_C_NR (32) +#define S3C2410_GPIO_D_NR (32) +#define S3C2410_GPIO_E_NR (32) +#define S3C2410_GPIO_F_NR (32) +#define S3C2410_GPIO_G_NR (32) +#define S3C2410_GPIO_H_NR (32) +#define S3C2410_GPIO_J_NR (32) /* technically 16. */ +#define S3C2410_GPIO_K_NR (32) /* technically 16. */ +#define S3C2410_GPIO_L_NR (32) /* technically 15. */ +#define S3C2410_GPIO_M_NR (32) /* technically 2. */ + +#if CONFIG_S3C_GPIO_SPACE != 0 +#error CONFIG_S3C_GPIO_SPACE cannot be nonzero at the moment +#endif + +#define S3C2410_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0) + +#ifndef __ASSEMBLY__ + +enum s3c_gpio_number { + S3C2410_GPIO_A_START = 0, + S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A), + S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B), + S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C), + S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D), + S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E), + S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F), + S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G), + S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H), + S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J), + S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K), + S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L), +}; + +#endif /* __ASSEMBLY__ */ + +/* S3C2410 GPIO number definitions. */ + +#define S3C2410_GPA(_nr) (S3C2410_GPIO_A_START + (_nr)) +#define S3C2410_GPB(_nr) (S3C2410_GPIO_B_START + (_nr)) +#define S3C2410_GPC(_nr) (S3C2410_GPIO_C_START + (_nr)) +#define S3C2410_GPD(_nr) (S3C2410_GPIO_D_START + (_nr)) +#define S3C2410_GPE(_nr) (S3C2410_GPIO_E_START + (_nr)) +#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr)) +#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr)) +#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr)) +#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr)) +#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr)) +#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr)) +#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr)) + +#ifdef CONFIG_CPU_S3C244X +#define S3C_GPIO_END (S3C2410_GPJ(0) + 32) +#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) +#define S3C_GPIO_END (S3C2410_GPM(0) + 32) +#else +#define S3C_GPIO_END (S3C2410_GPH(0) + 32) +#endif + +#endif /* GPIO_SAMSUNG_S3C24XX_H */ diff --git a/arch/arm/mach-s3c/include/mach/gpio-samsung-s3c64xx.h b/arch/arm/mach-s3c/include/mach/gpio-samsung-s3c64xx.h new file mode 100644 index 000000000000..8ed144a0d474 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/gpio-samsung-s3c64xx.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C6400 - GPIO lib support + */ + +#ifndef GPIO_SAMSUNG_S3C64XX_H +#define GPIO_SAMSUNG_S3C64XX_H + +#ifdef CONFIG_GPIO_SAMSUNG + +/* GPIO bank sizes */ +#define S3C64XX_GPIO_A_NR (8) +#define S3C64XX_GPIO_B_NR (7) +#define S3C64XX_GPIO_C_NR (8) +#define S3C64XX_GPIO_D_NR (5) +#define S3C64XX_GPIO_E_NR (5) +#define S3C64XX_GPIO_F_NR (16) +#define S3C64XX_GPIO_G_NR (7) +#define S3C64XX_GPIO_H_NR (10) +#define S3C64XX_GPIO_I_NR (16) +#define S3C64XX_GPIO_J_NR (12) +#define S3C64XX_GPIO_K_NR (16) +#define S3C64XX_GPIO_L_NR (15) +#define S3C64XX_GPIO_M_NR (6) +#define S3C64XX_GPIO_N_NR (16) +#define S3C64XX_GPIO_O_NR (16) +#define S3C64XX_GPIO_P_NR (15) +#define S3C64XX_GPIO_Q_NR (9) + +/* GPIO bank numbes */ + +/* CONFIG_S3C_GPIO_SPACE allows the user to select extra + * space for debugging purposes so that any accidental + * change from one gpio bank to another can be caught. +*/ + +#define S3C64XX_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) + +enum s3c_gpio_number { + S3C64XX_GPIO_A_START = 0, + S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A), + S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B), + S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C), + S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D), + S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E), + S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F), + S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G), + S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H), + S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I), + S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J), + S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K), + S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L), + S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M), + S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N), + S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O), + S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P), +}; + +/* S3C64XX GPIO number definitions. */ + +#define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr)) +#define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr)) +#define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr)) +#define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr)) +#define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr)) +#define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr)) +#define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr)) +#define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr)) +#define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr)) +#define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr)) +#define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr)) +#define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr)) +#define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr)) +#define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr)) +#define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr)) +#define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr)) +#define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr)) + +/* the end of the S3C64XX specific gpios */ +#define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) +#define S3C_GPIO_END S3C64XX_GPIO_END + +/* define the number of gpios we need to the one after the GPQ() range */ +#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) + +#endif /* GPIO_SAMSUNG */ +#endif /* GPIO_SAMSUNG_S3C64XX_H */ + diff --git a/arch/arm/mach-s3c/include/mach/gpio-samsung.h b/arch/arm/mach-s3c/include/mach/gpio-samsung.h new file mode 100644 index 000000000000..02f6f4a96862 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/gpio-samsung.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "gpio-samsung-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "gpio-samsung-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/hardware-s3c24xx.h b/arch/arm/mach-s3c/include/mach/hardware-s3c24xx.h new file mode 100644 index 000000000000..33b37467d05f --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/hardware-s3c24xx.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003 Simtec Electronics + * Ben Dooks + * + * S3C2410 - hardware + */ + +#ifndef __ASM_ARCH_HARDWARE_S3C24XX_H +#define __ASM_ARCH_HARDWARE_S3C24XX_H + +extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg); + +#endif /* __ASM_ARCH_HARDWARE_S3C24XX_H */ diff --git a/arch/arm/mach-s3c/include/mach/io-s3c24xx.h b/arch/arm/mach-s3c/include/mach/io-s3c24xx.h new file mode 100644 index 000000000000..9b78b0a3d486 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/io-s3c24xx.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * arch/arm/mach-s3c2410/include/mach/io.h + * from arch/arm/mach-rpc/include/mach/io.h + * + * Copyright (C) 1997 Russell King + * (C) 2003 Simtec Electronics +*/ + +#ifndef __ASM_ARM_ARCH_IO_S3C24XX_H +#define __ASM_ARM_ARCH_IO_S3C24XX_H + +#include + +/* + * ISA style IO, for each machine to sort out mappings for, + * if it implements it. We reserve two 16M regions for ISA, + * so the PC/104 can use separate addresses for 8-bit and + * 16-bit port I/O. + */ +#define PCIO_BASE S3C_ADDR(0x02000000) +#define IO_SPACE_LIMIT 0x00ffffff +#define S3C24XX_VA_ISA_WORD (PCIO_BASE) +#define S3C24XX_VA_ISA_BYTE (PCIO_BASE + 0x01000000) + +#ifdef CONFIG_ISA + +#define inb(p) readb(S3C24XX_VA_ISA_BYTE + (p)) +#define inw(p) readw(S3C24XX_VA_ISA_WORD + (p)) +#define inl(p) readl(S3C24XX_VA_ISA_WORD + (p)) + +#define outb(v,p) writeb((v), S3C24XX_VA_ISA_BYTE + (p)) +#define outw(v,p) writew((v), S3C24XX_VA_ISA_WORD + (p)) +#define outl(v,p) writel((v), S3C24XX_VA_ISA_WORD + (p)) + +#define insb(p,d,l) readsb(S3C24XX_VA_ISA_BYTE + (p),d,l) +#define insw(p,d,l) readsw(S3C24XX_VA_ISA_WORD + (p),d,l) +#define insl(p,d,l) readsl(S3C24XX_VA_ISA_WORD + (p),d,l) + +#define outsb(p,d,l) writesb(S3C24XX_VA_ISA_BYTE + (p),d,l) +#define outsw(p,d,l) writesw(S3C24XX_VA_ISA_WORD + (p),d,l) +#define outsl(p,d,l) writesl(S3C24XX_VA_ISA_WORD + (p),d,l) + +#else + +#define __io(x) (PCIO_BASE + (x)) + +#endif + +#endif diff --git a/arch/arm/mach-s3c/include/mach/io.h b/arch/arm/mach-s3c/include/mach/io.h new file mode 100644 index 000000000000..30a0135708dc --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/io.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Krzysztof Kozlowski + */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "io-s3c24xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h b/arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h new file mode 100644 index 000000000000..aaf3bae08b52 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h @@ -0,0 +1,213 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks + */ + + +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H __FILE__ + +/* we keep the first set of CPU IRQs out of the range of + * the ISA space, so that the PC104 has them to itself + * and we don't end up having to do horrible things to the + * standard ISA drivers.... + */ + +#define S3C2410_CPUIRQ_OFFSET (16) + +#define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET) + +/* main cpu interrupts */ +#define IRQ_EINT0 S3C2410_IRQ(0) /* 16 */ +#define IRQ_EINT1 S3C2410_IRQ(1) +#define IRQ_EINT2 S3C2410_IRQ(2) +#define IRQ_EINT3 S3C2410_IRQ(3) +#define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */ +#define IRQ_EINT8t23 S3C2410_IRQ(5) +#define IRQ_RESERVED6 S3C2410_IRQ(6) /* for s3c2410 */ +#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440,s3c2443 */ +#define IRQ_BATT_FLT S3C2410_IRQ(7) +#define IRQ_TICK S3C2410_IRQ(8) /* 24 */ +#define IRQ_WDT S3C2410_IRQ(9) /* WDT/AC97 for s3c2443 */ +#define IRQ_TIMER0 S3C2410_IRQ(10) +#define IRQ_TIMER1 S3C2410_IRQ(11) +#define IRQ_TIMER2 S3C2410_IRQ(12) +#define IRQ_TIMER3 S3C2410_IRQ(13) +#define IRQ_TIMER4 S3C2410_IRQ(14) +#define IRQ_UART2 S3C2410_IRQ(15) +#define IRQ_LCD S3C2410_IRQ(16) /* 32 */ +#define IRQ_DMA0 S3C2410_IRQ(17) /* IRQ_DMA for s3c2443 */ +#define IRQ_DMA1 S3C2410_IRQ(18) +#define IRQ_DMA2 S3C2410_IRQ(19) +#define IRQ_DMA3 S3C2410_IRQ(20) +#define IRQ_SDI S3C2410_IRQ(21) +#define IRQ_SPI0 S3C2410_IRQ(22) +#define IRQ_UART1 S3C2410_IRQ(23) +#define IRQ_RESERVED24 S3C2410_IRQ(24) /* 40 */ +#define IRQ_NFCON S3C2410_IRQ(24) /* for s3c2440 */ +#define IRQ_USBD S3C2410_IRQ(25) +#define IRQ_USBH S3C2410_IRQ(26) +#define IRQ_IIC S3C2410_IRQ(27) +#define IRQ_UART0 S3C2410_IRQ(28) /* 44 */ +#define IRQ_SPI1 S3C2410_IRQ(29) +#define IRQ_RTC S3C2410_IRQ(30) +#define IRQ_ADCPARENT S3C2410_IRQ(31) + +/* interrupts generated from the external interrupts sources */ +#define IRQ_EINT0_2412 S3C2410_IRQ(32) +#define IRQ_EINT1_2412 S3C2410_IRQ(33) +#define IRQ_EINT2_2412 S3C2410_IRQ(34) +#define IRQ_EINT3_2412 S3C2410_IRQ(35) +#define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */ +#define IRQ_EINT5 S3C2410_IRQ(37) +#define IRQ_EINT6 S3C2410_IRQ(38) +#define IRQ_EINT7 S3C2410_IRQ(39) +#define IRQ_EINT8 S3C2410_IRQ(40) +#define IRQ_EINT9 S3C2410_IRQ(41) +#define IRQ_EINT10 S3C2410_IRQ(42) +#define IRQ_EINT11 S3C2410_IRQ(43) +#define IRQ_EINT12 S3C2410_IRQ(44) +#define IRQ_EINT13 S3C2410_IRQ(45) +#define IRQ_EINT14 S3C2410_IRQ(46) +#define IRQ_EINT15 S3C2410_IRQ(47) +#define IRQ_EINT16 S3C2410_IRQ(48) +#define IRQ_EINT17 S3C2410_IRQ(49) +#define IRQ_EINT18 S3C2410_IRQ(50) +#define IRQ_EINT19 S3C2410_IRQ(51) +#define IRQ_EINT20 S3C2410_IRQ(52) /* 68 */ +#define IRQ_EINT21 S3C2410_IRQ(53) +#define IRQ_EINT22 S3C2410_IRQ(54) +#define IRQ_EINT23 S3C2410_IRQ(55) + +#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT4 + 4) +#define IRQ_EINT(x) (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x))) + +#define IRQ_LCD_FIFO S3C2410_IRQ(56) +#define IRQ_LCD_FRAME S3C2410_IRQ(57) + +/* IRQs for the interal UARTs, and ADC + * these need to be ordered in number of appearance in the + * SUBSRC mask register +*/ + +#define S3C2410_IRQSUB(x) S3C2410_IRQ((x)+58) + +#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 74 */ +#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1) +#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2) + +#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 77 */ +#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4) +#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5) + +#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 80 */ +#define IRQ_S3CUART_TX2 S3C2410_IRQSUB(7) +#define IRQ_S3CUART_ERR2 S3C2410_IRQSUB(8) + +#define IRQ_TC S3C2410_IRQSUB(9) +#define IRQ_ADC S3C2410_IRQSUB(10) + +/* extra irqs for s3c2412 */ + +#define IRQ_S3C2412_CFSDI S3C2410_IRQ(21) + +#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13) +#define IRQ_S3C2412_CF S3C2410_IRQSUB(14) + + +#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5) +#define IRQ_S3C2416_DMA S3C2410_IRQ(17) +#define IRQ_S3C2416_UART3 S3C2410_IRQ(18) +#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20) +#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21) + +#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15) +#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16) +#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17) +#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18) +#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19) +#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20) +#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21) +#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22) +#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23) +#define IRQ_S32416_WDT S3C2410_IRQSUB(27) +#define IRQ_S32416_AC97 S3C2410_IRQSUB(28) + +/* second interrupt-register of s3c2416/s3c2450 */ + +#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 58 + 29) +#define IRQ_S3C2416_2D S3C2416_IRQ(0) +#define IRQ_S3C2416_IIC1 S3C2416_IRQ(1) +#define IRQ_S3C2416_RESERVED2 S3C2416_IRQ(2) +#define IRQ_S3C2416_RESERVED3 S3C2416_IRQ(3) +#define IRQ_S3C2416_PCM0 S3C2416_IRQ(4) +#define IRQ_S3C2416_PCM1 S3C2416_IRQ(5) +#define IRQ_S3C2416_I2S0 S3C2416_IRQ(6) +#define IRQ_S3C2416_I2S1 S3C2416_IRQ(7) + +/* extra irqs for s3c2440 */ + +#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ +#define IRQ_S3C2440_CAM_P S3C2410_IRQSUB(12) /* S3C2443 too */ +#define IRQ_S3C2440_WDT S3C2410_IRQSUB(13) +#define IRQ_S3C2440_AC97 S3C2410_IRQSUB(14) + +/* irqs for s3c2443 */ + +#define IRQ_S3C2443_DMA S3C2410_IRQ(17) /* IRQ_DMA1 */ +#define IRQ_S3C2443_UART3 S3C2410_IRQ(18) /* IRQ_DMA2 */ +#define IRQ_S3C2443_CFCON S3C2410_IRQ(19) /* IRQ_DMA3 */ +#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */ +#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */ + +#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */ + +#define IRQ_HSMMC0 IRQ_S3C2416_HSMMC0 +#define IRQ_HSMMC1 IRQ_S3C2443_HSMMC + +#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) +#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) +#define IRQ_S3C2443_LCD3 S3C2410_IRQSUB(16) +#define IRQ_S3C2443_LCD4 S3C2410_IRQSUB(17) + +#define IRQ_S3C2443_DMA0 S3C2410_IRQSUB(18) +#define IRQ_S3C2443_DMA1 S3C2410_IRQSUB(19) +#define IRQ_S3C2443_DMA2 S3C2410_IRQSUB(20) +#define IRQ_S3C2443_DMA3 S3C2410_IRQSUB(21) +#define IRQ_S3C2443_DMA4 S3C2410_IRQSUB(22) +#define IRQ_S3C2443_DMA5 S3C2410_IRQSUB(23) + +/* UART3 */ +#define IRQ_S3C2443_RX3 S3C2410_IRQSUB(24) +#define IRQ_S3C2443_TX3 S3C2410_IRQSUB(25) +#define IRQ_S3C2443_ERR3 S3C2410_IRQSUB(26) + +#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) +#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) + +#if defined(CONFIG_CPU_S3C2416) +#define NR_IRQS (IRQ_S3C2416_I2S1 + 1) +#else +#define NR_IRQS (IRQ_S3C2443_AC97 + 1) +#endif + +/* compatibility define. */ +#define IRQ_UART3 IRQ_S3C2443_UART3 +#define IRQ_S3CUART_RX3 IRQ_S3C2443_RX3 +#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 +#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 + +#define IRQ_LCD_VSYNC IRQ_S3C2443_LCD3 +#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2 + +#ifdef CONFIG_CPU_S3C2440 +#define IRQ_S3C244X_AC97 IRQ_S3C2440_AC97 +#else +#define IRQ_S3C244X_AC97 IRQ_S3C2443_AC97 +#endif + +/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ +#define FIQ_START IRQ_EINT0 + +#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h b/arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h new file mode 100644 index 000000000000..c244e480e6b3 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* linux/arch/arm/mach-s3c64xx/include/mach/irqs.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C64XX - IRQ support + */ + +#ifndef __ASM_MACH_S3C64XX_IRQS_H +#define __ASM_MACH_S3C64XX_IRQS_H __FILE__ + +/* we keep the first set of CPU IRQs out of the range of + * the ISA space, so that the PC104 has them to itself + * and we don't end up having to do horrible things to the + * standard ISA drivers.... + * + * note, since we're using the VICs, our start must be a + * mulitple of 32 to allow the common code to work + */ + +#define S3C_IRQ_OFFSET (32) + +#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET) + +#define IRQ_VIC0_BASE S3C_IRQ(0) +#define IRQ_VIC1_BASE S3C_IRQ(32) + +/* VIC based IRQs */ + +#define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x)) +#define S3C64XX_IRQ_VIC1(x) (IRQ_VIC1_BASE + (x)) + +/* VIC0 */ + +#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0) +#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1) +#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2) +#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3) +#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4) +#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5) +#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5) +#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6) +#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6) +#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7) +#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8) +#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8) +#define IRQ_POST0 S3C64XX_IRQ_VIC0(9) +#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10) +#define IRQ_2D S3C64XX_IRQ_VIC0(11) +#define IRQ_TVENC S3C64XX_IRQ_VIC0(12) +#define IRQ_SCALER S3C64XX_IRQ_VIC0(13) +#define IRQ_BATF S3C64XX_IRQ_VIC0(14) +#define IRQ_JPEG S3C64XX_IRQ_VIC0(15) +#define IRQ_MFC S3C64XX_IRQ_VIC0(16) +#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17) +#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18) +#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19) +#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20) +#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21) +#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22) +#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23) +#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24) +#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25) +#define IRQ_WDT S3C64XX_IRQ_VIC0(26) +#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27) +#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28) +#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29) +#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30) +#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31) + +/* VIC1 */ + +#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0) +#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1) +#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2) +#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3) +#define IRQ_AC97 S3C64XX_IRQ_VIC1(4) +#define IRQ_UART0 S3C64XX_IRQ_VIC1(5) +#define IRQ_UART1 S3C64XX_IRQ_VIC1(6) +#define IRQ_UART2 S3C64XX_IRQ_VIC1(7) +#define IRQ_UART3 S3C64XX_IRQ_VIC1(8) +#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9) +#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10) +#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11) +#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12) +#define IRQ_NFC S3C64XX_IRQ_VIC1(13) +#define IRQ_CFCON S3C64XX_IRQ_VIC1(14) +#define IRQ_USBH S3C64XX_IRQ_VIC1(15) +#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16) +#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17) +#define IRQ_IIC S3C64XX_IRQ_VIC1(18) +#define IRQ_HSItx S3C64XX_IRQ_VIC1(19) +#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20) +#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21) +#define IRQ_MSM S3C64XX_IRQ_VIC1(22) +#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23) +#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24) +#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25) +#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */ +#define IRQ_OTG S3C64XX_IRQ_VIC1(26) +#define IRQ_IRDA S3C64XX_IRQ_VIC1(27) +#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28) +#define IRQ_SEC S3C64XX_IRQ_VIC1(29) +#define IRQ_PENDN S3C64XX_IRQ_VIC1(30) +#define IRQ_TC IRQ_PENDN +#define IRQ_ADC S3C64XX_IRQ_VIC1(31) + +/* compatibility for device defines */ + +#define IRQ_IIC1 IRQ_S3C6410_IIC1 + +/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series + * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE + * which we place after the pair of VICs. */ + +#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5) + +#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE) +#define IRQ_EINT(x) S3C_EINT(x) +#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0)) + +/* Next the external interrupt groups. These are similar to the IRQ_EINT(x) + * that they are sourced from the GPIO pins but with a different scheme for + * priority and source indication. + * + * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO + * interrupts, but for historical reasons they are kept apart from these + * next interrupts. + * + * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the + * machine specific support files. + */ + +#define IRQ_EINT_GROUP1_NR (15) +#define IRQ_EINT_GROUP2_NR (8) +#define IRQ_EINT_GROUP3_NR (5) +#define IRQ_EINT_GROUP4_NR (14) +#define IRQ_EINT_GROUP5_NR (7) +#define IRQ_EINT_GROUP6_NR (10) +#define IRQ_EINT_GROUP7_NR (16) +#define IRQ_EINT_GROUP8_NR (15) +#define IRQ_EINT_GROUP9_NR (9) + +#define IRQ_EINT_GROUP_BASE S3C_EINT(28) +#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00) +#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR) +#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR) +#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR) +#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR) +#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR) +#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR) +#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR) +#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR) + +#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no)) + +/* Some boards have their own IRQs behind this */ +#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1) + +/* Set the default nr_irqs, boards can override if necessary */ +#define S3C64XX_NR_IRQS IRQ_BOARD_START + +/* Compatibility */ + +#define IRQ_ONENAND IRQ_ONENAND0 +#define IRQ_I2S0 IRQ_S3C6410_IIS + +#endif /* __ASM_MACH_S3C64XX_IRQS_H */ + diff --git a/arch/arm/mach-s3c/include/mach/irqs.h b/arch/arm/mach-s3c/include/mach/irqs.h new file mode 100644 index 000000000000..0bff1c1c8eb0 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/irqs.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "irqs-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "irqs-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/map-s3c24xx.h b/arch/arm/mach-s3c/include/mach/map-s3c24xx.h new file mode 100644 index 000000000000..a20c9fd0d855 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/map-s3c24xx.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003 Simtec Electronics + * Ben Dooks + * + * S3C2410 - Memory map definitions + */ + +#ifndef __ASM_ARCH_MAP_H +#define __ASM_ARCH_MAP_H + +#include +#include + +/* + * interrupt controller is the first thing we put in, to make + * the assembly code for the irq detection easier + */ +#define S3C2410_PA_IRQ (0x4A000000) +#define S3C24XX_SZ_IRQ SZ_1M + +/* memory controller registers */ +#define S3C2410_PA_MEMCTRL (0x48000000) +#define S3C24XX_SZ_MEMCTRL SZ_1M + +/* Timers */ +#define S3C2410_PA_TIMER (0x51000000) +#define S3C24XX_SZ_TIMER SZ_1M + +/* Clock and Power management */ +#define S3C24XX_SZ_CLKPWR SZ_1M + +/* USB Device port */ +#define S3C2410_PA_USBDEV (0x52000000) +#define S3C24XX_SZ_USBDEV SZ_1M + +/* Watchdog */ +#define S3C2410_PA_WATCHDOG (0x53000000) +#define S3C24XX_SZ_WATCHDOG SZ_1M + +/* Standard size definitions for peripheral blocks. */ + +#define S3C24XX_SZ_UART SZ_1M +#define S3C24XX_SZ_IIS SZ_1M +#define S3C24XX_SZ_ADC SZ_1M +#define S3C24XX_SZ_SPI SZ_1M +#define S3C24XX_SZ_SDI SZ_1M +#define S3C24XX_SZ_NAND SZ_1M +#define S3C24XX_SZ_GPIO SZ_1M + +/* USB host controller */ +#define S3C2410_PA_USBHOST (0x49000000) + +/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */ +#define S3C2416_PA_HSUDC (0x49800000) +#define S3C2416_SZ_HSUDC (SZ_4K) + +/* DMA controller */ +#define S3C2410_PA_DMA (0x4B000000) +#define S3C24XX_SZ_DMA SZ_1M + +/* Clock and Power management */ +#define S3C2410_PA_CLKPWR (0x4C000000) + +/* LCD controller */ +#define S3C2410_PA_LCD (0x4D000000) +#define S3C24XX_SZ_LCD SZ_1M + +/* NAND flash controller */ +#define S3C2410_PA_NAND (0x4E000000) + +/* IIC hardware controller */ +#define S3C2410_PA_IIC (0x54000000) + +/* IIS controller */ +#define S3C2410_PA_IIS (0x55000000) + +/* RTC */ +#define S3C2410_PA_RTC (0x57000000) +#define S3C24XX_SZ_RTC SZ_1M + +/* ADC */ +#define S3C2410_PA_ADC (0x58000000) + +/* SPI */ +#define S3C2410_PA_SPI (0x59000000) +#define S3C2443_PA_SPI0 (0x52000000) +#define S3C2443_PA_SPI1 S3C2410_PA_SPI +#define S3C2410_SPI1 (0x20) +#define S3C2412_SPI1 (0x100) + +/* SDI */ +#define S3C2410_PA_SDI (0x5A000000) + +/* CAMIF */ +#define S3C2440_PA_CAMIF (0x4F000000) +#define S3C2440_SZ_CAMIF SZ_1M + +/* AC97 */ + +#define S3C2440_PA_AC97 (0x5B000000) +#define S3C2440_SZ_AC97 SZ_1M + +/* S3C2443/S3C2416 High-speed SD/MMC */ +#define S3C2443_PA_HSMMC (0x4A800000) +#define S3C2416_PA_HSMMC0 (0x4AC00000) + +#define S3C2443_PA_FB (0x4C800000) + +/* S3C2412 memory and IO controls */ +#define S3C2412_PA_SSMC (0x4F000000) + +#define S3C2412_PA_EBI (0x48800000) + +/* physical addresses of all the chip-select areas */ + +#define S3C2410_CS0 (0x00000000) +#define S3C2410_CS1 (0x08000000) +#define S3C2410_CS2 (0x10000000) +#define S3C2410_CS3 (0x18000000) +#define S3C2410_CS4 (0x20000000) +#define S3C2410_CS5 (0x28000000) +#define S3C2410_CS6 (0x30000000) +#define S3C2410_CS7 (0x38000000) + +#define S3C2410_SDRAM_PA (S3C2410_CS6) + +/* Use a single interface for common resources between S3C24XX cpus */ + +#define S3C24XX_PA_IRQ S3C2410_PA_IRQ +#define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL +#define S3C24XX_PA_DMA S3C2410_PA_DMA +#define S3C24XX_PA_CLKPWR S3C2410_PA_CLKPWR +#define S3C24XX_PA_LCD S3C2410_PA_LCD +#define S3C24XX_PA_TIMER S3C2410_PA_TIMER +#define S3C24XX_PA_USBDEV S3C2410_PA_USBDEV +#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG +#define S3C24XX_PA_IIS S3C2410_PA_IIS +#define S3C24XX_PA_RTC S3C2410_PA_RTC +#define S3C24XX_PA_ADC S3C2410_PA_ADC +#define S3C24XX_PA_SPI S3C2410_PA_SPI +#define S3C24XX_PA_SPI1 (S3C2410_PA_SPI + S3C2410_SPI1) +#define S3C24XX_PA_SDI S3C2410_PA_SDI +#define S3C24XX_PA_NAND S3C2410_PA_NAND + +#define S3C_PA_FB S3C2443_PA_FB +#define S3C_PA_IIC S3C2410_PA_IIC +#define S3C_PA_USBHOST S3C2410_PA_USBHOST +#define S3C_PA_HSMMC0 S3C2416_PA_HSMMC0 +#define S3C_PA_HSMMC1 S3C2443_PA_HSMMC +#define S3C_PA_WDT S3C2410_PA_WATCHDOG +#define S3C_PA_NAND S3C24XX_PA_NAND + +#define S3C_PA_SPI0 S3C2443_PA_SPI0 +#define S3C_PA_SPI1 S3C2443_PA_SPI1 + +#define SAMSUNG_PA_TIMER S3C2410_PA_TIMER + +#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s3c/include/mach/map-s3c64xx.h b/arch/arm/mach-s3c/include/mach/map-s3c64xx.h new file mode 100644 index 000000000000..9372a535b7ba --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/map-s3c64xx.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C64XX - Memory map definitions + */ + +#ifndef __ASM_ARCH_MAP_H +#define __ASM_ARCH_MAP_H __FILE__ + +#include +#include + +/* + * Post-mux Chip Select Regions Xm0CSn_ + * These may be used by SROM, NAND or CF depending on settings + */ + +#define S3C64XX_PA_XM0CSN0 (0x10000000) +#define S3C64XX_PA_XM0CSN1 (0x18000000) +#define S3C64XX_PA_XM0CSN2 (0x20000000) +#define S3C64XX_PA_XM0CSN3 (0x28000000) +#define S3C64XX_PA_XM0CSN4 (0x30000000) +#define S3C64XX_PA_XM0CSN5 (0x38000000) + +/* HSMMC units */ +#define S3C64XX_PA_HSMMC(x) (0x7C200000 + ((x) * 0x100000)) +#define S3C64XX_PA_HSMMC0 S3C64XX_PA_HSMMC(0) +#define S3C64XX_PA_HSMMC1 S3C64XX_PA_HSMMC(1) +#define S3C64XX_PA_HSMMC2 S3C64XX_PA_HSMMC(2) + +#define S3C_PA_UART (0x7F005000) +#define S3C_PA_UART0 (S3C_PA_UART + 0x00) +#define S3C_PA_UART1 (S3C_PA_UART + 0x400) +#define S3C_PA_UART2 (S3C_PA_UART + 0x800) +#define S3C_PA_UART3 (S3C_PA_UART + 0xC00) +#define S3C_UART_OFFSET (0x400) + +/* See notes on UART VA mapping in debug-macro.S */ +#define S3C_VA_UARTx(x) (S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET)) + +#define S3C_VA_UART0 S3C_VA_UARTx(0) +#define S3C_VA_UART1 S3C_VA_UARTx(1) +#define S3C_VA_UART2 S3C_VA_UARTx(2) +#define S3C_VA_UART3 S3C_VA_UARTx(3) + +#define S3C64XX_PA_SROM (0x70000000) + +#define S3C64XX_PA_ONENAND0 (0x70100000) +#define S3C64XX_PA_ONENAND0_BUF (0x20000000) +#define S3C64XX_SZ_ONENAND0_BUF (SZ_64M) + +/* NAND and OneNAND1 controllers occupy the same register region + (depending on SoC POP version) */ +#define S3C64XX_PA_ONENAND1 (0x70200000) +#define S3C64XX_PA_ONENAND1_BUF (0x28000000) +#define S3C64XX_SZ_ONENAND1_BUF (SZ_64M) + +#define S3C64XX_PA_NAND (0x70200000) +#define S3C64XX_PA_FB (0x77100000) +#define S3C64XX_PA_USB_HSOTG (0x7C000000) +#define S3C64XX_PA_WATCHDOG (0x7E004000) +#define S3C64XX_PA_RTC (0x7E005000) +#define S3C64XX_PA_KEYPAD (0x7E00A000) +#define S3C64XX_PA_ADC (0x7E00B000) +#define S3C64XX_PA_SYSCON (0x7E00F000) +#define S3C64XX_PA_AC97 (0x7F001000) +#define S3C64XX_PA_IIS0 (0x7F002000) +#define S3C64XX_PA_IIS1 (0x7F003000) +#define S3C64XX_PA_TIMER (0x7F006000) +#define S3C64XX_PA_IIC0 (0x7F004000) +#define S3C64XX_PA_SPI0 (0x7F00B000) +#define S3C64XX_PA_SPI1 (0x7F00C000) +#define S3C64XX_PA_PCM0 (0x7F009000) +#define S3C64XX_PA_PCM1 (0x7F00A000) +#define S3C64XX_PA_IISV4 (0x7F00D000) +#define S3C64XX_PA_IIC1 (0x7F00F000) + +#define S3C64XX_PA_GPIO (0x7F008000) +#define S3C64XX_SZ_GPIO SZ_4K + +#define S3C64XX_PA_SDRAM (0x50000000) + +#define S3C64XX_PA_CFCON (0x70300000) + +#define S3C64XX_PA_VIC0 (0x71200000) +#define S3C64XX_PA_VIC1 (0x71300000) + +#define S3C64XX_PA_MODEM (0x74108000) + +#define S3C64XX_PA_USBHOST (0x74300000) + +#define S3C64XX_PA_USB_HSPHY (0x7C100000) + +/* compatibility defines. */ +#define S3C_PA_TIMER S3C64XX_PA_TIMER +#define S3C_PA_HSMMC0 S3C64XX_PA_HSMMC0 +#define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1 +#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2 +#define S3C_PA_IIC S3C64XX_PA_IIC0 +#define S3C_PA_IIC1 S3C64XX_PA_IIC1 +#define S3C_PA_NAND S3C64XX_PA_NAND +#define S3C_PA_ONENAND S3C64XX_PA_ONENAND0 +#define S3C_PA_ONENAND_BUF S3C64XX_PA_ONENAND0_BUF +#define S3C_SZ_ONENAND_BUF S3C64XX_SZ_ONENAND0_BUF +#define S3C_PA_FB S3C64XX_PA_FB +#define S3C_PA_USBHOST S3C64XX_PA_USBHOST +#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG +#define S3C_PA_RTC S3C64XX_PA_RTC +#define S3C_PA_WDT S3C64XX_PA_WATCHDOG +#define S3C_PA_SPI0 S3C64XX_PA_SPI0 +#define S3C_PA_SPI1 S3C64XX_PA_SPI1 + +#define SAMSUNG_PA_ADC S3C64XX_PA_ADC +#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON +#define SAMSUNG_PA_KEYPAD S3C64XX_PA_KEYPAD +#define SAMSUNG_PA_TIMER S3C64XX_PA_TIMER + +#endif /* __ASM_ARCH_6400_MAP_H */ diff --git a/arch/arm/mach-s3c/include/mach/map.h b/arch/arm/mach-s3c/include/mach/map.h new file mode 100644 index 000000000000..7cfb517d4886 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/map.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "map-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "map-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/pm-core-s3c24xx.h b/arch/arm/mach-s3c/include/mach/pm-core-s3c24xx.h new file mode 100644 index 000000000000..bcb7978a4e85 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/pm-core-s3c24xx.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c + */ + +#include +#include + +#include "regs-clock.h" +#include "regs-irq-s3c24xx.h" +#include + +static inline void s3c_pm_debug_init_uart(void) +{ +#ifdef CONFIG_SAMSUNG_PM_DEBUG + unsigned long tmp = __raw_readl(S3C2410_CLKCON); + + /* re-start uart clocks */ + tmp |= S3C2410_CLKCON_UART0; + tmp |= S3C2410_CLKCON_UART1; + tmp |= S3C2410_CLKCON_UART2; + + __raw_writel(tmp, S3C2410_CLKCON); + udelay(10); +#endif +} + +static inline void s3c_pm_arch_prepare_irqs(void) +{ + __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); + __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); + + /* ack any outstanding external interrupts before we go to sleep */ + + __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); + __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); + __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); + +} + +static inline void s3c_pm_arch_stop_clocks(void) +{ + __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ +} + +/* s3c2410_pm_show_resume_irqs + * + * print any IRQs asserted at resume time (ie, we woke from) +*/ +static inline void s3c_pm_show_resume_irqs(int start, unsigned long which, + unsigned long mask) +{ + int i; + + which &= ~mask; + + for (i = 0; i <= 31; i++) { + if (which & (1L< + * http://armlinux.simtec.co.uk/ + * + * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c + */ + +#ifndef __MACH_S3C64XX_PM_CORE_H +#define __MACH_S3C64XX_PM_CORE_H __FILE__ + +#include +#include + +#include +#include +#include + +static inline void s3c_pm_debug_init_uart(void) +{ +#ifdef CONFIG_SAMSUNG_PM_DEBUG + u32 tmp = __raw_readl(S3C_PCLK_GATE); + + /* As a note, since the S3C64XX UARTs generally have multiple + * clock sources, we simply enable PCLK at the moment and hope + * that the resume settings for the UART are suitable for the + * use with PCLK. + */ + + tmp |= S3C_CLKCON_PCLK_UART0; + tmp |= S3C_CLKCON_PCLK_UART1; + tmp |= S3C_CLKCON_PCLK_UART2; + tmp |= S3C_CLKCON_PCLK_UART3; + + __raw_writel(tmp, S3C_PCLK_GATE); + udelay(10); +#endif +} + +static inline void s3c_pm_arch_prepare_irqs(void) +{ + /* VIC should have already been taken care of */ + + /* clear any pending EINT0 interrupts */ + __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND); +} + +static inline void s3c_pm_arch_stop_clocks(void) +{ +} + +static inline void s3c_pm_arch_show_resume_irqs(void) +{ +} + +/* make these defines, we currently do not have any need to change + * the IRQ wake controls depending on the CPU we are running on */ +#ifdef CONFIG_PM_SLEEP +#define s3c_irqwake_eintallow ((1 << 28) - 1) +#define s3c_irqwake_intallow (~0) +#else +#define s3c_irqwake_eintallow 0 +#define s3c_irqwake_intallow 0 +#endif + +static inline void s3c_pm_restored_gpios(void) +{ + /* ensure sleep mode has been cleared from the system */ + + __raw_writel(0, S3C64XX_SLPEN); +} + +static inline void samsung_pm_saved_gpios(void) +{ + /* turn on the sleep mode and keep it there, as it seems that during + * suspend the xCON registers get re-set and thus you can end up with + * problems between going to sleep and resuming. + */ + + __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN); +} +#endif /* __MACH_S3C64XX_PM_CORE_H */ diff --git a/arch/arm/mach-s3c/include/mach/pm-core.h b/arch/arm/mach-s3c/include/mach/pm-core.h new file mode 100644 index 000000000000..b0e1d277f599 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/pm-core.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "pm-core-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "pm-core-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/regs-clock-s3c24xx.h b/arch/arm/mach-s3c/include/mach/regs-clock-s3c24xx.h new file mode 100644 index 000000000000..da4e7b3aeba6 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-clock-s3c24xx.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003-2006 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * + * S3C2410 clock register definitions + */ + +#ifndef __ASM_ARM_REGS_CLOCK +#define __ASM_ARM_REGS_CLOCK + +#include + +#define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) + +#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s))) + +#define S3C2410_LOCKTIME S3C2410_CLKREG(0x00) +#define S3C2410_MPLLCON S3C2410_CLKREG(0x04) +#define S3C2410_UPLLCON S3C2410_CLKREG(0x08) +#define S3C2410_CLKCON S3C2410_CLKREG(0x0C) +#define S3C2410_CLKSLOW S3C2410_CLKREG(0x10) +#define S3C2410_CLKDIVN S3C2410_CLKREG(0x14) + +#define S3C2410_CLKCON_IDLE (1<<2) +#define S3C2410_CLKCON_POWER (1<<3) +#define S3C2410_CLKCON_NAND (1<<4) +#define S3C2410_CLKCON_LCDC (1<<5) +#define S3C2410_CLKCON_USBH (1<<6) +#define S3C2410_CLKCON_USBD (1<<7) +#define S3C2410_CLKCON_PWMT (1<<8) +#define S3C2410_CLKCON_SDI (1<<9) +#define S3C2410_CLKCON_UART0 (1<<10) +#define S3C2410_CLKCON_UART1 (1<<11) +#define S3C2410_CLKCON_UART2 (1<<12) +#define S3C2410_CLKCON_GPIO (1<<13) +#define S3C2410_CLKCON_RTC (1<<14) +#define S3C2410_CLKCON_ADC (1<<15) +#define S3C2410_CLKCON_IIC (1<<16) +#define S3C2410_CLKCON_IIS (1<<17) +#define S3C2410_CLKCON_SPI (1<<18) + +#define S3C2410_CLKDIVN_PDIVN (1<<0) +#define S3C2410_CLKDIVN_HDIVN (1<<1) + +#define S3C2410_CLKSLOW_UCLK_OFF (1<<7) +#define S3C2410_CLKSLOW_MPLL_OFF (1<<5) +#define S3C2410_CLKSLOW_SLOW (1<<4) +#define S3C2410_CLKSLOW_SLOWVAL(x) (x) +#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7) + +#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) + +/* extra registers */ +#define S3C2440_CAMDIVN S3C2410_CLKREG(0x18) + +#define S3C2440_CLKCON_CAMERA (1<<19) +#define S3C2440_CLKCON_AC97 (1<<20) + +#define S3C2440_CLKDIVN_PDIVN (1<<0) +#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1) +#define S3C2440_CLKDIVN_HDIVN_1 (0<<1) +#define S3C2440_CLKDIVN_HDIVN_2 (1<<1) +#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1) +#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1) +#define S3C2440_CLKDIVN_UCLK (1<<3) + +#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0) +#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4) +#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8) +#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9) +#define S3C2440_CAMDIVN_DVSEN (1<<12) + +#define S3C2442_CAMDIVN_CAMCLK_DIV3 (1<<5) + +#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */ + +#if defined(CONFIG_CPU_S3C2412) + +#define S3C2412_OSCSET S3C2410_CLKREG(0x18) +#define S3C2412_CLKSRC S3C2410_CLKREG(0x1C) + +#define S3C2412_PLLCON_OFF (1<<20) + +#define S3C2412_CLKDIVN_PDIVN (1<<2) +#define S3C2412_CLKDIVN_HDIVN_MASK (3<<0) +#define S3C2412_CLKDIVN_ARMDIVN (1<<3) +#define S3C2412_CLKDIVN_DVSEN (1<<4) +#define S3C2412_CLKDIVN_HALFHCLK (1<<5) +#define S3C2412_CLKDIVN_USB48DIV (1<<6) +#define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8) +#define S3C2412_CLKDIVN_UARTDIV_SHIFT (8) +#define S3C2412_CLKDIVN_I2SDIV_MASK (15<<12) +#define S3C2412_CLKDIVN_I2SDIV_SHIFT (12) +#define S3C2412_CLKDIVN_CAMDIV_MASK (15<<16) +#define S3C2412_CLKDIVN_CAMDIV_SHIFT (16) + +#define S3C2412_CLKCON_WDT (1<<28) +#define S3C2412_CLKCON_SPI (1<<27) +#define S3C2412_CLKCON_IIS (1<<26) +#define S3C2412_CLKCON_IIC (1<<25) +#define S3C2412_CLKCON_ADC (1<<24) +#define S3C2412_CLKCON_RTC (1<<23) +#define S3C2412_CLKCON_GPIO (1<<22) +#define S3C2412_CLKCON_UART2 (1<<21) +#define S3C2412_CLKCON_UART1 (1<<20) +#define S3C2412_CLKCON_UART0 (1<<19) +#define S3C2412_CLKCON_SDI (1<<18) +#define S3C2412_CLKCON_PWMT (1<<17) +#define S3C2412_CLKCON_USBD (1<<16) +#define S3C2412_CLKCON_CAMCLK (1<<15) +#define S3C2412_CLKCON_UARTCLK (1<<14) +/* missing 13 */ +#define S3C2412_CLKCON_USB_HOST48 (1<<12) +#define S3C2412_CLKCON_USB_DEV48 (1<<11) +#define S3C2412_CLKCON_HCLKdiv2 (1<<10) +#define S3C2412_CLKCON_HCLKx2 (1<<9) +#define S3C2412_CLKCON_SDRAM (1<<8) +/* missing 7 */ +#define S3C2412_CLKCON_USBH S3C2410_CLKCON_USBH +#define S3C2412_CLKCON_LCDC S3C2410_CLKCON_LCDC +#define S3C2412_CLKCON_NAND S3C2410_CLKCON_NAND +#define S3C2412_CLKCON_DMA3 (1<<3) +#define S3C2412_CLKCON_DMA2 (1<<2) +#define S3C2412_CLKCON_DMA1 (1<<1) +#define S3C2412_CLKCON_DMA0 (1<<0) + +/* clock sourec controls */ + +#define S3C2412_CLKSRC_EXTCLKDIV_MASK (7 << 0) +#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT (0) +#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV (1<<3) +#define S3C2412_CLKSRC_MSYSCLK_MPLL (1<<4) +#define S3C2412_CLKSRC_USYSCLK_UPLL (1<<5) +#define S3C2412_CLKSRC_UARTCLK_MPLL (1<<8) +#define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9) +#define S3C2412_CLKSRC_USBCLK_HCLK (1<<10) +#define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11) +#define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12) +#define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14) + +#endif /* CONFIG_CPU_S3C2412 */ + +#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28) + +#endif /* __ASM_ARM_REGS_CLOCK */ diff --git a/arch/arm/mach-s3c/include/mach/regs-clock-s3c64xx.h b/arch/arm/mach-s3c/include/mach/regs-clock-s3c64xx.h new file mode 100644 index 000000000000..35a68767b318 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-clock-s3c64xx.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C64XX clock register definitions + */ + +#ifndef __PLAT_REGS_CLOCK_H +#define __PLAT_REGS_CLOCK_H __FILE__ + +/* + * FIXME: Remove remaining definitions + */ + +#define S3C_CLKREG(x) (S3C_VA_SYS + (x)) + +#define S3C_PCLK_GATE S3C_CLKREG(0x34) +#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C) +#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120) + +/* PCLK GATE Registers */ +#define S3C_CLKCON_PCLK_UART3 (1<<4) +#define S3C_CLKCON_PCLK_UART2 (1<<3) +#define S3C_CLKCON_PCLK_UART1 (1<<2) +#define S3C_CLKCON_PCLK_UART0 (1<<1) + +/* MEM_SYS_CFG */ +#define MEM_SYS_CFG_INDEP_CF 0x4000 +#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30 + +#endif /* _PLAT_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s3c/include/mach/regs-clock.h b/arch/arm/mach-s3c/include/mach/regs-clock.h new file mode 100644 index 000000000000..7df31f203d28 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-clock.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "regs-clock-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "regs-clock-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/regs-gpio-s3c24xx.h b/arch/arm/mach-s3c/include/mach/regs-gpio-s3c24xx.h new file mode 100644 index 000000000000..51827d5577b6 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-gpio-s3c24xx.h @@ -0,0 +1,608 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003-2004 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + * + * S3C2410 GPIO register definitions + */ + + +#ifndef __ASM_ARCH_REGS_GPIO_H +#define __ASM_ARCH_REGS_GPIO_H + +#include + +#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80) + +/* general configuration options */ + +#define S3C2410_GPIO_LEAVE (0xFFFFFFFF) +#define S3C2410_GPIO_INPUT (0xFFFFFFF0) /* not available on A */ +#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1) +#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */ +#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* bank A => addr/cs/nand */ +#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */ + +/* register address for the GPIO registers. + * S3C24XX_GPIOREG2 is for the second set of registers in the + * GPIO which move between s3c2410 and s3c2412 type systems */ + +#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO) +#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2) + + +/* configure GPIO ports A..G */ + +/* port A - S3C2410: 22bits, zero in bit X makes pin X output + * 1 makes port special function, this is default +*/ +#define S3C2410_GPACON S3C2410_GPIOREG(0x00) +#define S3C2410_GPADAT S3C2410_GPIOREG(0x04) + +#define S3C2410_GPA0_ADDR0 (1<<0) +#define S3C2410_GPA1_ADDR16 (1<<1) +#define S3C2410_GPA2_ADDR17 (1<<2) +#define S3C2410_GPA3_ADDR18 (1<<3) +#define S3C2410_GPA4_ADDR19 (1<<4) +#define S3C2410_GPA5_ADDR20 (1<<5) +#define S3C2410_GPA6_ADDR21 (1<<6) +#define S3C2410_GPA7_ADDR22 (1<<7) +#define S3C2410_GPA8_ADDR23 (1<<8) +#define S3C2410_GPA9_ADDR24 (1<<9) +#define S3C2410_GPA10_ADDR25 (1<<10) +#define S3C2410_GPA11_ADDR26 (1<<11) +#define S3C2410_GPA12_nGCS1 (1<<12) +#define S3C2410_GPA13_nGCS2 (1<<13) +#define S3C2410_GPA14_nGCS3 (1<<14) +#define S3C2410_GPA15_nGCS4 (1<<15) +#define S3C2410_GPA16_nGCS5 (1<<16) +#define S3C2410_GPA17_CLE (1<<17) +#define S3C2410_GPA18_ALE (1<<18) +#define S3C2410_GPA19_nFWE (1<<19) +#define S3C2410_GPA20_nFRE (1<<20) +#define S3C2410_GPA21_nRSTOUT (1<<21) +#define S3C2410_GPA22_nFCE (1<<22) + +/* 0x08 and 0x0c are reserved on S3C2410 */ + +/* S3C2410: + * GPB is 10 IO pins, each configured by 2 bits each in GPBCON. + * 00 = input, 01 = output, 10=special function, 11=reserved + + * bit 0,1 = pin 0, 2,3= pin 1... + * + * CPBUP = pull up resistor control, 1=disabled, 0=enabled +*/ + +#define S3C2410_GPBCON S3C2410_GPIOREG(0x10) +#define S3C2410_GPBDAT S3C2410_GPIOREG(0x14) +#define S3C2410_GPBUP S3C2410_GPIOREG(0x18) + +/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */ + +#define S3C2410_GPB0_TOUT0 (0x02 << 0) + +#define S3C2410_GPB1_TOUT1 (0x02 << 2) + +#define S3C2410_GPB2_TOUT2 (0x02 << 4) + +#define S3C2410_GPB3_TOUT3 (0x02 << 6) + +#define S3C2410_GPB4_TCLK0 (0x02 << 8) +#define S3C2410_GPB4_MASK (0x03 << 8) + +#define S3C2410_GPB5_nXBACK (0x02 << 10) +#define S3C2443_GPB5_XBACK (0x03 << 10) + +#define S3C2410_GPB6_nXBREQ (0x02 << 12) +#define S3C2443_GPB6_XBREQ (0x03 << 12) + +#define S3C2410_GPB7_nXDACK1 (0x02 << 14) +#define S3C2443_GPB7_XDACK1 (0x03 << 14) + +#define S3C2410_GPB8_nXDREQ1 (0x02 << 16) + +#define S3C2410_GPB9_nXDACK0 (0x02 << 18) +#define S3C2443_GPB9_XDACK0 (0x03 << 18) + +#define S3C2410_GPB10_nXDRE0 (0x02 << 20) +#define S3C2443_GPB10_XDREQ0 (0x03 << 20) + +#define S3C2410_GPB_PUPDIS(x) (1<<(x)) + +/* Port C consits of 16 GPIO/Special function + * + * almost identical setup to port b, but the special functions are mostly + * to do with the video system's sync/etc. +*/ + +#define S3C2410_GPCCON S3C2410_GPIOREG(0x20) +#define S3C2410_GPCDAT S3C2410_GPIOREG(0x24) +#define S3C2410_GPCUP S3C2410_GPIOREG(0x28) +#define S3C2410_GPC0_LEND (0x02 << 0) +#define S3C2410_GPC1_VCLK (0x02 << 2) +#define S3C2410_GPC2_VLINE (0x02 << 4) +#define S3C2410_GPC3_VFRAME (0x02 << 6) +#define S3C2410_GPC4_VM (0x02 << 8) +#define S3C2410_GPC5_LCDVF0 (0x02 << 10) +#define S3C2410_GPC6_LCDVF1 (0x02 << 12) +#define S3C2410_GPC7_LCDVF2 (0x02 << 14) +#define S3C2410_GPC8_VD0 (0x02 << 16) +#define S3C2410_GPC9_VD1 (0x02 << 18) +#define S3C2410_GPC10_VD2 (0x02 << 20) +#define S3C2410_GPC11_VD3 (0x02 << 22) +#define S3C2410_GPC12_VD4 (0x02 << 24) +#define S3C2410_GPC13_VD5 (0x02 << 26) +#define S3C2410_GPC14_VD6 (0x02 << 28) +#define S3C2410_GPC15_VD7 (0x02 << 30) +#define S3C2410_GPC_PUPDIS(x) (1<<(x)) + +/* + * S3C2410: Port D consists of 16 GPIO/Special function + * + * almost identical setup to port b, but the special functions are mostly + * to do with the video system's data. + * + * almost identical setup to port c +*/ + +#define S3C2410_GPDCON S3C2410_GPIOREG(0x30) +#define S3C2410_GPDDAT S3C2410_GPIOREG(0x34) +#define S3C2410_GPDUP S3C2410_GPIOREG(0x38) + +#define S3C2410_GPD0_VD8 (0x02 << 0) +#define S3C2442_GPD0_nSPICS1 (0x03 << 0) + +#define S3C2410_GPD1_VD9 (0x02 << 2) +#define S3C2442_GPD1_SPICLK1 (0x03 << 2) + +#define S3C2410_GPD2_VD10 (0x02 << 4) + +#define S3C2410_GPD3_VD11 (0x02 << 6) + +#define S3C2410_GPD4_VD12 (0x02 << 8) + +#define S3C2410_GPD5_VD13 (0x02 << 10) + +#define S3C2410_GPD6_VD14 (0x02 << 12) + +#define S3C2410_GPD7_VD15 (0x02 << 14) + +#define S3C2410_GPD8_VD16 (0x02 << 16) +#define S3C2440_GPD8_SPIMISO1 (0x03 << 16) + +#define S3C2410_GPD9_VD17 (0x02 << 18) +#define S3C2440_GPD9_SPIMOSI1 (0x03 << 18) + +#define S3C2410_GPD10_VD18 (0x02 << 20) +#define S3C2440_GPD10_SPICLK1 (0x03 << 20) + +#define S3C2410_GPD11_VD19 (0x02 << 22) + +#define S3C2410_GPD12_VD20 (0x02 << 24) + +#define S3C2410_GPD13_VD21 (0x02 << 26) + +#define S3C2410_GPD14_VD22 (0x02 << 28) +#define S3C2410_GPD14_nSS1 (0x03 << 28) + +#define S3C2410_GPD15_VD23 (0x02 << 30) +#define S3C2410_GPD15_nSS0 (0x03 << 30) + +#define S3C2410_GPD_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port E consists of 16 GPIO/Special function + * + * again, the same as port B, but dealing with I2S, SDI, and + * more miscellaneous functions + * + * GPIO / interrupt inputs +*/ + +#define S3C2410_GPECON S3C2410_GPIOREG(0x40) +#define S3C2410_GPEDAT S3C2410_GPIOREG(0x44) +#define S3C2410_GPEUP S3C2410_GPIOREG(0x48) + +#define S3C2410_GPE0_I2SLRCK (0x02 << 0) +#define S3C2443_GPE0_AC_nRESET (0x03 << 0) +#define S3C2410_GPE0_MASK (0x03 << 0) + +#define S3C2410_GPE1_I2SSCLK (0x02 << 2) +#define S3C2443_GPE1_AC_SYNC (0x03 << 2) +#define S3C2410_GPE1_MASK (0x03 << 2) + +#define S3C2410_GPE2_CDCLK (0x02 << 4) +#define S3C2443_GPE2_AC_BITCLK (0x03 << 4) + +#define S3C2410_GPE3_I2SSDI (0x02 << 6) +#define S3C2443_GPE3_AC_SDI (0x03 << 6) +#define S3C2410_GPE3_nSS0 (0x03 << 6) +#define S3C2410_GPE3_MASK (0x03 << 6) + +#define S3C2410_GPE4_I2SSDO (0x02 << 8) +#define S3C2443_GPE4_AC_SDO (0x03 << 8) +#define S3C2410_GPE4_I2SSDI (0x03 << 8) +#define S3C2410_GPE4_MASK (0x03 << 8) + +#define S3C2410_GPE5_SDCLK (0x02 << 10) +#define S3C2443_GPE5_SD1_CLK (0x02 << 10) +#define S3C2443_GPE5_AC_BITCLK (0x03 << 10) + +#define S3C2410_GPE6_SDCMD (0x02 << 12) +#define S3C2443_GPE6_SD1_CMD (0x02 << 12) +#define S3C2443_GPE6_AC_SDI (0x03 << 12) + +#define S3C2410_GPE7_SDDAT0 (0x02 << 14) +#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14) +#define S3C2443_GPE7_AC_SDO (0x03 << 14) + +#define S3C2410_GPE8_SDDAT1 (0x02 << 16) +#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16) +#define S3C2443_GPE8_AC_SYNC (0x03 << 16) + +#define S3C2410_GPE9_SDDAT2 (0x02 << 18) +#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18) +#define S3C2443_GPE9_AC_nRESET (0x03 << 18) + +#define S3C2410_GPE10_SDDAT3 (0x02 << 20) +#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20) + +#define S3C2410_GPE11_SPIMISO0 (0x02 << 22) + +#define S3C2410_GPE12_SPIMOSI0 (0x02 << 24) + +#define S3C2410_GPE13_SPICLK0 (0x02 << 26) + +#define S3C2410_GPE14_IICSCL (0x02 << 28) +#define S3C2410_GPE14_MASK (0x03 << 28) + +#define S3C2410_GPE15_IICSDA (0x02 << 30) +#define S3C2410_GPE15_MASK (0x03 << 30) + +#define S3C2440_GPE0_ACSYNC (0x03 << 0) +#define S3C2440_GPE1_ACBITCLK (0x03 << 2) +#define S3C2440_GPE2_ACRESET (0x03 << 4) +#define S3C2440_GPE3_ACIN (0x03 << 6) +#define S3C2440_GPE4_ACOUT (0x03 << 8) + +#define S3C2410_GPE_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port F consists of 8 GPIO/Special function + * + * GPIO / interrupt inputs + * + * GPFCON has 2 bits for each of the input pins on port F + * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined + * + * pull up works like all other ports. + * + * GPIO/serial/misc pins +*/ + +#define S3C2410_GPFCON S3C2410_GPIOREG(0x50) +#define S3C2410_GPFDAT S3C2410_GPIOREG(0x54) +#define S3C2410_GPFUP S3C2410_GPIOREG(0x58) + +#define S3C2410_GPF0_EINT0 (0x02 << 0) +#define S3C2410_GPF1_EINT1 (0x02 << 2) +#define S3C2410_GPF2_EINT2 (0x02 << 4) +#define S3C2410_GPF3_EINT3 (0x02 << 6) +#define S3C2410_GPF4_EINT4 (0x02 << 8) +#define S3C2410_GPF5_EINT5 (0x02 << 10) +#define S3C2410_GPF6_EINT6 (0x02 << 12) +#define S3C2410_GPF7_EINT7 (0x02 << 14) +#define S3C2410_GPF_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port G consists of 8 GPIO/IRQ/Special function + * + * GPGCON has 2 bits for each of the input pins on port G + * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func + * + * pull up works like all other ports. +*/ + +#define S3C2410_GPGCON S3C2410_GPIOREG(0x60) +#define S3C2410_GPGDAT S3C2410_GPIOREG(0x64) +#define S3C2410_GPGUP S3C2410_GPIOREG(0x68) + +#define S3C2410_GPG0_EINT8 (0x02 << 0) + +#define S3C2410_GPG1_EINT9 (0x02 << 2) + +#define S3C2410_GPG2_EINT10 (0x02 << 4) +#define S3C2410_GPG2_nSS0 (0x03 << 4) + +#define S3C2410_GPG3_EINT11 (0x02 << 6) +#define S3C2410_GPG3_nSS1 (0x03 << 6) + +#define S3C2410_GPG4_EINT12 (0x02 << 8) +#define S3C2410_GPG4_LCDPWREN (0x03 << 8) +#define S3C2443_GPG4_LCDPWRDN (0x03 << 8) + +#define S3C2410_GPG5_EINT13 (0x02 << 10) +#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) /* not s3c2443 */ + +#define S3C2410_GPG6_EINT14 (0x02 << 12) +#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12) + +#define S3C2410_GPG7_EINT15 (0x02 << 14) +#define S3C2410_GPG7_SPICLK1 (0x03 << 14) + +#define S3C2410_GPG8_EINT16 (0x02 << 16) + +#define S3C2410_GPG9_EINT17 (0x02 << 18) + +#define S3C2410_GPG10_EINT18 (0x02 << 20) + +#define S3C2410_GPG11_EINT19 (0x02 << 22) +#define S3C2410_GPG11_TCLK1 (0x03 << 22) +#define S3C2443_GPG11_CF_nIREQ (0x03 << 22) + +#define S3C2410_GPG12_EINT20 (0x02 << 24) +#define S3C2410_GPG12_XMON (0x03 << 24) +#define S3C2442_GPG12_nSPICS0 (0x03 << 24) +#define S3C2443_GPG12_nINPACK (0x03 << 24) + +#define S3C2410_GPG13_EINT21 (0x02 << 26) +#define S3C2410_GPG13_nXPON (0x03 << 26) +#define S3C2443_GPG13_CF_nREG (0x03 << 26) + +#define S3C2410_GPG14_EINT22 (0x02 << 28) +#define S3C2410_GPG14_YMON (0x03 << 28) +#define S3C2443_GPG14_CF_RESET (0x03 << 28) + +#define S3C2410_GPG15_EINT23 (0x02 << 30) +#define S3C2410_GPG15_nYPON (0x03 << 30) +#define S3C2443_GPG15_CF_PWR (0x03 << 30) + +#define S3C2410_GPG_PUPDIS(x) (1<<(x)) + +/* Port H consists of11 GPIO/serial/Misc pins + * + * GPHCON has 2 bits for each of the input pins on port H + * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func + * + * pull up works like all other ports. +*/ + +#define S3C2410_GPHCON S3C2410_GPIOREG(0x70) +#define S3C2410_GPHDAT S3C2410_GPIOREG(0x74) +#define S3C2410_GPHUP S3C2410_GPIOREG(0x78) + +#define S3C2410_GPH0_nCTS0 (0x02 << 0) +#define S3C2416_GPH0_TXD0 (0x02 << 0) + +#define S3C2410_GPH1_nRTS0 (0x02 << 2) +#define S3C2416_GPH1_RXD0 (0x02 << 2) + +#define S3C2410_GPH2_TXD0 (0x02 << 4) +#define S3C2416_GPH2_TXD1 (0x02 << 4) + +#define S3C2410_GPH3_RXD0 (0x02 << 6) +#define S3C2416_GPH3_RXD1 (0x02 << 6) + +#define S3C2410_GPH4_TXD1 (0x02 << 8) +#define S3C2416_GPH4_TXD2 (0x02 << 8) + +#define S3C2410_GPH5_RXD1 (0x02 << 10) +#define S3C2416_GPH5_RXD2 (0x02 << 10) + +#define S3C2410_GPH6_TXD2 (0x02 << 12) +#define S3C2416_GPH6_TXD3 (0x02 << 12) +#define S3C2410_GPH6_nRTS1 (0x03 << 12) +#define S3C2416_GPH6_nRTS2 (0x03 << 12) + +#define S3C2410_GPH7_RXD2 (0x02 << 14) +#define S3C2416_GPH7_RXD3 (0x02 << 14) +#define S3C2410_GPH7_nCTS1 (0x03 << 14) +#define S3C2416_GPH7_nCTS2 (0x03 << 14) + +#define S3C2410_GPH8_UCLK (0x02 << 16) +#define S3C2416_GPH8_nCTS0 (0x02 << 16) + +#define S3C2410_GPH9_CLKOUT0 (0x02 << 18) +#define S3C2442_GPH9_nSPICS0 (0x03 << 18) +#define S3C2416_GPH9_nRTS0 (0x02 << 18) + +#define S3C2410_GPH10_CLKOUT1 (0x02 << 20) +#define S3C2416_GPH10_nCTS1 (0x02 << 20) + +#define S3C2416_GPH11_nRTS1 (0x02 << 22) + +#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24) + +#define S3C2416_GPH13_CLKOUT0 (0x02 << 26) + +#define S3C2416_GPH14_CLKOUT1 (0x02 << 28) + +/* The S3C2412 and S3C2413 move the GPJ register set to after + * GPH, which means all registers after 0x80 are now offset by 0x10 + * for the 2412/2413 from the 2410/2440/2442 +*/ + +/* + * Port J consists of 13 GPIO/Camera pins. GPJCON has 2 bits + * for each of the pins on port J. + * 00 - input, 01 output, 10 - camera + * + * Pull up works like all other ports. + */ + +#define S3C2413_GPJCON S3C2410_GPIOREG(0x80) +#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84) +#define S3C2413_GPJUP S3C2410_GPIOREG(0x88) +#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C) + +/* S3C2443 and above */ +#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0) +#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4) +#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8) + +#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0) +#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4) +#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8) + +#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0) +#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4) +#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8) + +#define S3C2443_GPMCON S3C2410_GPIOREG(0x100) +#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104) +#define S3C2443_GPMUP S3C2410_GPIOREG(0x108) + +/* miscellaneous control */ +#define S3C2410_MISCCR S3C2410_GPIOREG(0x80) + +/* see clock.h for dclk definitions */ + +/* pullup control on databus */ +#define S3C2410_MISCCR_SPUCR_HEN (0<<0) +#define S3C2410_MISCCR_SPUCR_HDIS (1<<0) +#define S3C2410_MISCCR_SPUCR_LEN (0<<1) +#define S3C2410_MISCCR_SPUCR_LDIS (1<<1) + +#define S3C2410_MISCCR_USBDEV (0<<3) +#define S3C2410_MISCCR_USBHOST (1<<3) + +#define S3C2410_MISCCR_CLK0_MPLL (0<<4) +#define S3C2410_MISCCR_CLK0_UPLL (1<<4) +#define S3C2410_MISCCR_CLK0_FCLK (2<<4) +#define S3C2410_MISCCR_CLK0_HCLK (3<<4) +#define S3C2410_MISCCR_CLK0_PCLK (4<<4) +#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4) +#define S3C2410_MISCCR_CLK0_MASK (7<<4) + +#define S3C2412_MISCCR_CLK0_RTC (2<<4) + +#define S3C2410_MISCCR_CLK1_MPLL (0<<8) +#define S3C2410_MISCCR_CLK1_UPLL (1<<8) +#define S3C2410_MISCCR_CLK1_FCLK (2<<8) +#define S3C2410_MISCCR_CLK1_HCLK (3<<8) +#define S3C2410_MISCCR_CLK1_PCLK (4<<8) +#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8) +#define S3C2410_MISCCR_CLK1_MASK (7<<8) + +#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8) + +#define S3C2410_MISCCR_USBSUSPND0 (1<<12) +#define S3C2416_MISCCR_SEL_SUSPND (1<<12) +#define S3C2410_MISCCR_USBSUSPND1 (1<<13) + +#define S3C2410_MISCCR_nRSTCON (1<<16) + +#define S3C2410_MISCCR_nEN_SCLK0 (1<<17) +#define S3C2410_MISCCR_nEN_SCLK1 (1<<18) +#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */ +#define S3C2410_MISCCR_SDSLEEP (7<<17) + +#define S3C2416_MISCCR_FLT_I2C (1<<24) +#define S3C2416_MISCCR_HSSPI_EN2 (1<<31) + +/* external interrupt control... */ +/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7 + * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15 + * S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23 + * + * note S3C2410_EXTINT2 has filtering options for EINT16..EINT23 + * + * Samsung datasheet p9-25 +*/ +#define S3C2410_EXTINT0 S3C2410_GPIOREG(0x88) +#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C) +#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90) + +#define S3C24XX_EXTINT0 S3C24XX_GPIOREG2(0x88) +#define S3C24XX_EXTINT1 S3C24XX_GPIOREG2(0x8C) +#define S3C24XX_EXTINT2 S3C24XX_GPIOREG2(0x90) + +/* interrupt filtering control for EINT16..EINT23 */ +#define S3C2410_EINFLT0 S3C2410_GPIOREG(0x94) +#define S3C2410_EINFLT1 S3C2410_GPIOREG(0x98) +#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C) +#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0) + +#define S3C24XX_EINFLT0 S3C24XX_GPIOREG2(0x94) +#define S3C24XX_EINFLT1 S3C24XX_GPIOREG2(0x98) +#define S3C24XX_EINFLT2 S3C24XX_GPIOREG2(0x9C) +#define S3C24XX_EINFLT3 S3C24XX_GPIOREG2(0xA0) + +/* values for interrupt filtering */ +#define S3C2410_EINTFLT_PCLK (0x00) +#define S3C2410_EINTFLT_EXTCLK (1<<7) +#define S3C2410_EINTFLT_WIDTHMSK(x) ((x) & 0x3f) + +/* removed EINTxxxx defs from here, not meant for this */ + +/* GSTATUS have miscellaneous information in them + * + * These move between s3c2410 and s3c2412 style systems. + */ + +#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC) +#define S3C2410_GSTATUS1 S3C2410_GPIOREG(0x0B0) +#define S3C2410_GSTATUS2 S3C2410_GPIOREG(0x0B4) +#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8) +#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC) + +#define S3C2412_GSTATUS0 S3C2410_GPIOREG(0x0BC) +#define S3C2412_GSTATUS1 S3C2410_GPIOREG(0x0C0) +#define S3C2412_GSTATUS2 S3C2410_GPIOREG(0x0C4) +#define S3C2412_GSTATUS3 S3C2410_GPIOREG(0x0C8) +#define S3C2412_GSTATUS4 S3C2410_GPIOREG(0x0CC) + +#define S3C24XX_GSTATUS0 S3C24XX_GPIOREG2(0x0AC) +#define S3C24XX_GSTATUS1 S3C24XX_GPIOREG2(0x0B0) +#define S3C24XX_GSTATUS2 S3C24XX_GPIOREG2(0x0B4) +#define S3C24XX_GSTATUS3 S3C24XX_GPIOREG2(0x0B8) +#define S3C24XX_GSTATUS4 S3C24XX_GPIOREG2(0x0BC) + +#define S3C2410_GSTATUS0_nWAIT (1<<3) +#define S3C2410_GSTATUS0_NCON (1<<2) +#define S3C2410_GSTATUS0_RnB (1<<1) +#define S3C2410_GSTATUS0_nBATTFLT (1<<0) + +#define S3C2410_GSTATUS1_IDMASK (0xffff0000) +#define S3C2410_GSTATUS1_2410 (0x32410000) +#define S3C2410_GSTATUS1_2412 (0x32412001) +#define S3C2410_GSTATUS1_2416 (0x32416003) +#define S3C2410_GSTATUS1_2440 (0x32440000) +#define S3C2410_GSTATUS1_2442 (0x32440aaa) +/* some 2416 CPUs report this value also */ +#define S3C2410_GSTATUS1_2450 (0x32450003) + +#define S3C2410_GSTATUS2_WTRESET (1<<2) +#define S3C2410_GSTATUS2_OFFRESET (1<<1) +#define S3C2410_GSTATUS2_PONRESET (1<<0) + +/* 2412/2413 sleep configuration registers */ + +#define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C) +#define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C) +#define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C) +#define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C) +#define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C) +#define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C) + +/* definitions for each pin bit */ +#define S3C2412_GPIO_SLPCON_LOW ( 0x00 ) +#define S3C2412_GPIO_SLPCON_HIGH ( 0x01 ) +#define S3C2412_GPIO_SLPCON_IN ( 0x02 ) +#define S3C2412_GPIO_SLPCON_PULL ( 0x03 ) + +#define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2)) +#define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2)) +#define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2)) +#define S3C2412_SLPCON_PULL(x) ( 0x03 << ((x) * 2)) +#define S3C2412_SLPCON_EINT(x) ( 0x02 << ((x) * 2)) /* only IRQ pins */ +#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2)) + +#define S3C2412_SLPCON_ALL_LOW (0x0) +#define S3C2412_SLPCON_ALL_HIGH (0x11111111 | 0x44444444) +#define S3C2412_SLPCON_ALL_IN (0x22222222 | 0x88888888) +#define S3C2412_SLPCON_ALL_PULL (0x33333333) + +#endif /* __ASM_ARCH_REGS_GPIO_H */ + diff --git a/arch/arm/mach-s3c/include/mach/regs-gpio-s3c64xx.h b/arch/arm/mach-s3c/include/mach/regs-gpio-s3c64xx.h new file mode 100644 index 000000000000..592a2be3d2aa --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-gpio-s3c64xx.h @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C64XX - GPIO register definitions + */ + +#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H +#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__ + +/* Base addresses for each of the banks */ + +#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO + (reg)) + +#define S3C64XX_GPA_BASE S3C64XX_GPIOREG(0x0000) +#define S3C64XX_GPB_BASE S3C64XX_GPIOREG(0x0020) +#define S3C64XX_GPC_BASE S3C64XX_GPIOREG(0x0040) +#define S3C64XX_GPD_BASE S3C64XX_GPIOREG(0x0060) +#define S3C64XX_GPE_BASE S3C64XX_GPIOREG(0x0080) +#define S3C64XX_GPF_BASE S3C64XX_GPIOREG(0x00A0) +#define S3C64XX_GPG_BASE S3C64XX_GPIOREG(0x00C0) +#define S3C64XX_GPH_BASE S3C64XX_GPIOREG(0x00E0) +#define S3C64XX_GPI_BASE S3C64XX_GPIOREG(0x0100) +#define S3C64XX_GPJ_BASE S3C64XX_GPIOREG(0x0120) +#define S3C64XX_GPK_BASE S3C64XX_GPIOREG(0x0800) +#define S3C64XX_GPL_BASE S3C64XX_GPIOREG(0x0810) +#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820) +#define S3C64XX_GPN_BASE S3C64XX_GPIOREG(0x0830) +#define S3C64XX_GPO_BASE S3C64XX_GPIOREG(0x0140) +#define S3C64XX_GPP_BASE S3C64XX_GPIOREG(0x0160) +#define S3C64XX_GPQ_BASE S3C64XX_GPIOREG(0x0180) + +/* SPCON */ + +#define S3C64XX_SPCON S3C64XX_GPIOREG(0x1A0) + +#define S3C64XX_SPCON_DRVCON_CAM_MASK (0x3 << 30) +#define S3C64XX_SPCON_DRVCON_CAM_SHIFT (30) +#define S3C64XX_SPCON_DRVCON_CAM_2mA (0x0 << 30) +#define S3C64XX_SPCON_DRVCON_CAM_4mA (0x1 << 30) +#define S3C64XX_SPCON_DRVCON_CAM_7mA (0x2 << 30) +#define S3C64XX_SPCON_DRVCON_CAM_9mA (0x3 << 30) + +#define S3C64XX_SPCON_DRVCON_HSSPI_MASK (0x3 << 28) +#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT (28) +#define S3C64XX_SPCON_DRVCON_HSSPI_2mA (0x0 << 28) +#define S3C64XX_SPCON_DRVCON_HSSPI_4mA (0x1 << 28) +#define S3C64XX_SPCON_DRVCON_HSSPI_7mA (0x2 << 28) +#define S3C64XX_SPCON_DRVCON_HSSPI_9mA (0x3 << 28) + +#define S3C64XX_SPCON_DRVCON_HSMMC_MASK (0x3 << 26) +#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT (26) +#define S3C64XX_SPCON_DRVCON_HSMMC_2mA (0x0 << 26) +#define S3C64XX_SPCON_DRVCON_HSMMC_4mA (0x1 << 26) +#define S3C64XX_SPCON_DRVCON_HSMMC_7mA (0x2 << 26) +#define S3C64XX_SPCON_DRVCON_HSMMC_9mA (0x3 << 26) + +#define S3C64XX_SPCON_DRVCON_LCD_MASK (0x3 << 24) +#define S3C64XX_SPCON_DRVCON_LCD_SHIFT (24) +#define S3C64XX_SPCON_DRVCON_LCD_2mA (0x0 << 24) +#define S3C64XX_SPCON_DRVCON_LCD_4mA (0x1 << 24) +#define S3C64XX_SPCON_DRVCON_LCD_7mA (0x2 << 24) +#define S3C64XX_SPCON_DRVCON_LCD_9mA (0x3 << 24) + +#define S3C64XX_SPCON_DRVCON_MODEM_MASK (0x3 << 22) +#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT (22) +#define S3C64XX_SPCON_DRVCON_MODEM_2mA (0x0 << 22) +#define S3C64XX_SPCON_DRVCON_MODEM_4mA (0x1 << 22) +#define S3C64XX_SPCON_DRVCON_MODEM_7mA (0x2 << 22) +#define S3C64XX_SPCON_DRVCON_MODEM_9mA (0x3 << 22) + +#define S3C64XX_SPCON_nRSTOUT_OEN (1 << 21) + +#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK (0x3 << 18) +#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT (18) +#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA (0x0 << 18) +#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA (0x1 << 18) +#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA (0x2 << 18) +#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA (0x3 << 18) + +#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK (0x3 << 16) +#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT (16) +#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED (0x0 << 16) +#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN (0x1 << 16) +#define S3C64XX_SPCON_MEM1_DQS_PUD_UP (0x2 << 16) + +#define S3C64XX_SPCON_MEM1_D_PUD1_MASK (0x3 << 14) +#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT (14) +#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED (0x0 << 14) +#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN (0x1 << 14) +#define S3C64XX_SPCON_MEM1_D_PUD1_UP (0x2 << 14) + +#define S3C64XX_SPCON_MEM1_D_PUD0_MASK (0x3 << 12) +#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT (12) +#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED (0x0 << 12) +#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN (0x1 << 12) +#define S3C64XX_SPCON_MEM1_D_PUD0_UP (0x2 << 12) + +#define S3C64XX_SPCON_MEM0_D_PUD_MASK (0x3 << 8) +#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT (8) +#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED (0x0 << 8) +#define S3C64XX_SPCON_MEM0_D_PUD_DOWN (0x1 << 8) +#define S3C64XX_SPCON_MEM0_D_PUD_UP (0x2 << 8) + +#define S3C64XX_SPCON_USBH_DMPD (1 << 7) +#define S3C64XX_SPCON_USBH_DPPD (1 << 6) +#define S3C64XX_SPCON_USBH_PUSW2 (1 << 5) +#define S3C64XX_SPCON_USBH_PUSW1 (1 << 4) +#define S3C64XX_SPCON_USBH_SUSPND (1 << 3) + +#define S3C64XX_SPCON_LCD_SEL_MASK (0x3 << 0) +#define S3C64XX_SPCON_LCD_SEL_SHIFT (0) +#define S3C64XX_SPCON_LCD_SEL_HOST (0x0 << 0) +#define S3C64XX_SPCON_LCD_SEL_RGB (0x1 << 0) +#define S3C64XX_SPCON_LCD_SEL_606_656 (0x2 << 0) + + +/* External interrupt registers */ + +#define S3C64XX_EINT12CON S3C64XX_GPIOREG(0x200) +#define S3C64XX_EINT34CON S3C64XX_GPIOREG(0x204) +#define S3C64XX_EINT56CON S3C64XX_GPIOREG(0x208) +#define S3C64XX_EINT78CON S3C64XX_GPIOREG(0x20C) +#define S3C64XX_EINT9CON S3C64XX_GPIOREG(0x210) + +#define S3C64XX_EINT12FLTCON S3C64XX_GPIOREG(0x220) +#define S3C64XX_EINT34FLTCON S3C64XX_GPIOREG(0x224) +#define S3C64XX_EINT56FLTCON S3C64XX_GPIOREG(0x228) +#define S3C64XX_EINT78FLTCON S3C64XX_GPIOREG(0x22C) +#define S3C64XX_EINT9FLTCON S3C64XX_GPIOREG(0x230) + +#define S3C64XX_EINT12MASK S3C64XX_GPIOREG(0x240) +#define S3C64XX_EINT34MASK S3C64XX_GPIOREG(0x244) +#define S3C64XX_EINT56MASK S3C64XX_GPIOREG(0x248) +#define S3C64XX_EINT78MASK S3C64XX_GPIOREG(0x24C) +#define S3C64XX_EINT9MASK S3C64XX_GPIOREG(0x250) + +#define S3C64XX_EINT12PEND S3C64XX_GPIOREG(0x260) +#define S3C64XX_EINT34PEND S3C64XX_GPIOREG(0x264) +#define S3C64XX_EINT56PEND S3C64XX_GPIOREG(0x268) +#define S3C64XX_EINT78PEND S3C64XX_GPIOREG(0x26C) +#define S3C64XX_EINT9PEND S3C64XX_GPIOREG(0x270) + +#define S3C64XX_PRIORITY S3C64XX_GPIOREG(0x280) +#define S3C64XX_PRIORITY_ARB(x) (1 << (x)) + +#define S3C64XX_SERVICE S3C64XX_GPIOREG(0x284) +#define S3C64XX_SERVICEPEND S3C64XX_GPIOREG(0x288) + +#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900) +#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904) +#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910) +#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914) +#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918) +#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C) + +#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920) +#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924) + +/* GPIO sleep configuration */ + +#define S3C64XX_SPCONSLP S3C64XX_GPIOREG(0x880) + +#define S3C64XX_SPCONSLP_TDO_PULLDOWN (1 << 14) +#define S3C64XX_SPCONSLP_CKE1INIT (1 << 5) + +#define S3C64XX_SPCONSLP_RSTOUT_MASK (0x3 << 12) +#define S3C64XX_SPCONSLP_RSTOUT_OUT0 (0x0 << 12) +#define S3C64XX_SPCONSLP_RSTOUT_OUT1 (0x1 << 12) +#define S3C64XX_SPCONSLP_RSTOUT_HIZ (0x2 << 12) + +#define S3C64XX_SPCONSLP_KPCOL_MASK (0x3 << 0) +#define S3C64XX_SPCONSLP_KPCOL_OUT0 (0x0 << 0) +#define S3C64XX_SPCONSLP_KPCOL_OUT1 (0x1 << 0) +#define S3C64XX_SPCONSLP_KPCOL_INP (0x2 << 0) + + +#define S3C64XX_SLPEN S3C64XX_GPIOREG(0x930) + +#define S3C64XX_SLPEN_USE_xSLP (1 << 0) +#define S3C64XX_SLPEN_CFG_BYSLPEN (1 << 1) + +#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */ + diff --git a/arch/arm/mach-s3c/include/mach/regs-gpio.h b/arch/arm/mach-s3c/include/mach/regs-gpio.h new file mode 100644 index 000000000000..0d41cb76d440 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-gpio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "regs-gpio-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "regs-gpio-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/regs-irq-s3c24xx.h b/arch/arm/mach-s3c/include/mach/regs-irq-s3c24xx.h new file mode 100644 index 000000000000..2921b48c56b2 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-irq-s3c24xx.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2003 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + */ + + +#ifndef ___ASM_ARCH_REGS_IRQ_H +#define ___ASM_ARCH_REGS_IRQ_H + +#include + +/* interrupt controller */ + +#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ) +#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO) +#define S3C24XX_EINTREG(x) ((x) + S3C24XX_VA_GPIO2) + +#define S3C2410_SRCPND S3C2410_IRQREG(0x000) +#define S3C2410_INTMOD S3C2410_IRQREG(0x004) +#define S3C2410_INTMSK S3C2410_IRQREG(0x008) +#define S3C2410_PRIORITY S3C2410_IRQREG(0x00C) +#define S3C2410_INTPND S3C2410_IRQREG(0x010) +#define S3C2410_INTOFFSET S3C2410_IRQREG(0x014) +#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018) +#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C) + +#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030) +#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034) +#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040) +#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044) +#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048) +#define S3C2416_INTPND2 S3C2410_IRQREG(0x050) +#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054) +#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070) +#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074) + +/* mask: 0=enable, 1=disable + * 1 bit EINT, 4=EINT4, 23=EINT23 + * EINT0,1,2,3 are not handled here. +*/ + +#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4) +#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8) +#define S3C2412_EINTMASK S3C2410_EINTREG(0x0B4) +#define S3C2412_EINTPEND S3C2410_EINTREG(0X0B8) + +#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x0A4) +#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X0A8) + +#endif /* ___ASM_ARCH_REGS_IRQ_H */ diff --git a/arch/arm/mach-s3c/include/mach/regs-irq-s3c64xx.h b/arch/arm/mach-s3c/include/mach/regs-irq-s3c64xx.h new file mode 100644 index 000000000000..b18c7bcb61c5 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-irq-s3c64xx.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C64XX - IRQ register definitions + */ + +#ifndef __ASM_ARCH_REGS_IRQ_H +#define __ASM_ARCH_REGS_IRQ_H __FILE__ + + +#endif /* __ASM_ARCH_6400_REGS_IRQ_H */ diff --git a/arch/arm/mach-s3c/include/mach/regs-irq.h b/arch/arm/mach-s3c/include/mach/regs-irq.h new file mode 100644 index 000000000000..57f0dda8dbf5 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-irq.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "regs-irq-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "regs-irq-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c/include/mach/regs-s3c2443-clock.h new file mode 100644 index 000000000000..fefef7233f4b --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/regs-s3c2443-clock.h @@ -0,0 +1,238 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2007 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C2443 clock register definitions + */ + +#ifndef __ASM_ARM_REGS_S3C2443_CLOCK +#define __ASM_ARM_REGS_S3C2443_CLOCK + +#include +#include + +#define S3C2443_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) + +#define S3C2443_PLLCON_MDIVSHIFT 16 +#define S3C2443_PLLCON_PDIVSHIFT 8 +#define S3C2443_PLLCON_SDIVSHIFT 0 +#define S3C2443_PLLCON_MDIVMASK ((1<<(1+(23-16)))-1) +#define S3C2443_PLLCON_PDIVMASK ((1<<(1+(9-8)))-1) +#define S3C2443_PLLCON_SDIVMASK (3) + +#define S3C2443_MPLLCON S3C2443_CLKREG(0x10) +#define S3C2443_EPLLCON S3C2443_CLKREG(0x18) +#define S3C2443_CLKSRC S3C2443_CLKREG(0x20) +#define S3C2443_CLKDIV0 S3C2443_CLKREG(0x24) +#define S3C2443_CLKDIV1 S3C2443_CLKREG(0x28) +#define S3C2443_HCLKCON S3C2443_CLKREG(0x30) +#define S3C2443_PCLKCON S3C2443_CLKREG(0x34) +#define S3C2443_SCLKCON S3C2443_CLKREG(0x38) +#define S3C2443_PWRMODE S3C2443_CLKREG(0x40) +#define S3C2443_SWRST S3C2443_CLKREG(0x44) +#define S3C2443_BUSPRI0 S3C2443_CLKREG(0x50) +#define S3C2443_SYSID S3C2443_CLKREG(0x5C) +#define S3C2443_PWRCFG S3C2443_CLKREG(0x60) +#define S3C2443_RSTCON S3C2443_CLKREG(0x64) +#define S3C2443_PHYCTRL S3C2443_CLKREG(0x80) +#define S3C2443_PHYPWR S3C2443_CLKREG(0x84) +#define S3C2443_URSTCON S3C2443_CLKREG(0x88) +#define S3C2443_UCLKCON S3C2443_CLKREG(0x8C) + +#define S3C2443_PLLCON_OFF (1<<24) + +#define S3C2443_CLKSRC_EPLLREF_XTAL (2<<7) +#define S3C2443_CLKSRC_EPLLREF_EXTCLK (3<<7) +#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<7) +#define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<7) +#define S3C2443_CLKSRC_EPLLREF_MASK (3<<7) + +#define S3C2443_CLKSRC_EXTCLK_DIV (1<<3) + +#define S3C2443_CLKDIV0_HALF_HCLK (1<<3) +#define S3C2443_CLKDIV0_HALF_PCLK (1<<2) + +#define S3C2443_CLKDIV0_HCLKDIV_MASK (3<<0) + +#define S3C2443_CLKDIV0_EXTDIV_MASK (3<<6) +#define S3C2443_CLKDIV0_EXTDIV_SHIFT (6) + +#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4) +#define S3C2443_CLKDIV0_PREDIV_SHIFT (4) + +#define S3C2416_CLKDIV0_ARMDIV_MASK (7 << 9) +#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9) +#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9) +#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9) +#define S3C2443_CLKDIV0_ARMDIV_2 (8<<9) +#define S3C2443_CLKDIV0_ARMDIV_3 (2<<9) +#define S3C2443_CLKDIV0_ARMDIV_4 (9<<9) +#define S3C2443_CLKDIV0_ARMDIV_6 (10<<9) +#define S3C2443_CLKDIV0_ARMDIV_8 (11<<9) +#define S3C2443_CLKDIV0_ARMDIV_12 (13<<9) +#define S3C2443_CLKDIV0_ARMDIV_16 (15<<9) + +/* S3C2443_CLKDIV1 removed, only used in clock.c code */ + +#define S3C2443_CLKCON_NAND + +#define S3C2443_HCLKCON_DMA0 (1<<0) +#define S3C2443_HCLKCON_DMA1 (1<<1) +#define S3C2443_HCLKCON_DMA2 (1<<2) +#define S3C2443_HCLKCON_DMA3 (1<<3) +#define S3C2443_HCLKCON_DMA4 (1<<4) +#define S3C2443_HCLKCON_DMA5 (1<<5) +#define S3C2443_HCLKCON_CAMIF (1<<8) +#define S3C2443_HCLKCON_LCDC (1<<9) +#define S3C2443_HCLKCON_USBH (1<<11) +#define S3C2443_HCLKCON_USBD (1<<12) +#define S3C2416_HCLKCON_HSMMC0 (1<<15) +#define S3C2443_HCLKCON_HSMMC (1<<16) +#define S3C2443_HCLKCON_CFC (1<<17) +#define S3C2443_HCLKCON_SSMC (1<<18) +#define S3C2443_HCLKCON_DRAMC (1<<19) + +#define S3C2443_PCLKCON_UART0 (1<<0) +#define S3C2443_PCLKCON_UART1 (1<<1) +#define S3C2443_PCLKCON_UART2 (1<<2) +#define S3C2443_PCLKCON_UART3 (1<<3) +#define S3C2443_PCLKCON_IIC (1<<4) +#define S3C2443_PCLKCON_SDI (1<<5) +#define S3C2443_PCLKCON_HSSPI (1<<6) +#define S3C2443_PCLKCON_ADC (1<<7) +#define S3C2443_PCLKCON_AC97 (1<<8) +#define S3C2443_PCLKCON_IIS (1<<9) +#define S3C2443_PCLKCON_PWMT (1<<10) +#define S3C2443_PCLKCON_WDT (1<<11) +#define S3C2443_PCLKCON_RTC (1<<12) +#define S3C2443_PCLKCON_GPIO (1<<13) +#define S3C2443_PCLKCON_SPI0 (1<<14) +#define S3C2443_PCLKCON_SPI1 (1<<15) + +#define S3C2443_SCLKCON_DDRCLK (1<<16) +#define S3C2443_SCLKCON_SSMCCLK (1<<15) +#define S3C2443_SCLKCON_HSSPICLK (1<<14) +#define S3C2443_SCLKCON_HSMMCCLK_EXT (1<<13) +#define S3C2443_SCLKCON_HSMMCCLK_EPLL (1<<12) +#define S3C2443_SCLKCON_CAMCLK (1<<11) +#define S3C2443_SCLKCON_DISPCLK (1<<10) +#define S3C2443_SCLKCON_I2SCLK (1<<9) +#define S3C2443_SCLKCON_UARTCLK (1<<8) +#define S3C2443_SCLKCON_USBHOST (1<<1) + +#define S3C2443_PWRCFG_SLEEP (1<<15) + +#define S3C2443_PWRCFG_USBPHY (1 << 4) + +#define S3C2443_URSTCON_FUNCRST (1 << 2) +#define S3C2443_URSTCON_PHYRST (1 << 0) + +#define S3C2443_PHYCTRL_CLKSEL (1 << 3) +#define S3C2443_PHYCTRL_EXTCLK (1 << 2) +#define S3C2443_PHYCTRL_PLLSEL (1 << 1) +#define S3C2443_PHYCTRL_DSPORT (1 << 0) + +#define S3C2443_PHYPWR_COMMON_ON (1 << 31) +#define S3C2443_PHYPWR_ANALOG_PD (1 << 4) +#define S3C2443_PHYPWR_PLL_REFCLK (1 << 3) +#define S3C2443_PHYPWR_XO_ON (1 << 2) +#define S3C2443_PHYPWR_PLL_PWRDN (1 << 1) +#define S3C2443_PHYPWR_FSUSPEND (1 << 0) + +#define S3C2443_UCLKCON_DETECT_VBUS (1 << 31) +#define S3C2443_UCLKCON_FUNC_CLKEN (1 << 2) +#define S3C2443_UCLKCON_TCLKEN (1 << 0) + +#include + +static inline unsigned int +s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk) +{ + unsigned int mdiv, pdiv, sdiv; + uint64_t fvco; + + mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT; + pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT; + sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT; + + mdiv &= S3C2443_PLLCON_MDIVMASK; + pdiv &= S3C2443_PLLCON_PDIVMASK; + sdiv &= S3C2443_PLLCON_SDIVMASK; + + fvco = (uint64_t)baseclk * (2 * (mdiv + 8)); + do_div(fvco, pdiv << sdiv); + + return (unsigned int)fvco; +} + +static inline unsigned int +s3c2443_get_epll(unsigned int pllval, unsigned int baseclk) +{ + unsigned int mdiv, pdiv, sdiv; + uint64_t fvco; + + mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT; + pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT; + sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT; + + mdiv &= S3C2443_PLLCON_MDIVMASK; + pdiv &= S3C2443_PLLCON_PDIVMASK; + sdiv &= S3C2443_PLLCON_SDIVMASK; + + fvco = (uint64_t)baseclk * (mdiv + 8); + do_div(fvco, (pdiv + 2) << sdiv); + + return (unsigned int)fvco; +} + +static inline void s3c_hsudc_init_phy(void) +{ + u32 cfg; + + cfg = readl(S3C2443_PWRCFG) | S3C2443_PWRCFG_USBPHY; + writel(cfg, S3C2443_PWRCFG); + + cfg = readl(S3C2443_URSTCON); + cfg |= (S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST); + writel(cfg, S3C2443_URSTCON); + mdelay(1); + + cfg = readl(S3C2443_URSTCON); + cfg &= ~(S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST); + writel(cfg, S3C2443_URSTCON); + + cfg = readl(S3C2443_PHYCTRL); + cfg &= ~(S3C2443_PHYCTRL_CLKSEL | S3C2443_PHYCTRL_DSPORT); + cfg |= (S3C2443_PHYCTRL_EXTCLK | S3C2443_PHYCTRL_PLLSEL); + writel(cfg, S3C2443_PHYCTRL); + + cfg = readl(S3C2443_PHYPWR); + cfg &= ~(S3C2443_PHYPWR_FSUSPEND | S3C2443_PHYPWR_PLL_PWRDN | + S3C2443_PHYPWR_XO_ON | S3C2443_PHYPWR_PLL_REFCLK | + S3C2443_PHYPWR_ANALOG_PD); + cfg |= S3C2443_PHYPWR_COMMON_ON; + writel(cfg, S3C2443_PHYPWR); + + cfg = readl(S3C2443_UCLKCON); + cfg |= (S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN | + S3C2443_UCLKCON_TCLKEN); + writel(cfg, S3C2443_UCLKCON); +} + +static inline void s3c_hsudc_uninit_phy(void) +{ + u32 cfg; + + cfg = readl(S3C2443_PWRCFG) & ~S3C2443_PWRCFG_USBPHY; + writel(cfg, S3C2443_PWRCFG); + + writel(S3C2443_PHYPWR_FSUSPEND, S3C2443_PHYPWR); + + cfg = readl(S3C2443_UCLKCON) & ~S3C2443_UCLKCON_FUNC_CLKEN; + writel(cfg, S3C2443_UCLKCON); +} + +#endif /* __ASM_ARM_REGS_S3C2443_CLOCK */ + diff --git a/arch/arm/mach-s3c/include/mach/rtc-core-s3c24xx.h b/arch/arm/mach-s3c/include/mach/rtc-core-s3c24xx.h new file mode 100644 index 000000000000..e7258b2423fc --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/rtc-core-s3c24xx.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011 Heiko Stuebner + * + * Samsung RTC Controller core functions + */ + +#ifndef __RTC_CORE_S3C24XX_H +#define __RTC_CORE_S3C24XX_H __FILE__ + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code + */ + +extern struct platform_device s3c_device_rtc; + +/* re-define device name depending on support. */ +static inline void s3c_rtc_setname(char *name) +{ + s3c_device_rtc.name = name; +} + +#endif /* __RTC_CORE_S3C24XX_H */ diff --git a/arch/arm/mach-s3c/include/mach/s3c2412.h b/arch/arm/mach-s3c/include/mach/s3c2412.h new file mode 100644 index 000000000000..1ae369c81beb --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/s3c2412.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + */ + +#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H +#define __ARCH_ARM_MACH_S3C24XX_S3C2412_H __FILE__ + +#include + +#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) +#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x)) + +#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x)) +#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o))) + +#define S3C2412_REFRESH S3C2412_MEMREG(0x10) + +#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x4) + +#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x0) + +#endif /* __ARCH_ARM_MACH_S3C24XX_S3C2412_H */ diff --git a/arch/arm/mach-s3c/include/plat/adc-core.h b/arch/arm/mach-s3c/include/plat/adc-core.h new file mode 100644 index 000000000000..039f6862b6a7 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/adc-core.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Samsung ADC Controller core functions + */ + +#ifndef __ASM_PLAT_ADC_CORE_H +#define __ASM_PLAT_ADC_CORE_H __FILE__ + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code + */ + +/* re-define device name depending on support. */ +static inline void s3c_adc_setname(char *name) +{ +#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX) + s3c_device_adc.name = name; +#endif +} + +#endif /* __ASM_PLAT_ADC_CORE_H */ diff --git a/arch/arm/mach-s3c/include/plat/cpu.h b/arch/arm/mach-s3c/include/plat/cpu.h new file mode 100644 index 000000000000..20ff98d05c53 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/cpu.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks + * + * Header file for Samsung CPU support + */ + +/* todo - fix when rmk changes iodescs to use `void __iomem *` */ + +#ifndef __SAMSUNG_PLAT_CPU_H +#define __SAMSUNG_PLAT_CPU_H + +extern unsigned long samsung_cpu_id; + +#define S3C2410_CPU_ID 0x32410000 +#define S3C2410_CPU_MASK 0xFFFFFFFF + +#define S3C24XX_CPU_ID 0x32400000 +#define S3C24XX_CPU_MASK 0xFFF00000 + +#define S3C2412_CPU_ID 0x32412000 +#define S3C2412_CPU_MASK 0xFFFFF000 + +#define S3C6400_CPU_ID 0x36400000 +#define S3C6410_CPU_ID 0x36410000 +#define S3C64XX_CPU_MASK 0xFFFFF000 + +#define S5PV210_CPU_ID 0x43110000 +#define S5PV210_CPU_MASK 0xFFFFF000 + +#define IS_SAMSUNG_CPU(name, id, mask) \ +static inline int is_samsung_##name(void) \ +{ \ + return ((samsung_cpu_id & mask) == (id & mask)); \ +} + +IS_SAMSUNG_CPU(s3c2410, S3C2410_CPU_ID, S3C2410_CPU_MASK) +IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK) +IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK) +IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK) +IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK) + +#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \ + defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \ + defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \ + defined(CONFIG_CPU_S3C2443) +# define soc_is_s3c24xx() is_samsung_s3c24xx() +# define soc_is_s3c2410() is_samsung_s3c2410() +#else +# define soc_is_s3c24xx() 0 +# define soc_is_s3c2410() 0 +#endif + +#if defined(CONFIG_CPU_S3C2412) +# define soc_is_s3c2412() is_samsung_s3c2412() +#else +# define soc_is_s3c2412() 0 +#endif + +#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) +# define soc_is_s3c6400() is_samsung_s3c6400() +# define soc_is_s3c6410() is_samsung_s3c6410() +# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) +#else +# define soc_is_s3c6400() 0 +# define soc_is_s3c6410() 0 +# define soc_is_s3c64xx() 0 +#endif + +#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE } + +#ifndef KHZ +#define KHZ (1000) +#endif + +#ifndef MHZ +#define MHZ (1000*1000) +#endif + +#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000) + +/* forward declaration */ +struct s3c24xx_uart_resources; +struct platform_device; +struct s3c2410_uartcfg; +struct map_desc; + +/* per-cpu initialisation function table. */ + +struct cpu_table { + unsigned long idcode; + unsigned long idmask; + void (*map_io)(void); + void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no); + void (*init_clocks)(int xtal); + int (*init)(void); + const char *name; +}; + +extern void s3c_init_cpu(unsigned long idcode, + struct cpu_table *cpus, unsigned int cputab_size); + +/* core initialisation functions */ + +extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); + +extern void s3c64xx_init_cpu(void); + +extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +extern void s3c24xx_init_clocks(int xtal); + +extern void s3c24xx_init_uartdevs(char *name, + struct s3c24xx_uart_resources *res, + struct s3c2410_uartcfg *cfg, int no); + +extern struct syscore_ops s3c2410_pm_syscore_ops; +extern struct syscore_ops s3c2412_pm_syscore_ops; +extern struct syscore_ops s3c2416_pm_syscore_ops; +extern struct syscore_ops s3c244x_pm_syscore_ops; + +extern struct bus_type s3c6410_subsys; + +#endif diff --git a/arch/arm/mach-s3c/include/plat/devs.h b/arch/arm/mach-s3c/include/plat/devs.h new file mode 100644 index 000000000000..02b0c5750572 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/devs.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks + * + * Header file for s3c2410 standard platform devices + */ + +#ifndef __PLAT_DEVS_H +#define __PLAT_DEVS_H __FILE__ + +#include + +struct s3c24xx_uart_resources { + struct resource *resources; + unsigned long nr_resources; +}; + +extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; +extern struct s3c24xx_uart_resources s3c64xx_uart_resources[]; + +extern struct platform_device *s3c24xx_uart_devs[]; +extern struct platform_device *s3c24xx_uart_src[]; + +extern struct platform_device s3c64xx_device_ac97; +extern struct platform_device s3c64xx_device_iis0; +extern struct platform_device s3c64xx_device_iis1; +extern struct platform_device s3c64xx_device_iisv4; +extern struct platform_device s3c64xx_device_onenand1; +extern struct platform_device s3c64xx_device_pcm0; +extern struct platform_device s3c64xx_device_pcm1; +extern struct platform_device s3c64xx_device_spi0; +extern struct platform_device s3c64xx_device_spi1; +extern struct platform_device s3c64xx_device_spi2; + +extern struct platform_device s3c_device_adc; +extern struct platform_device s3c_device_cfcon; +extern struct platform_device s3c_device_fb; +extern struct platform_device s3c_device_hwmon; +extern struct platform_device s3c_device_hsmmc0; +extern struct platform_device s3c_device_hsmmc1; +extern struct platform_device s3c_device_hsmmc2; +extern struct platform_device s3c_device_hsmmc3; +extern struct platform_device s3c_device_i2c0; +extern struct platform_device s3c_device_i2c1; +extern struct platform_device s3c_device_i2c2; +extern struct platform_device s3c_device_i2c3; +extern struct platform_device s3c_device_i2c4; +extern struct platform_device s3c_device_i2c5; +extern struct platform_device s3c_device_i2c6; +extern struct platform_device s3c_device_i2c7; +extern struct platform_device s3c_device_iis; +extern struct platform_device s3c_device_lcd; +extern struct platform_device s3c_device_nand; +extern struct platform_device s3c_device_ohci; +extern struct platform_device s3c_device_onenand; +extern struct platform_device s3c_device_rtc; +extern struct platform_device s3c_device_sdi; +extern struct platform_device s3c_device_spi0; +extern struct platform_device s3c_device_spi1; +extern struct platform_device s3c_device_ts; +extern struct platform_device s3c_device_timer[]; +extern struct platform_device s3c_device_usbgadget; +extern struct platform_device s3c_device_usb_hsotg; +extern struct platform_device s3c_device_usb_hsudc; +extern struct platform_device s3c_device_wdt; + +extern struct platform_device samsung_asoc_idma; +extern struct platform_device samsung_device_keypad; +extern struct platform_device samsung_device_pwm; + +/* s3c2440 specific devices */ + +#ifdef CONFIG_CPU_S3C2440 + +extern struct platform_device s3c_device_camif; +extern struct platform_device s3c_device_ac97; + +#endif + +/** + * s3c_set_platdata() - helper for setting platform data + * @pd: The default platform data for this device. + * @pdsize: The size of the platform data. + * @pdev: Pointer to the device to fill in. + * + * This helper replaces a number of calls that copy and then set the + * platform data of the device. + */ +extern void *s3c_set_platdata(void *pd, size_t pdsize, + struct platform_device *pdev); + +#endif /* __PLAT_DEVS_H */ diff --git a/arch/arm/mach-s3c/include/plat/fb.h b/arch/arm/mach-s3c/include/plat/fb.h new file mode 100644 index 000000000000..615d381ae32e --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/fb.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C - FB platform data definitions + */ + +#ifndef __PLAT_S3C_FB_H +#define __PLAT_S3C_FB_H __FILE__ + +#include + +/** + * s3c_fb_set_platdata() - Setup the FB device with platform data. + * @pd: The platform data to set. The data is copied from the passed structure + * so the machine data can mark the data __initdata so that any unused + * machines will end up dumping their data at runtime. + */ +extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd); + +/** + * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD + * + * Initialise the GPIO for an 24bpp LCD display on the RGB interface. + */ +extern void s3c64xx_fb_gpio_setup_24bpp(void); + +#endif /* __PLAT_S3C_FB_H */ diff --git a/arch/arm/mach-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/mach-s3c/include/plat/gpio-cfg-helpers.h new file mode 100644 index 000000000000..db0c56f5ca15 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/gpio-cfg-helpers.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * Samsung Platform - GPIO pin configuration helper definitions + */ + +/* This is meant for core cpu support, machine or other driver files + * should not be including this header. + */ + +#ifndef __PLAT_GPIO_CFG_HELPERS_H +#define __PLAT_GPIO_CFG_HELPERS_H __FILE__ + +/* As a note, all gpio configuration functions are entered exclusively, either + * with the relevant lock held or the system prevented from doing anything else + * by disabling interrupts. +*/ + +static inline int samsung_gpio_do_setcfg(struct samsung_gpio_chip *chip, + unsigned int off, unsigned int config) +{ + return (chip->config->set_config)(chip, off, config); +} + +static inline unsigned samsung_gpio_do_getcfg(struct samsung_gpio_chip *chip, + unsigned int off) +{ + return (chip->config->get_config)(chip, off); +} + +static inline int samsung_gpio_do_setpull(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull) +{ + return (chip->config->set_pull)(chip, off, pull); +} + +static inline samsung_gpio_pull_t samsung_gpio_do_getpull(struct samsung_gpio_chip *chip, + unsigned int off) +{ + return chip->config->get_pull(chip, off); +} + +/* Pull-{up,down} resistor controls. + * + * S3C2410,S3C2440 = Pull-UP, + * S3C2412,S3C2413 = Pull-Down + * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef] + * S3C2443 = Pull-Both [not same as S3C6400] + */ + +/** + * s3c24xx_gpio_setpull_1up() - Pull configuration for choice of up or none. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @param: pull: The pull mode being requested. + * + * This is a helper function for the case where we have GPIOs with one + * bit configuring the presence of a pull-up resistor. + */ +extern int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); + +/** + * s3c24xx_gpio_setpull_1down() - Pull configuration for choice of down or none + * @chip: The gpio chip that is being configured + * @off: The offset for the GPIO being configured + * @param: pull: The pull mode being requested + * + * This is a helper function for the case where we have GPIOs with one + * bit configuring the presence of a pull-down resistor. + */ +extern int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); + +/** + * samsung_gpio_setpull_upown() - Pull configuration for choice of up, + * down or none + * + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @param: pull: The pull mode being requested. + * + * This is a helper function for the case where we have GPIOs with two + * bits configuring the presence of a pull resistor, in the following + * order: + * 00 = No pull resistor connected + * 01 = Pull-up resistor connected + * 10 = Pull-down resistor connected + */ +extern int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); + +/** + * samsung_gpio_getpull_updown() - Get configuration for choice of up, + * down or none + * + * @chip: The gpio chip that the GPIO pin belongs to + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-{up,down} resistor + * for the given GPIO in the same case as samsung_gpio_setpull_upown. +*/ +extern samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip, + unsigned int off); + +/** + * s3c24xx_gpio_getpull_1up() - Get configuration for choice of up or none + * @chip: The gpio chip that the GPIO pin belongs to + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-up resistor for the + * given GPIO in the same case as s3c24xx_gpio_setpull_1up. +*/ +extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip, + unsigned int off); + +/** + * s3c24xx_gpio_getpull_1down() - Get configuration for choice of down or none + * @chip: The gpio chip that the GPIO pin belongs to + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-down resistor for the + * given GPIO in the same case as s3c24xx_gpio_setpull_1down. +*/ +extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip, + unsigned int off); + +/** + * s3c2443_gpio_setpull() - Pull configuration for s3c2443. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @param: pull: The pull mode being requested. + * + * This is a helper function for the case where we have GPIOs with two + * bits configuring the presence of a pull resistor, in the following + * order: + * 00 = Pull-up resistor connected + * 10 = Pull-down resistor connected + * x1 = No pull up resistor + */ +extern int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip, + unsigned int off, samsung_gpio_pull_t pull); + +/** + * s3c2443_gpio_getpull() - Get configuration for s3c2443 pull resistors + * @chip: The gpio chip that the GPIO pin belongs to. + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-{up,down} resistor for the + * given GPIO in the same case as samsung_gpio_setpull_upown. +*/ +extern samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip, + unsigned int off); + +#endif /* __PLAT_GPIO_CFG_HELPERS_H */ diff --git a/arch/arm/mach-s3c/include/plat/gpio-cfg.h b/arch/arm/mach-s3c/include/plat/gpio-cfg.h new file mode 100644 index 000000000000..469c220e092b --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/gpio-cfg.h @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C Platform - GPIO pin configuration + */ + +/* This file contains the necessary definitions to get the basic gpio + * pin configuration done such as setting a pin to input or output or + * changing the pull-{up,down} configurations. + */ + +/* Note, this interface is being added to the s3c64xx arch first and will + * be added to the s3c24xx systems later. + */ + +#ifndef __PLAT_GPIO_CFG_H +#define __PLAT_GPIO_CFG_H __FILE__ + +#include + +typedef unsigned int __bitwise samsung_gpio_pull_t; + +/* forward declaration if gpio-core.h hasn't been included */ +struct samsung_gpio_chip; + +/** + * struct samsung_gpio_cfg GPIO configuration + * @cfg_eint: Configuration setting when used for external interrupt source + * @get_pull: Read the current pull configuration for the GPIO + * @set_pull: Set the current pull configuration for the GPIO + * @set_config: Set the current configuration for the GPIO + * @get_config: Read the current configuration for the GPIO + * + * Each chip can have more than one type of GPIO bank available and some + * have different capabilites even when they have the same control register + * layouts. Provide an point to vector control routine and provide any + * per-bank configuration information that other systems such as the + * external interrupt code will need. + * + * @sa samsung_gpio_cfgpin + * @sa s3c_gpio_getcfg + * @sa s3c_gpio_setpull + * @sa s3c_gpio_getpull + */ +struct samsung_gpio_cfg { + unsigned int cfg_eint; + + samsung_gpio_pull_t (*get_pull)(struct samsung_gpio_chip *chip, unsigned offs); + int (*set_pull)(struct samsung_gpio_chip *chip, unsigned offs, + samsung_gpio_pull_t pull); + + unsigned (*get_config)(struct samsung_gpio_chip *chip, unsigned offs); + int (*set_config)(struct samsung_gpio_chip *chip, unsigned offs, + unsigned config); +}; + +#define S3C_GPIO_SPECIAL_MARK (0xfffffff0) +#define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x)) + +/* Defines for generic pin configurations */ +#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) +#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) +#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) + +#define samsung_gpio_is_cfg_special(_cfg) \ + (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK) + +/** + * s3c_gpio_cfgpin() - Change the GPIO function of a pin. + * @pin pin The pin number to configure. + * @to to The configuration for the pin's function. + * + * Configure which function is actually connected to the external + * pin, such as an gpio input, output or some form of special function + * connected to an internal peripheral block. + * + * The @to parameter can be one of the generic S3C_GPIO_INPUT, S3C_GPIO_OUTPUT + * or S3C_GPIO_SFN() to indicate one of the possible values that the helper + * will then generate the correct bit mask and shift for the configuration. + * + * If a bank of GPIOs all needs to be set to special-function 2, then + * the following code will work: + * + * for (gpio = start; gpio < end; gpio++) + * s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + * + * The @to parameter can also be a specific value already shifted to the + * correct position in the control register, although these are discouraged + * in newer kernels and are only being kept for compatibility. + */ +extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); + +/** + * s3c_gpio_getcfg - Read the current function for a GPIO pin + * @pin: The pin to read the configuration value for. + * + * Read the configuration state of the given @pin, returning a value that + * could be passed back to s3c_gpio_cfgpin(). + * + * @sa s3c_gpio_cfgpin + */ +extern unsigned s3c_gpio_getcfg(unsigned int pin); + +/** + * s3c_gpio_cfgpin_range() - Change the GPIO function for configuring pin range + * @start: The pin number to start at + * @nr: The number of pins to configure from @start. + * @cfg: The configuration for the pin's function + * + * Call s3c_gpio_cfgpin() for the @nr pins starting at @start. + * + * @sa s3c_gpio_cfgpin. + */ +extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, + unsigned int cfg); + +/* Define values for the pull-{up,down} available for each gpio pin. + * + * These values control the state of the weak pull-{up,down} resistors + * available on most pins on the S3C series. Not all chips support both + * up or down settings, and it may be dependent on the chip that is being + * used to whether the particular mode is available. + */ +#define S3C_GPIO_PULL_NONE ((__force samsung_gpio_pull_t)0x00) +#define S3C_GPIO_PULL_DOWN ((__force samsung_gpio_pull_t)0x01) +#define S3C_GPIO_PULL_UP ((__force samsung_gpio_pull_t)0x02) + +/** + * s3c_gpio_setpull() - set the state of a gpio pin pull resistor + * @pin: The pin number to configure the pull resistor. + * @pull: The configuration for the pull resistor. + * + * This function sets the state of the pull-{up,down} resistor for the + * specified pin. It will return 0 if successful, or a negative error + * code if the pin cannot support the requested pull setting. + * + * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP. +*/ +extern int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull); + +/** + * s3c_gpio_getpull() - get the pull resistor state of a gpio pin + * @pin: The pin number to get the settings for + * + * Read the pull resistor value for the specified pin. +*/ +extern samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin); + +/* configure `all` aspects of an gpio */ + +/** + * s3c_gpio_cfgall_range() - configure range of gpio functtion and pull. + * @start: The gpio number to start at. + * @nr: The number of gpio to configure from @start. + * @cfg: The configuration to use + * @pull: The pull setting to use. + * + * Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting + * @gpio and running for @size. + * + * @sa s3c_gpio_cfgpin + * @sa s3c_gpio_setpull + * @sa s3c_gpio_cfgpin_range + */ +extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, + unsigned int cfg, samsung_gpio_pull_t pull); + +static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size, + unsigned int cfg) +{ + return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE); +} + +#endif /* __PLAT_GPIO_CFG_H */ diff --git a/arch/arm/mach-s3c/include/plat/gpio-core.h b/arch/arm/mach-s3c/include/plat/gpio-core.h new file mode 100644 index 000000000000..c0bfceb88340 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/gpio-core.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C Platform - GPIO core + */ + +#ifndef __PLAT_SAMSUNG_GPIO_CORE_H +#define __PLAT_SAMSUNG_GPIO_CORE_H + +/* Bring in machine-local definitions, especially S3C_GPIO_END */ +#include +#include + +#define GPIOCON_OFF (0x00) +#define GPIODAT_OFF (0x04) + +#define con_4bit_shift(__off) ((__off) * 4) + +/* Define the core gpiolib support functions that the s3c platforms may + * need to extend or change depending on the hardware and the s3c chip + * selected at build or found at run time. + * + * These definitions are not intended for driver inclusion, there is + * nothing here that should not live outside the platform and core + * specific code. +*/ + +struct samsung_gpio_chip; + +/** + * struct samsung_gpio_pm - power management (suspend/resume) information + * @save: Routine to save the state of the GPIO block + * @resume: Routine to resume the GPIO block. + */ +struct samsung_gpio_pm { + void (*save)(struct samsung_gpio_chip *chip); + void (*resume)(struct samsung_gpio_chip *chip); +}; + +struct samsung_gpio_cfg; + +/** + * struct samsung_gpio_chip - wrapper for specific implementation of gpio + * @chip: The chip structure to be exported via gpiolib. + * @base: The base pointer to the gpio configuration registers. + * @group: The group register number for gpio interrupt support. + * @irq_base: The base irq number. + * @config: special function and pull-resistor control information. + * @lock: Lock for exclusive access to this gpio bank. + * @pm_save: Save information for suspend/resume support. + * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not. + * + * This wrapper provides the necessary information for the Samsung + * specific gpios being registered with gpiolib. + * + * The lock protects each gpio bank from multiple access of the shared + * configuration registers, or from reading of data whilst another thread + * is writing to the register set. + * + * Each chip has its own lock to avoid any contention between different + * CPU cores trying to get one lock for different GPIO banks, where each + * bank of GPIO has its own register space and configuration registers. + */ +struct samsung_gpio_chip { + struct gpio_chip chip; + struct samsung_gpio_cfg *config; + struct samsung_gpio_pm *pm; + void __iomem *base; + int irq_base; + int group; + spinlock_t lock; +#ifdef CONFIG_PM + u32 pm_save[4]; +#endif + u32 bitmap_gpio_int; +}; + +static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc) +{ + return container_of(gpc, struct samsung_gpio_chip, chip); +} + +/** + * samsung_gpiolib_to_irq - convert gpio pin to irq number + * @chip: The gpio chip that the pin belongs to. + * @offset: The offset of the pin in the chip. + * + * This helper returns the irq number calculated from the chip->irq_base and + * the provided offset. + */ +extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset); + +/* exported for core SoC support to change */ +extern struct samsung_gpio_cfg s3c24xx_gpiocfg_default; + +#ifdef CONFIG_S3C_GPIO_TRACK +extern struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END]; + +static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int chip) +{ + return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL; +} +#else +/* machine specific code should provide samsung_gpiolib_getchip */ + +extern struct samsung_gpio_chip s3c24xx_gpios[]; + +static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin) +{ + struct samsung_gpio_chip *chip; + + if (pin > S3C_GPIO_END) + return NULL; + + chip = &s3c24xx_gpios[pin/32]; + return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL; +} + +static inline void s3c_gpiolib_track(struct samsung_gpio_chip *chip) { } +#endif + +#ifdef CONFIG_PM +extern struct samsung_gpio_pm samsung_gpio_pm_1bit; +extern struct samsung_gpio_pm samsung_gpio_pm_2bit; +extern struct samsung_gpio_pm samsung_gpio_pm_4bit; +#define __gpio_pm(x) x +#else +#define samsung_gpio_pm_1bit NULL +#define samsung_gpio_pm_2bit NULL +#define samsung_gpio_pm_4bit NULL +#define __gpio_pm(x) NULL + +#endif /* CONFIG_PM */ + +/* locking wrappers to deal with multiple access to the same gpio bank */ +#define samsung_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) +#define samsung_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) + +#endif /* __PLAT_SAMSUNG_GPIO_CORE_H */ diff --git a/arch/arm/mach-s3c/include/plat/iic-core.h b/arch/arm/mach-s3c/include/plat/iic-core.h new file mode 100644 index 000000000000..c5cfd5af3874 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/iic-core.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * + * S3C - I2C Controller core functions + */ + +#ifndef __ASM_ARCH_IIC_CORE_H +#define __ASM_ARCH_IIC_CORE_H __FILE__ + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code + */ + +/* re-define device name depending on support. */ +static inline void s3c_i2c0_setname(char *name) +{ + /* currently this device is always compiled in */ + s3c_device_i2c0.name = name; +} + +static inline void s3c_i2c1_setname(char *name) +{ +#ifdef CONFIG_S3C_DEV_I2C1 + s3c_device_i2c1.name = name; +#endif +} + +static inline void s3c_i2c2_setname(char *name) +{ +#ifdef CONFIG_S3C_DEV_I2C2 + s3c_device_i2c2.name = name; +#endif +} + +#endif /* __ASM_ARCH_IIC_H */ diff --git a/arch/arm/mach-s3c/include/plat/keypad.h b/arch/arm/mach-s3c/include/plat/keypad.h new file mode 100644 index 000000000000..9754b9a29945 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/keypad.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Samsung Platform - Keypad platform data definitions + * + * Copyright (C) 2010 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + */ + +#ifndef __PLAT_SAMSUNG_KEYPAD_H +#define __PLAT_SAMSUNG_KEYPAD_H + +#include + +/** + * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device. + * @pd: Platform data to register to device. + * + * Register the given platform data for use with Samsung Keypad device. + * The call will copy the platform data, so the board definitions can + * make the structure itself __initdata. + */ +extern void samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd); + +/* defined by architecture to configure gpio. */ +extern void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols); + +#endif /* __PLAT_SAMSUNG_KEYPAD_H */ diff --git a/arch/arm/mach-s3c/include/plat/map-base.h b/arch/arm/mach-s3c/include/plat/map-base.h new file mode 100644 index 000000000000..34b39ded0e2e --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/map-base.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2003, 2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C - Memory map definitions (virtual addresses) + */ + +#ifndef __ASM_PLAT_MAP_H +#define __ASM_PLAT_MAP_H __FILE__ + +/* Fit all our registers in at 0xF6000000 upwards, trying to use as + * little of the VA space as possible so vmalloc and friends have a + * better chance of getting memory. + * + * we try to ensure stuff like the IRQ registers are available for + * an single MOVS instruction (ie, only 8 bits of set data) + */ + +#define S3C_ADDR_BASE 0xF6000000 + +#ifndef __ASSEMBLY__ +#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) +#else +#define S3C_ADDR(x) (S3C_ADDR_BASE + (x)) +#endif + +#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */ +#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */ +#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */ +#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */ +#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */ +#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */ + +/* This is used for the CPU specific mappings that may be needed, so that + * they do not need to directly used S3C_ADDR() and thus make it easier to + * modify the space for mapping. + */ +#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x)) + +#endif /* __ASM_PLAT_MAP_H */ diff --git a/arch/arm/mach-s3c/include/plat/map-s3c.h b/arch/arm/mach-s3c/include/plat/map-s3c.h new file mode 100644 index 000000000000..bf247d836684 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/map-s3c.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks + * + * S3C24XX - Memory map definitions + */ + +#ifndef __ASM_PLAT_MAP_S3C_H +#define __ASM_PLAT_MAP_S3C_H __FILE__ + +#include + +#define S3C24XX_VA_IRQ S3C_VA_IRQ +#define S3C24XX_VA_MEMCTRL S3C_VA_MEM +#define S3C24XX_VA_UART S3C_VA_UART + +#define S3C24XX_VA_TIMER S3C_VA_TIMER +#define S3C24XX_VA_CLKPWR S3C_VA_SYS +#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG + +#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) +#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00100000) + +#define S3C2410_PA_UART (0x50000000) +#define S3C24XX_PA_UART S3C2410_PA_UART + +/* + * GPIO ports + * + * the calculation for the VA of this must ensure that + * it is the same distance apart from the UART in the + * phsyical address space, as the initial mapping for the IO + * is done as a 1:1 mapping. This puts it (currently) at + * 0xFA800000, which is not in the way of any current mapping + * by the base system. +*/ + +#define S3C2410_PA_GPIO (0x56000000) +#define S3C24XX_PA_GPIO S3C2410_PA_GPIO + +#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART) +#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000) + +#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000) +#define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000) + +#define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY + +#define S3C2410_ADDR(x) S3C_ADDR(x) + +/* deal with the registers that move under the 2412/2413 */ + +#if defined(CONFIG_CPU_S3C2412) +#ifndef __ASSEMBLY__ +extern void __iomem *s3c24xx_va_gpio2; +#endif +#ifdef CONFIG_CPU_S3C2412_ONLY +#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10) +#else +#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2 +#endif +#else +#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO +#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO +#endif + +#include + +#endif /* __ASM_PLAT_MAP_S3C_H */ diff --git a/arch/arm/mach-s3c/include/plat/map-s5p.h b/arch/arm/mach-s3c/include/plat/map-s5p.h new file mode 100644 index 000000000000..3812085f8761 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/map-s5p.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Memory map definitions + */ + +#ifndef __ASM_PLAT_MAP_S5P_H +#define __ASM_PLAT_MAP_S5P_H __FILE__ + +#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) +#define VA_VIC0 VA_VIC(0) +#define VA_VIC1 VA_VIC(1) +#define VA_VIC2 VA_VIC(2) +#define VA_VIC3 VA_VIC(3) + +#include + +#endif /* __ASM_PLAT_MAP_S5P_H */ diff --git a/arch/arm/mach-s3c/include/plat/pm-common.h b/arch/arm/mach-s3c/include/plat/pm-common.h new file mode 100644 index 000000000000..18b9607e1e39 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/pm-common.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Tomasz Figa + * Copyright (c) 2004 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Written by Ben Dooks, + */ + +#ifndef __PLAT_SAMSUNG_PM_COMMON_H +#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__ + +#include +#include + +/* sleep save info */ + +/** + * struct sleep_save - save information for shared peripherals. + * @reg: Pointer to the register to save. + * @val: Holder for the value saved from reg. + * + * This describes a list of registers which is used by the pm core and + * other subsystem to save and restore register values over suspend. + */ +struct sleep_save { + void __iomem *reg; + unsigned long val; +}; + +#define SAVE_ITEM(x) \ + { .reg = (x) } + +/* helper functions to save/restore lists of registers. */ + +extern void s3c_pm_do_save(struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count); + +#endif diff --git a/arch/arm/mach-s3c/include/plat/pm.h b/arch/arm/mach-s3c/include/plat/pm.h new file mode 100644 index 000000000000..2746137f9794 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/pm.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2004 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Written by Ben Dooks, + */ + +/* s3c_pm_init + * + * called from board at initialisation time to setup the power + * management +*/ + +#include + +struct device; + +#ifdef CONFIG_SAMSUNG_PM + +extern __init int s3c_pm_init(void); +extern __init int s3c64xx_pm_init(void); + +#else + +static inline int s3c_pm_init(void) +{ + return 0; +} + +static inline int s3c64xx_pm_init(void) +{ + return 0; +} +#endif + +/* configuration for the IRQ mask over sleep */ +extern unsigned long s3c_irqwake_intmask; +extern unsigned long s3c_irqwake_eintmask; + +/* per-cpu sleep functions */ + +extern void (*pm_cpu_prep)(void); +extern int (*pm_cpu_sleep)(unsigned long); + +/* Flags for PM Control */ + +extern unsigned long s3c_pm_flags; + +/* from sleep.S */ + +extern int s3c2410_cpu_suspend(unsigned long); + +#ifdef CONFIG_PM_SLEEP +extern int s3c_irq_wake(struct irq_data *data, unsigned int state); +extern void s3c_cpu_resume(void); +#else +#define s3c_irq_wake NULL +#define s3c_cpu_resume NULL +#endif + +#ifdef CONFIG_SAMSUNG_PM +extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); +#else +#define s3c_irqext_wake NULL +#endif + +#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK +/** + * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs + * @set: set bits for the state of the LEDs + * @clear: clear bits for the state of the LEDs. + */ +extern void s3c_pm_debug_smdkled(u32 set, u32 clear); + +#else +static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { } +#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */ + +/** + * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ + * + * Setup all the necessary GPIO pins for waking the system on external + * interrupt. + */ +extern void s3c_pm_configure_extint(void); + +#ifdef CONFIG_GPIO_SAMSUNG +/** + * samsung_pm_restore_gpios() - restore the state of the gpios after sleep. + * + * Restore the state of the GPIO pins after sleep, which may involve ensuring + * that we do not glitch the state of the pins from that the bootloader's + * resume code has done. +*/ +extern void samsung_pm_restore_gpios(void); + +/** + * samsung_pm_save_gpios() - save the state of the GPIOs for restoring after sleep. + * + * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios(). + */ +extern void samsung_pm_save_gpios(void); +#else +static inline void samsung_pm_restore_gpios(void) {} +static inline void samsung_pm_save_gpios(void) {} +#endif + +extern void s3c_pm_save_core(void); +extern void s3c_pm_restore_core(void); diff --git a/arch/arm/mach-s3c/include/plat/pwm-core.h b/arch/arm/mach-s3c/include/plat/pwm-core.h new file mode 100644 index 000000000000..05e3448642a1 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/pwm-core.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2013 Tomasz Figa + * + * Samsung PWM controller platform data helpers. + */ + +#ifndef __ASM_ARCH_PWM_CORE_H +#define __ASM_ARCH_PWM_CORE_H __FILE__ + +#include + +#ifdef CONFIG_SAMSUNG_DEV_PWM +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd); +#else +static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { } +#endif + +#endif /* __ASM_ARCH_PWM_CORE_H */ diff --git a/arch/arm/mach-s3c/include/plat/regs-adc.h b/arch/arm/mach-s3c/include/plat/regs-adc.h new file mode 100644 index 000000000000..58953c7381dd --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/regs-adc.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2004 Shannon Holland + * + * S3C2410 ADC registers + */ + +#ifndef __ASM_ARCH_REGS_ADC_H +#define __ASM_ARCH_REGS_ADC_H "regs-adc.h" + +#define S3C2410_ADCREG(x) (x) + +#define S3C2410_ADCCON S3C2410_ADCREG(0x00) +#define S3C2410_ADCTSC S3C2410_ADCREG(0x04) +#define S3C2410_ADCDLY S3C2410_ADCREG(0x08) +#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C) +#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10) +#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14) +#define S3C2443_ADCMUX S3C2410_ADCREG(0x18) +#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18) +#define S5P_ADCMUX S3C2410_ADCREG(0x1C) +#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20) + + +/* ADCCON Register Bits */ +#define S3C64XX_ADCCON_RESSEL (1<<16) +#define S3C2410_ADCCON_ECFLG (1<<15) +#define S3C2410_ADCCON_PRSCEN (1<<14) +#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6) +#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6) +#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3) +#define S3C2410_ADCCON_MUXMASK (0x7<<3) +#define S3C2416_ADCCON_RESSEL (1 << 3) +#define S3C2410_ADCCON_STDBM (1<<2) +#define S3C2410_ADCCON_READ_START (1<<1) +#define S3C2410_ADCCON_ENABLE_START (1<<0) +#define S3C2410_ADCCON_STARTMASK (0x3<<0) + + +/* ADCTSC Register Bits */ +#define S3C2443_ADCTSC_UD_SEN (1 << 8) +#define S3C2410_ADCTSC_YM_SEN (1<<7) +#define S3C2410_ADCTSC_YP_SEN (1<<6) +#define S3C2410_ADCTSC_XM_SEN (1<<5) +#define S3C2410_ADCTSC_XP_SEN (1<<4) +#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3) +#define S3C2410_ADCTSC_AUTO_PST (1<<2) +#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0) + +/* ADCDAT0 Bits */ +#define S3C2410_ADCDAT0_UPDOWN (1<<15) +#define S3C2410_ADCDAT0_AUTO_PST (1<<14) +#define S3C2410_ADCDAT0_XY_PST (0x3<<12) +#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF) + +/* ADCDAT1 Bits */ +#define S3C2410_ADCDAT1_UPDOWN (1<<15) +#define S3C2410_ADCDAT1_AUTO_PST (1<<14) +#define S3C2410_ADCDAT1_XY_PST (0x3<<12) +#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF) + +#endif /* __ASM_ARCH_REGS_ADC_H */ + + diff --git a/arch/arm/mach-s3c/include/plat/regs-irqtype.h b/arch/arm/mach-s3c/include/plat/regs-irqtype.h new file mode 100644 index 000000000000..ec5c4c5fdd8f --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/regs-irqtype.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C - IRQ detection types. + */ + +/* values for S3C2410_EXTINT0/1/2 and other cpus in the series, including + * the S3C64XX +*/ +#define S3C2410_EXTINT_LOWLEV (0x00) +#define S3C2410_EXTINT_HILEV (0x01) +#define S3C2410_EXTINT_FALLEDGE (0x02) +#define S3C2410_EXTINT_RISEEDGE (0x04) +#define S3C2410_EXTINT_BOTHEDGE (0x06) diff --git a/arch/arm/mach-s3c/include/plat/sdhci.h b/arch/arm/mach-s3c/include/plat/sdhci.h new file mode 100644 index 000000000000..5731e42ea208 --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/sdhci.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C Platform - SDHCI (HSMMC) platform data definitions + */ + +#ifndef __PLAT_S3C_SDHCI_H +#define __PLAT_S3C_SDHCI_H __FILE__ + +#include +#include + +/* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data + * @pd: The default platform data for this device. + * @set: Pointer to the platform data to fill in. + */ +extern void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd, + struct s3c_sdhci_platdata *set); + +/** + * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device. + * @pd: Platform data to register to device. + * + * Register the given platform data for use withe S3C SDHCI device. + * The call will copy the platform data, so the board definitions can + * make the structure itself __initdata. + */ +extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd); +extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd); +extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd); +extern void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd); + +/* Default platform data, exported so that per-cpu initialisation can + * set the correct one when there are more than one cpu type selected. +*/ + +extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata; +extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata; +extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata; +extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata; + +/* Helper function availability */ + +extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w); +extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w); +extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w); +extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w); +extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w); + +/* S3C2416 SDHCI setup */ + +#ifdef CONFIG_S3C2416_SETUP_SDHCI +static inline void s3c2416_default_sdhci0(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC + s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio; +#endif /* CONFIG_S3C_DEV_HSMMC */ +} + +static inline void s3c2416_default_sdhci1(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC1 + s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio; +#endif /* CONFIG_S3C_DEV_HSMMC1 */ +} + +#else +static inline void s3c2416_default_sdhci0(void) { } +static inline void s3c2416_default_sdhci1(void) { } + +#endif /* CONFIG_S3C2416_SETUP_SDHCI */ + +/* S3C64XX SDHCI setup */ + +#ifdef CONFIG_S3C64XX_SETUP_SDHCI +static inline void s3c6400_default_sdhci0(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC + s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; +#endif +} + +static inline void s3c6400_default_sdhci1(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC1 + s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; +#endif +} + +static inline void s3c6400_default_sdhci2(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC2 + s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; +#endif +} + +static inline void s3c6410_default_sdhci0(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC + s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; +#endif +} + +static inline void s3c6410_default_sdhci1(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC1 + s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; +#endif +} + +static inline void s3c6410_default_sdhci2(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC2 + s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; +#endif +} + +#else +static inline void s3c6410_default_sdhci0(void) { } +static inline void s3c6410_default_sdhci1(void) { } +static inline void s3c6410_default_sdhci2(void) { } +static inline void s3c6400_default_sdhci0(void) { } +static inline void s3c6400_default_sdhci1(void) { } +static inline void s3c6400_default_sdhci2(void) { } + +#endif /* CONFIG_S3C64XX_SETUP_SDHCI */ + +static inline void s3c_sdhci_setname(int id, char *name) +{ + switch (id) { +#ifdef CONFIG_S3C_DEV_HSMMC + case 0: + s3c_device_hsmmc0.name = name; + break; +#endif +#ifdef CONFIG_S3C_DEV_HSMMC1 + case 1: + s3c_device_hsmmc1.name = name; + break; +#endif +#ifdef CONFIG_S3C_DEV_HSMMC2 + case 2: + s3c_device_hsmmc2.name = name; + break; +#endif +#ifdef CONFIG_S3C_DEV_HSMMC3 + case 3: + s3c_device_hsmmc3.name = name; + break; +#endif + default: + break; + } +} +#endif /* __PLAT_S3C_SDHCI_H */ diff --git a/arch/arm/mach-s3c/include/plat/usb-phy.h b/arch/arm/mach-s3c/include/plat/usb-phy.h new file mode 100644 index 000000000000..759d66a0773a --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/usb-phy.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + */ + +#ifndef __PLAT_SAMSUNG_USB_PHY_H +#define __PLAT_SAMSUNG_USB_PHY_H __FILE__ + +extern int s3c_usb_phy_init(struct platform_device *pdev, int type); +extern int s3c_usb_phy_exit(struct platform_device *pdev, int type); + +#endif /* __PLAT_SAMSUNG_USB_PHY_H */ diff --git a/arch/arm/mach-s3c/include/plat/wakeup-mask.h b/arch/arm/mach-s3c/include/plat/wakeup-mask.h new file mode 100644 index 000000000000..630909e6630b --- /dev/null +++ b/arch/arm/mach-s3c/include/plat/wakeup-mask.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2010 Ben Dooks + * + * Support for wakeup mask interrupts on newer SoCs + */ + +#ifndef __PLAT_WAKEUP_MASK_H +#define __PLAT_WAKEUP_MASK_H __file__ + +/* if no irq yet defined, but still want to mask */ +#define NO_WAKEUP_IRQ (0x90000000) + +/** + * struct samsung_wakeup_mask - wakeup mask information + * @irq: The interrupt associated with this wakeup. + * @bit: The bit, as a (1 << bitno) controlling this source. + */ +struct samsung_wakeup_mask { + unsigned int irq; + u32 bit; +}; + +/** + * samsung_sync_wakemask - sync wakeup mask information for pm + * @reg: The register that is used. + * @masks: The list of masks to use. + * @nr_masks: The number of entries pointed to buy @masks. + * + * Synchronise the wakeup mask information at suspend time from the list + * of interrupts and control bits in @masks. We do this at suspend time + * as overriding the relevant irq chips is harder and the register is only + * required to be correct before we enter sleep. + */ +extern void samsung_sync_wakemask(void __iomem *reg, + const struct samsung_wakeup_mask *masks, + int nr_masks); + +#endif /* __PLAT_WAKEUP_MASK_H */ diff --git a/arch/arm/mach-s3c/init.c b/arch/arm/mach-s3c/init.c new file mode 100644 index 000000000000..e9acf02ef3c3 --- /dev/null +++ b/arch/arm/mach-s3c/init.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2008 Simtec Electronics +// Ben Dooks +// http://armlinux.simtec.co.uk/ +// +// S3C series CPU initialisation + +/* + * NOTE: Code in this file is not used on S3C64xx when booting with + * Device Tree support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +static struct cpu_table *cpu; + +static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode, + struct cpu_table *tab, + unsigned int count) +{ + for (; count != 0; count--, tab++) { + if ((idcode & tab->idmask) == (tab->idcode & tab->idmask)) + return tab; + } + + return NULL; +} + +void __init s3c_init_cpu(unsigned long idcode, + struct cpu_table *cputab, unsigned int cputab_size) +{ + cpu = s3c_lookup_cpu(idcode, cputab, cputab_size); + + if (cpu == NULL) { + printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode); + panic("Unknown S3C24XX CPU"); + } + + printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); + + if (cpu->init == NULL) { + printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); + panic("Unsupported Samsung CPU"); + } + + if (cpu->map_io) + cpu->map_io(); +} + +/* s3c24xx_init_clocks + * + * Initialise the clock subsystem and associated information from the + * given master crystal value. + * + * xtal = 0 -> use default PLL crystal value (normally 12MHz) + * != 0 -> PLL crystal value in Hz +*/ + +void __init s3c24xx_init_clocks(int xtal) +{ + if (xtal == 0) + xtal = 12*1000*1000; + + if (cpu == NULL) + panic("s3c24xx_init_clocks: no cpu setup?\n"); + + if (cpu->init_clocks == NULL) + panic("s3c24xx_init_clocks: cpu has no clock init\n"); + else + (cpu->init_clocks)(xtal); +} + +/* uart management */ +#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS) +static int nr_uarts __initdata = 0; + +#ifdef CONFIG_SERIAL_SAMSUNG_UARTS +static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS]; +#endif + +/* s3c24xx_init_uartdevs + * + * copy the specified platform data and configuration into our central + * set of devices, before the data is thrown away after the init process. + * + * This also fills in the array passed to the serial driver for the + * early initialisation of the console. +*/ + +void __init s3c24xx_init_uartdevs(char *name, + struct s3c24xx_uart_resources *res, + struct s3c2410_uartcfg *cfg, int no) +{ +#ifdef CONFIG_SERIAL_SAMSUNG_UARTS + struct platform_device *platdev; + struct s3c2410_uartcfg *cfgptr = uart_cfgs; + struct s3c24xx_uart_resources *resp; + int uart; + + memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no); + + for (uart = 0; uart < no; uart++, cfg++, cfgptr++) { + platdev = s3c24xx_uart_src[cfgptr->hwport]; + + resp = res + cfgptr->hwport; + + s3c24xx_uart_devs[uart] = platdev; + + platdev->name = name; + platdev->resource = resp->resources; + platdev->num_resources = resp->nr_resources; + + platdev->dev.platform_data = cfgptr; + } + + nr_uarts = no; +#endif +} + +void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + if (cpu == NULL) + return; + + if (cpu->init_uarts == NULL && IS_ENABLED(CONFIG_SAMSUNG_ATAGS)) { + printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n"); + } else + (cpu->init_uarts)(cfg, no); +} +#endif + +static int __init s3c_arch_init(void) +{ + int ret; + + /* init is only needed for ATAGS based platforms */ + if (!IS_ENABLED(CONFIG_ATAGS) || + (!soc_is_s3c24xx() && !soc_is_s3c64xx())) + return 0; + + // do the correct init for cpu + + if (cpu == NULL) { + /* Not needed when booting with device tree. */ + if (of_have_populated_dt()) + return 0; + panic("s3c_arch_init: NULL cpu\n"); + } + + ret = (cpu->init)(); + if (ret != 0) + return ret; +#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS) + ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts); +#endif + return ret; +} + +arch_initcall(s3c_arch_init); diff --git a/arch/arm/mach-s3c/iotiming-s3c2410.c b/arch/arm/mach-s3c/iotiming-s3c2410.c new file mode 100644 index 000000000000..d91f26efd07a --- /dev/null +++ b/arch/arm/mach-s3c/iotiming-s3c2410.c @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2006-2009 Simtec Electronics +// http://armlinux.simtec.co.uk/ +// Ben Dooks +// +// S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "regs-mem-s3c24xx.h" + +#define print_ns(x) ((x) / 10), ((x) % 10) + +/** + * s3c2410_print_timing - print bank timing data for debug purposes + * @pfx: The prefix to put on the output + * @timings: The timing inforamtion to print. +*/ +static void s3c2410_print_timing(const char *pfx, + struct s3c_iotimings *timings) +{ + struct s3c2410_iobank_timing *bt; + int bank; + + for (bank = 0; bank < MAX_BANKS; bank++) { + bt = timings->bank[bank].io_2410; + if (!bt) + continue; + + printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, " + "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank, + print_ns(bt->tacs), + print_ns(bt->tcos), + print_ns(bt->tacc), + print_ns(bt->tcoh), + print_ns(bt->tcah)); + } +} + +/** + * bank_reg - convert bank number to pointer to the control register. + * @bank: The IO bank number. + */ +static inline void __iomem *bank_reg(unsigned int bank) +{ + return S3C2410_BANKCON0 + (bank << 2); +} + +/** + * bank_is_io - test whether bank is used for IO + * @bankcon: The bank control register. + * + * This is a simplistic test to see if any BANKCON[x] is not an IO + * bank. It currently does not take into account whether BWSCON has + * an illegal width-setting in it, or if the pin connected to nCS[x] + * is actually being handled as a chip-select. + */ +static inline int bank_is_io(unsigned long bankcon) +{ + return !(bankcon & S3C2410_BANKCON_SDRAM); +} + +/** + * to_div - convert cycle time to divisor + * @cyc: The cycle time, in 10ths of nanoseconds. + * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. + * + * Convert the given cycle time into the divisor to use to obtain it from + * HCLK. +*/ +static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns) +{ + if (cyc == 0) + return 0; + + return DIV_ROUND_UP(cyc, hclk_tns); +} + +/** + * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4 + * @cyc: The cycle time, in 10ths of nanoseconds. + * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. + * @v: Pointer to register to alter. + * @shift: The shift to get to the control bits. + * + * Calculate the divisor, and turn it into the correct control bits to + * set in the result, @v. + */ +static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns, + unsigned long *v, int shift) +{ + unsigned int div = to_div(cyc, hclk_tns); + unsigned long val; + + s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n", + __func__, cyc, hclk_tns, shift, div); + + switch (div) { + case 0: + val = 0; + break; + case 1: + val = 1; + break; + case 2: + val = 2; + break; + case 3: + case 4: + val = 3; + break; + default: + return -1; + } + + *v |= val << shift; + return 0; +} + +static int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v) +{ + /* Currently no support for Tacp calculations. */ + return 0; +} + +/** + * calc_tacc - calculate divisor control for tacc. + * @cyc: The cycle time, in 10ths of nanoseconds. + * @nwait_en: IS nWAIT enabled for this bank. + * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. + * @v: Pointer to register to alter. + * + * Calculate the divisor control for tACC, taking into account whether + * the bank has nWAIT enabled. The result is used to modify the value + * pointed to by @v. +*/ +static int calc_tacc(unsigned int cyc, int nwait_en, + unsigned long hclk_tns, unsigned long *v) +{ + unsigned int div = to_div(cyc, hclk_tns); + unsigned long val; + + s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n", + __func__, cyc, nwait_en, hclk_tns, div); + + /* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */ + if (nwait_en && div < 4) + div = 4; + + switch (div) { + case 0: + val = 0; + break; + + case 1: + case 2: + case 3: + case 4: + val = div - 1; + break; + + case 5: + case 6: + val = 4; + break; + + case 7: + case 8: + val = 5; + break; + + case 9: + case 10: + val = 6; + break; + + case 11: + case 12: + case 13: + case 14: + val = 7; + break; + + default: + return -1; + } + + *v |= val << 8; + return 0; +} + +/** + * s3c2410_calc_bank - calculate bank timing information + * @cfg: The configuration we need to calculate for. + * @bt: The bank timing information. + * + * Given the cycle timine for a bank @bt, calculate the new BANKCON + * setting for the @cfg timing. This updates the timing information + * ready for the cpu frequency change. + */ +static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg, + struct s3c2410_iobank_timing *bt) +{ + unsigned long hclk = cfg->freq.hclk_tns; + unsigned long res; + int ret; + + res = bt->bankcon; + res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16); + + /* tacp: 2,3,4,5 */ + /* tcah: 0,1,2,4 */ + /* tcoh: 0,1,2,4 */ + /* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */ + /* tcos: 0,1,2,4 */ + /* tacs: 0,1,2,4 */ + + ret = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT); + ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT); + ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT); + ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT); + + if (ret) + return -EINVAL; + + ret |= calc_tacp(bt->tacp, hclk, &res); + ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res); + + if (ret) + return -EINVAL; + + bt->bankcon = res; + return 0; +} + +static const unsigned int tacc_tab[] = { + [0] = 1, + [1] = 2, + [2] = 3, + [3] = 4, + [4] = 6, + [5] = 9, + [6] = 10, + [7] = 14, +}; + +/** + * get_tacc - turn tACC value into cycle time + * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. + * @val: The bank timing register value, shifed down. + */ +static unsigned int get_tacc(unsigned long hclk_tns, + unsigned long val) +{ + val &= 7; + return hclk_tns * tacc_tab[val]; +} + +/** + * get_0124 - turn 0/1/2/4 divider into cycle time + * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. + * @val: The bank timing register value, shifed down. + */ +static unsigned int get_0124(unsigned long hclk_tns, + unsigned long val) +{ + val &= 3; + return hclk_tns * ((val == 3) ? 4 : val); +} + +/** + * s3c2410_iotiming_getbank - turn BANKCON into cycle time information + * @cfg: The frequency configuration + * @bt: The bank timing to fill in (uses cached BANKCON) + * + * Given the BANKCON setting in @bt and the current frequency settings + * in @cfg, update the cycle timing information. + */ +static void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg, + struct s3c2410_iobank_timing *bt) +{ + unsigned long bankcon = bt->bankcon; + unsigned long hclk = cfg->freq.hclk_tns; + + bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT); + bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT); + bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT); + bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT); + bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT); +} + +/** + * s3c2410_iotiming_debugfs - debugfs show io bank timing information + * @seq: The seq_file to write output to using seq_printf(). + * @cfg: The current configuration. + * @iob: The IO bank information to decode. + */ +void s3c2410_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob) +{ + struct s3c2410_iobank_timing *bt = iob->io_2410; + unsigned long bankcon = bt->bankcon; + unsigned long hclk = cfg->freq.hclk_tns; + unsigned int tacs; + unsigned int tcos; + unsigned int tacc; + unsigned int tcoh; + unsigned int tcah; + + seq_printf(seq, "BANKCON=0x%08lx\n", bankcon); + + tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT); + tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT); + tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT); + tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT); + tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT); + + seq_printf(seq, + "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n", + print_ns(bt->tacs), + print_ns(bt->tcos), + print_ns(bt->tacc), + print_ns(bt->tcoh), + print_ns(bt->tcah)); + + seq_printf(seq, + "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n", + print_ns(tacs), + print_ns(tcos), + print_ns(tacc), + print_ns(tcoh), + print_ns(tcah)); +} + +/** + * s3c2410_iotiming_calc - Calculate bank timing for frequency change. + * @cfg: The frequency configuration + * @iot: The IO timing information to fill out. + * + * Calculate the new values for the banks in @iot based on the new + * frequency information in @cfg. This is then used by s3c2410_iotiming_set() + * to update the timing when necessary. + */ +int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot) +{ + struct s3c2410_iobank_timing *bt; + unsigned long bankcon; + int bank; + int ret; + + for (bank = 0; bank < MAX_BANKS; bank++) { + bankcon = __raw_readl(bank_reg(bank)); + bt = iot->bank[bank].io_2410; + + if (!bt) + continue; + + bt->bankcon = bankcon; + + ret = s3c2410_calc_bank(cfg, bt); + if (ret) { + printk(KERN_ERR "%s: cannot calculate bank %d io\n", + __func__, bank); + goto err; + } + + s3c_freq_iodbg("%s: bank %d: con=%08lx\n", + __func__, bank, bt->bankcon); + } + + return 0; + err: + return ret; +} + +/** + * s3c2410_iotiming_set - set the IO timings from the given setup. + * @cfg: The frequency configuration + * @iot: The IO timing information to use. + * + * Set all the currently used IO bank timing information generated + * by s3c2410_iotiming_calc() once the core has validated that all + * the new values are within permitted bounds. + */ +void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot) +{ + struct s3c2410_iobank_timing *bt; + int bank; + + /* set the io timings from the specifier */ + + for (bank = 0; bank < MAX_BANKS; bank++) { + bt = iot->bank[bank].io_2410; + if (!bt) + continue; + + __raw_writel(bt->bankcon, bank_reg(bank)); + } +} + +/** + * s3c2410_iotiming_get - Get the timing information from current registers. + * @cfg: The frequency configuration + * @timings: The IO timing information to fill out. + * + * Calculate the @timings timing information from the current frequency + * information in @cfg, and the new frequency configuration + * through all the IO banks, reading the state and then updating @iot + * as necessary. + * + * This is used at the moment on initialisation to get the current + * configuration so that boards do not have to carry their own setup + * if the timings are correct on initialisation. + */ + +int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings) +{ + struct s3c2410_iobank_timing *bt; + unsigned long bankcon; + unsigned long bwscon; + int bank; + + bwscon = __raw_readl(S3C2410_BWSCON); + + /* look through all banks to see what is currently set. */ + + for (bank = 0; bank < MAX_BANKS; bank++) { + bankcon = __raw_readl(bank_reg(bank)); + + if (!bank_is_io(bankcon)) + continue; + + s3c_freq_iodbg("%s: bank %d: con %08lx\n", + __func__, bank, bankcon); + + bt = kzalloc(sizeof(*bt), GFP_KERNEL); + if (!bt) + return -ENOMEM; + + /* find out in nWait is enabled for bank. */ + + if (bank != 0) { + unsigned long tmp = S3C2410_BWSCON_GET(bwscon, bank); + if (tmp & S3C2410_BWSCON_WS) + bt->nwait_en = 1; + } + + timings->bank[bank].io_2410 = bt; + bt->bankcon = bankcon; + + s3c2410_iotiming_getbank(cfg, bt); + } + + s3c2410_print_timing("get", timings); + return 0; +} diff --git a/arch/arm/mach-s3c/iotiming-s3c2412.c b/arch/arm/mach-s3c/iotiming-s3c2412.c new file mode 100644 index 000000000000..a22b5611697d --- /dev/null +++ b/arch/arm/mach-s3c/iotiming-s3c2412.c @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2006-2008 Simtec Electronics +// http://armlinux.simtec.co.uk/ +// Ben Dooks +// +// S3C2412/S3C2443 (PL093 based) IO timing support + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +#define print_ns(x) ((x) / 10), ((x) % 10) + +/** + * s3c2412_print_timing - print timing information via printk. + * @pfx: The prefix to print each line with. + * @iot: The IO timing information + */ +static void s3c2412_print_timing(const char *pfx, struct s3c_iotimings *iot) +{ + struct s3c2412_iobank_timing *bt; + unsigned int bank; + + for (bank = 0; bank < MAX_BANKS; bank++) { + bt = iot->bank[bank].io_2412; + if (!bt) + continue; + + printk(KERN_DEBUG "%s: %d: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d" + "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", pfx, bank, + print_ns(bt->idcy), + print_ns(bt->wstrd), + print_ns(bt->wstwr), + print_ns(bt->wstoen), + print_ns(bt->wstwen), + print_ns(bt->wstbrd)); + } +} + +/** + * to_div - turn a cycle length into a divisor setting. + * @cyc_tns: The cycle time in 10ths of nanoseconds. + * @clk_tns: The clock period in 10ths of nanoseconds. + */ +static inline unsigned int to_div(unsigned int cyc_tns, unsigned int clk_tns) +{ + return cyc_tns ? DIV_ROUND_UP(cyc_tns, clk_tns) : 0; +} + +/** + * calc_timing - calculate timing divisor value and check in range. + * @hwtm: The hardware timing in 10ths of nanoseconds. + * @clk_tns: The clock period in 10ths of nanoseconds. + * @err: Pointer to err variable to update in event of failure. + */ +static unsigned int calc_timing(unsigned int hwtm, unsigned int clk_tns, + unsigned int *err) +{ + unsigned int ret = to_div(hwtm, clk_tns); + + if (ret > 0xf) + *err = -EINVAL; + + return ret; +} + +/** + * s3c2412_calc_bank - calculate the bank divisor settings. + * @cfg: The current frequency configuration. + * @bt: The bank timing. + */ +static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg, + struct s3c2412_iobank_timing *bt) +{ + unsigned int hclk = cfg->freq.hclk_tns; + int err = 0; + + bt->smbidcyr = calc_timing(bt->idcy, hclk, &err); + bt->smbwstrd = calc_timing(bt->wstrd, hclk, &err); + bt->smbwstwr = calc_timing(bt->wstwr, hclk, &err); + bt->smbwstoen = calc_timing(bt->wstoen, hclk, &err); + bt->smbwstwen = calc_timing(bt->wstwen, hclk, &err); + bt->smbwstbrd = calc_timing(bt->wstbrd, hclk, &err); + + return err; +} + +/** + * s3c2412_iotiming_debugfs - debugfs show io bank timing information + * @seq: The seq_file to write output to using seq_printf(). + * @cfg: The current configuration. + * @iob: The IO bank information to decode. +*/ +void s3c2412_iotiming_debugfs(struct seq_file *seq, + struct s3c_cpufreq_config *cfg, + union s3c_iobank *iob) +{ + struct s3c2412_iobank_timing *bt = iob->io_2412; + + seq_printf(seq, + "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d" + "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", + print_ns(bt->idcy), + print_ns(bt->wstrd), + print_ns(bt->wstwr), + print_ns(bt->wstoen), + print_ns(bt->wstwen), + print_ns(bt->wstbrd)); +} + +/** + * s3c2412_iotiming_calc - calculate all the bank divisor settings. + * @cfg: The current frequency configuration. + * @iot: The bank timing information. + * + * Calculate the timing information for all the banks that are + * configured as IO, using s3c2412_calc_bank(). + */ +int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot) +{ + struct s3c2412_iobank_timing *bt; + int bank; + int ret; + + for (bank = 0; bank < MAX_BANKS; bank++) { + bt = iot->bank[bank].io_2412; + if (!bt) + continue; + + ret = s3c2412_calc_bank(cfg, bt); + if (ret) { + printk(KERN_ERR "%s: cannot calculate bank %d io\n", + __func__, bank); + goto err; + } + } + + return 0; + err: + return ret; +} + +/** + * s3c2412_iotiming_set - set the timing information + * @cfg: The current frequency configuration. + * @iot: The bank timing information. + * + * Set the IO bank information from the details calculated earlier from + * calling s3c2412_iotiming_calc(). + */ +void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *iot) +{ + struct s3c2412_iobank_timing *bt; + void __iomem *regs; + int bank; + + /* set the io timings from the specifier */ + + for (bank = 0; bank < MAX_BANKS; bank++) { + bt = iot->bank[bank].io_2412; + if (!bt) + continue; + + regs = S3C2412_SSMC_BANK(bank); + + __raw_writel(bt->smbidcyr, regs + SMBIDCYR); + __raw_writel(bt->smbwstrd, regs + SMBWSTRDR); + __raw_writel(bt->smbwstwr, regs + SMBWSTWRR); + __raw_writel(bt->smbwstoen, regs + SMBWSTOENR); + __raw_writel(bt->smbwstwen, regs + SMBWSTWENR); + __raw_writel(bt->smbwstbrd, regs + SMBWSTBRDR); + } +} + +static inline unsigned int s3c2412_decode_timing(unsigned int clock, u32 reg) +{ + return (reg & 0xf) * clock; +} + +static void s3c2412_iotiming_getbank(struct s3c_cpufreq_config *cfg, + struct s3c2412_iobank_timing *bt, + unsigned int bank) +{ + unsigned long clk = cfg->freq.hclk_tns; /* ssmc clock??? */ + void __iomem *regs = S3C2412_SSMC_BANK(bank); + + bt->idcy = s3c2412_decode_timing(clk, __raw_readl(regs + SMBIDCYR)); + bt->wstrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTRDR)); + bt->wstoen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTOENR)); + bt->wstwen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTWENR)); + bt->wstbrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTBRDR)); +} + +/** + * bank_is_io - return true if bank is (possibly) IO. + * @bank: The bank number. + * @bankcfg: The value of S3C2412_EBI_BANKCFG. + */ +static inline bool bank_is_io(unsigned int bank, u32 bankcfg) +{ + if (bank < 2) + return true; + + return !(bankcfg & (1 << bank)); +} + +int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg, + struct s3c_iotimings *timings) +{ + struct s3c2412_iobank_timing *bt; + u32 bankcfg = __raw_readl(S3C2412_EBI_BANKCFG); + unsigned int bank; + + /* look through all banks to see what is currently set. */ + + for (bank = 0; bank < MAX_BANKS; bank++) { + if (!bank_is_io(bank, bankcfg)) + continue; + + bt = kzalloc(sizeof(*bt), GFP_KERNEL); + if (!bt) + return -ENOMEM; + + timings->bank[bank].io_2412 = bt; + s3c2412_iotiming_getbank(cfg, bt, bank); + } + + s3c2412_print_timing("get", timings); + return 0; +} + +/* this is in here as it is so small, it doesn't currently warrant a file + * to itself. We expect that any s3c24xx needing this is going to also + * need the iotiming support. + */ +void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) +{ + struct s3c_cpufreq_board *board = cfg->board; + u32 refresh; + + WARN_ON(board == NULL); + + /* Reduce both the refresh time (in ns) and the frequency (in MHz) + * down to ensure that we do not overflow 32 bit numbers. + * + * This should work for HCLK up to 133MHz and refresh period up + * to 30usec. + */ + + refresh = (cfg->freq.hclk / 100) * (board->refresh / 10); + refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */ + refresh &= ((1 << 16) - 1); + + s3c_freq_dbg("%s: refresh value %u\n", __func__, (unsigned int)refresh); + + __raw_writel(refresh, S3C2412_REFRESH); +} diff --git a/arch/arm/mach-s3c/irq-pm-s3c24xx.c b/arch/arm/mach-s3c/irq-pm-s3c24xx.c new file mode 100644 index 000000000000..e0131b16a4af --- /dev/null +++ b/arch/arm/mach-s3c/irq-pm-s3c24xx.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2003-2004 Simtec Electronics +// Ben Dooks +// http://armlinux.simtec.co.uk/ +// +// S3C24XX - IRQ PM code + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +int s3c_irq_wake(struct irq_data *data, unsigned int state) +{ + unsigned long irqbit = 1 << data->hwirq; + + if (!(s3c_irqwake_intallow & irqbit)) + return -ENOENT; + + pr_info("wake %s for hwirq %lu\n", + state ? "enabled" : "disabled", data->hwirq); + + if (!state) + s3c_irqwake_intmask |= irqbit; + else + s3c_irqwake_intmask &= ~irqbit; + + return 0; +} + +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C2410_INTMSK), + SAVE_ITEM(S3C2410_INTSUBMSK), +}; + +/* the extint values move between the s3c2410/s3c2440 and the s3c2412 + * so we use an array to hold them, and to calculate the address of + * the register at run-time +*/ + +static unsigned long save_extint[3]; +static unsigned long save_eintflt[4]; +static unsigned long save_eintmask; + +static int s3c24xx_irq_suspend(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(save_extint); i++) + save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); + + for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) + save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); + + s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); + save_eintmask = __raw_readl(S3C24XX_EINTMASK); + + return 0; +} + +static void s3c24xx_irq_resume(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(save_extint); i++) + __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); + + for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) + __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); + + s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); + __raw_writel(save_eintmask, S3C24XX_EINTMASK); +} + +struct syscore_ops s3c24xx_irq_syscore_ops = { + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, +}; + +#ifdef CONFIG_CPU_S3C2416 +static struct sleep_save s3c2416_irq_save[] = { + SAVE_ITEM(S3C2416_INTMSK2), +}; + +static int s3c2416_irq_suspend(void) +{ + s3c_pm_do_save(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save)); + + return 0; +} + +static void s3c2416_irq_resume(void) +{ + s3c_pm_do_restore(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save)); +} + +struct syscore_ops s3c2416_irq_syscore_ops = { + .suspend = s3c2416_irq_suspend, + .resume = s3c2416_irq_resume, +}; +#endif diff --git a/arch/arm/mach-s3c/irq-pm-s3c64xx.c b/arch/arm/mach-s3c/irq-pm-s3c64xx.c new file mode 100644 index 000000000000..31b221190479 --- /dev/null +++ b/arch/arm/mach-s3c/irq-pm-s3c64xx.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2008 Openmoko, Inc. +// Copyright 2008 Simtec Electronics +// Ben Dooks +// http://armlinux.simtec.co.uk/ +// +// S3C64XX - Interrupt handling Power Management + +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +/* We handled all the IRQ types in this code, to save having to make several + * small files to handle each different type separately. Having the EINT_GRP + * code here shouldn't be as much bloat as the IRQ table space needed when + * they are enabled. The added benefit is we ensure that these registers are + * in the same state as we suspended. + */ + +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C64XX_PRIORITY), + SAVE_ITEM(S3C64XX_EINT0CON0), + SAVE_ITEM(S3C64XX_EINT0CON1), + SAVE_ITEM(S3C64XX_EINT0FLTCON0), + SAVE_ITEM(S3C64XX_EINT0FLTCON1), + SAVE_ITEM(S3C64XX_EINT0FLTCON2), + SAVE_ITEM(S3C64XX_EINT0FLTCON3), + SAVE_ITEM(S3C64XX_EINT0MASK), +}; + +static struct irq_grp_save { + u32 fltcon; + u32 con; + u32 mask; +} eint_grp_save[5]; + +#ifndef CONFIG_SERIAL_SAMSUNG_UARTS +#define SERIAL_SAMSUNG_UARTS 0 +#else +#define SERIAL_SAMSUNG_UARTS CONFIG_SERIAL_SAMSUNG_UARTS +#endif + +static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS]; + +static int s3c64xx_irq_pm_suspend(void) +{ + struct irq_grp_save *grp = eint_grp_save; + int i; + + S3C_PMDBG("%s: suspending IRQs\n", __func__); + + s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); + + for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++) + irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM); + + for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { + grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4)); + grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4)); + grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4)); + } + + return 0; +} + +static void s3c64xx_irq_pm_resume(void) +{ + struct irq_grp_save *grp = eint_grp_save; + int i; + + S3C_PMDBG("%s: resuming IRQs\n", __func__); + + s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); + + for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++) + __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM); + + for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { + __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4)); + __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4)); + __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4)); + } + + S3C_PMDBG("%s: IRQ configuration restored\n", __func__); +} + +static struct syscore_ops s3c64xx_irq_syscore_ops = { + .suspend = s3c64xx_irq_pm_suspend, + .resume = s3c64xx_irq_pm_resume, +}; + +static __init int s3c64xx_syscore_init(void) +{ + /* Appropriate drivers (pinctrl, uart) handle this when using DT. */ + if (of_have_populated_dt() || !soc_is_s3c64xx()) + return 0; + + register_syscore_ops(&s3c64xx_irq_syscore_ops); + + return 0; +} + +core_initcall(s3c64xx_syscore_init); diff --git a/arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c b/arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c new file mode 100644 index 000000000000..84cf86376ded --- /dev/null +++ b/arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include + +EXPORT_SYMBOL(s3c24xx_spi_fiq_rx); +EXPORT_SYMBOL(s3c24xx_spi_fiq_txrx); +EXPORT_SYMBOL(s3c24xx_spi_fiq_tx); diff --git a/arch/arm/mach-s3c/irq-s3c24xx-fiq.S b/arch/arm/mach-s3c/irq-s3c24xx-fiq.S new file mode 100644 index 000000000000..2a84535a14fd --- /dev/null +++ b/arch/arm/mach-s3c/irq-s3c24xx-fiq.S @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* linux/drivers/spi/spi_s3c24xx_fiq.S + * + * Copyright 2009 Simtec Electronics + * Ben Dooks + * + * S3C24XX SPI - FIQ pseudo-DMA transfer code +*/ + +#include +#include + +#include +#include + +#include + +#define S3C2410_SPTDAT (0x10) +#define S3C2410_SPRDAT (0x14) + + .text + + @ entry to these routines is as follows, with the register names + @ defined in fiq.h so that they can be shared with the C files which + @ setup the calling registers. + @ + @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND + @ fiq_rtmp Temporary register to hold tx/rx data + @ fiq_rspi The base of the SPI register block + @ fiq_rtx The tx buffer pointer + @ fiq_rrx The rx buffer pointer + @ fiq_rcount The number of bytes to move + + @ each entry starts with a word entry of how long it is + @ and an offset to the irq acknowledgment word + +ENTRY(s3c24xx_spi_fiq_rx) +s3c24xx_spi_fix_rx: + .word fiq_rx_end - fiq_rx_start + .word fiq_rx_irq_ack - fiq_rx_start +fiq_rx_start: + ldr fiq_rtmp, fiq_rx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + mov fiq_rtmp, #0xff + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + @@ set IRQ controller so that next op will trigger IRQ + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_rx_irq_ack: + .word 0 +fiq_rx_end: + +ENTRY(s3c24xx_spi_fiq_txrx) +s3c24xx_spi_fiq_txrx: + .word fiq_txrx_end - fiq_txrx_start + .word fiq_txrx_irq_ack - fiq_txrx_start +fiq_txrx_start: + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + ldr fiq_rtmp, fiq_txrx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_txrx_irq_ack: + .word 0 + +fiq_txrx_end: + +ENTRY(s3c24xx_spi_fiq_tx) +s3c24xx_spi_fix_tx: + .word fiq_tx_end - fiq_tx_start + .word fiq_tx_irq_ack - fiq_tx_start +fiq_tx_start: + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + + ldr fiq_rtmp, fiq_tx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_tx_irq_ack: + .word 0 + +fiq_tx_end: + + .end diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c new file mode 100644 index 000000000000..3965347cacf0 --- /dev/null +++ b/arch/arm/mach-s3c/irq-s3c24xx.c @@ -0,0 +1,1337 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * S3C24XX IRQ handling + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * Copyright (c) 2012 Heiko Stuebner +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define S3C_IRQTYPE_NONE 0 +#define S3C_IRQTYPE_EINT 1 +#define S3C_IRQTYPE_EDGE 2 +#define S3C_IRQTYPE_LEVEL 3 + +struct s3c_irq_data { + unsigned int type; + unsigned long offset; + unsigned long parent_irq; + + /* data gets filled during init */ + struct s3c_irq_intc *intc; + unsigned long sub_bits; + struct s3c_irq_intc *sub_intc; +}; + +/* + * Structure holding the controller data + * @reg_pending register holding pending irqs + * @reg_intpnd special register intpnd in main intc + * @reg_mask mask register + * @domain irq_domain of the controller + * @parent parent controller for ext and sub irqs + * @irqs irq-data, always s3c_irq_data[32] + */ +struct s3c_irq_intc { + void __iomem *reg_pending; + void __iomem *reg_intpnd; + void __iomem *reg_mask; + struct irq_domain *domain; + struct s3c_irq_intc *parent; + struct s3c_irq_data *irqs; +}; + +/* + * Array holding pointers to the global controller structs + * [0] ... main_intc + * [1] ... sub_intc + * [2] ... main_intc2 on s3c2416 + */ +static struct s3c_irq_intc *s3c_intc[3]; + +static void s3c_irq_mask(struct irq_data *data) +{ + struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data); + struct s3c_irq_intc *intc = irq_data->intc; + struct s3c_irq_intc *parent_intc = intc->parent; + struct s3c_irq_data *parent_data; + unsigned long mask; + unsigned int irqno; + + mask = readl_relaxed(intc->reg_mask); + mask |= (1UL << irq_data->offset); + writel_relaxed(mask, intc->reg_mask); + + if (parent_intc) { + parent_data = &parent_intc->irqs[irq_data->parent_irq]; + + /* check to see if we need to mask the parent IRQ + * The parent_irq is always in main_intc, so the hwirq + * for find_mapping does not need an offset in any case. + */ + if ((mask & parent_data->sub_bits) == parent_data->sub_bits) { + irqno = irq_find_mapping(parent_intc->domain, + irq_data->parent_irq); + s3c_irq_mask(irq_get_irq_data(irqno)); + } + } +} + +static void s3c_irq_unmask(struct irq_data *data) +{ + struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data); + struct s3c_irq_intc *intc = irq_data->intc; + struct s3c_irq_intc *parent_intc = intc->parent; + unsigned long mask; + unsigned int irqno; + + mask = readl_relaxed(intc->reg_mask); + mask &= ~(1UL << irq_data->offset); + writel_relaxed(mask, intc->reg_mask); + + if (parent_intc) { + irqno = irq_find_mapping(parent_intc->domain, + irq_data->parent_irq); + s3c_irq_unmask(irq_get_irq_data(irqno)); + } +} + +static inline void s3c_irq_ack(struct irq_data *data) +{ + struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data); + struct s3c_irq_intc *intc = irq_data->intc; + unsigned long bitval = 1UL << irq_data->offset; + + writel_relaxed(bitval, intc->reg_pending); + if (intc->reg_intpnd) + writel_relaxed(bitval, intc->reg_intpnd); +} + +static int s3c_irq_type(struct irq_data *data, unsigned int type) +{ + switch (type) { + case IRQ_TYPE_NONE: + break; + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_BOTH: + irq_set_handler(data->irq, handle_edge_irq); + break; + case IRQ_TYPE_LEVEL_LOW: + case IRQ_TYPE_LEVEL_HIGH: + irq_set_handler(data->irq, handle_level_irq); + break; + default: + pr_err("No such irq type %d\n", type); + return -EINVAL; + } + + return 0; +} + +static int s3c_irqext_type_set(void __iomem *gpcon_reg, + void __iomem *extint_reg, + unsigned long gpcon_offset, + unsigned long extint_offset, + unsigned int type) +{ + unsigned long newvalue = 0, value; + + /* Set the GPIO to external interrupt mode */ + value = readl_relaxed(gpcon_reg); + value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset); + writel_relaxed(value, gpcon_reg); + + /* Set the external interrupt to pointed trigger type */ + switch (type) + { + case IRQ_TYPE_NONE: + pr_warn("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: + pr_err("No such irq type %d\n", type); + return -EINVAL; + } + + value = readl_relaxed(extint_reg); + value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset); + writel_relaxed(value, extint_reg); + + return 0; +} + +static int s3c_irqext_type(struct irq_data *data, unsigned int type) +{ + void __iomem *extint_reg; + void __iomem *gpcon_reg; + unsigned long gpcon_offset, extint_offset; + + if ((data->hwirq >= 4) && (data->hwirq <= 7)) { + gpcon_reg = S3C2410_GPFCON; + extint_reg = S3C24XX_EXTINT0; + gpcon_offset = (data->hwirq) * 2; + extint_offset = (data->hwirq) * 4; + } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) { + gpcon_reg = S3C2410_GPGCON; + extint_reg = S3C24XX_EXTINT1; + gpcon_offset = (data->hwirq - 8) * 2; + extint_offset = (data->hwirq - 8) * 4; + } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) { + gpcon_reg = S3C2410_GPGCON; + extint_reg = S3C24XX_EXTINT2; + gpcon_offset = (data->hwirq - 8) * 2; + extint_offset = (data->hwirq - 16) * 4; + } else { + return -EINVAL; + } + + return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset, + extint_offset, type); +} + +static int s3c_irqext0_type(struct irq_data *data, unsigned int type) +{ + void __iomem *extint_reg; + void __iomem *gpcon_reg; + unsigned long gpcon_offset, extint_offset; + + if (data->hwirq <= 3) { + gpcon_reg = S3C2410_GPFCON; + extint_reg = S3C24XX_EXTINT0; + gpcon_offset = (data->hwirq) * 2; + extint_offset = (data->hwirq) * 4; + } else { + return -EINVAL; + } + + return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset, + extint_offset, type); +} + +static struct irq_chip s3c_irq_chip = { + .name = "s3c", + .irq_ack = s3c_irq_ack, + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_set_type = s3c_irq_type, + .irq_set_wake = s3c_irq_wake +}; + +static struct irq_chip s3c_irq_level_chip = { + .name = "s3c-level", + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_ack = s3c_irq_ack, + .irq_set_type = s3c_irq_type, +}; + +static struct irq_chip s3c_irqext_chip = { + .name = "s3c-ext", + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_ack = s3c_irq_ack, + .irq_set_type = s3c_irqext_type, + .irq_set_wake = s3c_irqext_wake +}; + +static struct irq_chip s3c_irq_eint0t4 = { + .name = "s3c-ext0", + .irq_ack = s3c_irq_ack, + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_set_wake = s3c_irq_wake, + .irq_set_type = s3c_irqext0_type, +}; + +static void s3c_irq_demux(struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); + struct s3c_irq_intc *intc = irq_data->intc; + struct s3c_irq_intc *sub_intc = irq_data->sub_intc; + unsigned int n, offset, irq; + unsigned long src, msk; + + /* we're using individual domains for the non-dt case + * and one big domain for the dt case where the subintc + * starts at hwirq number 32. + */ + offset = irq_domain_get_of_node(intc->domain) ? 32 : 0; + + chained_irq_enter(chip, desc); + + src = readl_relaxed(sub_intc->reg_pending); + msk = readl_relaxed(sub_intc->reg_mask); + + src &= ~msk; + src &= irq_data->sub_bits; + + while (src) { + n = __ffs(src); + src &= ~(1 << n); + irq = irq_find_mapping(sub_intc->domain, offset + n); + generic_handle_irq(irq); + } + + chained_irq_exit(chip, desc); +} + +static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, + struct pt_regs *regs, int intc_offset) +{ + int pnd; + int offset; + + pnd = readl_relaxed(intc->reg_intpnd); + if (!pnd) + return false; + + /* non-dt machines use individual domains */ + if (!irq_domain_get_of_node(intc->domain)) + intc_offset = 0; + + /* We have a problem that the INTOFFSET register does not always + * show one interrupt. Occasionally we get two interrupts through + * the prioritiser, and this causes the INTOFFSET register to show + * what looks like the logical-or of the two interrupt numbers. + * + * Thanks to Klaus, Shannon, et al for helping to debug this problem + */ + offset = readl_relaxed(intc->reg_intpnd + 4); + + /* Find the bit manually, when the offset is wrong. + * The pending register only ever contains the one bit of the next + * interrupt to handle. + */ + if (!(pnd & (1 << offset))) + offset = __ffs(pnd); + + handle_domain_irq(intc->domain, intc_offset + offset, regs); + return true; +} + +asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) +{ + do { + if (likely(s3c_intc[0])) + if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) + continue; + + if (s3c_intc[2]) + if (s3c24xx_handle_intc(s3c_intc[2], regs, 64)) + continue; + + break; + } while (1); +} + +#ifdef CONFIG_FIQ +/** + * s3c24xx_set_fiq - set the FIQ routing + * @irq: IRQ number to route to FIQ on processor. + * @ack_ptr: pointer to a location for storing the bit mask + * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing. + * + * Change the state of the IRQ to FIQ routing depending on @irq and @on. If + * @on is true, the @irq is checked to see if it can be routed and the + * interrupt controller updated to route the IRQ. If @on is false, the FIQ + * routing is cleared, regardless of which @irq is specified. + * + * returns the mask value for the register. + */ +int s3c24xx_set_fiq(unsigned int irq, u32 *ack_ptr, bool on) +{ + u32 intmod; + unsigned offs; + + if (on) { + offs = irq - FIQ_START; + if (offs > 31) + return 0; + + intmod = 1 << offs; + } else { + intmod = 0; + } + + if (ack_ptr) + *ack_ptr = intmod; + writel_relaxed(intmod, S3C2410_INTMOD); + + return intmod; +} + +EXPORT_SYMBOL_GPL(s3c24xx_set_fiq); +#endif + +static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct s3c_irq_intc *intc = h->host_data; + struct s3c_irq_data *irq_data = &intc->irqs[hw]; + struct s3c_irq_intc *parent_intc; + struct s3c_irq_data *parent_irq_data; + unsigned int irqno; + + /* attach controller pointer to irq_data */ + irq_data->intc = intc; + irq_data->offset = hw; + + parent_intc = intc->parent; + + /* set handler and flags */ + switch (irq_data->type) { + case S3C_IRQTYPE_NONE: + return 0; + case S3C_IRQTYPE_EINT: + /* On the S3C2412, the EINT0to3 have a parent irq + * but need the s3c_irq_eint0t4 chip + */ + if (parent_intc && (!soc_is_s3c2412() || hw >= 4)) + irq_set_chip_and_handler(virq, &s3c_irqext_chip, + handle_edge_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_eint0t4, + handle_edge_irq); + break; + case S3C_IRQTYPE_EDGE: + if (parent_intc || intc->reg_pending == S3C2416_SRCPND2) + irq_set_chip_and_handler(virq, &s3c_irq_level_chip, + handle_edge_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_chip, + handle_edge_irq); + break; + case S3C_IRQTYPE_LEVEL: + if (parent_intc) + irq_set_chip_and_handler(virq, &s3c_irq_level_chip, + handle_level_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_chip, + handle_level_irq); + break; + default: + pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type); + return -EINVAL; + } + + irq_set_chip_data(virq, irq_data); + + if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) { + if (irq_data->parent_irq > 31) { + pr_err("irq-s3c24xx: parent irq %lu is out of range\n", + irq_data->parent_irq); + return -EINVAL; + } + + parent_irq_data = &parent_intc->irqs[irq_data->parent_irq]; + parent_irq_data->sub_intc = intc; + parent_irq_data->sub_bits |= (1UL << hw); + + /* attach the demuxer to the parent irq */ + irqno = irq_find_mapping(parent_intc->domain, + irq_data->parent_irq); + if (!irqno) { + pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n", + irq_data->parent_irq); + return -EINVAL; + } + irq_set_chained_handler(irqno, s3c_irq_demux); + } + + return 0; +} + +static const struct irq_domain_ops s3c24xx_irq_ops = { + .map = s3c24xx_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static void s3c24xx_clear_intc(struct s3c_irq_intc *intc) +{ + void __iomem *reg_source; + unsigned long pend; + unsigned long last; + int i; + + /* if intpnd is set, read the next pending irq from there */ + reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending; + + last = 0; + for (i = 0; i < 4; i++) { + pend = readl_relaxed(reg_source); + + if (pend == 0 || pend == last) + break; + + writel_relaxed(pend, intc->reg_pending); + if (intc->reg_intpnd) + writel_relaxed(pend, intc->reg_intpnd); + + pr_info("irq: clearing pending status %08x\n", (int)pend); + last = pend; + } +} + +static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np, + struct s3c_irq_data *irq_data, + struct s3c_irq_intc *parent, + unsigned long address) +{ + struct s3c_irq_intc *intc; + void __iomem *base = (void *)0xf6000000; /* static mapping */ + int irq_num; + int irq_start; + int ret; + + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL); + if (!intc) + return ERR_PTR(-ENOMEM); + + intc->irqs = irq_data; + + if (parent) + intc->parent = parent; + + /* select the correct data for the controller. + * Need to hard code the irq num start and offset + * to preserve the static mapping for now + */ + switch (address) { + case 0x4a000000: + pr_debug("irq: found main intc\n"); + intc->reg_pending = base; + intc->reg_mask = base + 0x08; + intc->reg_intpnd = base + 0x10; + irq_num = 32; + irq_start = S3C2410_IRQ(0); + break; + case 0x4a000018: + pr_debug("irq: found subintc\n"); + intc->reg_pending = base + 0x18; + intc->reg_mask = base + 0x1c; + irq_num = 29; + irq_start = S3C2410_IRQSUB(0); + break; + case 0x4a000040: + pr_debug("irq: found intc2\n"); + intc->reg_pending = base + 0x40; + intc->reg_mask = base + 0x48; + intc->reg_intpnd = base + 0x50; + irq_num = 8; + irq_start = S3C2416_IRQ(0); + break; + case 0x560000a4: + pr_debug("irq: found eintc\n"); + base = (void *)0xfd000000; + + intc->reg_mask = base + 0xa4; + intc->reg_pending = base + 0xa8; + irq_num = 24; + irq_start = S3C2410_IRQ(32); + break; + default: + pr_err("irq: unsupported controller address\n"); + ret = -EINVAL; + goto err; + } + + /* now that all the data is complete, init the irq-domain */ + s3c24xx_clear_intc(intc); + intc->domain = irq_domain_add_legacy(np, irq_num, irq_start, + 0, &s3c24xx_irq_ops, + intc); + if (!intc->domain) { + pr_err("irq: could not create irq-domain\n"); + ret = -EINVAL; + goto err; + } + + set_handle_irq(s3c24xx_handle_irq); + + return intc; + +err: + kfree(intc); + return ERR_PTR(ret); +} + +static struct s3c_irq_data __maybe_unused init_eint[32] = { + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */ +}; + +#ifdef CONFIG_CPU_S3C2410 +static struct s3c_irq_data init_s3c2410base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2410subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ +}; + +void __init s3c2410_init_irq(void) +{ +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2410subint[0], + s3c_intc[0], 0x4a000018); + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); +} +#endif + +#ifdef CONFIG_CPU_S3C2412 +static struct s3c_irq_data init_s3c2412base[32] = { + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2412eint[32] = { + { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */ +}; + +static struct s3c_irq_data init_s3c2412subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_NONE, }, + { .type = S3C_IRQTYPE_NONE, }, + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */ +}; + +void __init s3c2412_init_irq(void) +{ + pr_info("S3C2412: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_s3c2412eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2412subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_CPU_S3C2416 +static struct s3c_irq_data init_s3c2416base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */ + { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* NAND */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_NONE, }, + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2416subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +static struct s3c_irq_data init_s3c2416_second[32] = { + { .type = S3C_IRQTYPE_EDGE }, /* 2D */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */ +}; + +void __init s3c2416_init_irq(void) +{ + pr_info("S3C2416: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2416subint[0], + s3c_intc[0], 0x4a000018); + + s3c_intc[2] = s3c24xx_init_intc(NULL, &init_s3c2416_second[0], + NULL, 0x4a000040); +} + +#endif + +#ifdef CONFIG_CPU_S3C2440 +static struct s3c_irq_data init_s3c2440base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2440subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +void __init s3c2440_init_irq(void) +{ + pr_info("S3C2440: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2440subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_CPU_S3C2442 +static struct s3c_irq_data init_s3c2442base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2442subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */ +}; + +void __init s3c2442_init_irq(void) +{ + pr_info("S3C2442: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2442subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_CPU_S3C2443 +static struct s3c_irq_data init_s3c2443base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */ + { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* CFON */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* NAND */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + + +static struct s3c_irq_data init_s3c2443subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +void __init s3c2443_init_irq(void) +{ + pr_info("S3C2443: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2443subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_OF +static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + unsigned int ctrl_num = hw / 32; + unsigned int intc_hw = hw % 32; + struct s3c_irq_intc *intc = s3c_intc[ctrl_num]; + struct s3c_irq_intc *parent_intc = intc->parent; + struct s3c_irq_data *irq_data = &intc->irqs[intc_hw]; + + /* attach controller pointer to irq_data */ + irq_data->intc = intc; + irq_data->offset = intc_hw; + + if (!parent_intc) + irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_edge_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_level_chip, + handle_edge_irq); + + irq_set_chip_data(virq, irq_data); + + return 0; +} + +/* Translate our of irq notation + * format: + */ +static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type) +{ + struct s3c_irq_intc *intc; + struct s3c_irq_intc *parent_intc; + struct s3c_irq_data *irq_data; + struct s3c_irq_data *parent_irq_data; + int irqno; + + if (WARN_ON(intsize < 4)) + return -EINVAL; + + if (intspec[0] > 2 || !s3c_intc[intspec[0]]) { + pr_err("controller number %d invalid\n", intspec[0]); + return -EINVAL; + } + intc = s3c_intc[intspec[0]]; + + *out_hwirq = intspec[0] * 32 + intspec[2]; + *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK; + + parent_intc = intc->parent; + if (parent_intc) { + irq_data = &intc->irqs[intspec[2]]; + irq_data->parent_irq = intspec[1]; + parent_irq_data = &parent_intc->irqs[irq_data->parent_irq]; + parent_irq_data->sub_intc = intc; + parent_irq_data->sub_bits |= (1UL << intspec[2]); + + /* parent_intc is always s3c_intc[0], so no offset */ + irqno = irq_create_mapping(parent_intc->domain, intspec[1]); + if (irqno < 0) { + pr_err("irq: could not map parent interrupt\n"); + return irqno; + } + + irq_set_chained_handler(irqno, s3c_irq_demux); + } + + return 0; +} + +static const struct irq_domain_ops s3c24xx_irq_ops_of = { + .map = s3c24xx_irq_map_of, + .xlate = s3c24xx_irq_xlate_of, +}; + +struct s3c24xx_irq_of_ctrl { + char *name; + unsigned long offset; + struct s3c_irq_intc **handle; + struct s3c_irq_intc **parent; + struct irq_domain_ops *ops; +}; + +static int __init s3c_init_intc_of(struct device_node *np, + struct device_node *interrupt_parent, + struct s3c24xx_irq_of_ctrl *s3c_ctrl, int num_ctrl) +{ + struct s3c_irq_intc *intc; + struct s3c24xx_irq_of_ctrl *ctrl; + struct irq_domain *domain; + void __iomem *reg_base; + int i; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("irq-s3c24xx: could not map irq registers\n"); + return -EINVAL; + } + + domain = irq_domain_add_linear(np, num_ctrl * 32, + &s3c24xx_irq_ops_of, NULL); + if (!domain) { + pr_err("irq: could not create irq-domain\n"); + return -EINVAL; + } + + for (i = 0; i < num_ctrl; i++) { + ctrl = &s3c_ctrl[i]; + + pr_debug("irq: found controller %s\n", ctrl->name); + + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL); + if (!intc) + return -ENOMEM; + + intc->domain = domain; + intc->irqs = kcalloc(32, sizeof(struct s3c_irq_data), + GFP_KERNEL); + if (!intc->irqs) { + kfree(intc); + return -ENOMEM; + } + + if (ctrl->parent) { + intc->reg_pending = reg_base + ctrl->offset; + intc->reg_mask = reg_base + ctrl->offset + 0x4; + + if (*(ctrl->parent)) { + intc->parent = *(ctrl->parent); + } else { + pr_warn("irq: parent of %s missing\n", + ctrl->name); + kfree(intc->irqs); + kfree(intc); + continue; + } + } else { + intc->reg_pending = reg_base + ctrl->offset; + intc->reg_mask = reg_base + ctrl->offset + 0x08; + intc->reg_intpnd = reg_base + ctrl->offset + 0x10; + } + + s3c24xx_clear_intc(intc); + s3c_intc[i] = intc; + } + + set_handle_irq(s3c24xx_handle_irq); + + return 0; +} + +static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = { + { + .name = "intc", + .offset = 0, + }, { + .name = "subintc", + .offset = 0x18, + .parent = &s3c_intc[0], + } +}; + +int __init s3c2410_init_intc_of(struct device_node *np, + struct device_node *interrupt_parent) +{ + return s3c_init_intc_of(np, interrupt_parent, + s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl)); +} +IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of); + +static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = { + { + .name = "intc", + .offset = 0, + }, { + .name = "subintc", + .offset = 0x18, + .parent = &s3c_intc[0], + }, { + .name = "intc2", + .offset = 0x40, + } +}; + +int __init s3c2416_init_intc_of(struct device_node *np, + struct device_node *interrupt_parent) +{ + return s3c_init_intc_of(np, interrupt_parent, + s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl)); +} +IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c2416_init_intc_of); +#endif diff --git a/arch/arm/mach-s3c/irq-uart-s3c64xx.h b/arch/arm/mach-s3c/irq-uart-s3c64xx.h new file mode 100644 index 000000000000..78eccdce95a7 --- /dev/null +++ b/arch/arm/mach-s3c/irq-uart-s3c64xx.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010 Simtec Electronics + * Ben Dooks + * + * Header file for Samsung SoC UART IRQ demux for S3C64XX and later + */ + +struct s3c_uart_irq { + void __iomem *regs; + unsigned int base_irq; + unsigned int parent_irq; +}; + +extern void s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs); + diff --git a/arch/arm/mach-s3c/mach-amlm5900.c b/arch/arm/mach-s3c/mach-amlm5900.c new file mode 100644 index 000000000000..724240e1b662 --- /dev/null +++ b/arch/arm/mach-s3c/mach-amlm5900.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (c) 2006 American Microsystems Limited +// David Anders +// +// @History: +// derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by +// Ben Dooks + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "s3c24xx.h" + +static struct resource amlm5900_nor_resource = + DEFINE_RES_MEM(0x00000000, SZ_16M); + +static struct mtd_partition amlm5900_mtd_partitions[] = { + { + .name = "System", + .size = 0x240000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "Kernel", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "Ramdisk", + .size = 0x300000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "JFFS2", + .size = 0x9A0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "Settings", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data amlm5900_flash_data = { + .width = 2, + .parts = amlm5900_mtd_partitions, + .nr_parts = ARRAY_SIZE(amlm5900_mtd_partitions), +}; + +static struct platform_device amlm5900_device_nor = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &amlm5900_flash_data, + }, + .num_resources = 1, + .resource = &amlm5900_nor_resource, +}; + +static struct map_desc amlm5900_iodesc[] __initdata = { +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg amlm5900_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + +static struct gpiod_lookup_table amlm5900_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct platform_device *amlm5900_devices[] __initdata = { +#ifdef CONFIG_FB_S3C2410 + &s3c_device_lcd, +#endif + &s3c_device_adc, + &s3c_device_wdt, + &s3c_device_i2c0, + &s3c_device_ohci, + &s3c_device_rtc, + &s3c_device_usbgadget, + &s3c_device_sdi, + &amlm5900_device_nor, +}; + +static void __init amlm5900_map_io(void) +{ + s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); + s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); +} + +static void __init amlm5900_init_time(void) +{ + s3c2410_init_clocks(12000000); + samsung_timer_init(); +} + +#ifdef CONFIG_FB_S3C2410 +static struct s3c2410fb_display __initdata amlm5900_lcd_info = { + .width = 160, + .height = 160, + + .type = S3C2410_LCDCON1_STN4, + + .pixclock = 680000, /* HCLK = 100MHz */ + .xres = 160, + .yres = 160, + .bpp = 4, + .left_margin = 1 << (4 + 3), + .right_margin = 8 << 3, + .hsync_len = 48, + .upper_margin = 0, + .lower_margin = 0, + + .lcdcon5 = 0x00000001, +}; + +static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = { + + .displays = &amlm5900_lcd_info, + .num_displays = 1, + .default_display = 0, + + .gpccon = 0xaaaaaaaa, + .gpccon_mask = 0xffffffff, + .gpccon_reg = S3C2410_GPCCON, + .gpcup = 0x0000ffff, + .gpcup_mask = 0xffffffff, + .gpcup_reg = S3C2410_GPCUP, + + .gpdcon = 0xaaaaaaaa, + .gpdcon_mask = 0xffffffff, + .gpdcon_reg = S3C2410_GPDCON, + .gpdup = 0x0000ffff, + .gpdup_mask = 0xffffffff, + .gpdup_reg = S3C2410_GPDUP, +}; +#endif + +static irqreturn_t +amlm5900_wake_interrupt(int irq, void *ignored) +{ + return IRQ_HANDLED; +} + +static void amlm5900_init_pm(void) +{ + int ret = 0; + + ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt, + IRQF_TRIGGER_RISING | IRQF_SHARED, + "amlm5900_wakeup", &amlm5900_wake_interrupt); + if (ret != 0) { + printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret); + } else { + enable_irq_wake(IRQ_EINT9); + /* configure the suspend/resume status pin */ + s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); + s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP); + } +} +static void __init amlm5900_init(void) +{ + amlm5900_init_pm(); +#ifdef CONFIG_FB_S3C2410 + s3c24xx_fb_set_platdata(&amlm5900_fb_info); +#endif + s3c_i2c0_set_platdata(NULL); + gpiod_add_lookup_table(&amlm5900_mmc_gpio_table); + platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); +} + +MACHINE_START(AML_M5900, "AML_M5900") + .atag_offset = 0x100, + .map_io = amlm5900_map_io, + .init_irq = s3c2410_init_irq, + .init_machine = amlm5900_init, + .init_time = amlm5900_init_time, +MACHINE_END diff --git a/arch/arm/mach-s3c/mach-anubis.c b/arch/arm/mach-s3c/mach-anubis.c new file mode 100644 index 000000000000..83b2f7fb268e --- /dev/null +++ b/arch/arm/mach-s3c/mach-anubis.c @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2003-2009 Simtec Electronics +// http://armlinux.simtec.co.uk/ +// Ben Dooks + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "anubis.h" +#include "s3c24xx.h" +#include "simtec.h" + +#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics" + +static struct map_desc anubis_iodesc[] __initdata = { + /* ISA IO areas */ + + { + .virtual = (u32)S3C24XX_VA_ISA_BYTE, + .pfn = __phys_to_pfn(0x0), + .length = SZ_4M, + .type = MT_DEVICE, + }, { + .virtual = (u32)S3C24XX_VA_ISA_WORD, + .pfn = __phys_to_pfn(0x0), + .length = SZ_4M, + .type = MT_DEVICE, + }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + + /* CPLD control registers */ + + { + .virtual = (u32)ANUBIS_VA_CTRL1, + .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (u32)ANUBIS_VA_IDREG, + .pfn = __phys_to_pfn(ANUBIS_PA_IDREG), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, + }, + [1] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, + }, +}; + +/* NAND Flash on Anubis board */ + +static int external_map[] = { 2 }; +static int chip0_map[] = { 0 }; +static int chip1_map[] = { 1 }; + +static struct mtd_partition __initdata anubis_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_16K, + .offset = SZ_16K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct mtd_partition __initdata anubis_default_nand_part_large[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_128K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_128K, + .offset = SZ_128K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + +/* the Anubis has 3 selectable slots for nand-flash, the two + * on-board chip areas, as well as the external slot. + * + * Note, there is no current hot-plug support for the External + * socket. +*/ + +static struct s3c2410_nand_set __initdata anubis_nand_sets[] = { + [1] = { + .name = "External", + .nr_chips = 1, + .nr_map = external_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part, + }, + [0] = { + .name = "chip0", + .nr_chips = 1, + .nr_map = chip0_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part, + }, + [2] = { + .name = "chip1", + .nr_chips = 1, + .nr_map = chip1_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part, + }, +}; + +static void anubis_nand_select(struct s3c2410_nand_set *set, int slot) +{ + unsigned int tmp; + + slot = set->nr_map[slot] & 3; + + pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n", + slot, set, set->nr_map); + + tmp = __raw_readb(ANUBIS_VA_CTRL1); + tmp &= ~ANUBIS_CTRL1_NANDSEL; + tmp |= slot; + + pr_debug("anubis_nand: ctrl1 now %02x\n", tmp); + + __raw_writeb(tmp, ANUBIS_VA_CTRL1); +} + +static struct s3c2410_platform_nand __initdata anubis_nand_info = { + .tacls = 25, + .twrph0 = 55, + .twrph1 = 40, + .nr_sets = ARRAY_SIZE(anubis_nand_sets), + .sets = anubis_nand_sets, + .select_chip = anubis_nand_select, + .ecc_mode = NAND_ECC_SOFT, +}; + +/* IDE channels */ + +static struct pata_platform_info anubis_ide_platdata = { + .ioport_shift = 5, +}; + +static struct resource anubis_ide0_resource[] = { + [0] = DEFINE_RES_MEM(S3C2410_CS3, 8 * 32), + [2] = DEFINE_RES_MEM(S3C2410_CS3 + (1 << 26) + (6 * 32), 32), + [3] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0), +}; + +static struct platform_device anubis_device_ide0 = { + .name = "pata_platform", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_ide0_resource), + .resource = anubis_ide0_resource, + .dev = { + .platform_data = &anubis_ide_platdata, + .coherent_dma_mask = ~0, + }, +}; + +static struct resource anubis_ide1_resource[] = { + [0] = DEFINE_RES_MEM(S3C2410_CS4, 8 * 32), + [1] = DEFINE_RES_MEM(S3C2410_CS4 + (1 << 26) + (6 * 32), 32), + [2] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0), +}; + +static struct platform_device anubis_device_ide1 = { + .name = "pata_platform", + .id = 1, + .num_resources = ARRAY_SIZE(anubis_ide1_resource), + .resource = anubis_ide1_resource, + .dev = { + .platform_data = &anubis_ide_platdata, + .coherent_dma_mask = ~0, + }, +}; + +/* Asix AX88796 10/100 ethernet controller */ + +static struct ax_plat_data anubis_asix_platdata = { + .flags = AXFLG_MAC_FROMDEV, + .wordlength = 2, + .dcr_val = 0x48, + .rcr_val = 0x40, +}; + +static struct resource anubis_asix_resource[] = { + [0] = DEFINE_RES_MEM(S3C2410_CS5, 0x20 * 0x20), + [1] = DEFINE_RES_IRQ(ANUBIS_IRQ_ASIX), +}; + +static struct platform_device anubis_device_asix = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_asix_resource), + .resource = anubis_asix_resource, + .dev = { + .platform_data = &anubis_asix_platdata, + } +}; + +/* SM501 */ + +static struct resource anubis_sm501_resource[] = { + [0] = DEFINE_RES_MEM(S3C2410_CS2, SZ_8M), + [1] = DEFINE_RES_MEM(S3C2410_CS2 + SZ_64M - SZ_2M, SZ_2M), + [2] = DEFINE_RES_IRQ(IRQ_EINT0), +}; + +static struct sm501_initdata anubis_sm501_initdata = { + .gpio_high = { + .set = 0x3F000000, /* 24bit panel */ + .mask = 0x0, + }, + .misc_timing = { + .set = 0x010100, /* SDRAM timing */ + .mask = 0x1F1F00, + }, + .misc_control = { + .set = SM501_MISC_PNL_24BIT, + .mask = 0, + }, + + .devices = SM501_USE_GPIO, + + /* set the SDRAM and bus clocks */ + .mclk = 72 * MHZ, + .m1xclk = 144 * MHZ, +}; + +static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = { + [0] = { + .bus_num = 1, + .pin_scl = 44, + .pin_sda = 45, + }, + [1] = { + .bus_num = 2, + .pin_scl = 40, + .pin_sda = 41, + }, +}; + +static struct sm501_platdata anubis_sm501_platdata = { + .init = &anubis_sm501_initdata, + .gpio_base = -1, + .gpio_i2c = anubis_sm501_gpio_i2c, + .gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c), +}; + +static struct platform_device anubis_device_sm501 = { + .name = "sm501", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_sm501_resource), + .resource = anubis_sm501_resource, + .dev = { + .platform_data = &anubis_sm501_platdata, + }, +}; + +/* Standard Anubis devices */ + +static struct platform_device *anubis_devices[] __initdata = { + &s3c2410_device_dclk, + &s3c_device_ohci, + &s3c_device_wdt, + &s3c_device_adc, + &s3c_device_i2c0, + &s3c_device_rtc, + &s3c_device_nand, + &anubis_device_ide0, + &anubis_device_ide1, + &anubis_device_asix, + &anubis_device_sm501, +}; + +/* I2C devices. */ + +static struct i2c_board_info anubis_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("tps65011", 0x48), + .irq = IRQ_EINT20, + } +}; + +/* Audio setup */ +static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = { + .have_mic = 1, + .have_lout = 1, + .output_cdclk = 1, + .use_mpllin = 1, + .amp_gpio = S3C2410_GPB(2), + .amp_gain[0] = S3C2410_GPD(10), + .amp_gain[1] = S3C2410_GPD(11), +}; + +static void __init anubis_map_io(void) +{ + s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); + s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + + /* check for the newer revision boards with large page nand */ + + if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) { + printk(KERN_INFO "ANUBIS-B detected (revision %d)\n", + __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK); + anubis_nand_sets[0].partitions = anubis_default_nand_part_large; + anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large); + } else { + /* ensure that the GPIO is setup */ + gpio_request_one(S3C2410_GPA(0), GPIOF_OUT_INIT_HIGH, NULL); + gpio_free(S3C2410_GPA(0)); + } +} + +static void __init anubis_init_time(void) +{ + s3c2440_init_clocks(12000000); + samsung_timer_init(); +} + +static void __init anubis_init(void) +{ + s3c_i2c0_set_platdata(NULL); + s3c_nand_set_platdata(&anubis_nand_info); + simtec_audio_add(NULL, false, &anubis_audio); + + platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices)); + + i2c_register_board_info(0, anubis_i2c_devs, + ARRAY_SIZE(anubis_i2c_devs)); +} + + +MACHINE_START(ANUBIS, "Simtec-Anubis") + /* Maintainer: Ben Dooks */ + .atag_offset = 0x100, + .map_io = anubis_map_io, + .init_machine = anubis_init, + .init_irq = s3c2440_init_irq, + .init_time = anubis_init_time, +MACHINE_END diff --git a/arch/arm/mach-s3c/mach-anw6410.c b/arch/arm/mach-s3c/mach-anw6410.c new file mode 100644 index 000000000000..ff183ced8e6e --- /dev/null +++ b/arch/arm/mach-s3c/mach-anw6410.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2008 Openmoko, Inc. +// Copyright 2008 Simtec Electronics +// Ben Dooks +// http://armlinux.simtec.co.uk/ +// Copyright 2009 Kwangwoo Lee +// Kwangwoo Lee + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include