diff options
139 files changed, 2632 insertions, 2045 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 244c61835a6..c6a82c74fcb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -769,8 +769,10 @@ config ARCH_SA1100 config ARCH_S3C24XX bool "Samsung S3C24XX SoCs" select ARCH_HAS_CPUFREQ - select ARCH_USES_GETTIMEOFFSET select CLKDEV_LOOKUP + select CLKSRC_MMIO + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -787,10 +789,11 @@ config ARCH_S3C64XX bool "Samsung S3C64XX" select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB - select ARCH_USES_GETTIMEOFFSET select ARM_VIC select CLKDEV_LOOKUP + select CLKSRC_MMIO select CPU_V6 + select GENERIC_CLOCKEVENTS select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -824,9 +827,11 @@ config ARCH_S5P64X0 config ARCH_S5PC100 bool "Samsung S5PC100" - select ARCH_USES_GETTIMEOFFSET select CLKDEV_LOOKUP + select CLKSRC_MMIO select CPU_V7 + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi new file mode 100644 index 00000000000..fe5c6f21327 --- /dev/null +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -0,0 +1,98 @@ +/* + * Device Tree Source for Renesas r8a7779 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Simon Horman + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/include/ "skeleton.dtsi" + +/ { + compatible = "renesas,r8a7779"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <2>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <3>; + }; + }; + + gic: interrupt-controller@f0001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0xf0001000 0x1000>, + <0xf0000100 0x100>; + }; + + i2c0: i2c@0xffc70000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0xffc70000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 79 0x4>; + }; + + i2c1: i2c@0xffc71000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0xffc71000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 82 0x4>; + }; + + i2c2: i2c@0xffc72000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0xffc72000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 80 0x4>; + }; + + i2c3: i2c@0xffc73000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0xffc73000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 81 0x4>; + }; + + thermal@ffc48000 { + compatible = "renesas,rcar-thermal"; + reg = <0xffc48000 0x38>; + }; + + sata: sata@fc600000 { + compatible = "renesas,rcar-sata"; + reg = <0xfc600000 0x2000>; + interrupt-parent = <&gic>; + interrupts = <0 100 0x4>; + }; +}; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 2998a08afc2..0204f4cc9eb 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -169,6 +169,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "at91sam9261-lcdfb.0", &hck1), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g10-lcdfb.0", &hck1), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 92e0f861084..629ea5fc95c 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -488,7 +488,6 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -505,6 +504,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) return; } + if (cpu_is_at91sam9g10()) + at91_lcdc_device.name = "at91sam9g10-lcdfb"; + else + at91_lcdc_device.name = "at91sam9261-lcdfb"; + #if defined(CONFIG_FB_ATMEL_STN) at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index b9fc60d1b33..2282fd7ad3e 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -190,6 +190,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9263-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ed666f5cb01..858c8aac2da 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -848,7 +848,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91sam9263-lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index d3addee43d8..c68960d8224 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -228,6 +228,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("hclk", &macb_clk), /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g45-lcdfb.0", &lcdc_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g45es-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 827c9f2a70f..fe626d431b6 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -981,7 +981,6 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -997,6 +996,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) if (!data) return; + if (cpu_is_at91sam9g45es()) + at91_lcdc_device.name = "at91sam9g45es-lcdfb"; + else + at91_lcdc_device.name = "at91sam9g45-lcdfb"; + at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index eb98704db2d..3de3e04d0f8 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -179,6 +179,7 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "at91sam9rl-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index ddf223ff35c..352468f265a 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -514,7 +514,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91sam9rl-lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 70f94c87479..2f45906d6ee 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -276,8 +276,8 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_ONENAND select S5P_DEV_TV select S5P_GPIO_INT - select S5P_HRT select S5P_SETUP_MIPIPHY + select SAMSUNG_HRT help Machine support for Samsung Mobile Universal S5PC210 Reference Board. diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index d63d399c7ba..bdd957978d9 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -822,6 +822,7 @@ static int __init exynos_init_irq_eint(void) static const struct of_device_id exynos_pinctrl_ids[] = { { .compatible = "samsung,exynos4210-pinctrl", }, { .compatible = "samsung,exynos4x12-pinctrl", }, + { .compatible = "samsung,exynos5250-pinctrl", }, }; struct device_node *pctrl_np, *wkup_np; const char *wkup_compat = "samsung,exynos4210-wakeup-eint"; diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index 497fcb793dc..c870b0aaa5e 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -41,7 +41,7 @@ #include <plat/mfc.h> #include <plat/sdhci.h> #include <plat/fimc-core.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include <plat/camport.h> #include <mach/map.h> @@ -1094,7 +1094,7 @@ static void __init universal_map_io(void) exynos_init_io(NULL, 0); s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); - s5p_set_timer_source(S5P_PWM2, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4); } static void s5p_tv_setup(void) @@ -1152,7 +1152,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") .map_io = universal_map_io, .init_machine = universal_machine_init, .init_late = exynos_init_late, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .reserve = &universal_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index 37f513d1588..0a8663c5f2b 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -30,6 +30,7 @@ config CPU_S3C2410 select S3C2410_CLOCK select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX select S3C2410_PM if PM + select SAMSUNG_HRT help Support for S3C2410 and S3C2410A family from the S3C24XX line of Samsung Mobile CPUs. @@ -41,6 +42,7 @@ config CPU_S3C2412 select CPU_LLSERIAL_S3C2440 select S3C2412_DMA if S3C24XX_DMA select S3C2412_PM if PM + select SAMSUNG_HRT help Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line @@ -53,6 +55,7 @@ config CPU_S3C2416 select S3C2443_COMMON select S3C2443_DMA if S3C24XX_DMA select SAMSUNG_CLKSRC + select SAMSUNG_HRT help Support for the S3C2416 SoC from the S3C24XX line @@ -63,6 +66,7 @@ config CPU_S3C2440 select S3C2410_CLOCK select S3C2410_PM if PM select S3C2440_DMA if S3C24XX_DMA + select SAMSUNG_HRT help Support for S3C2440 Samsung Mobile CPU based systems. @@ -72,6 +76,7 @@ config CPU_S3C2442 select CPU_LLSERIAL_S3C2440 select S3C2410_CLOCK select S3C2410_PM if PM + select SAMSUNG_HRT help Support for S3C2442 Samsung Mobile CPU based systems. @@ -87,6 +92,7 @@ config CPU_S3C2443 select S3C2443_COMMON select S3C2443_DMA if S3C24XX_DMA select SAMSUNG_CLKSRC + select SAMSUNG_HRT help Support for the S3C2443 SoC from the S3C24XX line @@ -401,6 +407,7 @@ config S3C2412_DMA config S3C2412_PM bool select S3C2412_PM_SLEEP + select SAMSUNG_WAKEMASK help Internal config node to apply S3C2412 power management diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index af53d27d5c3..be6e4d0e6f1 100644 --- a/arch/arm/mach-s3c24xx/Makefile +++ b/arch/arm/mach-s3c24xx/Makefile @@ -22,7 +22,7 @@ obj-$(CONFIG_S3C2410_DMA) += dma-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 irq-s3c2412.o clock-s3c2412.o +obj-$(CONFIG_CPU_S3C2412) += s3c2412.o clock-s3c2412.o obj-$(CONFIG_S3C2412_CPUFREQ) += cpufreq-s3c2412.o obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o @@ -31,9 +31,9 @@ obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock-s3c2416.o obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o -obj-$(CONFIG_CPU_S3C2440) += s3c2440.o irq-s3c2440.o clock-s3c2440.o +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o clock-s3c2440.o obj-$(CONFIG_CPU_S3C2442) += s3c2442.o -obj-$(CONFIG_CPU_S3C244X) += s3c244x.o irq-s3c244x.o clock-s3c244x.o +obj-$(CONFIG_CPU_S3C244X) += s3c244x.o clock-s3c244x.o obj-$(CONFIG_S3C2440_CPUFREQ) += cpufreq-s3c2440.o obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o diff --git a/arch/arm/mach-s3c24xx/bast-irq.c b/arch/arm/mach-s3c24xx/bast-irq.c index c0daa9590b4..cb1b791954d 100644 --- a/arch/arm/mach-s3c24xx/bast-irq.c +++ b/arch/arm/mach-s3c24xx/bast-irq.c @@ -34,8 +34,6 @@ #include <mach/hardware.h> #include <mach/regs-irq.h> -#include <plat/irq.h> - #include "bast.h" #define irqdbf(x...) diff --git a/arch/arm/mach-s3c24xx/clock-s3c2410.c b/arch/arm/mach-s3c24xx/clock-s3c2410.c index 641266f3d15..34fffdf6fc1 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2410.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2410.c @@ -40,7 +40,6 @@ #include <mach/regs-clock.h> #include <mach/regs-gpio.h> -#include <plat/s3c2410.h> #include <plat/clock.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-s3c24xx/clock-s3c2412.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c index d10b695a906..2cc017da88f 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2412.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2412.c @@ -41,7 +41,6 @@ #include <mach/regs-clock.h> #include <mach/regs-gpio.h> -#include <plat/s3c2412.h> #include <plat/clock.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c index 14a81c2317a..036056cea57 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2416.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c @@ -14,7 +14,6 @@ #include <linux/init.h> #include <linux/clk.h> -#include <plat/s3c2416.h> #include <plat/clock.h> #include <plat/clock-clksrc.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c index bdaba59b42d..0a53051b078 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2443.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c @@ -41,7 +41,6 @@ #include <plat/cpu-freq.h> -#include <plat/s3c2443.h> #include <plat/clock.h> #include <plat/clock-clksrc.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c index 3b2cf6db363..404444dd384 100644 --- a/arch/arm/mach-s3c24xx/common-smdk.c +++ b/arch/arm/mach-s3c24xx/common-smdk.c @@ -41,11 +41,12 @@ #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/common-smdk.h> #include <plat/gpio-cfg.h> #include <plat/devs.h> #include <plat/pm.h> +#include "common-smdk.h" + /* LED devices */ static struct s3c24xx_led_platdata smdk_pdata_led4 = { diff --git a/arch/arm/plat-samsung/include/plat/common-smdk.h b/arch/arm/mach-s3c24xx/common-smdk.h index ba028f1ed30..98f733e1cb4 100644 --- a/arch/arm/plat-samsung/include/plat/common-smdk.h +++ b/arch/arm/mach-s3c24xx/common-smdk.h @@ -1,5 +1,4 @@ -/* linux/arch/arm/plat-samsung/include/plat/common-smdk.h - * +/* * Copyright (c) 2006 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index 6bcf87f65f9..d97533d21ac 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -47,14 +47,11 @@ #include <plat/cpu.h> #include <plat/devs.h> #include <plat/clock.h> -#include <plat/s3c2410.h> -#include <plat/s3c2412.h> -#include <plat/s3c2416.h> -#include <plat/s3c244x.h> -#include <plat/s3c2443.h> #include <plat/cpu-freq.h> #include <plat/pll.h> +#include "common.h" + /* table of supported CPUs */ static const char name_s3c2410[] = "S3C2410"; diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h index ed6276fcaa3..abefeb38bba 100644 --- a/arch/arm/mach-s3c24xx/common.h +++ b/arch/arm/mach-s3c24xx/common.h @@ -12,8 +12,97 @@ #ifndef __ARCH_ARM_MACH_S3C24XX_COMMON_H #define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__ -void s3c2410_restart(char mode, const char *cmd); -void s3c244x_restart(char mode, const char *cmd); +struct s3c2410_uartcfg; + +#ifdef CONFIG_CPU_S3C2410 +extern int s3c2410_init(void); +extern int s3c2410a_init(void); +extern void s3c2410_map_io(void); +extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void s3c2410_init_clocks(int xtal); +extern void s3c2410_restart(char mode, const char *cmd); +#else +#define s3c2410_init_clocks NULL +#define s3c2410_init_uarts NULL +#define s3c2410_map_io NULL +#define s3c2410_init NULL +#define s3c2410a_init NULL +#endif + +#ifdef CONFIG_CPU_S3C2412 +extern int s3c2412_init(void); +extern void s3c2412_map_io(void); +extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void s3c2412_init_clocks(int xtal); +extern int s3c2412_baseclk_add(void); +extern void s3c2412_restart(char mode, const char *cmd); +extern void s3c2412_init_irq(void); +#else +#define s3c2412_init_clocks NULL +#define s3c2412_init_uarts NULL +#define s3c2412_map_io NULL +#define s3c2412_init NULL +#endif + +#ifdef CONFIG_CPU_S3C2416 +extern int s3c2416_init(void); +extern void s3c2416_map_io(void); +extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void s3c2416_init_clocks(int xtal); +extern int s3c2416_baseclk_add(void); +extern void s3c2416_restart(char mode, const char *cmd); +extern void s3c2416_init_irq(void); + +extern struct syscore_ops s3c2416_irq_syscore_ops; +#else +#define s3c2416_init_clocks NULL +#define s3c2416_init_uarts NULL +#define s3c2416_map_io NULL +#define s3c2416_init NULL +#endif + +#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) +extern void s3c244x_map_io(void); +extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void s3c244x_init_clocks(int xtal); +extern void s3c244x_restart(char mode, const char *cmd); +#else +#define s3c244x_init_clocks NULL +#define s3c244x_init_uarts NULL +#endif + +#ifdef CONFIG_CPU_S3C2440 +extern int s3c2440_init(void); +extern void s3c2440_map_io(void); +extern void s3c2440_init_irq(void); +#else +#define s3c2440_init NULL +#define s3c2440_map_io NULL +#endif + +#ifdef CONFIG_CPU_S3C2442 +extern int s3c2442_init(void); +extern void s3c2442_map_io(void); +extern void s3c2442_init_irq(void); +#else +#define s3c2442_init NULL +#define s3c2442_map_io NULL +#endif + +#ifdef CONFIG_CPU_S3C2443 +extern int s3c2443_init(void); +extern void s3c2443_map_io(void); +extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void s3c2443_init_clocks(int xtal); +extern int s3c2443_baseclk_add(void); +extern void s3c2443_restart(char mode, const char *cmd); +extern void s3c2443_init_irq(void); +#else +#define s3c2443_init_clocks NULL +#define s3c2443_init_uarts NULL +#define s3c2443_map_io NULL +#define s3c2443_init NULL +#endif extern struct syscore_ops s3c24xx_irq_syscore_ops; diff --git a/arch/arm/mach-s3c24xx/dma-s3c2410.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c index 25d085adc93..a6c94b82095 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2410.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2410.c @@ -28,7 +28,6 @@ #include <plat/regs-ac97.h> #include <plat/regs-dma.h> #include <mach/regs-lcd.h> -#include <mach/regs-sdi.h> #include <plat/regs-iis.h> #include <plat/regs-spi.h> diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c index d2408ba372c..c0e8c3f5057 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2412.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2412.c @@ -28,7 +28,6 @@ #include <plat/regs-ac97.h> #include <plat/regs-dma.h> #include <mach/regs-lcd.h> -#include <mach/regs-sdi.h> #include <plat/regs-iis.h> #include <plat/regs-spi.h> diff --git a/arch/arm/mach-s3c24xx/dma-s3c2440.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c index 0b86e74d104..1c08eccd942 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2440.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2440.c @@ -28,7 +28,6 @@ #include <plat/regs-ac97.h> #include <plat/regs-dma.h> #include <mach/regs-lcd.h> -#include <mach/regs-sdi.h> #include <plat/regs-iis.h> #include <plat/regs-spi.h> diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c index 05536254a3f..000e4c69fce 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2443.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c @@ -28,7 +28,6 @@ #include <plat/regs-ac97.h> #include <plat/regs-dma.h> #include <mach/regs-lcd.h> -#include <mach/regs-sdi.h> #include <plat/regs-iis.h> #include <plat/regs-spi.h> diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index b7a9f4d469e..43cada8019b 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -59,49 +59,53 @@ #define IRQ_ADCPARENT S3C2410_IRQ(31) /* interrupts generated from the external interrupts sources */ -#define IRQ_EINT4 S3C2410_IRQ(32) /* 48 */ -#define IRQ_EINT5 S3C2410_IRQ(33) -#define IRQ_EINT6 S3C2410_IRQ(34) -#define IRQ_EINT7 S3C2410_IRQ(35) -#define IRQ_EINT8 S3C2410_IRQ(36) -#define IRQ_EINT9 S3C2410_IRQ(37) -#define IRQ_EINT10 S3C2410_IRQ(38) -#define IRQ_EINT11 S3C2410_IRQ(39) -#define IRQ_EINT12 S3C2410_IRQ(40) -#define IRQ_EINT13 S3C2410_IRQ(41) -#define IRQ_EINT14 S3C2410_IRQ(42) -#define IRQ_EINT15 S3C2410_IRQ(43) -#define IRQ_EINT16 S3C2410_IRQ(44) -#define IRQ_EINT17 S3C2410_IRQ(45) -#define IRQ_EINT18 S3C2410_IRQ(46) -#define IRQ_EINT19 S3C2410_IRQ(47) -#define IRQ_EINT20 S3C2410_IRQ(48) /* 64 */ -#define IRQ_EINT21 S3C2410_IRQ(49) -#define IRQ_EINT22 S3C2410_IRQ(50) -#define IRQ_EINT23 S3C2410_IRQ(51) +#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(52) -#define IRQ_LCD_FRAME S3C2410_IRQ(53) +#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)+54) +#define S3C2410_IRQSUB(x) S3C2410_IRQ((x)+58) -#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 70 */ +#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) /* 73 */ +#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) /* 76 */ +#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 80 */ #define IRQ_S3CUART_TX2 S3C2410_IRQSUB(7) #define IRQ_S3CUART_ERR2 S3C2410_IRQSUB(8) @@ -136,7 +140,7 @@ /* second interrupt-register of s3c2416/s3c2450 */ -#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 54 + 29) +#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) diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h deleted file mode 100644 index cbf2d8884e3..00000000000 --- a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h +++ /dev/null @@ -1,127 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h - * - * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 MMC/SDIO register definitions -*/ - -#ifndef __ASM_ARM_REGS_SDI -#define __ASM_ARM_REGS_SDI "regs-sdi.h" - -#define S3C2410_SDICON (0x00) -#define S3C2410_SDIPRE (0x04) -#define S3C2410_SDICMDARG (0x08) -#define S3C2410_SDICMDCON (0x0C) -#define S3C2410_SDICMDSTAT (0x10) -#define S3C2410_SDIRSP0 (0x14) -#define S3C2410_SDIRSP1 (0x18) -#define S3C2410_SDIRSP2 (0x1C) -#define S3C2410_SDIRSP3 (0x20) -#define S3C2410_SDITIMER (0x24) -#define S3C2410_SDIBSIZE (0x28) -#define S3C2410_SDIDCON (0x2C) -#define S3C2410_SDIDCNT (0x30) -#define S3C2410_SDIDSTA (0x34) -#define S3C2410_SDIFSTA (0x38) - -#define S3C2410_SDIDATA (0x3C) -#define S3C2410_SDIIMSK (0x40) - -#define S3C2440_SDIDATA (0x40) -#define S3C2440_SDIIMSK (0x3C) - -#define S3C2440_SDICON_SDRESET (1<<8) -#define S3C2440_SDICON_MMCCLOCK (1<<5) -#define S3C2410_SDICON_BYTEORDER (1<<4) -#define S3C2410_SDICON_SDIOIRQ (1<<3) -#define S3C2410_SDICON_RWAITEN (1<<2) -#define S3C2410_SDICON_FIFORESET (1<<1) -#define S3C2410_SDICON_CLOCKTYPE (1<<0) - -#define S3C2410_SDICMDCON_ABORT (1<<12) -#define S3C2410_SDICMDCON_WITHDATA (1<<11) -#define S3C2410_SDICMDCON_LONGRSP (1<<10) -#define S3C2410_SDICMDCON_WAITRSP (1<<9) -#define S3C2410_SDICMDCON_CMDSTART (1<<8) -#define S3C2410_SDICMDCON_SENDERHOST (1<<6) -#define S3C2410_SDICMDCON_INDEX (0x3f) - -#define S3C2410_SDICMDSTAT_CRCFAIL (1<<12) -#define S3C2410_SDICMDSTAT_CMDSENT (1<<11) -#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10) -#define S3C2410_SDICMDSTAT_RSPFIN (1<<9) -#define S3C2410_SDICMDSTAT_XFERING (1<<8) -#define S3C2410_SDICMDSTAT_INDEX (0xff) - -#define S3C2440_SDIDCON_DS_BYTE (0<<22) -#define S3C2440_SDIDCON_DS_HALFWORD (1<<22) -#define S3C2440_SDIDCON_DS_WORD (2<<22) -#define S3C2410_SDIDCON_IRQPERIOD (1<<21) -#define S3C2410_SDIDCON_TXAFTERRESP (1<<20) -#define S3C2410_SDIDCON_RXAFTERCMD (1<<19) -#define S3C2410_SDIDCON_BUSYAFTERCMD (1<<18) -#define S3C2410_SDIDCON_BLOCKMODE (1<<17) -#define S3C2410_SDIDCON_WIDEBUS (1<<16) -#define S3C2410_SDIDCON_DMAEN (1<<15) -#define S3C2410_SDIDCON_STOP (1<<14) -#define S3C2440_SDIDCON_DATSTART (1<<14) -#define S3C2410_SDIDCON_DATMODE (3<<12) -#define S3C2410_SDIDCON_BLKNUM (0x7ff) - -/* constants for S3C2410_SDIDCON_DATMODE */ -#define S3C2410_SDIDCON_XFER_READY (0<<12) -#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12) -#define S3C2410_SDIDCON_XFER_RXSTART (2<<12) -#define S3C2410_SDIDCON_XFER_TXSTART (3<<12) - -#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) -#define S3C2410_SDIDCNT_BLKNUM_SHIFT (12) - -#define S3C2410_SDIDSTA_RDYWAITREQ (1<<10) -#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9) -#define S3C2410_SDIDSTA_FIFOFAIL (1<<8) /* reserved on 2440 */ -#define S3C2410_SDIDSTA_CRCFAIL (1<<7) -#define S3C2410_SDIDSTA_RXCRCFAIL (1<<6) -#define S3C2410_SDIDSTA_DATATIMEOUT (1<<5) -#define S3C2410_SDIDSTA_XFERFINISH (1<<4) -#define S3C2410_SDIDSTA_BUSYFINISH (1<<3) -#define S3C2410_SDIDSTA_SBITERR (1<<2) /* reserved on 2410a/2440 */ -#define S3C2410_SDIDSTA_TXDATAON (1<<1) -#define S3C2410_SDIDSTA_RXDATAON (1<<0) - -#define S3C2440_SDIFSTA_FIFORESET (1<<16) -#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */ -#define S3C2410_SDIFSTA_TFDET (1<<13) -#define S3C2410_SDIFSTA_RFDET (1<<12) -#define S3C2410_SDIFSTA_TFHALF (1<<11) -#define S3C2410_SDIFSTA_TFEMPTY (1<<10) -#define S3C2410_SDIFSTA_RFLAST (1<<9) -#define S3C2410_SDIFSTA_RFFULL (1<<8) -#define S3C2410_SDIFSTA_RFHALF (1<<7) -#define S3C2410_SDIFSTA_COUNTMASK (0x7f) - -#define S3C2410_SDIIMSK_RESPONSECRC (1<<17) -#define S3C2410_SDIIMSK_CMDSENT (1<<16) -#define S3C2410_SDIIMSK_CMDTIMEOUT (1<<15) -#define S3C2410_SDIIMSK_RESPONSEND (1<<14) -#define S3C2410_SDIIMSK_READWAIT (1<<13) -#define S3C2410_SDIIMSK_SDIOIRQ (1<<12) -#define S3C2410_SDIIMSK_FIFOFAIL (1<<11) -#define S3C2410_SDIIMSK_CRCSTATUS (1<<10) -#define S3C2410_SDIIMSK_DATACRC (1<<9) -#define S3C2410_SDIIMSK_DATATIMEOUT (1<<8) -#define S3C2410_SDIIMSK_DATAFINISH (1<<7) -#define S3C2410_SDIIMSK_BUSYFINISH (1<<6) -#define S3C2410_SDIIMSK_SBITERR (1<<5) /* reserved 2440/2410a */ -#define S3C2410_SDIIMSK_TXFIFOHALF (1<<4) -#define S3C2410_SDIIMSK_TXFIFOEMPTY (1<<3) -#define S3C2410_SDIIMSK_RXFIFOLAST (1<<2) -#define S3C2410_SDIIMSK_RXFIFOFULL (1<<1) -#define S3C2410_SDIIMSK_RXFIFOHALF (1<<0) - -#endif /* __ASM_ARM_REGS_SDI */ diff --git a/arch/arm/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c index e1199599873..b91341ef2b2 100644 --- a/arch/arm/mach-s3c24xx/irq-pm.c +++ b/arch/arm/mach-s3c24xx/irq-pm.c @@ -16,10 +16,15 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/syscore_ops.h> +#include <linux/io.h> #include <plat/cpu.h> #include <plat/pm.h> -#include <plat/irq.h> +#include <plat/map-base.h> +#include <plat/map-s3c.h> + +#include <mach/regs-irq.h> +#include <mach/regs-gpio.h> #include <asm/irq.h> diff --git a/arch/arm/mach-s3c24xx/irq-s3c2412.c b/arch/arm/mach-s3c24xx/irq-s3c2412.c deleted file mode 100644 index 67d763178d3..00000000000 --- a/arch/arm/mach-s3c24xx/irq-s3c2412.c +++ /dev/null @@ -1,215 +0,0 @@ -/* linux/arch/arm/mach-s3c2412/irq.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/device.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/irq.h> - -#include <asm/mach/irq.h> - -#include <mach/regs-irq.h> -#include <mach/regs-gpio.h> - -#include <plat/cpu.h> -#include <plat/irq.h> -#include <plat/pm.h> - -#include "s3c2412-power.h" - -#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) -#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0)))) - -/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by - * having them turn up in both the INT* and the EINT* registers. Whilst - * both show the status, they both now need to be acked when the IRQs - * go off. -*/ - -static void -s3c2412_irq_mask(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - unsigned long mask; - - mask = __raw_readl(S3C2410_INTMSK); - __raw_writel(mask | bitval, S3C2410_INTMSK); - - mask = __raw_readl(S3C2412_EINTMASK); - __raw_writel(mask | bitval, S3C2412_EINTMASK); -} - -static inline void -s3c2412_irq_ack(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - - __raw_writel(bitval, S3C2412_EINTPEND); - __raw_writel(bitval, S3C2410_SRCPND); - __raw_writel(bitval, S3C2410_INTPND); -} - -static inline void -s3c2412_irq_maskack(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - unsigned long mask; - - mask = __raw_readl(S3C2410_INTMSK); - __raw_writel(mask|bitval, S3C2410_INTMSK); - - mask = __raw_readl(S3C2412_EINTMASK); - __raw_writel(mask | bitval, S3C2412_EINTMASK); - - __raw_writel(bitval, S3C2412_EINTPEND); - __raw_writel(bitval, S3C2410_SRCPND); - __raw_writel(bitval, S3C2410_INTPND); -} - -static void -s3c2412_irq_unmask(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - unsigned long mask; - - mask = __raw_readl(S3C2412_EINTMASK); - __raw_writel(mask & ~bitval, S3C2412_EINTMASK); - - mask = __raw_readl(S3C2410_INTMSK); - __raw_writel(mask & ~bitval, S3C2410_INTMSK); -} - -static struct irq_chip s3c2412_irq_eint0t4 = { - .irq_ack = s3c2412_irq_ack, - .irq_mask = s3c2412_irq_mask, - .irq_unmask = s3c2412_irq_unmask, - .irq_set_wake = s3c_irq_wake, - .irq_set_type = s3c_irqext_type, -}; - -#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0))) - -/* CF and SDI sub interrupts */ - -static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc) -{ - unsigned int subsrc, submsk; - - subsrc = __raw_readl(S3C2410_SUBSRCPND); - submsk = __raw_readl(S3C2410_INTSUBMSK); - - subsrc &= ~submsk; - - if (subsrc & INTBIT(IRQ_S3C2412_SDI)) - generic_handle_irq(IRQ_S3C2412_SDI); - - if (subsrc & INTBIT(IRQ_S3C2412_CF)) - generic_handle_irq(IRQ_S3C2412_CF); -} - -#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0)) -#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF) - -static void s3c2412_irq_cfsdi_mask(struct irq_data *data) -{ - s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI); -} - -static void s3c2412_irq_cfsdi_unmask(struct irq_data *data) -{ - s3c_irqsub_unmask(data->irq, INTMSK_CFSDI); -} - -static void s3c2412_irq_cfsdi_ack(struct irq_data *data) -{ - s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI); -} - -static struct irq_chip s3c2412_irq_cfsdi = { - .name = "s3c2412-cfsdi", - .irq_ack = s3c2412_irq_cfsdi_ack, - .irq_mask = s3c2412_irq_cfsdi_mask, - .irq_unmask = s3c2412_irq_cfsdi_unmask, -}; - -static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state) -{ - unsigned long pwrcfg; - - pwrcfg = __raw_readl(S3C2412_PWRCFG); - if (state) - pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ; - else - pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ; - __raw_writel(pwrcfg, S3C2412_PWRCFG); - - return s3c_irq_chip.irq_set_wake(data, state); -} - -static struct irq_chip s3c2412_irq_rtc_chip; - -static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif) -{ - unsigned int irqno; - - for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { - irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4, - handle_edge_irq); - set_irq_flags(irqno, IRQF_VALID); - } - - /* add demux support for CF/SDI */ - - irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi); - - for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) { - irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi, - handle_level_irq); - set_irq_flags(irqno, IRQF_VALID); - } - - /* change RTC IRQ's set wake method */ - - s3c2412_irq_rtc_chip = s3c_irq_chip; - s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake; - - irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip); - - return 0; -} - -static struct subsys_interface s3c2412_irq_interface = { - .name = "s3c2412_irq", - .subsys = &s3c2412_subsys, - .add_dev = s3c2412_irq_add, -}; - -static int s3c2412_irq_init(void) -{ - return subsys_interface_register(&s3c2412_irq_interface); -} - -arch_initcall(s3c2412_irq_init); diff --git a/arch/arm/mach-s3c24xx/irq-s3c2440.c b/arch/arm/mach-s3c24xx/irq-s3c2440.c deleted file mode 100644 index 4a18cde439c..00000000000 --- a/arch/arm/mach-s3c24xx/irq-s3c2440.c +++ /dev/null @@ -1,128 +0,0 @@ -/* linux/arch/arm/mach-s3c2440/irq.c - * - * Copyright (c) 2003-2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/device.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/irq.h> - -#include <asm/mach/irq.h> - -#include <mach/regs-irq.h> -#include <mach/regs-gpio.h> - -#include <plat/cpu.h> -#include <plat/pm.h> -#include <plat/irq.h> - -/* WDT/AC97 */ - -static void s3c_irq_demux_wdtac97(unsigned int irq, - struct irq_desc *desc) -{ - unsigned int subsrc, submsk; - - /* read the current pending interrupts, and the mask - * for what it is available */ - - subsrc = __raw_readl(S3C2410_SUBSRCPND); - submsk = __raw_readl(S3C2410_INTSUBMSK); - - subsrc &= ~submsk; - subsrc >>= 13; - subsrc &= 3; - - if (subsrc != 0) { - if (subsrc & 1) { - generic_handle_irq(IRQ_S3C2440_WDT); - } - if (subsrc & 2) { - generic_handle_irq(IRQ_S3C2440_AC97); - } - } -} - - -#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) - -static void -s3c_irq_wdtac97_mask(struct irq_data *data) -{ - s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13); -} - -static void -s3c_irq_wdtac97_unmask(struct irq_data *data) -{ - s3c_irqsub_unmask(data->irq, INTMSK_WDT); -} - -static void -s3c_irq_wdtac97_ack(struct irq_data *data) -{ - s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13); -} - -static struct irq_chip s3c_irq_wdtac97 = { - .irq_mask = s3c_irq_wdtac97_mask, - .irq_unmask = s3c_irq_wdtac97_unmask, - .irq_ack = s3c_irq_wdtac97_ack, -}; - -static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif) -{ - unsigned int irqno; - - printk("S3C2440: IRQ Support\n"); - - /* add new chained handler for wdt, ac7 */ - - irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip, - handle_level_irq); - irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); - - for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { - irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97, - handle_level_irq); - set_irq_flags(irqno, IRQF_VALID); - } - - return 0; -} - -static struct subsys_interface s3c2440_irq_interface = { - .name = "s3c2440_irq", - .subsys = &s3c2440_subsys, - .add_dev = s3c2440_irq_add, -}; - -static int s3c2440_irq_init(void) -{ - return subsys_interface_register(&s3c2440_irq_interface); -} - -arch_initcall(s3c2440_irq_init); - diff --git a/arch/arm/mach-s3c24xx/irq-s3c244x.c b/arch/arm/mach-s3c24xx/irq-s3c244x.c deleted file mode 100644 index 5fe8e58d3af..00000000000 --- a/arch/arm/mach-s3c24xx/irq-s3c244x.c +++ /dev/null @@ -1,142 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c - * - * Copyright (c) 2003-2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/device.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/irq.h> - -#include <asm/mach/irq.h> - -#include <mach/regs-irq.h> -#include <mach/regs-gpio.h> - -#include <plat/cpu.h> -#include <plat/pm.h> -#include <plat/irq.h> - -/* camera irq */ - -static void s3c_irq_demux_cam(unsigned int irq, - struct irq_desc *desc) -{ - unsigned int subsrc, submsk; - - /* read the current pending interrupts, and the mask - * for what it is available */ - - subsrc = __raw_readl(S3C2410_SUBSRCPND); - submsk = __raw_readl(S3C2410_INTSUBMSK); - - subsrc &= ~submsk; - subsrc >>= 11; - subsrc &= 3; - - if (subsrc != 0) { - if (subsrc & 1) { - generic_handle_irq(IRQ_S3C2440_CAM_C); - } - if (subsrc & 2) { - generic_handle_irq(IRQ_S3C2440_CAM_P); - } - } -} - -#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) - -static void -s3c_irq_cam_mask(struct irq_data *data) -{ - s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11); -} - -static void -s3c_irq_cam_unmask(struct irq_data *data) -{ - s3c_irqsub_unmask(data->irq, INTMSK_CAM); -} - -static void -s3c_irq_cam_ack(struct irq_data *data) -{ - s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11); -} - -static struct irq_chip s3c_irq_cam = { - .irq_mask = s3c_irq_cam_mask, - .irq_unmask = s3c_irq_cam_unmask, - .irq_ack = s3c_irq_cam_ack, -}; - -static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif) -{ - unsigned int irqno; - - irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip, - handle_level_irq); - set_irq_flags(IRQ_NFCON, IRQF_VALID); - - /* add chained handler for camera */ - - irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip, - handle_level_irq); - irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam); - - for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { - irq_set_chip_and_handler(irqno, &s3c_irq_cam, - handle_level_irq); - set_irq_flags(irqno, IRQF_VALID); - } - - return 0; -} - -static struct subsys_interface s3c2440_irq_interface = { - .name = "s3c2440_irq", - .subsys = &s3c2440_subsys, - .add_dev = s3c244x_irq_add, -}; - -static int s3c2440_irq_init(void) -{ - return subsys_interface_register(&s3c2440_irq_interface); -} - -arch_initcall(s3c2440_irq_init); - -static struct subsys_interface s3c2442_irq_interface = { - .name = "s3c2442_irq", - .subsys = &s3c2442_subsys, - .add_dev = s3c244x_irq_add, -}; - - -static int s3c2442_irq_init(void) -{ - return subsys_interface_register(&s3c2442_irq_interface); -} - -arch_initcall(s3c2442_irq_init); diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index cb9f5e011e7..3f3de749209 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -34,7 +34,6 @@ #include <plat/cpu.h> #include <plat/regs-irqtype.h> #include <plat/pm.h> -#include <plat/irq.h> #define S3C_IRQTYPE_NONE 0 #define S3C_IRQTYPE_EINT 1 @@ -175,8 +174,7 @@ static int s3c_irqext_type_set(void __iomem *gpcon_reg, return 0; } -/* FIXME: make static when it's out of plat-samsung/irq.h */ -int s3c_irqext_type(struct irq_data *data, unsigned int type) +static int s3c_irqext_type(struct irq_data *data, unsigned int type) { void __iomem *extint_reg; void __iomem *gpcon_reg; @@ -224,7 +222,7 @@ static int s3c_irqext0_type(struct irq_data *data, unsigned int type) extint_offset, type); } -struct irq_chip s3c_irq_chip = { +static struct irq_chip s3c_irq_chip = { .name = "s3c", .irq_ack = s3c_irq_ack, .irq_mask = s3c_irq_mask, @@ -232,7 +230,7 @@ struct irq_chip s3c_irq_chip = { .irq_set_wake = s3c_irq_wake }; -struct irq_chip s3c_irq_level_chip = { +static struct irq_chip s3c_irq_level_chip = { .name = "s3c-level", .irq_mask = s3c_irq_mask, .irq_unmask = s3c_irq_unmask, @@ -344,7 +342,10 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, case S3C_IRQTYPE_NONE: return 0; case S3C_IRQTYPE_EINT: - if (irq_data->parent_irq) + /* On the S3C2412, the EINT0to3 have a parent irq + * but need the s3c_irq_eint0t4 chip + */ + if (irq_data->parent_irq && (!soc_is_s3c2412() || hw >= 4)) irq_set_chip_and_handler(virq, &s3c_irqext_chip, handle_edge_irq); else @@ -452,7 +453,6 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, void __iomem *base = (void *)0xf6000000; /* static mapping */ int irq_num; int irq_start; - int irq_offset; int ret; intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL); @@ -476,7 +476,6 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, intc->reg_intpnd = base + 0x10; irq_num = 32; irq_start = S3C2410_IRQ(0); - irq_offset = 0; break; case 0x4a000018: pr_debug("irq: found subintc\n"); @@ -484,7 +483,6 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, intc->reg_mask = base + 0x1c; irq_num = 29; irq_start = S3C2410_IRQSUB(0); - irq_offset = 0; break; case 0x4a000040: pr_debug("irq: found intc2\n"); @@ -493,7 +491,6 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, intc->reg_intpnd = base + 0x50; irq_num = 8; irq_start = S3C2416_IRQ(0); - irq_offset = 0; break; case 0x560000a4: pr_debug("irq: found eintc\n"); @@ -501,9 +498,8 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, intc->reg_mask = base + 0xa4; intc->reg_pending = base + 0x08; - irq_num = 20; + irq_num = 24; irq_start = S3C2410_IRQ(32); - irq_offset = 4; break; default: pr_err("irq: unsupported controller address\n"); @@ -514,7 +510,7 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, /* 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, - irq_offset, &s3c24xx_irq_ops, + 0, &s3c24xx_irq_ops, intc); if (!intc->domain) { pr_err("irq: could not create irq-domain\n"); @@ -628,6 +624,108 @@ void __init s3c24xx_init_irq(void) s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); } +#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 s3c2412_init_irq(void) +{ + struct s3c_irq_intc *main_intc; + + pr_info("S3C2412: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + main_intc = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL, 0x4a000000); + if (IS_ERR(main_intc)) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018); +} +#endif + #ifdef CONFIG_CPU_S3C2416 static struct s3c_irq_data init_s3c2416base[32] = { { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ @@ -731,6 +829,154 @@ void __init s3c2416_init_irq(void) #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 }, /* TC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +void __init s3c2440_init_irq(void) +{ + struct s3c_irq_intc *main_intc; + + pr_info("S3C2440: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + main_intc = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL, 0x4a000000); + if (IS_ERR(main_intc)) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2440subint[0], main_intc, 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 }, /* TC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */ +}; + +void __init s3c2442_init_irq(void) +{ + struct s3c_irq_intc *main_intc; + + pr_info("S3C2442: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + main_intc = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, 0x4a000000); + if (IS_ERR(main_intc)) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2442subint[0], main_intc, 0x4a000018); +} +#endif + #ifdef CONFIG_CPU_S3C2443 static struct s3c_irq_data init_s3c2443base[32] = { { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c index 0e0279e7915..432144cb54a 100644 --- a/arch/arm/mach-s3c24xx/mach-amlm5900.c +++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c @@ -63,6 +63,8 @@ #include <linux/mtd/map.h> #include <linux/mtd/physmap.h> +#include <plat/samsung-time.h> + #include "common.h" static struct resource amlm5900_nor_resource = @@ -160,6 +162,7 @@ static void __init amlm5900_map_io(void) s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } #ifdef CONFIG_FB_S3C2410 @@ -237,6 +240,6 @@ MACHINE_START(AML_M5900, "AML_M5900") .map_io = amlm5900_map_io, .init_irq = s3c24xx_init_irq, .init_machine = amlm5900_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c index bb595f15ce3..c1fb6c37867 100644 --- a/arch/arm/mach-s3c24xx/mach-anubis.c +++ b/arch/arm/mach-s3c24xx/mach-anubis.c @@ -49,6 +49,7 @@ #include <plat/devs.h> #include <plat/cpu.h> #include <linux/platform_data/asoc-s3c24xx_simtec.h> +#include <plat/samsung-time.h> #include "anubis.h" #include "common.h" @@ -410,6 +411,7 @@ static void __init anubis_map_io(void) s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); s3c24xx_init_clocks(0); 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 */ @@ -443,7 +445,7 @@ MACHINE_START(ANUBIS, "Simtec-Anubis") .atag_offset = 0x100, .map_io = anubis_map_io, .init_machine = anubis_init, - .init_irq = s3c24xx_init_irq, - .init_time = s3c24xx_timer_init, + .init_irq = s3c2440_init_irq, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c index b4bc60c78eb..6dfeeb7ef46 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -48,6 +48,7 @@ #include <plat/devs.h> #include <plat/cpu.h> #include <linux/platform_data/mmc-s3cmci.h> +#include <plat/samsung-time.h> #include "common.h" @@ -192,6 +193,7 @@ static void __init at2440evb_map_io(void) s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); s3c24xx_init_clocks(16934400); s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init at2440evb_init(void) @@ -209,7 +211,7 @@ MACHINE_START(AT2440EVB, "AT2440EVB") .atag_offset = 0x100, .map_io = at2440evb_map_io, .init_machine = at2440evb_init, - .init_irq = s3c24xx_init_irq, - .init_time = s3c24xx_timer_init, + .init_irq = s3c2440_init_irq, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c index ca661808104..eabe2db42ef 100644 --- a/arch/arm/mach-s3c24xx/mach-bast.c +++ b/arch/arm/mach-s3c24xx/mach-bast.c @@ -55,6 +55,7 @@ #include <plat/devs.h> #include <plat/gpio-cfg.h> #include <plat/regs-serial.h> +#include <plat/samsung-time.h> #include "bast.h" #include "common.h" @@ -576,6 +577,7 @@ static void __init bast_map_io(void) s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init bast_init(void) @@ -605,6 +607,6 @@ MACHINE_START(BAST, "Simtec-BAST") .map_io = bast_map_io, .init_irq = s3c24xx_init_irq, .init_machine = bast_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index a25e8c5a7b4..13d8d073675 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -81,6 +81,7 @@ #include <plat/gpio-cfg.h> #include <plat/pm.h> #include <plat/regs-serial.h> +#include <plat/samsung-time.h> #include "common.h" #include "gta02.h" @@ -501,6 +502,7 @@ static void __init gta02_map_io(void) s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } @@ -587,8 +589,8 @@ MACHINE_START(NEO1973_GTA02, "GTA02") /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */ .atag_offset = 0x100, .map_io = gta02_map_io, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2442_init_irq, .init_machine = gta02_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index 79bc0830d74..8dd66010284 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -62,7 +62,7 @@ #include <plat/pll.h> #include <plat/pm.h> #include <plat/regs-serial.h> - +#include <plat/samsung-time.h> #include "common.h" #include "h1940.h" @@ -646,6 +646,7 @@ static void __init h1940_map_io(void) s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* setup PM */ @@ -741,6 +742,6 @@ MACHINE_START(H1940, "IPAQ-H1940") .reserve = h1940_reserve, .init_irq = h1940_init_irq, .init_machine = h1940_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index 54e83c1f780..a45fcd8ccf7 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c @@ -46,14 +46,15 @@ #include <linux/mtd/nand_ecc.h> #include <linux/mtd/partitions.h> -#include <plat/s3c2412.h> #include <plat/gpio-cfg.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> #include <plat/pm.h> #include <linux/platform_data/usb-s3c2410_udc.h> +#include <plat/samsung-time.h> +#include "common.h" #include "s3c2412-power.h" static struct map_desc jive_iodesc[] __initdata = { @@ -506,6 +507,7 @@ static void __init jive_map_io(void) s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void jive_power_off(void) @@ -658,9 +660,9 @@ MACHINE_START(JIVE, "JIVE") /* Maintainer: Ben Dooks <ben-linux@fluff.org> */ .atag_offset = 0x100, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2412_init_irq, .map_io = jive_map_io, .init_machine = jive_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2412_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 2865e5919f2..a83db46320b 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -56,6 +56,7 @@ #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> #include <sound/s3c24xx_uda134x.h> @@ -525,6 +526,7 @@ static void __init mini2440_map_io(void) s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } /* @@ -686,7 +688,7 @@ MACHINE_START(MINI2440, "MINI2440") .atag_offset = 0x100, .map_io = mini2440_map_io, .init_machine = mini2440_init, - .init_irq = s3c24xx_init_irq, - .init_time = s3c24xx_timer_init, + .init_irq = s3c2440_init_irq, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c index d9d04b24029..73a690f431e 100644 --- a/arch/arm/mach-s3c24xx/mach-n30.c +++ b/arch/arm/mach-s3c24xx/mach-n30.c @@ -48,8 +48,8 @@ #include <plat/cpu.h> #include <plat/devs.h> #include <linux/platform_data/mmc-s3cmci.h> -#include <plat/s3c2410.h> #include <linux/platform_data/usb-s3c2410_udc.h> +#include <plat/samsung-time.h> #include "common.h" @@ -536,6 +536,7 @@ static void __init n30_map_io(void) n30_hwinit(); s3c24xx_init_clocks(0); s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } /* GPB3 is the line that controls the pull-up for the USB D+ line */ @@ -589,7 +590,7 @@ MACHINE_START(N30, "Acer-N30") Ben Dooks <ben-linux@fluff.org> */ .atag_offset = 0x100, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .init_machine = n30_init, .init_irq = s3c24xx_init_irq, .map_io = n30_map_io, @@ -600,7 +601,7 @@ MACHINE_START(N35, "Acer-N35") /* Maintainer: Christer Weinigel <christer@weinigel.se> */ .atag_offset = 0x100, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .init_machine = n30_init, .init_irq = s3c24xx_init_irq, .map_io = n30_map_io, diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c index a454e246186..01f4354206f 100644 --- a/arch/arm/mach-s3c24xx/mach-nexcoder.c +++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c @@ -41,11 +41,10 @@ #include <linux/platform_data/i2c-s3c2410.h> #include <plat/gpio-cfg.h> -#include <plat/s3c2410.h> -#include <plat/s3c244x.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> #include "common.h" @@ -137,6 +136,7 @@ static void __init nexcoder_map_io(void) s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); nexcoder_sensorboard_init(); } @@ -152,7 +152,7 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") .atag_offset = 0x100, .map_io = nexcoder_map_io, .init_machine = nexcoder_init, - .init_irq = s3c24xx_init_irq, - .init_time = s3c24xx_timer_init, + .init_irq = s3c2440_init_irq, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c index ae2cbdf3e3c..58d6fbe5bf1 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris.c +++ b/arch/arm/mach-s3c24xx/mach-osiris.c @@ -45,6 +45,7 @@ #include <plat/devs.h> #include <plat/gpio-cfg.h> #include <plat/regs-serial.h> +#include <plat/samsung-time.h> #include <mach/hardware.h> #include <mach/regs-gpio.h> @@ -384,6 +385,7 @@ static void __init osiris_map_io(void) s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* check for the newer revision boards with large page nand */ @@ -424,8 +426,8 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS") /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ .atag_offset = 0x100, .map_io = osiris_map_io, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2440_init_irq, .init_machine = osiris_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c index 40a47d6c6a8..7b8670746b6 100644 --- a/arch/arm/mach-s3c24xx/mach-otom.c +++ b/arch/arm/mach-s3c24xx/mach-otom.c @@ -33,7 +33,7 @@ #include <plat/cpu.h> #include <plat/devs.h> #include <plat/regs-serial.h> -#include <plat/s3c2410.h> +#include <plat/samsung-time.h> #include "common.h" #include "otom.h" @@ -102,6 +102,7 @@ static void __init otom11_map_io(void) s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init otom11_init(void) @@ -116,6 +117,6 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1") .map_io = otom11_map_io, .init_machine = otom11_init, .init_irq = s3c24xx_init_irq, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c index 56175f0941b..71cf29b12d1 100644 --- a/arch/arm/mach-s3c24xx/mach-qt2410.c +++ b/arch/arm/mach-s3c24xx/mach-qt2410.c @@ -55,13 +55,14 @@ #include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/common-smdk.h> #include <plat/gpio-cfg.h> #include <plat/devs.h> #include <plat/cpu.h> #include <plat/pm.h> +#include <plat/samsung-time.h> #include "common.h" +#include "common-smdk.h" static struct map_desc qt2410_iodesc[] __initdata = { { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE } @@ -304,6 +305,7 @@ static void __init qt2410_map_io(void) s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc)); s3c24xx_init_clocks(12*1000*1000); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init qt2410_machine_init(void) @@ -343,6 +345,6 @@ MACHINE_START(QT2410, "QT2410") .map_io = qt2410_map_io, .init_irq = s3c24xx_init_irq, .init_machine = qt2410_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 1f9ba2ae528..e4d67a33ebe 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -58,6 +58,7 @@ #include <plat/pm.h> #include <plat/regs-iic.h> #include <plat/regs-serial.h> +#include <plat/samsung-time.h> #include "common.h" #include "h1940.h" @@ -741,6 +742,7 @@ static void __init rx1950_map_io(void) s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc)); s3c24xx_init_clocks(16934000); s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* setup PM */ @@ -811,8 +813,8 @@ MACHINE_START(RX1950, "HP iPAQ RX1950") .atag_offset = 0x100, .map_io = rx1950_map_io, .reserve = rx1950_reserve, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2442_init_irq, .init_machine = rx1950_init_machine, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c index f20418a2fb1..3bc6231d0a1 100644 --- a/arch/arm/mach-s3c24xx/mach-rx3715.c +++ b/arch/arm/mach-s3c24xx/mach-rx3715.c @@ -49,6 +49,7 @@ #include <plat/devs.h> #include <plat/pm.h> #include <plat/regs-serial.h> +#include <plat/samsung-time.h> #include "common.h" #include "h1940.h" @@ -179,6 +180,7 @@ static void __init rx3715_map_io(void) s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); s3c24xx_init_clocks(16934000); s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } /* H1940 and RX3715 need to reserve this for suspend */ @@ -188,11 +190,6 @@ static void __init rx3715_reserve(void) memblock_reserve(0x30081000, 0x1000); } -static void __init rx3715_init_irq(void) -{ - s3c24xx_init_irq(); -} - static void __init rx3715_init_machine(void) { #ifdef CONFIG_PM_H1940 @@ -210,8 +207,8 @@ MACHINE_START(RX3715, "IPAQ-RX3715") .atag_offset = 0x100, .map_io = rx3715_map_io, .reserve = rx3715_reserve, - .init_irq = rx3715_init_irq, + .init_irq = s3c2440_init_irq, .init_machine = rx3715_init_machine, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c index e184bfa9613..fd96f7fc330 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2410.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c @@ -51,10 +51,10 @@ #include <plat/devs.h> #include <plat/cpu.h> - -#include <plat/common-smdk.h> +#include <plat/samsung-time.h> #include "common.h" +#include "common-smdk.h" static struct map_desc smdk2410_iodesc[] __initdata = { /* nothing here yet */ @@ -101,6 +101,7 @@ static void __init smdk2410_map_io(void) s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdk2410_init(void) @@ -117,6 +118,6 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc .map_io = smdk2410_map_io, .init_irq = s3c24xx_init_irq, .init_machine = smdk2410_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c index 86d7847c9d4..8146e920f10 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2413.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2413.c @@ -41,13 +41,13 @@ #include <linux/platform_data/i2c-s3c2410.h> #include <mach/fb.h> -#include <plat/s3c2410.h> -#include <plat/s3c2412.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> -#include <plat/common-smdk.h> +#include "common.h" +#include "common-smdk.h" static struct map_desc smdk2413_iodesc[] __initdata = { }; @@ -106,6 +106,7 @@ static void __init smdk2413_map_io(void) s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdk2413_machine_init(void) @@ -129,10 +130,10 @@ MACHINE_START(S3C2413, "S3C2413") .atag_offset = 0x100, .fixup = smdk2413_fixup, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2412_init_irq, .map_io = smdk2413_map_io, .init_machine = smdk2413_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2412_restart, MACHINE_END @@ -141,10 +142,10 @@ MACHINE_START(SMDK2412, "SMDK2412") .atag_offset = 0x100, .fixup = smdk2413_fixup, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2412_init_irq, .map_io = smdk2413_map_io, .init_machine = smdk2413_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2412_restart, MACHINE_END @@ -153,9 +154,9 @@ MACHINE_START(SMDK2413, "SMDK2413") .atag_offset = 0x100, .fixup = smdk2413_fixup, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2412_init_irq, .map_io = smdk2413_map_io, .init_machine = smdk2413_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2412_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c index ebb2e61f3d0..cb46847c66b 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2416.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c @@ -42,7 +42,6 @@ #include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/s3c2416.h> #include <plat/gpio-cfg.h> #include <plat/clock.h> #include <plat/devs.h> @@ -51,10 +50,12 @@ #include <plat/sdhci.h> #include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/s3c-hsudc.h> +#include <plat/samsung-time.h> #include <plat/fb.h> -#include <plat/common-smdk.h> +#include "common.h" +#include "common-smdk.h" static struct map_desc smdk2416_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -221,6 +222,7 @@ static void __init smdk2416_map_io(void) s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdk2416_machine_init(void) @@ -253,6 +255,6 @@ MACHINE_START(SMDK2416, "SMDK2416") .init_irq = s3c2416_init_irq, .map_io = smdk2416_map_io, .init_machine = smdk2416_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2416_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c index 08cc38c8a4a..de2e5d39a84 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2440.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c @@ -38,15 +38,13 @@ #include <mach/fb.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/s3c2410.h> -#include <plat/s3c244x.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> - -#include <plat/common-smdk.h> +#include <plat/samsung-time.h> #include "common.h" +#include "common-smdk.h" static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -163,6 +161,7 @@ static void __init smdk2440_map_io(void) s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(16934400); s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdk2440_machine_init(void) @@ -178,9 +177,9 @@ MACHINE_START(S3C2440, "SMDK2440") /* Maintainer: Ben Dooks <ben-linux@fluff.org> */ .atag_offset = 0x100, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2440_init_irq, .map_io = smdk2440_map_io, .init_machine = smdk2440_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c index fc65d74d3c7..9435c3bef18 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2443.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c @@ -38,13 +38,13 @@ #include <mach/fb.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/s3c2410.h> -#include <plat/s3c2443.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> -#include <plat/common-smdk.h> +#include "common.h" +#include "common-smdk.h" static struct map_desc smdk2443_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -122,6 +122,7 @@ static void __init smdk2443_map_io(void) s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdk2443_machine_init(void) @@ -143,6 +144,6 @@ MACHINE_START(SMDK2443, "SMDK2443") .init_irq = s3c2443_init_irq, .map_io = smdk2443_map_io, .init_machine = smdk2443_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2443_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c index 24b3d79e7b2..31dfe589e34 100644 --- a/arch/arm/mach-s3c24xx/mach-tct_hammer.c +++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c @@ -53,6 +53,7 @@ #include <linux/mtd/partitions.h> #include <linux/mtd/map.h> #include <linux/mtd/physmap.h> +#include <plat/samsung-time.h> #include "common.h" @@ -136,6 +137,7 @@ static void __init tct_hammer_map_io(void) s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init tct_hammer_init(void) @@ -149,6 +151,6 @@ MACHINE_START(TCT_HAMMER, "TCT_HAMMER") .map_io = tct_hammer_map_io, .init_irq = s3c24xx_init_irq, .init_machine = tct_hammer_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c index ec42d1e4e46..deeb8a0a403 100644 --- a/arch/arm/mach-s3c24xx/mach-vr1000.c +++ b/arch/arm/mach-s3c24xx/mach-vr1000.c @@ -45,6 +45,7 @@ #include <plat/cpu.h> #include <plat/devs.h> #include <plat/regs-serial.h> +#include <plat/samsung-time.h> #include "bast.h" #include "common.h" @@ -332,6 +333,7 @@ static void __init vr1000_map_io(void) s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init vr1000_init(void) @@ -354,6 +356,6 @@ MACHINE_START(VR1000, "Thorcom-VR1000") .map_io = vr1000_map_io, .init_machine = vr1000_init, .init_irq = s3c24xx_init_irq, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2410_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index 3e2bfddc9df..b66588428ec 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c @@ -41,12 +41,12 @@ #include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/s3c2410.h> -#include <plat/s3c2412.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> +#include "common.h" static struct map_desc vstms_iodesc[] __initdata = { }; @@ -143,6 +143,7 @@ static void __init vstms_map_io(void) s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init vstms_init(void) @@ -157,9 +158,9 @@ MACHINE_START(VSTMS, "VSTMS") .atag_offset = 0x100, .fixup = vstms_fixup, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2412_init_irq, .init_machine = vstms_init, .map_io = vstms_map_io, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c2412_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/pm-s3c2412.c b/arch/arm/mach-s3c24xx/pm-s3c2412.c index 668a78a8b19..d75f95e487e 100644 --- a/arch/arm/mach-s3c24xx/pm-s3c2412.c +++ b/arch/arm/mach-s3c24xx/pm-s3c2412.c @@ -29,7 +29,7 @@ #include <plat/cpu.h> #include <plat/pm.h> -#include <plat/s3c2412.h> +#include <plat/wakeup-mask.h> #include "regs-dsc.h" #include "s3c2412-power.h" @@ -52,8 +52,15 @@ static int s3c2412_cpu_suspend(unsigned long arg) return 1; /* Aborting suspend */ } +/* mapping of interrupts to parts of the wakeup mask */ +static struct samsung_wakeup_mask wake_irqs[] = { + { .irq = IRQ_RTC, .bit = S3C2412_PWRCFG_RTC_MASKIRQ, }, +}; + static void s3c2412_pm_prepare(void) { + samsung_sync_wakemask(S3C2412_PWRCFG, + wake_irqs, ARRAY_SIZE(wake_irqs)); } static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif) diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c index 9ebef95da72..d850ea5adac 100644 --- a/arch/arm/mach-s3c24xx/s3c2410.c +++ b/arch/arm/mach-s3c24xx/s3c2410.c @@ -37,7 +37,6 @@ #include <mach/regs-clock.h> #include <plat/regs-serial.h> -#include <plat/s3c2410.h> #include <plat/cpu.h> #include <plat/devs.h> #include <plat/clock.h> diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c index 0d592159a5c..0f864d4c97d 100644 --- a/arch/arm/mach-s3c24xx/s3c2412.c +++ b/arch/arm/mach-s3c24xx/s3c2412.c @@ -44,7 +44,6 @@ #include <plat/pm.h> #include <plat/regs-serial.h> #include <plat/regs-spi.h> -#include <plat/s3c2412.h> #include "common.h" #include "regs-dsc.h" diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c index e30476db029..b9c5d382daf 100644 --- a/arch/arm/mach-s3c24xx/s3c2416.c +++ b/arch/arm/mach-s3c24xx/s3c2416.c @@ -50,7 +50,6 @@ #include <plat/gpio-core.h> #include <plat/gpio-cfg.h> #include <plat/gpio-cfg-helpers.h> -#include <plat/s3c2416.h> #include <plat/devs.h> #include <plat/cpu.h> #include <plat/sdhci.h> diff --git a/arch/arm/mach-s3c24xx/s3c2440.c b/arch/arm/mach-s3c24xx/s3c2440.c index 559e394e898..5f9d6569475 100644 --- a/arch/arm/mach-s3c24xx/s3c2440.c +++ b/arch/arm/mach-s3c24xx/s3c2440.c @@ -33,7 +33,6 @@ #include <plat/devs.h> #include <plat/cpu.h> -#include <plat/s3c244x.h> #include <plat/pm.h> #include <plat/gpio-core.h> diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c index f732826c235..6819961f6b1 100644 --- a/arch/arm/mach-s3c24xx/s3c2442.c +++ b/arch/arm/mach-s3c24xx/s3c2442.c @@ -44,7 +44,6 @@ #include <plat/clock.h> #include <plat/cpu.h> -#include <plat/s3c244x.h> #include <plat/pm.h> #include <plat/gpio-core.h> diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c index 165b6a6b3da..8328cd65bf3 100644 --- a/arch/arm/mach-s3c24xx/s3c2443.c +++ b/arch/arm/mach-s3c24xx/s3c2443.c @@ -36,7 +36,6 @@ #include <plat/gpio-core.h> #include <plat/gpio-cfg.h> #include <plat/gpio-cfg-helpers.h> -#include <plat/s3c2443.h> #include <plat/devs.h> #include <plat/cpu.h> #include <plat/fb-core.h> diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c index ad2671baa91..2a35edb6735 100644 --- a/arch/arm/mach-s3c24xx/s3c244x.c +++ b/arch/arm/mach-s3c24xx/s3c244x.c @@ -37,8 +37,6 @@ #include <plat/regs-serial.h> #include <mach/regs-gpio.h> -#include <plat/s3c2410.h> -#include <plat/s3c244x.h> #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 131c8628471..283cb77d472 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -17,11 +17,13 @@ config PLAT_S3C64XX # Configuration options for the S3C6410 CPU config CPU_S3C6400 + select SAMSUNG_HRT bool help Enable S3C6400 CPU support config CPU_S3C6410 + select SAMSUNG_HRT bool help Enable S3C6410 CPU support diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index 728eef3296b..35e3f54574e 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -49,6 +49,7 @@ #include <plat/devs.h> #include <plat/cpu.h> #include <mach/regs-gpio.h> +#include <plat/samsung-time.h> #include "common.h" #include "regs-modem.h" @@ -208,6 +209,7 @@ static void __init anw6410_map_io(void) s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); anw6410_lcd_mode_set(); } @@ -232,6 +234,6 @@ MACHINE_START(ANW6410, "A&W6410") .map_io = anw6410_map_io, .init_machine = anw6410_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 1acf02bace5..8ad88ace795 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -64,6 +64,7 @@ #include <plat/adc.h> #include <linux/platform_data/i2c-s3c2410.h> #include <plat/pm.h> +#include <plat/samsung-time.h> #include "common.h" #include "crag6410.h" @@ -744,6 +745,7 @@ static void __init crag6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* LCD type and Bypass set by bootloader */ } @@ -868,6 +870,6 @@ MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410") .map_io = crag6410_map_io, .init_machine = crag6410_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index 7212eb9cfeb..5b7f357d8c2 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -41,6 +41,7 @@ #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> #include "common.h" @@ -248,6 +249,7 @@ static void __init hmt_map_io(void) s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init hmt_machine_init(void) @@ -275,6 +277,6 @@ MACHINE_START(HMT, "Airgoo-HMT") .map_io = hmt_map_io, .init_machine = hmt_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index 4b41fcdaa7b..fc043e3ecdf 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -41,6 +41,7 @@ #include <video/platform_lcd.h> #include <video/samsung_fimd.h> +#include <plat/samsung-time.h> #include "common.h" #include "regs-modem.h" @@ -232,6 +233,7 @@ static void __init mini6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* set the LCD type */ tmp = __raw_readl(S3C64XX_SPCON); @@ -354,6 +356,6 @@ MACHINE_START(MINI6410, "MINI6410") .map_io = mini6410_map_io, .init_machine = mini6410_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c index 8d3cedd995f..7e2c3908f1f 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c64xx/mach-ncp.c @@ -43,6 +43,7 @@ #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/samsung-time.h> #include "common.h" @@ -87,6 +88,7 @@ static void __init ncp_map_io(void) s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init ncp_machine_init(void) @@ -103,6 +105,6 @@ MACHINE_START(NCP, "NCP") .map_io = ncp_map_io, .init_machine = ncp_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index fa12bd21ad8..8bed37b3d5a 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c @@ -42,6 +42,7 @@ #include <video/platform_lcd.h> #include <video/samsung_fimd.h> +#include <plat/samsung-time.h> #include "common.h" #include "regs-modem.h" @@ -211,6 +212,7 @@ static void __init real6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* set the LCD type */ tmp = __raw_readl(S3C64XX_SPCON); @@ -333,6 +335,6 @@ MACHINE_START(REAL6410, "REAL6410") .map_io = real6410_map_io, .init_machine = real6410_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index fc3e9b32e26..58ac9904127 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -38,6 +38,7 @@ #include <linux/platform_data/touchscreen-s3c2410.h> #include <video/platform_lcd.h> +#include <plat/samsung-time.h> #include "common.h" #include "regs-modem.h" @@ -378,6 +379,7 @@ void __init smartq_map_io(void) s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); smartq_lcd_mode_set(); } diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c index ca2afcfce57..8aca5daf3d0 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq5.c +++ b/arch/arm/mach-s3c64xx/mach-smartq5.c @@ -28,6 +28,7 @@ #include <plat/devs.h> #include <plat/fb.h> #include <plat/gpio-cfg.h> +#include <plat/samsung-time.h> #include "common.h" #include "mach-smartq.h" @@ -155,6 +156,6 @@ MACHINE_START(SMARTQ5, "SmartQ 5") .map_io = smartq_map_io, .init_machine = smartq5_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c index 37bb0c632a5..a052e107c0b 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq7.c +++ b/arch/arm/mach-s3c64xx/mach-smartq7.c @@ -28,6 +28,7 @@ #include <plat/devs.h> #include <plat/fb.h> #include <plat/gpio-cfg.h> +#include <plat/samsung-time.h> #include "common.h" #include "mach-smartq.h" @@ -171,6 +172,6 @@ MACHINE_START(SMARTQ7, "SmartQ 7") .map_io = smartq_map_io, .init_machine = smartq7_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index a392869c834..d70c0843aea 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -35,6 +35,7 @@ #include <plat/devs.h> #include <plat/cpu.h> #include <linux/platform_data/i2c-s3c2410.h> +#include <plat/samsung-time.h> #include "common.h" @@ -66,6 +67,7 @@ static void __init smdk6400_map_io(void) s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static struct platform_device *smdk6400_devices[] __initdata = { @@ -92,6 +94,6 @@ MACHINE_START(SMDK6400, "SMDK6400") .map_io = smdk6400_map_io, .init_machine = smdk6400_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index ba7544e2d04..bd3295a19ad 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -69,6 +69,7 @@ #include <linux/platform_data/touchscreen-s3c2410.h> #include <plat/keypad.h> #include <plat/backlight.h> +#include <plat/samsung-time.h> #include "common.h" #include "regs-modem.h" @@ -634,6 +635,7 @@ static void __init smdk6410_map_io(void) s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); /* set the LCD type */ @@ -702,6 +704,6 @@ MACHINE_START(SMDK6410, "SMDK6410") .map_io = smdk6410_map_io, .init_machine = smdk6410_machine_init, .init_late = s3c64xx_init_late, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s3c64xx_restart, MACHINE_END diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig index e8742cb7ddd..5a707bdb9ea 100644 --- a/arch/arm/mach-s5p64x0/Kconfig +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -9,16 +9,16 @@ if ARCH_S5P64X0 config CPU_S5P6440 bool - select S5P_HRT select S5P_SLEEP if PM select SAMSUNG_DMADEV + select SAMSUNG_HRT select SAMSUNG_WAKEMASK if PM help Enable S5P6440 CPU support config CPU_S5P6450 bool - select S5P_HRT + select SAMSUNG_HRT select S5P_SLEEP if PM select SAMSUNG_DMADEV select SAMSUNG_WAKEMASK if PM diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c index e23723a5a21..73f71a698a3 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@ -48,7 +48,7 @@ #include <plat/pll.h> #include <plat/adc.h> #include <linux/platform_data/touchscreen-s3c2410.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include <plat/backlight.h> #include <plat/fb.h> #include <plat/sdhci.h> @@ -229,7 +229,7 @@ static void __init smdk6440_map_io(void) s5p64x0_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void s5p6440_set_lcd_interface(void) @@ -273,6 +273,6 @@ MACHINE_START(SMDK6440, "SMDK6440") .init_irq = s5p6440_init_irq, .map_io = smdk6440_map_io, .init_machine = smdk6440_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .restart = s5p64x0_restart, MACHINE_END diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c index ca10963a959..18303e12019 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -48,7 +48,7 @@ #include <plat/pll.h> #include <plat/adc.h> #include <linux/platform_data/touchscreen-s3c2410.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include <plat/backlight.h> #include <plat/fb.h> #include <plat/sdhci.h> @@ -248,7 +248,7 @@ static void __init smdk6450_map_io(void) s5p64x0_init_io(NULL, 0); s3c24xx_init_clocks(19200000); s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void s5p6450_set_lcd_interface(void) @@ -292,6 +292,6 @@ MACHINE_START(SMDK6450, "SMDK6450") .init_irq = s5p6450_init_irq, .map_io = smdk6450_map_io, .init_machine = smdk6450_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .restart = s5p64x0_restart, MACHINE_END diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index 15170be97a7..2f456a4533b 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -11,6 +11,7 @@ config CPU_S5PC100 bool select S5P_EXT_INT select SAMSUNG_DMADEV + select SAMSUNG_HRT help Enable S5PC100 CPU support diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index 185a1958389..8c880f76f27 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c @@ -51,6 +51,7 @@ #include <linux/platform_data/touchscreen-s3c2410.h> #include <linux/platform_data/asoc-s3c.h> #include <plat/backlight.h> +#include <plat/samsung-time.h> #include "common.h" @@ -221,6 +222,7 @@ static void __init smdkc100_map_io(void) s5pc100_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdkc100_uartcfgs, ARRAY_SIZE(smdkc100_uartcfgs)); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdkc100_machine_init(void) @@ -255,6 +257,6 @@ MACHINE_START(SMDKC100, "SMDKC100") .init_irq = s5pc100_init_irq, .map_io = smdkc100_map_io, .init_machine = smdkc100_machine_init, - .init_time = s3c24xx_timer_init, + .init_time = samsung_timer_init, .restart = s5pc100_restart, MACHINE_END diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 92ad72f0ef9..0963283a7c5 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -12,10 +12,10 @@ if ARCH_S5PV210 config CPU_S5PV210 bool select S5P_EXT_INT - select S5P_HRT select S5P_PM if PM select S5P_SLEEP if PM select SAMSUNG_DMADEV + select SAMSUNG_HRT help Enable S5PV210 CPU support diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 11900a8e88a..ed2b85485b9 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c @@ -38,7 +38,7 @@ #include <plat/fb.h> #include <plat/fimc-core.h> #include <plat/sdhci.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include "common.h" @@ -651,7 +651,7 @@ static void __init aquila_map_io(void) s5pv210_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init aquila_machine_init(void) @@ -686,6 +686,6 @@ MACHINE_START(AQUILA, "Aquila") .init_irq = s5pv210_init_irq, .map_io = aquila_map_io, .init_machine = aquila_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .restart = s5pv210_restart, MACHINE_END diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index e373de44a8b..30b24ad84f4 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -47,7 +47,7 @@ #include <plat/keypad.h> #include <plat/sdhci.h> #include <plat/clock.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include <plat/mfc.h> #include <plat/camport.h> @@ -908,7 +908,7 @@ static void __init goni_map_io(void) s5pv210_init_io(NULL, 0); s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init goni_reserve(void) @@ -973,7 +973,7 @@ MACHINE_START(GONI, "GONI") .init_irq = s5pv210_init_irq, .map_io = goni_map_io, .init_machine = goni_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .reserve = &goni_reserve, .restart = s5pv210_restart, MACHINE_END diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index 28bd0248a3e..7c0ed07a78a 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -29,7 +29,7 @@ #include <linux/platform_data/ata-samsung_cf.h> #include <linux/platform_data/i2c-s3c2410.h> #include <plat/pm.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include <plat/mfc.h> #include "common.h" @@ -120,7 +120,7 @@ static void __init smdkc110_map_io(void) s5pv210_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init smdkc110_reserve(void) @@ -153,7 +153,7 @@ MACHINE_START(SMDKC110, "SMDKC110") .init_irq = s5pv210_init_irq, .map_io = smdkc110_map_io, .init_machine = smdkc110_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .restart = s5pv210_restart, .reserve = &smdkc110_reserve, MACHINE_END diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 3c73f36869b..d50b6f12446 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -44,7 +44,7 @@ #include <plat/keypad.h> #include <plat/pm.h> #include <plat/fb.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include <plat/backlight.h> #include <plat/mfc.h> #include <plat/clock.h> @@ -285,7 +285,7 @@ static void __init smdkv210_map_io(void) s5pv210_init_io(NULL, 0); s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs)); - s5p_set_timer_source(S5P_PWM2, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4); } static void __init smdkv210_reserve(void) @@ -329,7 +329,7 @@ MACHINE_START(SMDKV210, "SMDKV210") .init_irq = s5pv210_init_irq, .map_io = smdkv210_map_io, .init_machine = smdkv210_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .restart = s5pv210_restart, .reserve = &smdkv210_reserve, MACHINE_END diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c index 2d4c5531819..579afe89842 100644 --- a/arch/arm/mach-s5pv210/mach-torbreck.c +++ b/arch/arm/mach-s5pv210/mach-torbreck.c @@ -26,7 +26,7 @@ #include <plat/devs.h> #include <plat/cpu.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> #include "common.h" @@ -106,7 +106,7 @@ static void __init torbreck_map_io(void) s5pv210_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } static void __init torbreck_machine_init(void) @@ -130,6 +130,6 @@ MACHINE_START(TORBRECK, "TORBRECK") .init_irq = s5pv210_init_irq, .map_io = torbreck_map_io, .init_machine = torbreck_machine_init, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .restart = s5pv210_restart, MACHINE_END diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 9255546e7bf..75d413c004b 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -16,6 +16,7 @@ config ARCH_SH73A0 select CPU_V7 select I2C select SH_CLK_CPG + select RENESAS_INTC_IRQPIN config ARCH_R8A7740 bool "R-Mobile A1 (R8A77400)" @@ -31,6 +32,7 @@ config ARCH_R8A7779 select SH_CLK_CPG select USB_ARCH_HAS_EHCI select USB_ARCH_HAS_OHCI + select RENESAS_INTC_IRQPIN config ARCH_EMEV2 bool "Emma Mobile EV2" diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index e1fac57514b..b646ff4d742 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -14,10 +14,9 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o # SMP objects smp-y := platsmp.o headsmp.o -smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o -smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-sh73a0.o -smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o -smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o +smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o +smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o +smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o # IRQ objects obj-$(CONFIG_ARCH_SH7372) += entry-intc.o diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 7f3a6b7e7b7..d34d12ae496 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -81,7 +81,7 @@ static struct resource smsc9221_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = intcs_evt2irq(0x260), /* IRQ3 */ + .start = irq_pin(3), /* IRQ3 */ .flags = IORESOURCE_IRQ, }, }; @@ -115,7 +115,7 @@ static struct resource usb_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = intcs_evt2irq(0x220), /* IRQ1 */ + .start = irq_pin(1), /* IRQ1 */ .flags = IORESOURCE_IRQ, }, }; @@ -138,7 +138,7 @@ struct usbhs_private { struct renesas_usbhs_platform_info info; }; -#define IRQ15 intcs_evt2irq(0x03e0) +#define IRQ15 irq_pin(15) #define USB_PHY_MODE (1 << 4) #define USB_PHY_INT_EN ((1 << 3) | (1 << 2)) #define USB_PHY_ON (1 << 1) @@ -563,25 +563,25 @@ static struct i2c_board_info i2c0_devices[] = { }, { I2C_BOARD_INFO("ak8975", 0x0c), - .irq = intcs_evt2irq(0x3380), /* IRQ28 */ + .irq = irq_pin(28), /* IRQ28 */ }, { I2C_BOARD_INFO("adxl34x", 0x1d), - .irq = intcs_evt2irq(0x3340), /* IRQ26 */ + .irq = irq_pin(26), /* IRQ26 */ }, }; static struct i2c_board_info i2c1_devices[] = { { I2C_BOARD_INFO("st1232-ts", 0x55), - .irq = intcs_evt2irq(0x300), /* IRQ8 */ + .irq = irq_pin(8), /* IRQ8 */ }, }; static struct i2c_board_info i2c3_devices[] = { { I2C_BOARD_INFO("pcf8575", 0x20), - .irq = intcs_evt2irq(0x3260), /* IRQ19 */ + .irq = irq_pin(19), /* IRQ19 */ .platform_data = &pcf8575_pdata, }, }; diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index 19ce885a3b4..1feb9a2286a 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c @@ -593,29 +593,42 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), + CLKDEV_DEV_ID("e6c80000.sci", &mstp_clks[MSTP200]), CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), + CLKDEV_DEV_ID("e6c70000.sci", &mstp_clks[MSTP201]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), + CLKDEV_DEV_ID("e6c60000.sci", &mstp_clks[MSTP202]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), + CLKDEV_DEV_ID("e6c50000.sci", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), + CLKDEV_DEV_ID("e6c40000.sci", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), + CLKDEV_DEV_ID("e6c30000.sci", &mstp_clks[MSTP206]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), + CLKDEV_DEV_ID("e6cb0000.sci", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), + CLKDEV_DEV_ID("e6cd0000.sci", &mstp_clks[MSTP222]), CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), + CLKDEV_DEV_ID("e6cc0000.sci", &mstp_clks[MSTP230]), CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]), CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), + CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), + CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]), + CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP309]), CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), + CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* ICK */ CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]), diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index 1db36537255..d9edeaf6600 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -87,7 +87,8 @@ static struct clk div4_clks[DIV4_NR] = { }; enum { MSTP323, MSTP322, MSTP321, MSTP320, - MSTP101, MSTP100, + MSTP115, + MSTP103, MSTP101, MSTP100, MSTP030, MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, MSTP016, MSTP015, MSTP014, @@ -99,6 +100,8 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */ [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */ + [MSTP115] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 15, 0), /* SATA */ + [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_S], MSTPCR1, 3, 0), /* DU */ [MSTP101] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 1, 0), /* USB2 */ [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 0, 0), /* USB0/1 */ [MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0), /* I2C0 */ @@ -156,6 +159,8 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), /* MSTP32 clocks */ + CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ + CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */ CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */ CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ @@ -180,6 +185,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ + CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */ }; void __init r8a7779_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index afa5423a0f9..71843dd39e1 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -265,12 +265,12 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, static struct clk div4_clks[DIV4_NR] = { [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT), - [DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), + [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT), [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0), [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0), - [DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0), + [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0), [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0), [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0), [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0), @@ -581,10 +581,13 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ + CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */ CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ diff --git a/arch/arm/mach-shmobile/headsmp-sh73a0.S b/arch/arm/mach-shmobile/headsmp-scu.S index bec4c0d9b71..7d113f898e7 100644 --- a/arch/arm/mach-shmobile/headsmp-sh73a0.S +++ b/arch/arm/mach-shmobile/headsmp-scu.S @@ -1,5 +1,5 @@ /* - * SMP support for SoC sh73a0 + * Shared SCU setup for mach-shmobile * * Copyright (C) 2012 Bastian Hecht * @@ -35,11 +35,12 @@ * the physical address as the MMU is still turned off. */ .align 12 -ENTRY(sh73a0_secondary_vector) +ENTRY(shmobile_secondary_vector_scu) mrc p15, 0, r0, c0, c0, 5 @ read MIPDR and r0, r0, #3 @ mask out cpu ID lsl r0, r0, #3 @ we will shift by cpu_id * 8 bits - mov r1, #0xf0000000 @ SCU base address + ldr r1, 2f + ldr r1, [r1] @ SCU base address ldr r2, [r1, #8] @ SCU Power Status Register mov r3, #3 bic r2, r2, r3, lsl r0 @ Clear bits of our CPU (Run Mode) @@ -47,4 +48,10 @@ ENTRY(sh73a0_secondary_vector) ldr pc, 1f 1: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET -ENDPROC(sh73a0_secondary_vector) +2: .long shmobile_scu_base - PAGE_OFFSET + PLAT_PHYS_OFFSET +ENDPROC(shmobile_secondary_vector_scu) + + .text + .globl shmobile_scu_base +shmobile_scu_base: + .space 4 diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c deleted file mode 100644 index a1524e3367b..00000000000 --- a/arch/arm/mach-shmobile/hotplug.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * SMP support for R-Mobile / SH-Mobile - * - * Copyright (C) 2010 Magnus Damm - * - * Based on realview, Copyright (C) 2002 ARM Ltd, All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/smp.h> -#include <linux/cpumask.h> -#include <linux/delay.h> -#include <linux/of.h> -#include <mach/common.h> -#include <mach/r8a7779.h> -#include <mach/emev2.h> -#include <asm/cacheflush.h> -#include <asm/mach-types.h> - -static cpumask_t dead_cpus; - -void shmobile_cpu_die(unsigned int cpu) -{ - /* hardware shutdown code running on the CPU that is being offlined */ - flush_cache_all(); - dsb(); - - /* notify platform_cpu_kill() that hardware shutdown is finished */ - cpumask_set_cpu(cpu, &dead_cpus); - - /* wait for SoC code in platform_cpu_kill() to shut off CPU core - * power. CPU bring up starts from the reset vector. - */ - while (1) { - /* - * here's the WFI - */ - asm(".word 0xe320f003\n" - : - : - : "memory", "cc"); - } -} - -int shmobile_cpu_disable(unsigned int cpu) -{ - cpumask_clear_cpu(cpu, &dead_cpus); - /* - * we don't allow CPU 0 to be shutdown (it is still too special - * e.g. clock tick interrupts) - */ - return cpu == 0 ? -EPERM : 0; -} - -int shmobile_cpu_disable_any(unsigned int cpu) -{ - cpumask_clear_cpu(cpu, &dead_cpus); - return 0; -} - -int shmobile_cpu_is_dead(unsigned int cpu) -{ - return cpumask_test_cpu(cpu, &dead_cpus); -} diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index e48606d8a2b..03f73def2fc 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -8,6 +8,7 @@ extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, struct twd_local_timer; extern void shmobile_setup_console(void); extern void shmobile_secondary_vector(void); +extern void shmobile_secondary_vector_scu(void); struct clk; extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); @@ -33,23 +34,23 @@ extern int sh7372_do_idle_sysc(unsigned long sleep_mode); extern struct clk sh7372_extal1_clk; extern struct clk sh7372_extal2_clk; +extern void sh73a0_init_delay(void); extern void sh73a0_init_irq(void); extern void sh73a0_init_irq_dt(void); extern void sh73a0_map_io(void); extern void sh73a0_earlytimer_init(void); extern void sh73a0_add_early_devices(void); -extern void sh73a0_add_early_devices_dt(void); extern void sh73a0_add_standard_devices(void); extern void sh73a0_add_standard_devices_dt(void); extern void sh73a0_clock_init(void); extern void sh73a0_pinmux_init(void); extern void sh73a0_pm_init(void); -extern void sh73a0_secondary_vector(void); extern struct clk sh73a0_extal1_clk; extern struct clk sh73a0_extal2_clk; extern struct clk sh73a0_extcki_clk; extern struct clk sh73a0_extalr_clk; +extern void r8a7740_meram_workaround(void); extern void r8a7740_init_irq(void); extern void r8a7740_map_io(void); extern void r8a7740_add_early_devices(void); @@ -58,16 +59,18 @@ extern void r8a7740_clock_init(u8 md_ck); extern void r8a7740_pinmux_init(void); extern void r8a7740_pm_init(void); +extern void r8a7779_init_delay(void); extern void r8a7779_init_irq(void); +extern void r8a7779_init_irq_extpin(int irlm); +extern void r8a7779_init_irq_dt(void); extern void r8a7779_map_io(void); extern void r8a7779_earlytimer_init(void); extern void r8a7779_add_early_devices(void); extern void r8a7779_add_standard_devices(void); +extern void r8a7779_add_standard_devices_dt(void); extern void r8a7779_clock_init(void); extern void r8a7779_pinmux_init(void); extern void r8a7779_pm_init(void); -extern void r8a7740_meram_workaround(void); - extern void r8a7779_register_twd(void); #ifdef CONFIG_SUSPEND @@ -82,16 +85,7 @@ int shmobile_cpuidle_init(void); static inline int shmobile_cpuidle_init(void) { return 0; } #endif -extern void shmobile_cpu_die(unsigned int cpu); -extern int shmobile_cpu_disable(unsigned int cpu); -extern int shmobile_cpu_disable_any(unsigned int cpu); - -#ifdef CONFIG_HOTPLUG_CPU -extern int shmobile_cpu_is_dead(unsigned int cpu); -#else -static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; } -#endif - +extern void __iomem *shmobile_scu_base; extern void shmobile_smp_init_cpus(unsigned int ncores); static inline void __init shmobile_init_late(void) diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index 06a5da3c305..b2074e2acb1 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -5,10 +5,15 @@ /* GIC */ #define gic_spi(nr) ((nr) + 32) +#define gic_iid(nr) (nr) /* ICCIAR / interrupt ID */ /* INTCS */ #define INTCS_VECT_BASE 0x3400 #define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) #define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt)) +/* External IRQ pins */ +#define IRQPIN_BASE 2000 +#define irq_pin(nr) ((nr) + IRQPIN_BASE) + #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c index 8807c27f71f..b86dc890872 100644 --- a/arch/arm/mach-shmobile/intc-r8a7779.c +++ b/arch/arm/mach-shmobile/intc-r8a7779.c @@ -19,12 +19,16 @@ */ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/io.h> #include <linux/irqchip/arm-gic.h> +#include <linux/platform_data/irq-renesas-intc-irqpin.h> +#include <linux/irqchip.h> #include <mach/common.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <mach/r8a7779.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -38,18 +42,61 @@ #define INT2NTSR0 IOMEM(0xfe700060) #define INT2NTSR1 IOMEM(0xfe700064) +static struct renesas_intc_irqpin_config irqpin0_platform_data = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ + .sense_bitfield_width = 2, +}; + +static struct resource irqpin0_resources[] = { + DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */ + DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */ + DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */ + DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */ + DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */ + DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ +}; + +static struct platform_device irqpin0_device = { + .name = "renesas_intc_irqpin", + .id = 0, + .resource = irqpin0_resources, + .num_resources = ARRAY_SIZE(irqpin0_resources), + .dev = { + .platform_data = &irqpin0_platform_data, + }, +}; + +void __init r8a7779_init_irq_extpin(int irlm) +{ + void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); + unsigned long tmp; + + if (icr0) { + tmp = ioread32(icr0); + if (irlm) + tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */ + else + tmp &= ~(1 << 23); /* IRL mode - not supported */ + tmp |= (1 << 21); /* LVLMODE = 1 */ + iowrite32(tmp, icr0); + iounmap(icr0); + + if (irlm) + platform_device_register(&irqpin0_device); + } else + pr_warn("r8a7779: unable to setup external irq pin mode\n"); +} + static int r8a7779_set_wake(struct irq_data *data, unsigned int on) { return 0; /* always allow wakeup */ } -void __init r8a7779_init_irq(void) +static void __init r8a7779_init_irq_common(void) { - void __iomem *gic_dist_base = IOMEM(0xf0001000); - void __iomem *gic_cpu_base = IOMEM(0xf0000100); - - /* use GIC to handle interrupts */ - gic_init(0, 29, gic_dist_base, gic_cpu_base); gic_arch_extn.irq_set_wake = r8a7779_set_wake; /* route all interrupts to ARM */ @@ -63,3 +110,22 @@ void __init r8a7779_init_irq(void) __raw_writel(0xbffffffc, INT2SMSKCR3); __raw_writel(0x003fee3f, INT2SMSKCR4); } + +void __init r8a7779_init_irq(void) +{ + void __iomem *gic_dist_base = IOMEM(0xf0001000); + void __iomem *gic_cpu_base = IOMEM(0xf0000100); + + /* use GIC to handle interrupts */ + gic_init(0, 29, gic_dist_base, gic_cpu_base); + + r8a7779_init_irq_common(); +} + +#ifdef CONFIG_OF +void __init r8a7779_init_irq_dt(void) +{ + irqchip_init(); + r8a7779_init_irq_common(); +} +#endif diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 91faba666d4..19a26f4579b 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -260,108 +260,6 @@ static int sh73a0_set_wake(struct irq_data *data, unsigned int on) return 0; /* always allow wakeup */ } -#define RELOC_BASE 0x1200 - -/* INTCA IRQ pins at INTCS + RELOC_BASE to make space for GIC+INTC handling */ -#define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE) - -INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000, - INTCS_VECT_RELOC, "sh73a0-intca-irq-pins"); - -static int to_gic_irq(struct irq_data *data) -{ - unsigned int vect = irq2evt(data->irq) - INTCS_VECT_BASE; - - if (vect >= 0x3200) - vect -= 0x3000; - else - vect -= 0x0200; - - return gic_spi((vect >> 5) + 1); -} - -static int to_intca_reloc_irq(struct irq_data *data) -{ - return data->irq + (RELOC_BASE >> 5); -} - -#define irq_cb(cb, irq) irq_get_chip(irq)->cb(irq_get_irq_data(irq)) -#define irq_cbp(cb, irq, p...) irq_get_chip(irq)->cb(irq_get_irq_data(irq), p) - -static void intca_gic_enable(struct irq_data *data) -{ - irq_cb(irq_unmask, to_intca_reloc_irq(data)); - irq_cb(irq_unmask, to_gic_irq(data)); -} - -static void intca_gic_disable(struct irq_data *data) -{ - irq_cb(irq_mask, to_gic_irq(data)); - irq_cb(irq_mask, to_intca_reloc_irq(data)); -} - -static void intca_gic_mask_ack(struct irq_data *data) -{ - irq_cb(irq_mask, to_gic_irq(data)); - irq_cb(irq_mask_ack, to_intca_reloc_irq(data)); -} - -static void intca_gic_eoi(struct irq_data *data) -{ - irq_cb(irq_eoi, to_gic_irq(data)); -} - -static int intca_gic_set_type(struct irq_data *data, unsigned int type) -{ - return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type); -} - -#ifdef CONFIG_SMP -static int intca_gic_set_affinity(struct irq_data *data, - const struct cpumask *cpumask, - bool force) -{ - return irq_cbp(irq_set_affinity, to_gic_irq(data), cpumask, force); -} -#endif - -struct irq_chip intca_gic_irq_chip = { - .name = "INTCA-GIC", - .irq_mask = intca_gic_disable, - .irq_unmask = intca_gic_enable, - .irq_mask_ack = intca_gic_mask_ack, - .irq_eoi = intca_gic_eoi, - .irq_enable = intca_gic_enable, - .irq_disable = intca_gic_disable, - .irq_shutdown = intca_gic_disable, - .irq_set_type = intca_gic_set_type, - .irq_set_wake = sh73a0_set_wake, -#ifdef CONFIG_SMP - .irq_set_affinity = intca_gic_set_affinity, -#endif -}; - -static int to_intc_vect(int irq) -{ - unsigned int irq_pin = irq - gic_spi(1); - unsigned int offs; - - if (irq_pin < 16) - offs = 0x0200; - else - offs = 0x3000; - - return offs + (irq_pin << 5); -} - -static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id) -{ - generic_handle_irq(intcs_evt2irq(to_intc_vect(irq))); - return IRQ_HANDLED; -} - -static struct irqaction sh73a0_irq_pin_cascade[32]; - #define PINTER0_PHYS 0xe69000a0 #define PINTER1_PHYS 0xe69000a4 #define PINTER0_VIRT IOMEM(0xe69000a0) @@ -422,13 +320,11 @@ void __init sh73a0_init_irq(void) void __iomem *gic_dist_base = IOMEM(0xf0001000); void __iomem *gic_cpu_base = IOMEM(0xf0000100); void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); - int k, n; gic_init(0, 29, gic_dist_base, gic_cpu_base); gic_arch_extn.irq_set_wake = sh73a0_set_wake; register_intc_controller(&intcs_desc); - register_intc_controller(&intca_irq_pins_desc); register_intc_controller(&intc_pint0_desc); register_intc_controller(&intc_pint1_desc); @@ -438,19 +334,6 @@ void __init sh73a0_init_irq(void) sh73a0_intcs_cascade.dev_id = intevtsa; setup_irq(gic_spi(50), &sh73a0_intcs_cascade); - /* IRQ pins require special handling through INTCA and GIC */ - for (k = 0; k < 32; k++) { - sh73a0_irq_pin_cascade[k].name = "INTCA-GIC cascade"; - sh73a0_irq_pin_cascade[k].handler = sh73a0_irq_pin_demux; - setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]); - - n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k))); - WARN_ON(irq_alloc_desc_at(n, numa_node_id()) != n); - irq_set_chip_and_handler_name(n, &intca_gic_irq_chip, - handle_level_irq, "level"); - set_irq_flags(n, IRQF_VALID); /* yuck */ - } - /* PINT pins are sanely tied to the GIC as SPI */ sh73a0_pint0_cascade.name = "PINT0 cascade"; sh73a0_pint0_cascade.handler = sh73a0_pint0_demux; @@ -460,11 +343,3 @@ void __init sh73a0_init_irq(void) sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; setup_irq(gic_spi(34), &sh73a0_pint1_cascade); } - -#ifdef CONFIG_OF -void __init sh73a0_init_irq_dt(void) -{ - irqchip_init(); - gic_arch_extn.irq_set_wake = sh73a0_set_wake; -} -#endif diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 47662a581c0..e4545c15272 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -404,7 +404,7 @@ void __init emev2_add_standard_devices(void) ARRAY_SIZE(emev2_late_devices)); } -void __init emev2_init_delay(void) +static void __init emev2_init_delay(void) { shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */ } @@ -439,7 +439,7 @@ static const struct of_dev_auxdata emev2_auxdata_lookup[] __initconst = { { } }; -void __init emev2_add_standard_devices_dt(void) +static void __init emev2_add_standard_devices_dt(void) { of_platform_populate(NULL, of_default_bus_match_table, emev2_auxdata_lookup, NULL); diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index c54ff9b29fe..042df35e71a 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/input.h> @@ -28,6 +29,7 @@ #include <linux/serial_sci.h> #include <linux/sh_intc.h> #include <linux/sh_timer.h> +#include <linux/dma-mapping.h> #include <mach/hardware.h> #include <mach/irqs.h> #include <mach/r8a7779.h> @@ -91,7 +93,7 @@ static struct plat_sci_port scif0_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_spi(88)), + .irqs = SCIx_IRQ_MUXED(gic_iid(0x78)), }; static struct platform_device scif0_device = { @@ -108,7 +110,7 @@ static struct plat_sci_port scif1_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_spi(89)), + .irqs = SCIx_IRQ_MUXED(gic_iid(0x79)), }; static struct platform_device scif1_device = { @@ -125,7 +127,7 @@ static struct plat_sci_port scif2_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_spi(90)), + .irqs = SCIx_IRQ_MUXED(gic_iid(0x7a)), }; static struct platform_device scif2_device = { @@ -142,7 +144,7 @@ static struct plat_sci_port scif3_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_spi(91)), + .irqs = SCIx_IRQ_MUXED(gic_iid(0x7b)), }; static struct platform_device scif3_device = { @@ -159,7 +161,7 @@ static struct plat_sci_port scif4_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_spi(92)), + .irqs = SCIx_IRQ_MUXED(gic_iid(0x7c)), }; static struct platform_device scif4_device = { @@ -176,7 +178,7 @@ static struct plat_sci_port scif5_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_spi(93)), + .irqs = SCIx_IRQ_MUXED(gic_iid(0x7d)), }; static struct platform_device scif5_device = { @@ -203,7 +205,7 @@ static struct resource tmu00_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gic_spi(32), + .start = gic_iid(0x40), .flags = IORESOURCE_IRQ, }, }; @@ -233,7 +235,7 @@ static struct resource tmu01_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gic_spi(33), + .start = gic_iid(0x41), .flags = IORESOURCE_IRQ, }, }; @@ -255,7 +257,7 @@ static struct resource rcar_i2c0_res[] = { .end = 0xffc70fff, .flags = IORESOURCE_MEM, }, { - .start = gic_spi(79), + .start = gic_iid(0x6f), .flags = IORESOURCE_IRQ, }, }; @@ -273,7 +275,7 @@ static struct resource rcar_i2c1_res[] = { .end = 0xffc71fff, .flags = IORESOURCE_MEM, }, { - .start = gic_spi(82), + .start = gic_iid(0x72), .flags = IORESOURCE_IRQ, }, }; @@ -291,7 +293,7 @@ static struct resource rcar_i2c2_res[] = { .end = 0xffc72fff, .flags = IORESOURCE_MEM, }, { - .start = gic_spi(80), + .start = gic_iid(0x70), .flags = IORESOURCE_IRQ, }, }; @@ -309,7 +311,7 @@ static struct resource rcar_i2c3_res[] = { .end = 0xffc73fff, .flags = IORESOURCE_MEM, }, { - .start = gic_spi(81), + .start = gic_iid(0x71), .flags = IORESOURCE_IRQ, }, }; @@ -321,7 +323,31 @@ static struct platform_device i2c3_device = { .num_resources = ARRAY_SIZE(rcar_i2c3_res), }; -static struct platform_device *r8a7779_early_devices[] __initdata = { +static struct resource sata_resources[] = { + [0] = { + .name = "rcar-sata", + .start = 0xfc600000, + .end = 0xfc601fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = gic_iid(0x84), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sata_device = { + .name = "sata_rcar", + .id = -1, + .resource = sata_resources, + .num_resources = ARRAY_SIZE(sata_resources), + .dev = { + .dma_mask = &sata_device.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct platform_device *r8a7779_devices_dt[] __initdata = { &scif0_device, &scif1_device, &scif2_device, @@ -330,13 +356,14 @@ static struct platform_device *r8a7779_early_devices[] __initdata = { &scif5_device, &tmu00_device, &tmu01_device, +}; + +static struct platform_device *r8a7779_late_devices[] __initdata = { &i2c0_device, &i2c1_device, &i2c2_device, &i2c3_device, -}; - -static struct platform_device *r8a7779_late_devices[] __initdata = { + &sata_device, }; void __init r8a7779_add_standard_devices(void) @@ -349,8 +376,8 @@ void __init r8a7779_add_standard_devices(void) r8a7779_init_pm_domains(); - platform_add_devices(r8a7779_early_devices, - ARRAY_SIZE(r8a7779_early_devices)); + platform_add_devices(r8a7779_devices_dt, + ARRAY_SIZE(r8a7779_devices_dt)); platform_add_devices(r8a7779_late_devices, ARRAY_SIZE(r8a7779_late_devices)); } @@ -367,8 +394,8 @@ void __init r8a7779_earlytimer_init(void) void __init r8a7779_add_early_devices(void) { - early_platform_add_devices(r8a7779_early_devices, - ARRAY_SIZE(r8a7779_early_devices)); + early_platform_add_devices(r8a7779_devices_dt, + ARRAY_SIZE(r8a7779_devices_dt)); /* Early serial console setup is not included here due to * memory map collisions. The SCIF serial ports in r8a7779 @@ -386,3 +413,40 @@ void __init r8a7779_add_early_devices(void) * command line in case of the marzen board. */ } + +#ifdef CONFIG_USE_OF +void __init r8a7779_init_delay(void) +{ + shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */ +} + +static const struct of_dev_auxdata r8a7779_auxdata_lookup[] __initconst = { + {}, +}; + +void __init r8a7779_add_standard_devices_dt(void) +{ + /* clocks are setup late during boot in the case of DT */ + r8a7779_clock_init(); + + platform_add_devices(r8a7779_devices_dt, + ARRAY_SIZE(r8a7779_devices_dt)); + of_platform_populate(NULL, of_default_bus_match_table, + r8a7779_auxdata_lookup, NULL); +} + +static const char *r8a7779_compat_dt[] __initdata = { + "renesas,r8a7779", + NULL, +}; + +DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") + .map_io = r8a7779_map_io, + .init_early = r8a7779_init_delay, + .nr_irqs = NR_IRQS_LEGACY, + .init_irq = r8a7779_init_irq_dt, + .init_machine = r8a7779_add_standard_devices_dt, + .init_time = shmobile_timer_init, + .dt_compat = r8a7779_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index bdab575f88b..e8cd93a5c55 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -22,6 +22,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/platform_device.h> #include <linux/of_platform.h> #include <linux/delay.h> @@ -32,6 +33,7 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <linux/platform_data/sh_ipmmu.h> +#include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <mach/dma-register.h> #include <mach/hardware.h> #include <mach/irqs.h> @@ -810,7 +812,128 @@ static struct platform_device ipmmu_device = { .num_resources = ARRAY_SIZE(ipmmu_resources), }; -static struct platform_device *sh73a0_early_devices_dt[] __initdata = { +static struct renesas_intc_irqpin_config irqpin0_platform_data = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */ +}; + +static struct resource irqpin0_resources[] = { + DEFINE_RES_MEM(0xe6900000, 4), /* ICR1A */ + DEFINE_RES_MEM(0xe6900010, 4), /* INTPRI00A */ + DEFINE_RES_MEM(0xe6900020, 1), /* INTREQ00A */ + DEFINE_RES_MEM(0xe6900040, 1), /* INTMSK00A */ + DEFINE_RES_MEM(0xe6900060, 1), /* INTMSKCLR00A */ + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(2)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(3)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(4)), /* IRQ3 */ + DEFINE_RES_IRQ(gic_spi(5)), /* IRQ4 */ + DEFINE_RES_IRQ(gic_spi(6)), /* IRQ5 */ + DEFINE_RES_IRQ(gic_spi(7)), /* IRQ6 */ + DEFINE_RES_IRQ(gic_spi(8)), /* IRQ7 */ +}; + +static struct platform_device irqpin0_device = { + .name = "renesas_intc_irqpin", + .id = 0, + .resource = irqpin0_resources, + .num_resources = ARRAY_SIZE(irqpin0_resources), + .dev = { + .platform_data = &irqpin0_platform_data, + }, +}; + +static struct renesas_intc_irqpin_config irqpin1_platform_data = { + .irq_base = irq_pin(8), /* IRQ8 -> IRQ15 */ + .control_parent = true, /* Disable spurious IRQ10 */ +}; + +static struct resource irqpin1_resources[] = { + DEFINE_RES_MEM(0xe6900004, 4), /* ICR2A */ + DEFINE_RES_MEM(0xe6900014, 4), /* INTPRI10A */ + DEFINE_RES_MEM(0xe6900024, 1), /* INTREQ10A */ + DEFINE_RES_MEM(0xe6900044, 1), /* INTMSK10A */ + DEFINE_RES_MEM(0xe6900064, 1), /* INTMSKCLR10A */ + DEFINE_RES_IRQ(gic_spi(9)), /* IRQ8 */ + DEFINE_RES_IRQ(gic_spi(10)), /* IRQ9 */ + DEFINE_RES_IRQ(gic_spi(11)), /* IRQ10 */ + DEFINE_RES_IRQ(gic_spi(12)), /* IRQ11 */ + DEFINE_RES_IRQ(gic_spi(13)), /* IRQ12 */ + DEFINE_RES_IRQ(gic_spi(14)), /* IRQ13 */ + DEFINE_RES_IRQ(gic_spi(15)), /* IRQ14 */ + DEFINE_RES_IRQ(gic_spi(16)), /* IRQ15 */ +}; + +static struct platform_device irqpin1_device = { + .name = "renesas_intc_irqpin", + .id = 1, + .resource = irqpin1_resources, + .num_resources = ARRAY_SIZE(irqpin1_resources), + .dev = { + .platform_data = &irqpin1_platform_data, + }, +}; + +static struct renesas_intc_irqpin_config irqpin2_platform_data = { + .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */ +}; + +static struct resource irqpin2_resources[] = { + DEFINE_RES_MEM(0xe6900008, 4), /* ICR3A */ + DEFINE_RES_MEM(0xe6900018, 4), /* INTPRI20A */ + DEFINE_RES_MEM(0xe6900028, 1), /* INTREQ20A */ + DEFINE_RES_MEM(0xe6900048, 1), /* INTMSK20A */ + DEFINE_RES_MEM(0xe6900068, 1), /* INTMSKCLR20A */ + DEFINE_RES_IRQ(gic_spi(17)), /* IRQ16 */ + DEFINE_RES_IRQ(gic_spi(18)), /* IRQ17 */ + DEFINE_RES_IRQ(gic_spi(19)), /* IRQ18 */ + DEFINE_RES_IRQ(gic_spi(20)), /* IRQ19 */ + DEFINE_RES_IRQ(gic_spi(21)), /* IRQ20 */ + DEFINE_RES_IRQ(gic_spi(22)), /* IRQ21 */ + DEFINE_RES_IRQ(gic_spi(23)), /* IRQ22 */ + DEFINE_RES_IRQ(gic_spi(24)), /* IRQ23 */ +}; + +static struct platform_device irqpin2_device = { + .name = "renesas_intc_irqpin", + .id = 2, + .resource = irqpin2_resources, + .num_resources = ARRAY_SIZE(irqpin2_resources), + .dev = { + .platform_data = &irqpin2_platform_data, + }, +}; + +static struct renesas_intc_irqpin_config irqpin3_platform_data = { + .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */ +}; + +static struct resource irqpin3_resources[] = { + DEFINE_RES_MEM(0xe690000c, 4), /* ICR4A */ + DEFINE_RES_MEM(0xe690001c, 4), /* INTPRI30A */ + DEFINE_RES_MEM(0xe690002c, 1), /* INTREQ30A */ + DEFINE_RES_MEM(0xe690004c, 1), /* INTMSK30A */ + DEFINE_RES_MEM(0xe690006c, 1), /* INTMSKCLR30A */ + DEFINE_RES_IRQ(gic_spi(25)), /* IRQ24 */ + DEFINE_RES_IRQ(gic_spi(26)), /* IRQ25 */ + DEFINE_RES_IRQ(gic_spi(27)), /* IRQ26 */ + DEFINE_RES_IRQ(gic_spi(28)), /* IRQ27 */ + DEFINE_RES_IRQ(gic_spi(29)), /* IRQ28 */ + DEFINE_RES_IRQ(gic_spi(30)), /* IRQ29 */ + DEFINE_RES_IRQ(gic_spi(31)), /* IRQ30 */ + DEFINE_RES_IRQ(gic_spi(32)), /* IRQ31 */ +}; + +static struct platform_device irqpin3_device = { + .name = "renesas_intc_irqpin", + .id = 3, + .resource = irqpin3_resources, + .num_resources = ARRAY_SIZE(irqpin3_resources), + .dev = { + .platform_data = &irqpin3_platform_data, + }, +}; + +static struct platform_device *sh73a0_devices_dt[] __initdata = { &scif0_device, &scif1_device, &scif2_device, @@ -838,6 +961,10 @@ static struct platform_device *sh73a0_late_devices[] __initdata = { &dma0_device, &mpdma0_device, &pmu_device, + &irqpin0_device, + &irqpin1_device, + &irqpin2_device, + &irqpin3_device, }; #define SRCR2 IOMEM(0xe61580b0) @@ -847,8 +974,8 @@ void __init sh73a0_add_standard_devices(void) /* Clear software reset bit on SY-DMAC module */ __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); - platform_add_devices(sh73a0_early_devices_dt, - ARRAY_SIZE(sh73a0_early_devices_dt)); + platform_add_devices(sh73a0_devices_dt, + ARRAY_SIZE(sh73a0_devices_dt)); platform_add_devices(sh73a0_early_devices, ARRAY_SIZE(sh73a0_early_devices)); platform_add_devices(sh73a0_late_devices, @@ -867,8 +994,8 @@ void __init sh73a0_earlytimer_init(void) void __init sh73a0_add_early_devices(void) { - early_platform_add_devices(sh73a0_early_devices_dt, - ARRAY_SIZE(sh73a0_early_devices_dt)); + early_platform_add_devices(sh73a0_devices_dt, + ARRAY_SIZE(sh73a0_devices_dt)); early_platform_add_devices(sh73a0_early_devices, ARRAY_SIZE(sh73a0_early_devices)); @@ -878,23 +1005,9 @@ void __init sh73a0_add_early_devices(void) #ifdef CONFIG_USE_OF -/* Please note that the clock initialisation shcheme used in - * sh73a0_add_early_devices_dt() and sh73a0_add_standard_devices_dt() - * does not work with SMP as there is a yet to be resolved lock-up in - * workqueue initialisation. - * - * CONFIG_SMP should be disabled when using this code. - */ - -void __init sh73a0_add_early_devices_dt(void) +void __init sh73a0_init_delay(void) { shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ - - early_platform_add_devices(sh73a0_early_devices_dt, - ARRAY_SIZE(sh73a0_early_devices_dt)); - - /* setup early console here as well */ - shmobile_setup_console(); } static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = { @@ -906,8 +1019,8 @@ void __init sh73a0_add_standard_devices_dt(void) /* clocks are setup late during boot in the case of DT */ sh73a0_clock_init(); - platform_add_devices(sh73a0_early_devices_dt, - ARRAY_SIZE(sh73a0_early_devices_dt)); + platform_add_devices(sh73a0_devices_dt, + ARRAY_SIZE(sh73a0_devices_dt)); of_platform_populate(NULL, of_default_bus_match_table, sh73a0_auxdata_lookup, NULL); } @@ -918,10 +1031,11 @@ static const char *sh73a0_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") + .smp = smp_ops(sh73a0_smp_ops), .map_io = sh73a0_map_io, - .init_early = sh73a0_add_early_devices_dt, + .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_irq = sh73a0_init_irq_dt, + .init_irq = irqchip_init, .init_machine = sh73a0_add_standard_devices_dt, .init_time = shmobile_timer_init, .dt_compat = sh73a0_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 953eb1f9388..8225c16b371 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -28,63 +28,9 @@ #include <mach/emev2.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> -#include <asm/cacheflush.h> #define EMEV2_SCU_BASE 0x1e000000 -static DEFINE_SPINLOCK(scu_lock); -static void __iomem *scu_base; - -static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) -{ - unsigned long tmp; - - /* we assume this code is running on a different cpu - * than the one that is changing coherency setting */ - spin_lock(&scu_lock); - tmp = readl(scu_base + 8); - tmp &= ~clr; - tmp |= set; - writel(tmp, scu_base + 8); - spin_unlock(&scu_lock); - -} - -static unsigned int __init emev2_get_core_count(void) -{ - if (!scu_base) { - scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); - emev2_clock_init(); /* need ioremapped SMU */ - } - - WARN_ON_ONCE(!scu_base); - - return scu_base ? scu_get_core_count(scu_base) : 1; -} - -static int emev2_platform_cpu_kill(unsigned int cpu) -{ - return 0; /* not supported yet */ -} - -static int __maybe_unused emev2_cpu_kill(unsigned int cpu) -{ - int k; - - /* this function is running on another CPU than the offline target, - * here we need wait for shutdown code in platform_cpu_die() to - * finish before asking SoC-specific code to power off the CPU core. - */ - for (k = 0; k < 1000; k++) { - if (shmobile_cpu_is_dead(cpu)) - return emev2_platform_cpu_kill(cpu); - mdelay(1); - } - - return 0; -} - - static void __cpuinit emev2_secondary_init(unsigned int cpu) { gic_secondary_init(0); @@ -92,31 +38,30 @@ static void __cpuinit emev2_secondary_init(unsigned int cpu) static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) { - cpu = cpu_logical_map(cpu); - - /* enable cache coherency */ - modify_scu_cpu_psr(0, 3 << (cpu * 8)); - - /* Tell ROM loader about our vector (in headsmp.S) */ - emev2_set_boot_vector(__pa(shmobile_secondary_vector)); - - arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu))); return 0; } static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) { - int cpu = cpu_logical_map(0); + scu_enable(shmobile_scu_base); - scu_enable(scu_base); + /* Tell ROM loader about our vector (in headsmp-scu.S) */ + emev2_set_boot_vector(__pa(shmobile_secondary_vector_scu)); - /* enable cache coherency on CPU0 */ - modify_scu_cpu_psr(0, 3 << (cpu * 8)); + /* enable cache coherency on booting CPU */ + scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); } static void __init emev2_smp_init_cpus(void) { - unsigned int ncores = emev2_get_core_count(); + unsigned int ncores; + + /* setup EMEV2 specific SCU base */ + shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); + emev2_clock_init(); /* need ioremapped SMU */ + + ncores = shmobile_scu_base ? scu_get_core_count(shmobile_scu_base) : 1; shmobile_smp_init_cpus(ncores); } @@ -126,9 +71,4 @@ struct smp_operations emev2_smp_ops __initdata = { .smp_prepare_cpus = emev2_smp_prepare_cpus, .smp_secondary_init = emev2_secondary_init, .smp_boot_secondary = emev2_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = emev2_cpu_kill, - .cpu_die = shmobile_cpu_die, - .cpu_disable = shmobile_cpu_disable, -#endif }; diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 3a4acf23edc..ea4535a5c4e 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -26,11 +26,13 @@ #include <linux/irqchip/arm-gic.h> #include <mach/common.h> #include <mach/r8a7779.h> +#include <asm/cacheflush.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> #include <asm/smp_twd.h> #define AVECR IOMEM(0xfe700040) +#define R8A7779_SCU_BASE 0xf0000000 static struct r8a7779_pm_ch r8a7779_ch_cpu1 = { .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */ @@ -56,44 +58,14 @@ static struct r8a7779_pm_ch *r8a7779_ch_cpu[4] = { [3] = &r8a7779_ch_cpu3, }; -static void __iomem *scu_base_addr(void) -{ - return (void __iomem *)0xf0000000; -} - -static DEFINE_SPINLOCK(scu_lock); -static unsigned long tmp; - #ifdef CONFIG_HAVE_ARM_TWD -static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); - +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29); void __init r8a7779_register_twd(void) { twd_local_timer_register(&twd_local_timer); } #endif -static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) -{ - void __iomem *scu_base = scu_base_addr(); - - spin_lock(&scu_lock); - tmp = __raw_readl(scu_base + 8); - tmp &= ~clr; - tmp |= set; - spin_unlock(&scu_lock); - - /* disable cache coherency after releasing the lock */ - __raw_writel(tmp, scu_base + 8); -} - -static unsigned int __init r8a7779_get_core_count(void) -{ - void __iomem *scu_base = scu_base_addr(); - - return scu_get_core_count(scu_base); -} - static int r8a7779_platform_cpu_kill(unsigned int cpu) { struct r8a7779_pm_ch *ch = NULL; @@ -101,9 +73,6 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu) cpu = cpu_logical_map(cpu); - /* disable cache coherency */ - modify_scu_cpu_psr(3 << (cpu * 8), 0); - if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) ch = r8a7779_ch_cpu[cpu]; @@ -113,25 +82,6 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu) return ret ? ret : 1; } -static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu) -{ - int k; - - /* this function is running on another CPU than the offline target, - * here we need wait for shutdown code in platform_cpu_die() to - * finish before asking SoC-specific code to power off the CPU core. - */ - for (k = 0; k < 1000; k++) { - if (shmobile_cpu_is_dead(cpu)) - return r8a7779_platform_cpu_kill(cpu); - - mdelay(1); - } - - return 0; -} - - static void __cpuinit r8a7779_secondary_init(unsigned int cpu) { gic_secondary_init(0); @@ -144,9 +94,6 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct cpu = cpu_logical_map(cpu); - /* enable cache coherency */ - modify_scu_cpu_psr(0, 3 << (cpu * 8)); - if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) ch = r8a7779_ch_cpu[cpu]; @@ -158,15 +105,13 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) { - int cpu = cpu_logical_map(0); + scu_enable(shmobile_scu_base); - scu_enable(scu_base_addr()); + /* Map the reset vector (in headsmp-scu.S) */ + __raw_writel(__pa(shmobile_secondary_vector_scu), AVECR); - /* Map the reset vector (in headsmp.S) */ - __raw_writel(__pa(shmobile_secondary_vector), AVECR); - - /* enable cache coherency on CPU0 */ - modify_scu_cpu_psr(0, 3 << (cpu * 8)); + /* enable cache coherency on booting CPU */ + scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); r8a7779_pm_init(); @@ -178,10 +123,60 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) static void __init r8a7779_smp_init_cpus(void) { - unsigned int ncores = r8a7779_get_core_count(); + /* setup r8a7779 specific SCU base */ + shmobile_scu_base = IOMEM(R8A7779_SCU_BASE); + + shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base)); +} - shmobile_smp_init_cpus(ncores); +#ifdef CONFIG_HOTPLUG_CPU +static int r8a7779_scu_psr_core_disabled(int cpu) +{ + unsigned long mask = 3 << (cpu * 8); + + if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask) + return 1; + + return 0; +} + +static int r8a7779_cpu_kill(unsigned int cpu) +{ + int k; + + /* this function is running on another CPU than the offline target, + * here we need wait for shutdown code in platform_cpu_die() to + * finish before asking SoC-specific code to power off the CPU core. + */ + for (k = 0; k < 1000; k++) { + if (r8a7779_scu_psr_core_disabled(cpu)) + return r8a7779_platform_cpu_kill(cpu); + + mdelay(1); + } + + return 0; +} + +static void r8a7779_cpu_die(unsigned int cpu) +{ + dsb(); + flush_cache_all(); + + /* disable cache coherency */ + scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF); + + /* Endless loop until power off from r8a7779_cpu_kill() */ + while (1) + cpu_do_idle(); +} + +static int r8a7779_cpu_disable(unsigned int cpu) +{ + /* only CPU1->3 have power domains, do not allow hotplug of CPU0 */ + return cpu == 0 ? -EPERM : 0; } +#endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations r8a7779_smp_ops __initdata = { .smp_init_cpus = r8a7779_smp_init_cpus, @@ -190,7 +185,7 @@ struct smp_operations r8a7779_smp_ops __initdata = { .smp_boot_secondary = r8a7779_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_kill = r8a7779_cpu_kill, - .cpu_die = shmobile_cpu_die, - .cpu_disable = shmobile_cpu_disable, + .cpu_die = r8a7779_cpu_die, + .cpu_disable = r8a7779_cpu_disable, #endif }; diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index acb46a94ccd..5ae502b1643 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -39,26 +39,16 @@ #define PSTR_SHUTDOWN_MODE 3 -static void __iomem *scu_base_addr(void) -{ - return (void __iomem *)0xf0000000; -} +#define SH73A0_SCU_BASE 0xf0000000 #ifdef CONFIG_HAVE_ARM_TWD -static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, SH73A0_SCU_BASE + 0x600, 29); void __init sh73a0_register_twd(void) { twd_local_timer_register(&twd_local_timer); } #endif -static unsigned int __init sh73a0_get_core_count(void) -{ - void __iomem *scu_base = scu_base_addr(); - - return scu_get_core_count(scu_base); -} - static void __cpuinit sh73a0_secondary_init(unsigned int cpu) { gic_secondary_init(0); @@ -78,21 +68,22 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) { - scu_enable(scu_base_addr()); + scu_enable(shmobile_scu_base); - /* Map the reset vector (in headsmp-sh73a0.S) */ + /* Map the reset vector (in headsmp-scu.S) */ __raw_writel(0, APARMBAREA); /* 4k */ - __raw_writel(__pa(sh73a0_secondary_vector), SBAR); + __raw_writel(__pa(shmobile_secondary_vector_scu), SBAR); /* enable cache coherency on booting CPU */ - scu_power_mode(scu_base_addr(), SCU_PM_NORMAL); + scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); } static void __init sh73a0_smp_init_cpus(void) { - unsigned int ncores = sh73a0_get_core_count(); + /* setup sh73a0 specific SCU base */ + shmobile_scu_base = IOMEM(SH73A0_SCU_BASE); - shmobile_smp_init_cpus(ncores); + shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base)); } #ifdef CONFIG_HOTPLUG_CPU @@ -128,11 +119,16 @@ static void sh73a0_cpu_die(unsigned int cpu) flush_cache_all(); /* Set power off mode. This takes the CPU out of the MP cluster */ - scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF); + scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF); /* Enter shutdown mode */ cpu_do_idle(); } + +static int sh73a0_cpu_disable(unsigned int cpu) +{ + return 0; /* CPU0 and CPU1 supported */ +} #endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations sh73a0_smp_ops __initdata = { @@ -143,6 +139,6 @@ struct smp_operations sh73a0_smp_ops __initdata = { #ifdef CONFIG_HOTPLUG_CPU .cpu_kill = sh73a0_cpu_kill, .cpu_die = sh73a0_cpu_die, - .cpu_disable = shmobile_cpu_disable_any, + .cpu_disable = sh73a0_cpu_disable, #endif }; diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index a9d52167e16..b708b3e56d2 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -70,7 +70,7 @@ config S3C_LOWLEVEL_UART_PORT # timer options -config S5P_HRT +config SAMSUNG_HRT bool select SAMSUNG_DEV_PWM help diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 3a7c64d1814..a23c460299a 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -12,8 +12,7 @@ obj- := # Objects we always build independent of SoC choice obj-y += init.o cpu.o -obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o -obj-$(CONFIG_S5P_HRT) += s5p-time.o +obj-$(CONFIG_SAMSUNG_HRT) += samsung-time.o obj-$(CONFIG_SAMSUNG_CLOCK) += clock.o obj-$(CONFIG_SAMSUNG_CLOCK) += pwm-clock.o diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 37703ef6dfc..0f6c47a6475 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -23,6 +23,9 @@ extern unsigned long samsung_cpu_id; #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 @@ -53,6 +56,7 @@ static inline int is_samsung_##name(void) \ } 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) IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK) @@ -74,6 +78,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK) # define soc_is_s3c24xx() 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_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) #else @@ -192,10 +202,6 @@ extern void s3c24xx_init_uartdevs(char *name, struct s3c24xx_uart_resources *res, struct s3c2410_uartcfg *cfg, int no); -/* timer for 2410/2440 */ - -extern void s3c24xx_timer_init(void); - extern struct syscore_ops s3c2410_pm_syscore_ops; extern struct syscore_ops s3c2412_pm_syscore_ops; extern struct syscore_ops s3c2416_pm_syscore_ops; diff --git a/arch/arm/plat-samsung/include/plat/irq.h b/arch/arm/plat-samsung/include/plat/irq.h deleted file mode 100644 index e21a89bc26c..00000000000 --- a/arch/arm/plat-samsung/include/plat/irq.h +++ /dev/null @@ -1,116 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/irq.h - * - * Copyright (c) 2004-2005 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * Header file for S3C24XX CPU IRQ support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/regs-irq.h> -#include <mach/regs-gpio.h> - -#define irqdbf(x...) -#define irqdbf2(x...) - -#define EXTINT_OFF (IRQ_EINT4 - 4) - -/* these are exported for arch/arm/mach-* usage */ -extern struct irq_chip s3c_irq_level_chip; -extern struct irq_chip s3c_irq_chip; - -static inline void s3c_irqsub_mask(unsigned int irqno, - unsigned int parentbit, - int subcheck) -{ - unsigned long mask; - unsigned long submask; - - submask = __raw_readl(S3C2410_INTSUBMSK); - mask = __raw_readl(S3C2410_INTMSK); - - submask |= (1UL << (irqno - IRQ_S3CUART_RX0)); - - /* check to see if we need to mask the parent IRQ */ - - if ((submask & subcheck) == subcheck) - __raw_writel(mask | parentbit, S3C2410_INTMSK); - - /* write back masks */ - __raw_writel(submask, S3C2410_INTSUBMSK); - -} - -static inline void s3c_irqsub_unmask(unsigned int irqno, - unsigned int parentbit) -{ - unsigned long mask; - unsigned long submask; - - submask = __raw_readl(S3C2410_INTSUBMSK); - mask = __raw_readl(S3C2410_INTMSK); - - submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0)); - mask &= ~parentbit; - - /* write back masks */ - __raw_writel(submask, S3C2410_INTSUBMSK); - __raw_writel(mask, S3C2410_INTMSK); -} - - -static inline void s3c_irqsub_maskack(unsigned int irqno, - unsigned int parentmask, - unsigned int group) -{ - unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); - - s3c_irqsub_mask(irqno, parentmask, group); - - __raw_writel(bit, S3C2410_SUBSRCPND); - - /* only ack parent if we've got all the irqs (seems we must - * ack, all and hope that the irq system retriggers ok when - * the interrupt goes off again) - */ - - if (1) { - __raw_writel(parentmask, S3C2410_SRCPND); - __raw_writel(parentmask, S3C2410_INTPND); - } -} - -static inline void s3c_irqsub_ack(unsigned int irqno, - unsigned int parentmask, - unsigned int group) -{ - unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); - - __raw_writel(bit, S3C2410_SUBSRCPND); - - /* only ack parent if we've got all the irqs (seems we must - * ack, all and hope that the irq system retriggers ok when - * the interrupt goes off again) - */ - - if (1) { - __raw_writel(parentmask, S3C2410_SRCPND); - __raw_writel(parentmask, S3C2410_INTPND); - } -} - -/* exported for use in arch/arm/mach-s3c2410 */ - -#ifdef CONFIG_PM -extern int s3c_irq_wake(struct irq_data *data, unsigned int state); -#else -#define s3c_irq_wake NULL -#endif - -extern int s3c_irqext_type(struct irq_data *d, unsigned int type); diff --git a/arch/arm/plat-samsung/include/plat/s3c2410.h b/arch/arm/plat-samsung/include/plat/s3c2410.h deleted file mode 100644 index 55b0e5f51e9..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2410.h +++ /dev/null @@ -1,31 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c2410.h - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * Header file for s3c2410 machine directory - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -#ifdef CONFIG_CPU_S3C2410 - -extern int s3c2410_init(void); -extern int s3c2410a_init(void); - -extern void s3c2410_map_io(void); - -extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c2410_init_clocks(int xtal); - -#else -#define s3c2410_init_clocks NULL -#define s3c2410_init_uarts NULL -#define s3c2410_map_io NULL -#define s3c2410_init NULL -#define s3c2410a_init NULL -#endif diff --git a/arch/arm/plat-samsung/include/plat/s3c2412.h b/arch/arm/plat-samsung/include/plat/s3c2412.h deleted file mode 100644 index cbae50ddacc..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2412.h +++ /dev/null @@ -1,32 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c2412.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * Header file for s3c2412 cpu support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifdef CONFIG_CPU_S3C2412 - -extern int s3c2412_init(void); - -extern void s3c2412_map_io(void); - -extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c2412_init_clocks(int xtal); - -extern int s3c2412_baseclk_add(void); - -extern void s3c2412_restart(char mode, const char *cmd); -#else -#define s3c2412_init_clocks NULL -#define s3c2412_init_uarts NULL -#define s3c2412_map_io NULL -#define s3c2412_init NULL -#define s3c2412_restart NULL -#endif diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h deleted file mode 100644 index f27399a3c68..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2416.h +++ /dev/null @@ -1,37 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c2416.h - * - * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com> - * - * Header file for s3c2416 cpu support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifdef CONFIG_CPU_S3C2416 - -struct s3c2410_uartcfg; - -extern int s3c2416_init(void); - -extern void s3c2416_map_io(void); - -extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c2416_init_clocks(int xtal); - -extern int s3c2416_baseclk_add(void); - -extern void s3c2416_restart(char mode, const char *cmd); - -extern void s3c2416_init_irq(void); -extern struct syscore_ops s3c2416_irq_syscore_ops; - -#else -#define s3c2416_init_clocks NULL -#define s3c2416_init_uarts NULL -#define s3c2416_map_io NULL -#define s3c2416_init NULL -#define s3c2416_restart NULL -#endif diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h deleted file mode 100644 index 71b88ec4895..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ /dev/null @@ -1,36 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c2443.h - * - * Copyright (c) 2004-2005 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * Header file for s3c2443 cpu support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifdef CONFIG_CPU_S3C2443 - -struct s3c2410_uartcfg; - -extern int s3c2443_init(void); - -extern void s3c2443_map_io(void); - -extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c2443_init_clocks(int xtal); - -extern int s3c2443_baseclk_add(void); - -extern void s3c2443_restart(char mode, const char *cmd); - -extern void s3c2443_init_irq(void); -#else -#define s3c2443_init_clocks NULL -#define s3c2443_init_uarts NULL -#define s3c2443_map_io NULL -#define s3c2443_init NULL -#define s3c2443_restart NULL -#endif diff --git a/arch/arm/plat-samsung/include/plat/s3c244x.h b/arch/arm/plat-samsung/include/plat/s3c244x.h deleted file mode 100644 index ea0c961b760..00000000000 --- a/arch/arm/plat-samsung/include/plat/s3c244x.h +++ /dev/null @@ -1,42 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s3c244x.h - * - * Copyright (c) 2004-2005 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * Header file for S3C2440 and S3C2442 cpu support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) - -extern void s3c244x_map_io(void); - -extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c244x_init_clocks(int xtal); - -#else -#define s3c244x_init_clocks NULL -#define s3c244x_init_uarts NULL -#endif - -#ifdef CONFIG_CPU_S3C2440 -extern int s3c2440_init(void); - -extern void s3c2440_map_io(void); -#else -#define s3c2440_init NULL -#define s3c2440_map_io NULL -#endif - -#ifdef CONFIG_CPU_S3C2442 -extern int s3c2442_init(void); - -extern void s3c2442_map_io(void); -#else -#define s3c2442_init NULL -#define s3c2442_map_io NULL -#endif diff --git a/arch/arm/plat-samsung/include/plat/s5p-time.h b/arch/arm/plat-samsung/include/plat/s5p-time.h deleted file mode 100644 index 9c96f3586ce..00000000000 --- a/arch/arm/plat-samsung/include/plat/s5p-time.h +++ /dev/null @@ -1,40 +0,0 @@ -/* linux/arch/arm/plat-samsung/include/plat/s5p-time.h - * - * Copyright 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Header file for s5p time support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_PLAT_S5P_TIME_H -#define __ASM_PLAT_S5P_TIME_H __FILE__ - -/* S5P HR-Timer Clock mode */ -enum s5p_timer_mode { - S5P_PWM0, - S5P_PWM1, - S5P_PWM2, - S5P_PWM3, - S5P_PWM4, -}; - -struct s5p_timer_source { - unsigned int event_id; - unsigned int source_id; -}; - -/* Be able to sleep for atleast 4 seconds (usually more) */ -#define S5PTIMER_MIN_RANGE 4 - -#define TCNT_MAX 0xffffffff -#define NON_PERIODIC 0 -#define PERIODIC 1 - -extern void __init s5p_set_timer_source(enum s5p_timer_mode event, - enum s5p_timer_mode source); -extern void s5p_timer_init(void); -#endif /* __ASM_PLAT_S5P_TIME_H */ diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h new file mode 100644 index 00000000000..4cc99bb1f17 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/samsung-time.h @@ -0,0 +1,53 @@ +/* linux/arch/arm/plat-samsung/include/plat/samsung-time.h + * + * Copyright 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for samsung s3c and s5p time support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_SAMSUNG_TIME_H +#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__ + +/* SAMSUNG HR-Timer Clock mode */ +enum samsung_timer_mode { + SAMSUNG_PWM0, + SAMSUNG_PWM1, + SAMSUNG_PWM2, + SAMSUNG_PWM3, + SAMSUNG_PWM4, +}; + +struct samsung_timer_source { + unsigned int event_id; + unsigned int source_id; +}; + +/* Be able to sleep for atleast 4 seconds (usually more) */ +#define SAMSUNG_TIMER_MIN_RANGE 4 + +#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100) +#define TCNT_MAX 0xffff +#define TSCALER_DIV 25 +#define TDIV 50 +#define TSIZE 16 +#else +#define TCNT_MAX 0xffffffff +#define TSCALER_DIV 2 +#define TDIV 2 +#define TSIZE 32 +#endif + +#define NON_PERIODIC 0 +#define PERIODIC 1 + +extern void __init samsung_set_timer_source(enum samsung_timer_mode event, + enum samsung_timer_mode source); + +extern void __init samsung_timer_init(void); + +#endif /* __ASM_PLAT_SAMSUNG_TIME_H */ diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/samsung-time.c index e92510cf82e..f899cbc9b28 100644 --- a/arch/arm/plat-samsung/s5p-time.c +++ b/arch/arm/plat-samsung/samsung-time.c @@ -2,7 +2,7 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * - * S5P - Common hr-timer support + * samsung - Common hr-timer support (s3c and s5p) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -25,41 +25,41 @@ #include <mach/map.h> #include <plat/devs.h> #include <plat/regs-timer.h> -#include <plat/s5p-time.h> +#include <plat/samsung-time.h> static struct clk *tin_event; static struct clk *tin_source; static struct clk *tdiv_event; static struct clk *tdiv_source; static struct clk *timerclk; -static struct s5p_timer_source timer_source; +static struct samsung_timer_source timer_source; static unsigned long clock_count_per_tick; -static void s5p_timer_resume(void); +static void samsung_timer_resume(void); -static void s5p_time_stop(enum s5p_timer_mode mode) +static void samsung_time_stop(enum samsung_timer_mode mode) { unsigned long tcon; tcon = __raw_readl(S3C2410_TCON); switch (mode) { - case S5P_PWM0: + case SAMSUNG_PWM0: tcon &= ~S3C2410_TCON_T0START; break; - case S5P_PWM1: + case SAMSUNG_PWM1: tcon &= ~S3C2410_TCON_T1START; break; - case S5P_PWM2: + case SAMSUNG_PWM2: tcon &= ~S3C2410_TCON_T2START; break; - case S5P_PWM3: + case SAMSUNG_PWM3: tcon &= ~S3C2410_TCON_T3START; break; - case S5P_PWM4: + case SAMSUNG_PWM4: tcon &= ~S3C2410_TCON_T4START; break; @@ -70,7 +70,7 @@ static void s5p_time_stop(enum s5p_timer_mode mode) __raw_writel(tcon, S3C2410_TCON); } -static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) +static void samsung_time_setup(enum samsung_timer_mode mode, unsigned long tcnt) { unsigned long tcon; @@ -79,27 +79,27 @@ static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) tcnt--; switch (mode) { - case S5P_PWM0: + case SAMSUNG_PWM0: tcon &= ~(0x0f << 0); tcon |= S3C2410_TCON_T0MANUALUPD; break; - case S5P_PWM1: + case SAMSUNG_PWM1: tcon &= ~(0x0f << 8); tcon |= S3C2410_TCON_T1MANUALUPD; break; - case S5P_PWM2: + case SAMSUNG_PWM2: tcon &= ~(0x0f << 12); tcon |= S3C2410_TCON_T2MANUALUPD; break; - case S5P_PWM3: + case SAMSUNG_PWM3: tcon &= ~(0x0f << 16); tcon |= S3C2410_TCON_T3MANUALUPD; break; - case S5P_PWM4: + case SAMSUNG_PWM4: tcon &= ~(0x07 << 20); tcon |= S3C2410_TCON_T4MANUALUPD; break; @@ -114,14 +114,14 @@ static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) __raw_writel(tcon, S3C2410_TCON); } -static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) +static void samsung_time_start(enum samsung_timer_mode mode, bool periodic) { unsigned long tcon; tcon = __raw_readl(S3C2410_TCON); switch (mode) { - case S5P_PWM0: + case SAMSUNG_PWM0: tcon |= S3C2410_TCON_T0START; tcon &= ~S3C2410_TCON_T0MANUALUPD; @@ -131,7 +131,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) tcon &= ~S3C2410_TCON_T0RELOAD; break; - case S5P_PWM1: + case SAMSUNG_PWM1: tcon |= S3C2410_TCON_T1START; tcon &= ~S3C2410_TCON_T1MANUALUPD; @@ -141,7 +141,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) tcon &= ~S3C2410_TCON_T1RELOAD; break; - case S5P_PWM2: + case SAMSUNG_PWM2: tcon |= S3C2410_TCON_T2START; tcon &= ~S3C2410_TCON_T2MANUALUPD; @@ -151,7 +151,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) tcon &= ~S3C2410_TCON_T2RELOAD; break; - case S5P_PWM3: + case SAMSUNG_PWM3: tcon |= S3C2410_TCON_T3START; tcon &= ~S3C2410_TCON_T3MANUALUPD; @@ -161,7 +161,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) tcon &= ~S3C2410_TCON_T3RELOAD; break; - case S5P_PWM4: + case SAMSUNG_PWM4: tcon |= S3C2410_TCON_T4START; tcon &= ~S3C2410_TCON_T4MANUALUPD; @@ -178,24 +178,24 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) __raw_writel(tcon, S3C2410_TCON); } -static int s5p_set_next_event(unsigned long cycles, +static int samsung_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - s5p_time_setup(timer_source.event_id, cycles); - s5p_time_start(timer_source.event_id, NON_PERIODIC); + samsung_time_setup(timer_source.event_id, cycles); + samsung_time_start(timer_source.event_id, NON_PERIODIC); return 0; } -static void s5p_set_mode(enum clock_event_mode mode, +static void samsung_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - s5p_time_stop(timer_source.event_id); + samsung_time_stop(timer_source.event_id); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - s5p_time_setup(timer_source.event_id, clock_count_per_tick); - s5p_time_start(timer_source.event_id, PERIODIC); + samsung_time_setup(timer_source.event_id, clock_count_per_tick); + samsung_time_start(timer_source.event_id, PERIODIC); break; case CLOCK_EVT_MODE_ONESHOT: @@ -206,24 +206,24 @@ static void s5p_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_RESUME: - s5p_timer_resume(); + samsung_timer_resume(); break; } } -static void s5p_timer_resume(void) +static void samsung_timer_resume(void) { /* event timer restart */ - s5p_time_setup(timer_source.event_id, clock_count_per_tick); - s5p_time_start(timer_source.event_id, PERIODIC); + samsung_time_setup(timer_source.event_id, clock_count_per_tick); + samsung_time_start(timer_source.event_id, PERIODIC); /* source timer restart */ - s5p_time_setup(timer_source.source_id, TCNT_MAX); - s5p_time_start(timer_source.source_id, PERIODIC); + samsung_time_setup(timer_source.source_id, TCNT_MAX); + samsung_time_start(timer_source.source_id, PERIODIC); } -void __init s5p_set_timer_source(enum s5p_timer_mode event, - enum s5p_timer_mode source) +void __init samsung_set_timer_source(enum samsung_timer_mode event, + enum samsung_timer_mode source) { s3c_device_timer[event].dev.bus = &platform_bus_type; s3c_device_timer[source].dev.bus = &platform_bus_type; @@ -233,14 +233,14 @@ void __init s5p_set_timer_source(enum s5p_timer_mode event, } static struct clock_event_device time_event_device = { - .name = "s5p_event_timer", + .name = "samsung_event_timer", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .rating = 200, - .set_next_event = s5p_set_next_event, - .set_mode = s5p_set_mode, + .set_next_event = samsung_set_next_event, + .set_mode = samsung_set_mode, }; -static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) +static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; @@ -249,14 +249,14 @@ static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction s5p_clock_event_irq = { - .name = "s5p_time_irq", +static struct irqaction samsung_clock_event_irq = { + .name = "samsung_time_irq", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = s5p_clock_event_isr, + .handler = samsung_clock_event_isr, .dev_id = &time_event_device, }; -static void __init s5p_clockevent_init(void) +static void __init samsung_clockevent_init(void) { unsigned long pclk; unsigned long clock_rate; @@ -267,8 +267,8 @@ static void __init s5p_clockevent_init(void) tscaler = clk_get_parent(tdiv_event); - clk_set_rate(tscaler, pclk / 2); - clk_set_rate(tdiv_event, pclk / 2); + clk_set_rate(tscaler, pclk / TSCALER_DIV); + clk_set_rate(tdiv_event, pclk / TDIV); clk_set_parent(tin_event, tdiv_event); clock_rate = clk_get_rate(tin_event); @@ -278,22 +278,22 @@ static void __init s5p_clockevent_init(void) clockevents_config_and_register(&time_event_device, clock_rate, 1, -1); irq_number = timer_source.event_id + IRQ_TIMER0; - setup_irq(irq_number, &s5p_clock_event_irq); + setup_irq(irq_number, &samsung_clock_event_irq); } -static void __iomem *s5p_timer_reg(void) +static void __iomem *samsung_timer_reg(void) { unsigned long offset = 0; switch (timer_source.source_id) { - case S5P_PWM0: - case S5P_PWM1: - case S5P_PWM2: - case S5P_PWM3: + case SAMSUNG_PWM0: + case SAMSUNG_PWM1: + case SAMSUNG_PWM2: + case SAMSUNG_PWM3: offset = (timer_source.source_id * 0x0c) + 0x14; break; - case S5P_PWM4: + case SAMSUNG_PWM4: offset = 0x40; break; @@ -312,9 +312,9 @@ static void __iomem *s5p_timer_reg(void) * this wraps around for now, since it is just a relative time * stamp. (Inspired by U300 implementation.) */ -static u32 notrace s5p_read_sched_clock(void) +static u32 notrace samsung_read_sched_clock(void) { - void __iomem *reg = s5p_timer_reg(); + void __iomem *reg = samsung_timer_reg(); if (!reg) return 0; @@ -322,29 +322,29 @@ static u32 notrace s5p_read_sched_clock(void) return ~__raw_readl(reg); } -static void __init s5p_clocksource_init(void) +static void __init samsung_clocksource_init(void) { unsigned long pclk; unsigned long clock_rate; pclk = clk_get_rate(timerclk); - clk_set_rate(tdiv_source, pclk / 2); + clk_set_rate(tdiv_source, pclk / TDIV); clk_set_parent(tin_source, tdiv_source); clock_rate = clk_get_rate(tin_source); - s5p_time_setup(timer_source.source_id, TCNT_MAX); - s5p_time_start(timer_source.source_id, PERIODIC); + samsung_time_setup(timer_source.source_id, TCNT_MAX); + samsung_time_start(timer_source.source_id, PERIODIC); - setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); + setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate); - if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", - clock_rate, 250, 32, clocksource_mmio_readl_down)) - panic("s5p_clocksource_timer: can't register clocksource\n"); + if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer", + clock_rate, 250, TSIZE, clocksource_mmio_readl_down)) + panic("samsung_clocksource_timer: can't register clocksource\n"); } -static void __init s5p_timer_resources(void) +static void __init samsung_timer_resources(void) { unsigned long event_id = timer_source.event_id; @@ -386,9 +386,9 @@ static void __init s5p_timer_resources(void) clk_enable(tin_source); } -void __init s5p_timer_init(void) +void __init samsung_timer_init(void) { - s5p_timer_resources(); - s5p_clockevent_init(); - s5p_clocksource_init(); + samsung_timer_resources(); + samsung_clockevent_init(); + samsung_clocksource_init(); } diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c deleted file mode 100644 index 73defd00c3e..00000000000 --- a/arch/arm/plat-samsung/time.c +++ /dev/null @@ -1,287 +0,0 @@ -/* linux/arch/arm/plat-samsung/time.c - * - * Copyright (C) 2003-2005 Simtec Electronics - * Ben Dooks, <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/syscore_ops.h> - -#include <asm/mach-types.h> - -#include <asm/irq.h> -#include <mach/map.h> -#include <plat/regs-timer.h> -#include <mach/regs-irq.h> -#include <asm/mach/time.h> -#include <mach/tick.h> - -#include <plat/clock.h> -#include <plat/cpu.h> - -static unsigned long timer_startval; -static unsigned long timer_usec_ticks; - -#ifndef TICK_MAX -#define TICK_MAX (0xffff) -#endif - -#define TIMER_USEC_SHIFT 16 - -/* we use the shifted arithmetic to work out the ratio of timer ticks - * to usecs, as often the peripheral clock is not a nice even multiple - * of 1MHz. - * - * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok - * for the current HZ value of 200 without producing overflows. - * - * Original patch by Dimitry Andric, updated by Ben Dooks -*/ - - -/* timer_mask_usec_ticks - * - * given a clock and divisor, make the value to pass into timer_ticks_to_usec - * to scale the ticks into usecs -*/ - -static inline unsigned long -timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk) -{ - unsigned long den = pclk / 1000; - - return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den; -} - -/* timer_ticks_to_usec - * - * convert timer ticks to usec. -*/ - -static inline unsigned long timer_ticks_to_usec(unsigned long ticks) -{ - unsigned long res; - - res = ticks * timer_usec_ticks; - res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */ - - return res >> TIMER_USEC_SHIFT; -} - -/*** - * Returns microsecond since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - * IRQs are disabled before entering here from do_gettimeofday() - */ - -static u32 s3c2410_gettimeoffset(void) -{ - unsigned long tdone; - unsigned long tval; - - /* work out how many ticks have gone since last timer interrupt */ - - tval = __raw_readl(S3C2410_TCNTO(4)); - tdone = timer_startval - tval; - - /* check to see if there is an interrupt pending */ - - if (s3c24xx_ostimer_pending()) { - /* re-read the timer, and try and fix up for the missed - * interrupt. Note, the interrupt may go off before the - * timer has re-loaded from wrapping. - */ - - tval = __raw_readl(S3C2410_TCNTO(4)); - tdone = timer_startval - tval; - - if (tval != 0) - tdone += timer_startval; - } - - return timer_ticks_to_usec(tdone) * 1000; -} - - -/* - * IRQ handler for the timer - */ -static irqreturn_t -s3c2410_timer_interrupt(int irq, void *dev_id) -{ - timer_tick(); - return IRQ_HANDLED; -} - -static struct irqaction s3c2410_timer_irq = { - .name = "S3C2410 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = s3c2410_timer_interrupt, -}; - -#define use_tclk1_12() ( \ - machine_is_bast() || \ - machine_is_vr1000() || \ - machine_is_anubis() || \ - machine_is_osiris()) - -static struct clk *tin; -static struct clk *tdiv; -static struct clk *timerclk; - -/* - * Set up timer interrupt, and return the current time in seconds. - * - * Currently we only use timer4, as it is the only timer which has no - * other function that can be exploited externally - */ -static void s3c2410_timer_setup (void) -{ - unsigned long tcon; - unsigned long tcnt; - unsigned long tcfg1; - unsigned long tcfg0; - - tcnt = TICK_MAX; /* default value for tcnt */ - - /* configure the system for whichever machine is in use */ - - if (use_tclk1_12()) { - /* timer is at 12MHz, scaler is 1 */ - timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); - tcnt = 12000000 / HZ; - - tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; - tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; - __raw_writel(tcfg1, S3C2410_TCFG1); - } else { - unsigned long pclk; - struct clk *tscaler; - - /* for the h1940 (and others), we use the pclk from the core - * to generate the timer values. since values around 50 to - * 70MHz are not values we can directly generate the timer - * value from, we need to pre-scale and divide before using it. - * - * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz - * (8.45 ticks per usec) - */ - - pclk = clk_get_rate(timerclk); - - /* configure clock tick */ - - timer_usec_ticks = timer_mask_usec_ticks(6, pclk); - - tscaler = clk_get_parent(tdiv); - - clk_set_rate(tscaler, pclk / 3); - clk_set_rate(tdiv, pclk / 6); - clk_set_parent(tin, tdiv); - - tcnt = clk_get_rate(tin) / HZ; - } - - tcon = __raw_readl(S3C2410_TCON); - tcfg0 = __raw_readl(S3C2410_TCFG0); - tcfg1 = __raw_readl(S3C2410_TCFG1); - - /* timers reload after counting zero, so reduce the count by 1 */ - - tcnt--; - - printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n", - tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks); - - /* check to see if timer is within 16bit range... */ - if (tcnt > TICK_MAX) { - panic("setup_timer: HZ is too small, cannot configure timer!"); - return; - } - - __raw_writel(tcfg1, S3C2410_TCFG1); - __raw_writel(tcfg0, S3C2410_TCFG0); - - timer_startval = tcnt; - __raw_writel(tcnt, S3C2410_TCNTB(4)); - - /* ensure timer is stopped... */ - - tcon &= ~(7<<20); - tcon |= S3C2410_TCON_T4RELOAD; - tcon |= S3C2410_TCON_T4MANUALUPD; - - __raw_writel(tcon, S3C2410_TCON); - __raw_writel(tcnt, S3C2410_TCNTB(4)); - __raw_writel(tcnt, S3C2410_TCMPB(4)); - - /* start the timer running */ - tcon |= S3C2410_TCON_T4START; - tcon &= ~S3C2410_TCON_T4MANUALUPD; - __raw_writel(tcon, S3C2410_TCON); -} - -static void __init s3c2410_timer_resources(void) -{ - struct platform_device tmpdev; - - tmpdev.dev.bus = &platform_bus_type; - tmpdev.id = 4; - - timerclk = clk_get(NULL, "timers"); - if (IS_ERR(timerclk)) - panic("failed to get clock for system timer"); - - clk_enable(timerclk); - - if (!use_tclk1_12()) { - tmpdev.id = 4; - tmpdev.dev.init_name = "s3c24xx-pwm.4"; - tin = clk_get(&tmpdev.dev, "pwm-tin"); - if (IS_ERR(tin)) - panic("failed to get pwm-tin clock for system timer"); - - tdiv = clk_get(&tmpdev.dev, "pwm-tdiv"); - if (IS_ERR(tdiv)) - panic("failed to get pwm-tdiv clock for system timer"); - } - - clk_enable(tin); -} - -static struct syscore_ops s3c24xx_syscore_ops = { - .resume = s3c2410_timer_setup, -}; - -void __init s3c24xx_timer_init(void) -{ - arch_gettimeoffset = s3c2410_gettimeoffset; - - s3c2410_timer_resources(); - s3c2410_timer_setup(); - setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); - register_syscore_ops(&s3c24xx_syscore_ops); -} diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index b323d8d3185..7c2f6685bf4 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1453,7 +1453,7 @@ static struct resource atmel_lcdfb0_resource[] = { }, }; DEFINE_DEV_DATA(atmel_lcdfb, 0); -DEV_CLK(hck1, atmel_lcdfb0, hsb, 7); +DEV_CLK(hclk, atmel_lcdfb0, hsb, 7); static struct clk atmel_lcdfb0_pixclk = { .name = "lcdc_clk", .dev = &atmel_lcdfb0_device.dev, @@ -1530,6 +1530,8 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, memcpy(info, data, sizeof(struct atmel_lcdfb_info)); info->default_monspecs = monspecs; + pdev->name = "at32ap-lcdfb"; + platform_device_register(pdev); return pdev; @@ -2246,7 +2248,7 @@ static __initdata struct clk *init_clocks[] = { &atmel_twi0_pclk, &atmel_mci0_pclk, #if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) - &atmel_lcdfb0_hck1, + &atmel_lcdfb0_hclk, &atmel_lcdfb0_pixclk, #endif &ssc0_pclk, diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c index e6a553cb73e..4329a29a531 100644 --- a/drivers/clocksource/em_sti.c +++ b/drivers/clocksource/em_sti.c @@ -399,7 +399,18 @@ static struct platform_driver em_sti_device_driver = { } }; -module_platform_driver(em_sti_device_driver); +static int __init em_sti_init(void) +{ + return platform_driver_register(&em_sti_device_driver); +} + +static void __exit em_sti_exit(void) +{ + platform_driver_unregister(&em_sti_device_driver); +} + +subsys_initcall(em_sti_init); +module_exit(em_sti_exit); MODULE_AUTHOR("Magnus Damm"); MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver"); diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 488c14cc8db..08d0c418c94 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -54,62 +54,100 @@ struct sh_cmt_priv { struct clocksource cs; unsigned long total_cycles; bool cs_enabled; + + /* callbacks for CMSTR and CMCSR access */ + unsigned long (*read_control)(void __iomem *base, unsigned long offs); + void (*write_control)(void __iomem *base, unsigned long offs, + unsigned long value); + + /* callbacks for CMCNT and CMCOR access */ + unsigned long (*read_count)(void __iomem *base, unsigned long offs); + void (*write_count)(void __iomem *base, unsigned long offs, + unsigned long value); }; -static DEFINE_RAW_SPINLOCK(sh_cmt_lock); +/* Examples of supported CMT timer register layouts and I/O access widths: + * + * "16-bit counter and 16-bit control" as found on sh7263: + * CMSTR 0xfffec000 16-bit + * CMCSR 0xfffec002 16-bit + * CMCNT 0xfffec004 16-bit + * CMCOR 0xfffec006 16-bit + * + * "32-bit counter and 16-bit control" as found on sh7372, sh73a0, r8a7740: + * CMSTR 0xffca0000 16-bit + * CMCSR 0xffca0060 16-bit + * CMCNT 0xffca0064 32-bit + * CMCOR 0xffca0068 32-bit + */ + +static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) +{ + return ioread16(base + (offs << 1)); +} + +static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs) +{ + return ioread32(base + (offs << 2)); +} + +static void sh_cmt_write16(void __iomem *base, unsigned long offs, + unsigned long value) +{ + iowrite16(value, base + (offs << 1)); +} + +static void sh_cmt_write32(void __iomem *base, unsigned long offs, + unsigned long value) +{ + iowrite32(value, base + (offs << 2)); +} -#define CMSTR -1 /* shared register */ #define CMCSR 0 /* channel register */ #define CMCNT 1 /* channel register */ #define CMCOR 2 /* channel register */ -static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) +static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) { struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == CMSTR) { - offs = 0; - base -= cfg->channel_offset; - } else - offs = reg_nr; - - if (p->width == 16) - offs <<= 1; - else { - offs <<= 2; - if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) - return ioread32(base + offs); - } - return ioread16(base + offs); + return p->read_control(p->mapbase - cfg->channel_offset, 0); } -static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, - unsigned long value) +static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) +{ + return p->read_control(p->mapbase, CMCSR); +} + +static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) +{ + return p->read_count(p->mapbase, CMCNT); +} + +static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, + unsigned long value) { struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == CMSTR) { - offs = 0; - base -= cfg->channel_offset; - } else - offs = reg_nr; - - if (p->width == 16) - offs <<= 1; - else { - offs <<= 2; - if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) { - iowrite32(value, base + offs); - return; - } - } - iowrite16(value, base + offs); + p->write_control(p->mapbase - cfg->channel_offset, 0, value); +} + +static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, + unsigned long value) +{ + p->write_control(p->mapbase, CMCSR, value); +} + +static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, + unsigned long value) +{ + p->write_count(p->mapbase, CMCNT, value); +} + +static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p, + unsigned long value) +{ + p->write_count(p->mapbase, CMCOR, value); } static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, @@ -118,15 +156,15 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, unsigned long v1, v2, v3; int o1, o2; - o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; + o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit; /* Make sure the timer value is stable. Stolen from acpi_pm.c */ do { o2 = o1; - v1 = sh_cmt_read(p, CMCNT); - v2 = sh_cmt_read(p, CMCNT); - v3 = sh_cmt_read(p, CMCNT); - o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; + v1 = sh_cmt_read_cmcnt(p); + v2 = sh_cmt_read_cmcnt(p); + v3 = sh_cmt_read_cmcnt(p); + o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit; } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); @@ -134,6 +172,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, return v2; } +static DEFINE_RAW_SPINLOCK(sh_cmt_lock); static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) { @@ -142,14 +181,14 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) /* start stop register shared by multiple timer channels */ raw_spin_lock_irqsave(&sh_cmt_lock, flags); - value = sh_cmt_read(p, CMSTR); + value = sh_cmt_read_cmstr(p); if (start) value |= 1 << cfg->timer_bit; else value &= ~(1 << cfg->timer_bit); - sh_cmt_write(p, CMSTR, value); + sh_cmt_write_cmstr(p, value); raw_spin_unlock_irqrestore(&sh_cmt_lock, flags); } @@ -173,14 +212,14 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) /* configure channel, periodic mode and maximum timeout */ if (p->width == 16) { *rate = clk_get_rate(p->clk) / 512; - sh_cmt_write(p, CMCSR, 0x43); + sh_cmt_write_cmcsr(p, 0x43); } else { *rate = clk_get_rate(p->clk) / 8; - sh_cmt_write(p, CMCSR, 0x01a4); + sh_cmt_write_cmcsr(p, 0x01a4); } - sh_cmt_write(p, CMCOR, 0xffffffff); - sh_cmt_write(p, CMCNT, 0); + sh_cmt_write_cmcor(p, 0xffffffff); + sh_cmt_write_cmcnt(p, 0); /* * According to the sh73a0 user's manual, as CMCNT can be operated @@ -194,12 +233,12 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) * take RCLKx2 at maximum. */ for (k = 0; k < 100; k++) { - if (!sh_cmt_read(p, CMCNT)) + if (!sh_cmt_read_cmcnt(p)) break; udelay(1); } - if (sh_cmt_read(p, CMCNT)) { + if (sh_cmt_read_cmcnt(p)) { dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); ret = -ETIMEDOUT; goto err1; @@ -222,7 +261,7 @@ static void sh_cmt_disable(struct sh_cmt_priv *p) sh_cmt_start_stop_ch(p, 0); /* disable interrupts in CMT block */ - sh_cmt_write(p, CMCSR, 0); + sh_cmt_write_cmcsr(p, 0); /* stop clock */ clk_disable(p->clk); @@ -270,7 +309,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, if (new_match > p->max_match_value) new_match = p->max_match_value; - sh_cmt_write(p, CMCOR, new_match); + sh_cmt_write_cmcor(p, new_match); now = sh_cmt_get_counter(p, &has_wrapped); if (has_wrapped && (new_match > p->match_value)) { @@ -346,7 +385,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) struct sh_cmt_priv *p = dev_id; /* clear flags */ - sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits); + sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits); /* update clock source counter to begin with if enabled * the wrap flag should be cleared by the timer specific @@ -625,14 +664,6 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name, unsigned long clockevent_rating, unsigned long clocksource_rating) { - if (p->width == (sizeof(p->max_match_value) * 8)) - p->max_match_value = ~0; - else - p->max_match_value = (1 << p->width) - 1; - - p->match_value = p->max_match_value; - raw_spin_lock_init(&p->lock); - if (clockevent_rating) sh_cmt_register_clockevent(p, name, clockevent_rating); @@ -657,8 +688,6 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) goto err0; } - platform_set_drvdata(pdev, p); - res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&p->pdev->dev, "failed to get I/O memory\n"); @@ -693,32 +722,51 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) goto err1; } + p->read_control = sh_cmt_read16; + p->write_control = sh_cmt_write16; + if (resource_size(res) == 6) { p->width = 16; + p->read_count = sh_cmt_read16; + p->write_count = sh_cmt_write16; p->overflow_bit = 0x80; p->clear_bits = ~0x80; } else { p->width = 32; + p->read_count = sh_cmt_read32; + p->write_count = sh_cmt_write32; p->overflow_bit = 0x8000; p->clear_bits = ~0xc000; } + if (p->width == (sizeof(p->max_match_value) * 8)) + p->max_match_value = ~0; + else + p->max_match_value = (1 << p->width) - 1; + + p->match_value = p->max_match_value; + raw_spin_lock_init(&p->lock); + ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev), cfg->clockevent_rating, cfg->clocksource_rating); if (ret) { dev_err(&p->pdev->dev, "registration failed\n"); - goto err1; + goto err2; } p->cs_enabled = false; ret = setup_irq(irq, &p->irqaction); if (ret) { dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); - goto err1; + goto err2; } + platform_set_drvdata(pdev, p); + return 0; +err2: + clk_put(p->clk); err1: iounmap(p->mapbase); @@ -751,7 +799,6 @@ static int sh_cmt_probe(struct platform_device *pdev) ret = sh_cmt_setup(p, pdev); if (ret) { kfree(p); - platform_set_drvdata(pdev, NULL); pm_runtime_idle(&pdev->dev); return ret; } @@ -791,7 +838,7 @@ static void __exit sh_cmt_exit(void) } early_platform_init("earlytimer", &sh_cmt_device_driver); -module_init(sh_cmt_init); +subsys_initcall(sh_cmt_init); module_exit(sh_cmt_exit); MODULE_AUTHOR("Magnus Damm"); diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 83943e27cfa..4aac9ee0d0c 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -386,7 +386,7 @@ static void __exit sh_mtu2_exit(void) } early_platform_init("earlytimer", &sh_mtu2_device_driver); -module_init(sh_mtu2_init); +subsys_initcall(sh_mtu2_init); module_exit(sh_mtu2_exit); MODULE_AUTHOR("Magnus Damm"); diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index b4502edce2a..78b8dae4962 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -549,7 +549,7 @@ static void __exit sh_tmu_exit(void) } early_platform_init("earlytimer", &sh_tmu_device_driver); -module_init(sh_tmu_init); +subsys_initcall(sh_tmu_init); module_exit(sh_tmu_exit); MODULE_AUTHOR("Magnus Damm"); diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b3643ff007e..99e0fa49fcb 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -1122,8 +1122,12 @@ int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) #ifdef CONFIG_PLAT_S3C24XX static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) { - if (offset < 4) - return IRQ_EINT0 + 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; @@ -3024,6 +3028,7 @@ static __init int samsung_gpiolib_init(void) static const struct of_device_id exynos_pinctrl_ids[] = { { .compatible = "samsung,exynos4210-pinctrl", }, { .compatible = "samsung,exynos4x12-pinctrl", }, + { .compatible = "samsung,exynos5250-pinctrl", }, { .compatible = "samsung,exynos5440-pinctrl", }, }; for_each_matching_node(pctrl_np, exynos_pinctrl_ids) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index a350969e5ef..4a33351c25d 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -25,6 +25,14 @@ config ARM_VIC_NR The maximum number of VICs available in the system, for power management. +config RENESAS_INTC_IRQPIN + bool + select IRQ_DOMAIN + +config RENESAS_IRQC + bool + select IRQ_DOMAIN + config VERSATILE_FPGA_IRQ bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 98e3b87bdf1..e41ceb9bec2 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -8,4 +8,6 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o +obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o +obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c new file mode 100644 index 00000000000..5a68e5accec --- /dev/null +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -0,0 +1,547 @@ +/* + * Renesas INTC External IRQ Pin Driver + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/platform_data/irq-renesas-intc-irqpin.h> + +#define INTC_IRQPIN_MAX 8 /* maximum 8 interrupts per driver instance */ + +#define INTC_IRQPIN_REG_SENSE 0 /* ICRn */ +#define INTC_IRQPIN_REG_PRIO 1 /* INTPRInn */ +#define INTC_IRQPIN_REG_SOURCE 2 /* INTREQnn */ +#define INTC_IRQPIN_REG_MASK 3 /* INTMSKnn */ +#define INTC_IRQPIN_REG_CLEAR 4 /* INTMSKCLRnn */ +#define INTC_IRQPIN_REG_NR 5 + +/* INTC external IRQ PIN hardware register access: + * + * SENSE is read-write 32-bit with 2-bits or 4-bits per IRQ (*) + * PRIO is read-write 32-bit with 4-bits per IRQ (**) + * SOURCE is read-only 32-bit or 8-bit with 1-bit per IRQ (***) + * MASK is write-only 32-bit or 8-bit with 1-bit per IRQ (***) + * CLEAR is write-only 32-bit or 8-bit with 1-bit per IRQ (***) + * + * (*) May be accessed by more than one driver instance - lock needed + * (**) Read-modify-write access by one driver instance - lock needed + * (***) Accessed by one driver instance only - no locking needed + */ + +struct intc_irqpin_iomem { + void __iomem *iomem; + unsigned long (*read)(void __iomem *iomem); + void (*write)(void __iomem *iomem, unsigned long data); + int width; +}; + +struct intc_irqpin_irq { + int hw_irq; + int requested_irq; + int domain_irq; + struct intc_irqpin_priv *p; +}; + +struct intc_irqpin_priv { + struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR]; + struct intc_irqpin_irq irq[INTC_IRQPIN_MAX]; + struct renesas_intc_irqpin_config config; + unsigned int number_of_irqs; + struct platform_device *pdev; + struct irq_chip irq_chip; + struct irq_domain *irq_domain; + bool shared_irqs; + u8 shared_irq_mask; +}; + +static unsigned long intc_irqpin_read32(void __iomem *iomem) +{ + return ioread32(iomem); +} + +static unsigned long intc_irqpin_read8(void __iomem *iomem) +{ + return ioread8(iomem); +} + +static void intc_irqpin_write32(void __iomem *iomem, unsigned long data) +{ + iowrite32(data, iomem); +} + +static void intc_irqpin_write8(void __iomem *iomem, unsigned long data) +{ + iowrite8(data, iomem); +} + +static inline unsigned long intc_irqpin_read(struct intc_irqpin_priv *p, + int reg) +{ + struct intc_irqpin_iomem *i = &p->iomem[reg]; + + return i->read(i->iomem); +} + +static inline void intc_irqpin_write(struct intc_irqpin_priv *p, + int reg, unsigned long data) +{ + struct intc_irqpin_iomem *i = &p->iomem[reg]; + + i->write(i->iomem, data); +} + +static inline unsigned long intc_irqpin_hwirq_mask(struct intc_irqpin_priv *p, + int reg, int hw_irq) +{ + return BIT((p->iomem[reg].width - 1) - hw_irq); +} + +static inline void intc_irqpin_irq_write_hwirq(struct intc_irqpin_priv *p, + int reg, int hw_irq) +{ + intc_irqpin_write(p, reg, intc_irqpin_hwirq_mask(p, reg, hw_irq)); +} + +static DEFINE_RAW_SPINLOCK(intc_irqpin_lock); /* only used by slow path */ + +static void intc_irqpin_read_modify_write(struct intc_irqpin_priv *p, + int reg, int shift, + int width, int value) +{ + unsigned long flags; + unsigned long tmp; + + raw_spin_lock_irqsave(&intc_irqpin_lock, flags); + + tmp = intc_irqpin_read(p, reg); + tmp &= ~(((1 << width) - 1) << shift); + tmp |= value << shift; + intc_irqpin_write(p, reg, tmp); + + raw_spin_unlock_irqrestore(&intc_irqpin_lock, flags); +} + +static void intc_irqpin_mask_unmask_prio(struct intc_irqpin_priv *p, + int irq, int do_mask) +{ + int bitfield_width = 4; /* PRIO assumed to have fixed bitfield width */ + int shift = (7 - irq) * bitfield_width; /* PRIO assumed to be 32-bit */ + + intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_PRIO, + shift, bitfield_width, + do_mask ? 0 : (1 << bitfield_width) - 1); +} + +static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value) +{ + int bitfield_width = p->config.sense_bitfield_width; + int shift = (7 - irq) * bitfield_width; /* SENSE assumed to be 32-bit */ + + dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value); + + if (value >= (1 << bitfield_width)) + return -EINVAL; + + intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_SENSE, shift, + bitfield_width, value); + return 0; +} + +static void intc_irqpin_dbg(struct intc_irqpin_irq *i, char *str) +{ + dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", + str, i->requested_irq, i->hw_irq, i->domain_irq); +} + +static void intc_irqpin_irq_enable(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + intc_irqpin_dbg(&p->irq[hw_irq], "enable"); + intc_irqpin_irq_write_hwirq(p, INTC_IRQPIN_REG_CLEAR, hw_irq); +} + +static void intc_irqpin_irq_disable(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + intc_irqpin_dbg(&p->irq[hw_irq], "disable"); + intc_irqpin_irq_write_hwirq(p, INTC_IRQPIN_REG_MASK, hw_irq); +} + +static void intc_irqpin_shared_irq_enable(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + intc_irqpin_dbg(&p->irq[hw_irq], "shared enable"); + intc_irqpin_irq_write_hwirq(p, INTC_IRQPIN_REG_CLEAR, hw_irq); + + p->shared_irq_mask &= ~BIT(hw_irq); +} + +static void intc_irqpin_shared_irq_disable(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + intc_irqpin_dbg(&p->irq[hw_irq], "shared disable"); + intc_irqpin_irq_write_hwirq(p, INTC_IRQPIN_REG_MASK, hw_irq); + + p->shared_irq_mask |= BIT(hw_irq); +} + +static void intc_irqpin_irq_enable_force(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int irq = p->irq[irqd_to_hwirq(d)].requested_irq; + + intc_irqpin_irq_enable(d); + + /* enable interrupt through parent interrupt controller, + * assumes non-shared interrupt with 1:1 mapping + * needed for busted IRQs on some SoCs like sh73a0 + */ + irq_get_chip(irq)->irq_unmask(irq_get_irq_data(irq)); +} + +static void intc_irqpin_irq_disable_force(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int irq = p->irq[irqd_to_hwirq(d)].requested_irq; + + /* disable interrupt through parent interrupt controller, + * assumes non-shared interrupt with 1:1 mapping + * needed for busted IRQs on some SoCs like sh73a0 + */ + irq_get_chip(irq)->irq_mask(irq_get_irq_data(irq)); + intc_irqpin_irq_disable(d); +} + +#define INTC_IRQ_SENSE_VALID 0x10 +#define INTC_IRQ_SENSE(x) (x + INTC_IRQ_SENSE_VALID) + +static unsigned char intc_irqpin_sense[IRQ_TYPE_SENSE_MASK + 1] = { + [IRQ_TYPE_EDGE_FALLING] = INTC_IRQ_SENSE(0x00), + [IRQ_TYPE_EDGE_RISING] = INTC_IRQ_SENSE(0x01), + [IRQ_TYPE_LEVEL_LOW] = INTC_IRQ_SENSE(0x02), + [IRQ_TYPE_LEVEL_HIGH] = INTC_IRQ_SENSE(0x03), + [IRQ_TYPE_EDGE_BOTH] = INTC_IRQ_SENSE(0x04), +}; + +static int intc_irqpin_irq_set_type(struct irq_data *d, unsigned int type) +{ + unsigned char value = intc_irqpin_sense[type & IRQ_TYPE_SENSE_MASK]; + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + + if (!(value & INTC_IRQ_SENSE_VALID)) + return -EINVAL; + + return intc_irqpin_set_sense(p, irqd_to_hwirq(d), + value ^ INTC_IRQ_SENSE_VALID); +} + +static irqreturn_t intc_irqpin_irq_handler(int irq, void *dev_id) +{ + struct intc_irqpin_irq *i = dev_id; + struct intc_irqpin_priv *p = i->p; + unsigned long bit; + + intc_irqpin_dbg(i, "demux1"); + bit = intc_irqpin_hwirq_mask(p, INTC_IRQPIN_REG_SOURCE, i->hw_irq); + + if (intc_irqpin_read(p, INTC_IRQPIN_REG_SOURCE) & bit) { + intc_irqpin_write(p, INTC_IRQPIN_REG_SOURCE, ~bit); + intc_irqpin_dbg(i, "demux2"); + generic_handle_irq(i->domain_irq); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static irqreturn_t intc_irqpin_shared_irq_handler(int irq, void *dev_id) +{ + struct intc_irqpin_priv *p = dev_id; + unsigned int reg_source = intc_irqpin_read(p, INTC_IRQPIN_REG_SOURCE); + irqreturn_t status = IRQ_NONE; + int k; + + for (k = 0; k < 8; k++) { + if (reg_source & BIT(7 - k)) { + if (BIT(k) & p->shared_irq_mask) + continue; + + status |= intc_irqpin_irq_handler(irq, &p->irq[k]); + } + } + + return status; +} + +static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct intc_irqpin_priv *p = h->host_data; + + p->irq[hw].domain_irq = virq; + p->irq[hw].hw_irq = hw; + + intc_irqpin_dbg(&p->irq[hw], "map"); + irq_set_chip_data(virq, h->host_data); + irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID); /* kill me now */ + return 0; +} + +static struct irq_domain_ops intc_irqpin_irq_domain_ops = { + .map = intc_irqpin_irq_domain_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int intc_irqpin_probe(struct platform_device *pdev) +{ + struct renesas_intc_irqpin_config *pdata = pdev->dev.platform_data; + struct intc_irqpin_priv *p; + struct intc_irqpin_iomem *i; + struct resource *io[INTC_IRQPIN_REG_NR]; + struct resource *irq; + struct irq_chip *irq_chip; + void (*enable_fn)(struct irq_data *d); + void (*disable_fn)(struct irq_data *d); + const char *name = dev_name(&pdev->dev); + int ref_irq; + int ret; + int k; + + p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); + if (!p) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + ret = -ENOMEM; + goto err0; + } + + /* deal with driver instance configuration */ + if (pdata) + memcpy(&p->config, pdata, sizeof(*pdata)); + if (!p->config.sense_bitfield_width) + p->config.sense_bitfield_width = 4; /* default to 4 bits */ + + p->pdev = pdev; + platform_set_drvdata(pdev, p); + + /* get hold of manadatory IOMEM */ + for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { + io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k); + if (!io[k]) { + dev_err(&pdev->dev, "not enough IOMEM resources\n"); + ret = -EINVAL; + goto err0; + } + } + + /* allow any number of IRQs between 1 and INTC_IRQPIN_MAX */ + for (k = 0; k < INTC_IRQPIN_MAX; k++) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, k); + if (!irq) + break; + + p->irq[k].p = p; + p->irq[k].requested_irq = irq->start; + } + + p->number_of_irqs = k; + if (p->number_of_irqs < 1) { + dev_err(&pdev->dev, "not enough IRQ resources\n"); + ret = -EINVAL; + goto err0; + } + + /* ioremap IOMEM and setup read/write callbacks */ + for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { + i = &p->iomem[k]; + + switch (resource_size(io[k])) { + case 1: + i->width = 8; + i->read = intc_irqpin_read8; + i->write = intc_irqpin_write8; + break; + case 4: + i->width = 32; + i->read = intc_irqpin_read32; + i->write = intc_irqpin_write32; + break; + default: + dev_err(&pdev->dev, "IOMEM size mismatch\n"); + ret = -EINVAL; + goto err0; + } + + i->iomem = devm_ioremap_nocache(&pdev->dev, io[k]->start, + resource_size(io[k])); + if (!i->iomem) { + dev_err(&pdev->dev, "failed to remap IOMEM\n"); + ret = -ENXIO; + goto err0; + } + } + + /* mask all interrupts using priority */ + for (k = 0; k < p->number_of_irqs; k++) + intc_irqpin_mask_unmask_prio(p, k, 1); + + /* clear all pending interrupts */ + intc_irqpin_write(p, INTC_IRQPIN_REG_SOURCE, 0x0); + + /* scan for shared interrupt lines */ + ref_irq = p->irq[0].requested_irq; + p->shared_irqs = true; + for (k = 1; k < p->number_of_irqs; k++) { + if (ref_irq != p->irq[k].requested_irq) { + p->shared_irqs = false; + break; + } + } + + /* use more severe masking method if requested */ + if (p->config.control_parent) { + enable_fn = intc_irqpin_irq_enable_force; + disable_fn = intc_irqpin_irq_disable_force; + } else if (!p->shared_irqs) { + enable_fn = intc_irqpin_irq_enable; + disable_fn = intc_irqpin_irq_disable; + } else { + enable_fn = intc_irqpin_shared_irq_enable; + disable_fn = intc_irqpin_shared_irq_disable; + } + + irq_chip = &p->irq_chip; + irq_chip->name = name; + irq_chip->irq_mask = disable_fn; + irq_chip->irq_unmask = enable_fn; + irq_chip->irq_enable = enable_fn; + irq_chip->irq_disable = disable_fn; + irq_chip->irq_set_type = intc_irqpin_irq_set_type; + irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; + + p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, + p->number_of_irqs, + p->config.irq_base, + &intc_irqpin_irq_domain_ops, p); + if (!p->irq_domain) { + ret = -ENXIO; + dev_err(&pdev->dev, "cannot initialize irq domain\n"); + goto err0; + } + + if (p->shared_irqs) { + /* request one shared interrupt */ + if (devm_request_irq(&pdev->dev, p->irq[0].requested_irq, + intc_irqpin_shared_irq_handler, + IRQF_SHARED, name, p)) { + dev_err(&pdev->dev, "failed to request low IRQ\n"); + ret = -ENOENT; + goto err1; + } + } else { + /* request interrupts one by one */ + for (k = 0; k < p->number_of_irqs; k++) { + if (devm_request_irq(&pdev->dev, + p->irq[k].requested_irq, + intc_irqpin_irq_handler, + 0, name, &p->irq[k])) { + dev_err(&pdev->dev, + "failed to request low IRQ\n"); + ret = -ENOENT; + goto err1; + } + } + } + + /* unmask all interrupts on prio level */ + for (k = 0; k < p->number_of_irqs; k++) + intc_irqpin_mask_unmask_prio(p, k, 0); + + dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); + + /* warn in case of mismatch if irq base is specified */ + if (p->config.irq_base) { + if (p->config.irq_base != p->irq[0].domain_irq) + dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n", + p->config.irq_base, p->irq[0].domain_irq); + } + + return 0; + +err1: + irq_domain_remove(p->irq_domain); +err0: + return ret; +} + +static int intc_irqpin_remove(struct platform_device *pdev) +{ + struct intc_irqpin_priv *p = platform_get_drvdata(pdev); + + irq_domain_remove(p->irq_domain); + + return 0; +} + +static const struct of_device_id intc_irqpin_dt_ids[] = { + { .compatible = "renesas,intc-irqpin", }, + {}, +}; +MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); + +static struct platform_driver intc_irqpin_device_driver = { + .probe = intc_irqpin_probe, + .remove = intc_irqpin_remove, + .driver = { + .name = "renesas_intc_irqpin", + .of_match_table = intc_irqpin_dt_ids, + .owner = THIS_MODULE, + } +}; + +static int __init intc_irqpin_init(void) +{ + return platform_driver_register(&intc_irqpin_device_driver); +} +postcore_initcall(intc_irqpin_init); + +static void __exit intc_irqpin_exit(void) +{ + platform_driver_unregister(&intc_irqpin_device_driver); +} +module_exit(intc_irqpin_exit); + +MODULE_AUTHOR("Magnus Damm"); +MODULE_DESCRIPTION("Renesas INTC External IRQ Pin Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c new file mode 100644 index 00000000000..927bff373aa --- /dev/null +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -0,0 +1,307 @@ +/* + * Renesas IRQC Driver + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/platform_data/irq-renesas-irqc.h> + +#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ + +#define IRQC_REQ_STS 0x00 +#define IRQC_EN_STS 0x04 +#define IRQC_EN_SET 0x08 +#define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) +#define DETECT_STATUS 0x100 +#define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) + +struct irqc_irq { + int hw_irq; + int requested_irq; + int domain_irq; + struct irqc_priv *p; +}; + +struct irqc_priv { + void __iomem *iomem; + void __iomem *cpu_int_base; + struct irqc_irq irq[IRQC_IRQ_MAX]; + struct renesas_irqc_config config; + unsigned int number_of_irqs; + struct platform_device *pdev; + struct irq_chip irq_chip; + struct irq_domain *irq_domain; +}; + +static void irqc_dbg(struct irqc_irq *i, char *str) +{ + dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", + str, i->requested_irq, i->hw_irq, i->domain_irq); +} + +static void irqc_irq_enable(struct irq_data *d) +{ + struct irqc_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + irqc_dbg(&p->irq[hw_irq], "enable"); + iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_SET); +} + +static void irqc_irq_disable(struct irq_data *d) +{ + struct irqc_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + irqc_dbg(&p->irq[hw_irq], "disable"); + iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_STS); +} + +#define INTC_IRQ_SENSE_VALID 0x10 +#define INTC_IRQ_SENSE(x) (x + INTC_IRQ_SENSE_VALID) + +static unsigned char irqc_sense[IRQ_TYPE_SENSE_MASK + 1] = { + [IRQ_TYPE_LEVEL_LOW] = INTC_IRQ_SENSE(0x01), + [IRQ_TYPE_LEVEL_HIGH] = INTC_IRQ_SENSE(0x02), + [IRQ_TYPE_EDGE_FALLING] = INTC_IRQ_SENSE(0x04), /* Synchronous */ + [IRQ_TYPE_EDGE_RISING] = INTC_IRQ_SENSE(0x08), /* Synchronous */ + [IRQ_TYPE_EDGE_BOTH] = INTC_IRQ_SENSE(0x0c), /* Synchronous */ +}; + +static int irqc_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct irqc_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + unsigned char value = irqc_sense[type & IRQ_TYPE_SENSE_MASK]; + unsigned long tmp; + + irqc_dbg(&p->irq[hw_irq], "sense"); + + if (!(value & INTC_IRQ_SENSE_VALID)) + return -EINVAL; + + tmp = ioread32(p->iomem + IRQC_CONFIG(hw_irq)); + tmp &= ~0x3f; + tmp |= value ^ INTC_IRQ_SENSE_VALID; + iowrite32(tmp, p->iomem + IRQC_CONFIG(hw_irq)); + return 0; +} + +static irqreturn_t irqc_irq_handler(int irq, void *dev_id) +{ + struct irqc_irq *i = dev_id; + struct irqc_priv *p = i->p; + unsigned long bit = BIT(i->hw_irq); + + irqc_dbg(i, "demux1"); + + if (ioread32(p->iomem + DETECT_STATUS) & bit) { + iowrite32(bit, p->iomem + DETECT_STATUS); + irqc_dbg(i, "demux2"); + generic_handle_irq(i->domain_irq); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct irqc_priv *p = h->host_data; + + p->irq[hw].domain_irq = virq; + p->irq[hw].hw_irq = hw; + + irqc_dbg(&p->irq[hw], "map"); + irq_set_chip_data(virq, h->host_data); + irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID); /* kill me now */ + return 0; +} + +static struct irq_domain_ops irqc_irq_domain_ops = { + .map = irqc_irq_domain_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int irqc_probe(struct platform_device *pdev) +{ + struct renesas_irqc_config *pdata = pdev->dev.platform_data; + struct irqc_priv *p; + struct resource *io; + struct resource *irq; + struct irq_chip *irq_chip; + const char *name = dev_name(&pdev->dev); + int ret; + int k; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + ret = -ENOMEM; + goto err0; + } + + /* deal with driver instance configuration */ + if (pdata) + memcpy(&p->config, pdata, sizeof(*pdata)); + + p->pdev = pdev; + platform_set_drvdata(pdev, p); + + /* get hold of manadatory IOMEM */ + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!io) { + dev_err(&pdev->dev, "not enough IOMEM resources\n"); + ret = -EINVAL; + goto err1; + } + + /* allow any number of IRQs between 1 and IRQC_IRQ_MAX */ + for (k = 0; k < IRQC_IRQ_MAX; k++) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, k); + if (!irq) + break; + + p->irq[k].p = p; + p->irq[k].requested_irq = irq->start; + } + + p->number_of_irqs = k; + if (p->number_of_irqs < 1) { + dev_err(&pdev->dev, "not enough IRQ resources\n"); + ret = -EINVAL; + goto err1; + } + + /* ioremap IOMEM and setup read/write callbacks */ + p->iomem = ioremap_nocache(io->start, resource_size(io)); + if (!p->iomem) { + dev_err(&pdev->dev, "failed to remap IOMEM\n"); + ret = -ENXIO; + goto err2; + } + + p->cpu_int_base = p->iomem + IRQC_INT_CPU_BASE(0); /* SYS-SPI */ + + irq_chip = &p->irq_chip; + irq_chip->name = name; + irq_chip->irq_mask = irqc_irq_disable; + irq_chip->irq_unmask = irqc_irq_enable; + irq_chip->irq_enable = irqc_irq_enable; + irq_chip->irq_disable = irqc_irq_disable; + irq_chip->irq_set_type = irqc_irq_set_type; + irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; + + p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, + p->number_of_irqs, + p->config.irq_base, + &irqc_irq_domain_ops, p); + if (!p->irq_domain) { + ret = -ENXIO; + dev_err(&pdev->dev, "cannot initialize irq domain\n"); + goto err2; + } + + /* request interrupts one by one */ + for (k = 0; k < p->number_of_irqs; k++) { + if (request_irq(p->irq[k].requested_irq, irqc_irq_handler, + 0, name, &p->irq[k])) { + dev_err(&pdev->dev, "failed to request IRQ\n"); + ret = -ENOENT; + goto err3; + } + } + + dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); + + /* warn in case of mismatch if irq base is specified */ + if (p->config.irq_base) { + if (p->config.irq_base != p->irq[0].domain_irq) + dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n", + p->config.irq_base, p->irq[0].domain_irq); + } + + return 0; +err3: + for (; k >= 0; k--) + free_irq(p->irq[k - 1].requested_irq, &p->irq[k - 1]); + + irq_domain_remove(p->irq_domain); +err2: + iounmap(p->iomem); +err1: + kfree(p); +err0: + return ret; +} + +static int irqc_remove(struct platform_device *pdev) +{ + struct irqc_priv *p = platform_get_drvdata(pdev); + int k; + + for (k = 0; k < p->number_of_irqs; k++) + free_irq(p->irq[k].requested_irq, &p->irq[k]); + + irq_domain_remove(p->irq_domain); + iounmap(p->iomem); + kfree(p); + return 0; +} + +static const struct of_device_id irqc_dt_ids[] = { + { .compatible = "renesas,irqc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, irqc_dt_ids); + +static struct platform_driver irqc_device_driver = { + .probe = irqc_probe, + .remove = irqc_remove, + .driver = { + .name = "renesas_irqc", + .of_match_table = irqc_dt_ids, + .owner = THIS_MODULE, + } +}; + +static int __init irqc_init(void) +{ + return platform_driver_register(&irqc_device_driver); +} +postcore_initcall(irqc_init); + +static void __exit irqc_exit(void) +{ + platform_driver_unregister(&irqc_device_driver); +} +module_exit(irqc_exit); + +MODULE_AUTHOR("Magnus Damm"); +MODULE_DESCRIPTION("Renesas IRQC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 63fb265e0da..8d6794cdf89 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -25,14 +25,93 @@ #include <mach/dma.h> -#include <mach/regs-sdi.h> - #include <linux/platform_data/mmc-s3cmci.h> #include "s3cmci.h" #define DRIVER_NAME "s3c-mci" +#define S3C2410_SDICON (0x00) +#define S3C2410_SDIPRE (0x04) +#define S3C2410_SDICMDARG (0x08) +#define S3C2410_SDICMDCON (0x0C) +#define S3C2410_SDICMDSTAT (0x10) +#define S3C2410_SDIRSP0 (0x14) +#define S3C2410_SDIRSP1 (0x18) +#define S3C2410_SDIRSP2 (0x1C) +#define S3C2410_SDIRSP3 (0x20) +#define S3C2410_SDITIMER (0x24) +#define S3C2410_SDIBSIZE (0x28) +#define S3C2410_SDIDCON (0x2C) +#define S3C2410_SDIDCNT (0x30) +#define S3C2410_SDIDSTA (0x34) +#define S3C2410_SDIFSTA (0x38) + +#define S3C2410_SDIDATA (0x3C) +#define S3C2410_SDIIMSK (0x40) + +#define S3C2440_SDIDATA (0x40) +#define S3C2440_SDIIMSK (0x3C) + +#define S3C2440_SDICON_SDRESET (1 << 8) +#define S3C2410_SDICON_SDIOIRQ (1 << 3) +#define S3C2410_SDICON_FIFORESET (1 << 1) +#define S3C2410_SDICON_CLOCKTYPE (1 << 0) + +#define S3C2410_SDICMDCON_LONGRSP (1 << 10) +#define S3C2410_SDICMDCON_WAITRSP (1 << 9) +#define S3C2410_SDICMDCON_CMDSTART (1 << 8) +#define S3C2410_SDICMDCON_SENDERHOST (1 << 6) +#define S3C2410_SDICMDCON_INDEX (0x3f) + +#define S3C2410_SDICMDSTAT_CRCFAIL (1 << 12) +#define S3C2410_SDICMDSTAT_CMDSENT (1 << 11) +#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1 << 10) +#define S3C2410_SDICMDSTAT_RSPFIN (1 << 9) + +#define S3C2440_SDIDCON_DS_WORD (2 << 22) +#define S3C2410_SDIDCON_TXAFTERRESP (1 << 20) +#define S3C2410_SDIDCON_RXAFTERCMD (1 << 19) +#define S3C2410_SDIDCON_BLOCKMODE (1 << 17) +#define S3C2410_SDIDCON_WIDEBUS (1 << 16) +#define S3C2410_SDIDCON_DMAEN (1 << 15) +#define S3C2410_SDIDCON_STOP (1 << 14) +#define S3C2440_SDIDCON_DATSTART (1 << 14) + +#define S3C2410_SDIDCON_XFER_RXSTART (2 << 12) +#define S3C2410_SDIDCON_XFER_TXSTART (3 << 12) + +#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) + +#define S3C2410_SDIDSTA_SDIOIRQDETECT (1 << 9) +#define S3C2410_SDIDSTA_FIFOFAIL (1 << 8) +#define S3C2410_SDIDSTA_CRCFAIL (1 << 7) +#define S3C2410_SDIDSTA_RXCRCFAIL (1 << 6) +#define S3C2410_SDIDSTA_DATATIMEOUT (1 << 5) +#define S3C2410_SDIDSTA_XFERFINISH (1 << 4) +#define S3C2410_SDIDSTA_TXDATAON (1 << 1) +#define S3C2410_SDIDSTA_RXDATAON (1 << 0) + +#define S3C2440_SDIFSTA_FIFORESET (1 << 16) +#define S3C2440_SDIFSTA_FIFOFAIL (3 << 14) +#define S3C2410_SDIFSTA_TFDET (1 << 13) +#define S3C2410_SDIFSTA_RFDET (1 << 12) +#define S3C2410_SDIFSTA_COUNTMASK (0x7f) + +#define S3C2410_SDIIMSK_RESPONSECRC (1 << 17) +#define S3C2410_SDIIMSK_CMDSENT (1 << 16) +#define S3C2410_SDIIMSK_CMDTIMEOUT (1 << 15) +#define S3C2410_SDIIMSK_RESPONSEND (1 << 14) +#define S3C2410_SDIIMSK_SDIOIRQ (1 << 12) +#define S3C2410_SDIIMSK_FIFOFAIL (1 << 11) +#define S3C2410_SDIIMSK_CRCSTATUS (1 << 10) +#define S3C2410_SDIIMSK_DATACRC (1 << 9) +#define S3C2410_SDIIMSK_DATATIMEOUT (1 << 8) +#define S3C2410_SDIIMSK_DATAFINISH (1 << 7) +#define S3C2410_SDIIMSK_TXFIFOHALF (1 << 4) +#define S3C2410_SDIIMSK_RXFIFOLAST (1 << 2) +#define S3C2410_SDIIMSK_RXFIFOHALF (1 << 0) + enum dbg_channels { dbg_err = (1 << 0), dbg_debug = (1 << 1), diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 538b9ddaadf..8738933a57d 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -677,3 +677,111 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .label = "exynos4x12-gpio-ctrl3", }, }; + +/* pin banks of exynos5250 pin-controller 0 */ +static struct samsung_pin_bank exynos5250_pin_banks0[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), + EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), + EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), + EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c), + EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10), + EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14), + EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpb3", 0x18), + EXYNOS_PIN_BANK_EINTG(7, 0x0E0, "gpc0", 0x1c), + EXYNOS_PIN_BANK_EINTG(4, 0x100, "gpc1", 0x20), + EXYNOS_PIN_BANK_EINTG(7, 0x120, "gpc2", 0x24), + EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpc3", 0x28), + EXYNOS_PIN_BANK_EINTG(4, 0x160, "gpd0", 0x2c), + EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpd1", 0x30), + EXYNOS_PIN_BANK_EINTG(7, 0x2E0, "gpc4", 0x34), + EXYNOS_PIN_BANK_EINTN(6, 0x1A0, "gpy0"), + EXYNOS_PIN_BANK_EINTN(4, 0x1C0, "gpy1"), + EXYNOS_PIN_BANK_EINTN(6, 0x1E0, "gpy2"), + EXYNOS_PIN_BANK_EINTN(8, 0x200, "gpy3"), + EXYNOS_PIN_BANK_EINTN(8, 0x220, "gpy4"), + EXYNOS_PIN_BANK_EINTN(8, 0x240, "gpy5"), + EXYNOS_PIN_BANK_EINTN(8, 0x260, "gpy6"), + EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), + EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), + EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), + EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), +}; + +/* pin banks of exynos5250 pin-controller 1 */ +static struct samsung_pin_bank exynos5250_pin_banks1[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), + EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), + EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08), + EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpf1", 0x0c), + EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10), + EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14), + EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18), + EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gph0", 0x1c), + EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph1", 0x20), +}; + +/* pin banks of exynos5250 pin-controller 2 */ +static struct samsung_pin_bank exynos5250_pin_banks2[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), + EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), + EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08), + EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpv3", 0x0c), + EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpv4", 0x10), +}; + +/* pin banks of exynos5250 pin-controller 3 */ +static struct samsung_pin_bank exynos5250_pin_banks3[] = { + EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), +}; + +/* + * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes + * four gpio/pin-mux/pinconfig controllers. + */ +struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { + { + /* pin-controller instance 0 data */ + .pin_banks = exynos5250_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks0), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .weint_con = EXYNOS_WKUP_ECON_OFFSET, + .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, + .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .eint_wkup_init = exynos_eint_wkup_init, + .label = "exynos5250-gpio-ctrl0", + }, { + /* pin-controller instance 1 data */ + .pin_banks = exynos5250_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks1), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .label = "exynos5250-gpio-ctrl1", + }, { + /* pin-controller instance 2 data */ + .pin_banks = exynos5250_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks2), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .label = "exynos5250-gpio-ctrl2", + }, { + /* pin-controller instance 3 data */ + .pin_banks = exynos5250_pin_banks3, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks3), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .label = "exynos5250-gpio-ctrl3", + }, +}; diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index f206df17565..3d5cf639aa4 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -948,6 +948,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { .data = (void *)exynos4210_pin_ctrl }, { .compatible = "samsung,exynos4x12-pinctrl", .data = (void *)exynos4x12_pin_ctrl }, + { .compatible = "samsung,exynos5250-pinctrl", + .data = (void *)exynos5250_pin_ctrl }, {}, }; MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index e2d4e67f7e8..ee964aadce0 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h @@ -237,5 +237,6 @@ struct samsung_pmx_func { /* list of all exported SoC specific data */ extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; +extern struct samsung_pin_ctrl exynos5250_pin_ctrl[]; #endif /* __PINCTRL_SAMSUNG_H */ diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 709008e9412..6f15c03077a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2733,9 +2733,9 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -/* IRQ pins through INTCS with IRQ0->15 from 0x200 and IRQ16-31 from 0x3200 */ -#define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5)) -#define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5)) +/* External IRQ pins mapped at IRQPIN_BASE */ +#define EXT_IRQ16L(n) irq_pin(n) +#define EXT_IRQ16H(n) irq_pin(n) static struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0), diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 025428e04c3..c1a2914447e 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -34,6 +34,77 @@ #define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ #define ATMEL_LCDC_FIFO_SIZE 512 /* words */ +struct atmel_lcdfb_config { + bool have_alt_pixclock; + bool have_hozval; + bool have_intensity_bit; +}; + +static struct atmel_lcdfb_config at91sam9261_config = { + .have_hozval = true, + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at91sam9263_config = { + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at91sam9g10_config = { + .have_hozval = true, +}; + +static struct atmel_lcdfb_config at91sam9g45_config = { + .have_alt_pixclock = true, +}; + +static struct atmel_lcdfb_config at91sam9g45es_config = { +}; + +static struct atmel_lcdfb_config at91sam9rl_config = { + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at32ap_config = { + .have_hozval = true, +}; + +static const struct platform_device_id atmel_lcdfb_devtypes[] = { + { + .name = "at91sam9261-lcdfb", + .driver_data = (unsigned long)&at91sam9261_config, + }, { + .name = "at91sam9263-lcdfb", + .driver_data = (unsigned long)&at91sam9263_config, + }, { + .name = "at91sam9g10-lcdfb", + .driver_data = (unsigned long)&at91sam9g10_config, + }, { + .name = "at91sam9g45-lcdfb", + .driver_data = (unsigned long)&at91sam9g45_config, + }, { + .name = "at91sam9g45es-lcdfb", + .driver_data = (unsigned long)&at91sam9g45es_config, + }, { + .name = "at91sam9rl-lcdfb", + .driver_data = (unsigned long)&at91sam9rl_config, + }, { + .name = "at32ap-lcdfb", + .driver_data = (unsigned long)&at32ap_config, + }, { + /* terminator */ + } +}; + +static struct atmel_lcdfb_config * +atmel_lcdfb_get_config(struct platform_device *pdev) +{ + unsigned long data; + + data = platform_get_device_id(pdev)->driver_data; + + return (struct atmel_lcdfb_config *)data; +} + #if defined(CONFIG_ARCH_AT91) #define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ | FBINFO_PARTIAL_PAN_OK \ @@ -193,14 +264,16 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { .accel = FB_ACCEL_NONE, }; -static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) +static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo, + unsigned long xres) { + unsigned long lcdcon2; unsigned long value; - if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000())) + if (!sinfo->config->have_hozval) return xres; + lcdcon2 = lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2); value = xres; if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) { /* STN display */ @@ -423,7 +496,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, break; case 16: /* Older SOCs use IBGR:555 rather than BGR:565. */ - if (sinfo->have_intensity_bit) + if (sinfo->config->have_intensity_bit) var->green.length = 5; else var->green.length = 6; @@ -531,7 +604,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) /* Now, the LCDC core... */ /* Set pixel clock */ - if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) + if (sinfo->config->have_alt_pixclock) pix_factor = 1; clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; @@ -591,8 +664,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value); /* Horizontal value (aka line size) */ - hozval_linesz = compute_hozval(info->var.xres, - lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2)); + hozval_linesz = compute_hozval(sinfo, info->var.xres); /* Display size */ value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET; @@ -684,7 +756,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red, case FB_VISUAL_PSEUDOCOLOR: if (regno < 256) { - if (sinfo->have_intensity_bit) { + if (sinfo->config->have_intensity_bit) { /* old style I+BGR:555 */ val = ((red >> 11) & 0x001f); val |= ((green >> 6) & 0x03e0); @@ -821,15 +893,13 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo) static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) { - if (sinfo->bus_clk) - clk_enable(sinfo->bus_clk); + clk_enable(sinfo->bus_clk); clk_enable(sinfo->lcdc_clk); } static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) { - if (sinfo->bus_clk) - clk_disable(sinfo->bus_clk); + clk_disable(sinfo->bus_clk); clk_disable(sinfo->lcdc_clk); } @@ -874,10 +944,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) } sinfo->info = info; sinfo->pdev = pdev; - if (cpu_is_at91sam9261() || cpu_is_at91sam9263() || - cpu_is_at91sam9rl()) { - sinfo->have_intensity_bit = true; - } + sinfo->config = atmel_lcdfb_get_config(pdev); + if (!sinfo->config) + goto free_info; strcpy(info->fix.id, sinfo->pdev->name); info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; @@ -888,13 +957,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) info->fix = atmel_lcdfb_fix; /* Enable LCDC Clocks */ - if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000()) { - sinfo->bus_clk = clk_get(dev, "hck1"); - if (IS_ERR(sinfo->bus_clk)) { - ret = PTR_ERR(sinfo->bus_clk); - goto free_info; - } + sinfo->bus_clk = clk_get(dev, "hclk"); + if (IS_ERR(sinfo->bus_clk)) { + ret = PTR_ERR(sinfo->bus_clk); + goto free_info; } sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); if (IS_ERR(sinfo->lcdc_clk)) { @@ -1055,8 +1121,7 @@ stop_clk: atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); put_bus_clk: - if (sinfo->bus_clk) - clk_put(sinfo->bus_clk); + clk_put(sinfo->bus_clk); free_info: framebuffer_release(info); out: @@ -1081,8 +1146,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) unregister_framebuffer(info); atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); - if (sinfo->bus_clk) - clk_put(sinfo->bus_clk); + clk_put(sinfo->bus_clk); fb_dealloc_cmap(&info->cmap); free_irq(sinfo->irq_base, info); iounmap(sinfo->mmio); @@ -1151,7 +1215,7 @@ static struct platform_driver atmel_lcdfb_driver = { .remove = __exit_p(atmel_lcdfb_remove), .suspend = atmel_lcdfb_suspend, .resume = atmel_lcdfb_resume, - + .id_table = atmel_lcdfb_devtypes, .driver = { .name = "atmel_lcdfb", .owner = THIS_MODULE, diff --git a/include/linux/platform_data/irq-renesas-intc-irqpin.h b/include/linux/platform_data/irq-renesas-intc-irqpin.h new file mode 100644 index 00000000000..e4cb911066a --- /dev/null +++ b/include/linux/platform_data/irq-renesas-intc-irqpin.h @@ -0,0 +1,29 @@ +/* + * Renesas INTC External IRQ Pin Driver + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __IRQ_RENESAS_INTC_IRQPIN_H__ +#define __IRQ_RENESAS_INTC_IRQPIN_H__ + +struct renesas_intc_irqpin_config { + unsigned int sense_bitfield_width; + unsigned int irq_base; + bool control_parent; +}; + +#endif /* __IRQ_RENESAS_INTC_IRQPIN_H__ */ diff --git a/include/linux/platform_data/irq-renesas-irqc.h b/include/linux/platform_data/irq-renesas-irqc.h new file mode 100644 index 00000000000..3ae17b3e00e --- /dev/null +++ b/include/linux/platform_data/irq-renesas-irqc.h @@ -0,0 +1,27 @@ +/* + * Renesas IRQC Driver + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __IRQ_RENESAS_IRQC_H__ +#define __IRQ_RENESAS_IRQC_H__ + +struct renesas_irqc_config { + unsigned int irq_base; +}; + +#endif /* __IRQ_RENESAS_IRQC_H__ */ diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h index 8deb22672ad..0f5a2fc69af 100644 --- a/include/video/atmel_lcdc.h +++ b/include/video/atmel_lcdc.h @@ -31,6 +31,7 @@ #define ATMEL_LCDC_WIRING_BGR 0 #define ATMEL_LCDC_WIRING_RGB 1 +struct atmel_lcdfb_config; /* LCD Controller info data structure, stored in device platform_data */ struct atmel_lcdfb_info { @@ -61,7 +62,8 @@ struct atmel_lcdfb_info { void (*atmel_lcdfb_power_control)(int on); struct fb_monspecs *default_monspecs; u32 pseudo_palette[16]; - bool have_intensity_bit; + + struct atmel_lcdfb_config *config; }; #define ATMEL_LCDC_DMABADDR1 0x00 |