From 6f8d7ea275eb2a27fd62211e93921a82f367f939 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 09:59:17 -0800 Subject: [PATCH 01/14] ARM: S3C24XX: move s3c244x irq init to common irq code Base for further modifications. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/Makefile | 2 +- arch/arm/mach-s3c24xx/irq-s3c244x.c | 142 ---------------------------- arch/arm/mach-s3c24xx/irq.c | 105 ++++++++++++++++++++ 3 files changed, 106 insertions(+), 143 deletions(-) delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c244x.c diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index af53d27d5c36..051b8f99d2fd 100644 --- a/arch/arm/mach-s3c24xx/Makefile +++ b/arch/arm/mach-s3c24xx/Makefile @@ -33,7 +33,7 @@ obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o obj-$(CONFIG_CPU_S3C2440) += s3c2440.o irq-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/irq-s3c244x.c b/arch/arm/mach-s3c24xx/irq-s3c244x.c deleted file mode 100644 index 5fe8e58d3afd..000000000000 --- 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 - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include -#include - -/* 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 c1b96f7cc587..1fea3ddd123d 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -729,6 +729,111 @@ void __init s3c2416_init_irq(void) #endif +#ifdef CONFIG_CPU_S3C244X +/* 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); +#endif + #ifdef CONFIG_CPU_S3C2443 static struct s3c_irq_data init_s3c2443base[32] = { { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ From ce6c164bf0ea44fad7969e1f1027d4f6cfb30360 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 09:59:20 -0800 Subject: [PATCH 02/14] ARM: S3C24XX: create dedicated irq init functions for s3c2440 and s3c2442 s3c2440 and s3c2442 need separate init functions, as the s3c2440 contains even more differing irqs that will be moved in the following patch. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/common.h | 2 + arch/arm/mach-s3c24xx/irq.c | 53 +++++++++++++------------- arch/arm/mach-s3c24xx/mach-anubis.c | 2 +- arch/arm/mach-s3c24xx/mach-at2440evb.c | 2 +- arch/arm/mach-s3c24xx/mach-gta02.c | 2 +- arch/arm/mach-s3c24xx/mach-mini2440.c | 2 +- arch/arm/mach-s3c24xx/mach-nexcoder.c | 2 +- arch/arm/mach-s3c24xx/mach-osiris.c | 2 +- arch/arm/mach-s3c24xx/mach-rx1950.c | 2 +- arch/arm/mach-s3c24xx/mach-rx3715.c | 7 +--- arch/arm/mach-s3c24xx/mach-smdk2440.c | 2 +- 11 files changed, 38 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h index 8a2b4137ddb6..362a8cd32eb0 100644 --- a/arch/arm/mach-s3c24xx/common.h +++ b/arch/arm/mach-s3c24xx/common.h @@ -73,6 +73,7 @@ extern void s3c244x_restart(char mode, const char *cmd); #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 @@ -81,6 +82,7 @@ extern void s3c2440_map_io(void); #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 diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index 1fea3ddd123d..2c59b2d99a81 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -783,10 +783,13 @@ static struct irq_chip s3c_irq_cam = { .irq_ack = s3c_irq_cam_ack, }; -static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif) +#ifdef CONFIG_CPU_S3C2440 +void __init s3c2440_init_irq(void) { unsigned int irqno; + s3c24xx_init_irq(); + irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip, handle_level_irq); set_irq_flags(IRQ_NFCON, IRQF_VALID); @@ -802,36 +805,34 @@ static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif) handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } - - return 0; } +#endif -static struct subsys_interface s3c2440_irq_interface = { - .name = "s3c2440_irq", - .subsys = &s3c2440_subsys, - .add_dev = s3c244x_irq_add, -}; - -static int s3c2440_irq_init(void) +#ifdef CONFIG_CPU_S3C2442 +void __init s3c2442_init_irq(void) { - return subsys_interface_register(&s3c2440_irq_interface); + unsigned int irqno; + + s3c24xx_init_irq(); + + 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); + } } +#endif -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); #endif #ifdef CONFIG_CPU_S3C2443 diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c index 24f1a04ccc88..c1fb6c37867f 100644 --- a/arch/arm/mach-s3c24xx/mach-anubis.c +++ b/arch/arm/mach-s3c24xx/mach-anubis.c @@ -445,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_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 2bf6c8c24317..6dfeeb7ef469 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -211,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_irq = s3c2440_init_irq, .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index 84a750d46d4b..13d8d073675a 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -589,7 +589,7 @@ MACHINE_START(NEO1973_GTA02, "GTA02") /* Maintainer: Nelson Castillo */ .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 = samsung_timer_init, .restart = s3c244x_restart, diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 29f106cb370e..a83db46320bc 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -688,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_irq = s3c2440_init_irq, .init_time = samsung_timer_init, .restart = s3c244x_restart, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c index 5c826d10a66d..01f4354206f9 100644 --- a/arch/arm/mach-s3c24xx/mach-nexcoder.c +++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c @@ -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_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 4c90ffda4e11..58d6fbe5bf1f 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris.c +++ b/arch/arm/mach-s3c24xx/mach-osiris.c @@ -426,7 +426,7 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS") /* Maintainer: Ben Dooks */ .atag_offset = 0x100, .map_io = osiris_map_io, - .init_irq = s3c24xx_init_irq, + .init_irq = s3c2440_init_irq, .init_machine = osiris_init, .init_time = samsung_timer_init, .restart = s3c244x_restart, diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 799af43b4e6a..e4d67a33ebee 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -813,7 +813,7 @@ 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 = samsung_timer_init, .restart = s3c244x_restart, diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c index 0a3c96452f0f..3bc6231d0a1f 100644 --- a/arch/arm/mach-s3c24xx/mach-rx3715.c +++ b/arch/arm/mach-s3c24xx/mach-rx3715.c @@ -190,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 @@ -212,7 +207,7 @@ 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 = samsung_timer_init, .restart = s3c244x_restart, diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c index f56cb08e6d1c..de2e5d39a847 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2440.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c @@ -177,7 +177,7 @@ MACHINE_START(S3C2440, "SMDK2440") /* Maintainer: Ben Dooks */ .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 = samsung_timer_init, From 2286cf467e460eabfd0a188c5c5fb46955dcf024 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 09:59:24 -0800 Subject: [PATCH 03/14] ARM: S3C24XX: move s3c2440 irqs to common irq code Will be integrated in the following patch. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/Makefile | 2 +- arch/arm/mach-s3c24xx/irq-s3c2440.c | 128 ---------------------------- arch/arm/mach-s3c24xx/irq.c | 88 +++++++++++++++++++ 3 files changed, 89 insertions(+), 129 deletions(-) delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2440.c diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index 051b8f99d2fd..90412607fb47 100644 --- a/arch/arm/mach-s3c24xx/Makefile +++ b/arch/arm/mach-s3c24xx/Makefile @@ -31,7 +31,7 @@ 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 clock-s3c244x.o obj-$(CONFIG_S3C2440_CPUFREQ) += cpufreq-s3c2440.o diff --git a/arch/arm/mach-s3c24xx/irq-s3c2440.c b/arch/arm/mach-s3c24xx/irq-s3c2440.c deleted file mode 100644 index 4a18cde439cc..000000000000 --- 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 - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include -#include - -/* 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.c b/arch/arm/mach-s3c24xx/irq.c index 2c59b2d99a81..1804e23baad3 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -784,6 +784,94 @@ static struct irq_chip s3c_irq_cam = { }; #ifdef CONFIG_CPU_S3C2440 +/* 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); + void __init s3c2440_init_irq(void) { unsigned int irqno; From 7cefed5e6b4b61b6bed309e9405eda0a00e9b66c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 09:59:27 -0800 Subject: [PATCH 04/14] ARM: S3C24XX: integrate s3c2440 irqs into common init Now all the arch_initcalls for s3c244x irqs are gone. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/irq.c | 46 +++++++++++-------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index 1804e23baad3..025c89897f19 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -838,44 +838,12 @@ static struct irq_chip s3c_irq_wdtac97 = { .irq_ack = s3c_irq_wdtac97_ack, }; -static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif) +void __init s3c2440_init_irq(void) { 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); - -void __init s3c2440_init_irq(void) -{ - unsigned int irqno; - s3c24xx_init_irq(); irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip, @@ -893,6 +861,18 @@ void __init s3c2440_init_irq(void) handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } + + /* 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); + } } #endif From 70644ade48ae88f88f4935c4d2f3331c3ef177a1 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 09:59:31 -0800 Subject: [PATCH 05/14] ARM: S3C24XX: transform s3c2442 irqs into new structure Simply declare a correct mapping structure to use the common irq code. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/irq.c | 78 ++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index 025c89897f19..7d4061980bb2 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -877,27 +877,75 @@ void __init s3c2440_init_irq(void) #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) { - unsigned int irqno; + struct s3c_irq_intc *main_intc; - s3c24xx_init_irq(); + pr_info("S3C2442: IRQ Support\n"); - irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip, - handle_level_irq); - set_irq_flags(IRQ_NFCON, IRQF_VALID); +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif - /* 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); + 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 From f0301673ff7ad8aae45c4a95613771d34b1cf052 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 09:59:35 -0800 Subject: [PATCH 06/14] ARM: S3C24XX: transform s3c2440 irqs into new structure As always a mapping structure is everything needed. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/irq.c | 196 +++++++++++------------------------- 1 file changed, 61 insertions(+), 135 deletions(-) diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index 7d4061980bb2..ddb6752e5948 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -729,150 +729,78 @@ void __init s3c2416_init_irq(void) #endif -#ifdef CONFIG_CPU_S3C244X -/* 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, +#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 */ }; -#ifdef CONFIG_CPU_S3C2440 -/* 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 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) { - unsigned int irqno; + struct s3c_irq_intc *main_intc; - printk("S3C2440: IRQ Support\n"); + pr_info("S3C2440: IRQ Support\n"); - s3c24xx_init_irq(); +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif - 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); + 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; } - /* 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); - } + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2440subint[0], main_intc, 0x4a000018); } #endif @@ -949,8 +877,6 @@ void __init s3c2442_init_irq(void) } #endif -#endif - #ifdef CONFIG_CPU_S3C2443 static struct s3c_irq_data init_s3c2443base[32] = { { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ From 592957085e3763b9339a6a281f1aeb1247cdd245 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:09:10 -0800 Subject: [PATCH 07/14] ARM: S3C24XX: use samsung_sync_wakemask in s3c2412 pm Originally the s3c2412 used a overidden irq chip to set the rtc wakeup flag. But with using the samsung_sync_wakemask function the same can be achieved without introducing soc specific irq functions. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/Kconfig | 1 + arch/arm/mach-s3c24xx/irq-s3c2412.c | 23 ----------------------- arch/arm/mach-s3c24xx/pm-s3c2412.c | 8 ++++++++ 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index 0c5e4fb61117..0a8663c5f2ba 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -407,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/irq-s3c2412.c b/arch/arm/mach-s3c24xx/irq-s3c2412.c index 67d763178d3f..e6fd954c5fd4 100644 --- a/arch/arm/mach-s3c24xx/irq-s3c2412.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2412.c @@ -155,22 +155,6 @@ static struct irq_chip s3c2412_irq_cfsdi = { .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; @@ -191,13 +175,6 @@ static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif) 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; } diff --git a/arch/arm/mach-s3c24xx/pm-s3c2412.c b/arch/arm/mach-s3c24xx/pm-s3c2412.c index 4c4bc1c83b77..d75f95e487ee 100644 --- a/arch/arm/mach-s3c24xx/pm-s3c2412.c +++ b/arch/arm/mach-s3c24xx/pm-s3c2412.c @@ -29,6 +29,7 @@ #include #include +#include #include "regs-dsc.h" #include "s3c2412-power.h" @@ -51,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) From d3d5a2c9e6cf9723fe7ba9ad918540ad53ae381c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:09:13 -0800 Subject: [PATCH 08/14] ARM: S3C24XX: move s3c2412 irq init to common code Base for further cleanups Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/Makefile | 2 +- arch/arm/mach-s3c24xx/irq-s3c2412.c | 192 ---------------------------- arch/arm/mach-s3c24xx/irq.c | 154 ++++++++++++++++++++++ 3 files changed, 155 insertions(+), 193 deletions(-) delete mode 100644 arch/arm/mach-s3c24xx/irq-s3c2412.c diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index 90412607fb47..be6e4d0e6f1a 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 diff --git a/arch/arm/mach-s3c24xx/irq-s3c2412.c b/arch/arm/mach-s3c24xx/irq-s3c2412.c deleted file mode 100644 index e6fd954c5fd4..000000000000 --- a/arch/arm/mach-s3c24xx/irq-s3c2412.c +++ /dev/null @@ -1,192 +0,0 @@ -/* linux/arch/arm/mach-s3c2412/irq.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#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_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); - } - - 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.c b/arch/arm/mach-s3c24xx/irq.c index ddb6752e5948..2bb4a97e527e 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -626,6 +626,160 @@ void __init s3c24xx_init_irq(void) s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); } +#ifdef CONFIG_CPU_S3C2412 + +#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_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); + } + + 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); +#endif + #ifdef CONFIG_CPU_S3C2416 static struct s3c_irq_data init_s3c2416base[32] = { { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ From 0da09930d515da5848eba343e965ebbc853c8a44 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:09:18 -0800 Subject: [PATCH 09/14] ARM: S3C24XX: modify s3c2412 irq init to initialize all irqs Combines the two independent init steps for the irqs into one. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/common.h | 1 + arch/arm/mach-s3c24xx/irq.c | 19 +++---------------- arch/arm/mach-s3c24xx/mach-jive.c | 2 +- arch/arm/mach-s3c24xx/mach-smdk2413.c | 6 +++--- arch/arm/mach-s3c24xx/mach-vstms.c | 2 +- 5 files changed, 9 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h index 362a8cd32eb0..abefeb38bba4 100644 --- a/arch/arm/mach-s3c24xx/common.h +++ b/arch/arm/mach-s3c24xx/common.h @@ -36,6 +36,7 @@ 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 diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index 2bb4a97e527e..55a73c4d2c95 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -743,10 +743,12 @@ static struct irq_chip s3c2412_irq_cfsdi = { .irq_unmask = s3c2412_irq_cfsdi_unmask, }; -static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif) +void s3c2412_init_irq(void) { unsigned int irqno; + s3c24xx_init_irq(); + for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4, handle_edge_irq); @@ -762,22 +764,7 @@ static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif) handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } - - 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); #endif #ifdef CONFIG_CPU_S3C2416 diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index aade943288c7..a45fcd8ccf79 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c @@ -660,7 +660,7 @@ MACHINE_START(JIVE, "JIVE") /* Maintainer: Ben Dooks */ .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 = samsung_timer_init, diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c index 8e3f1d9bbb7c..8146e920f10d 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2413.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2413.c @@ -130,7 +130,7 @@ 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 = samsung_timer_init, @@ -142,7 +142,7 @@ 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 = samsung_timer_init, @@ -154,7 +154,7 @@ 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 = samsung_timer_init, diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index 622a1ed24509..b66588428ec9 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c @@ -158,7 +158,7 @@ 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 = samsung_timer_init, From 4245944c71f90c0b38659e4a4f0d7741c79ef2b0 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:09:21 -0800 Subject: [PATCH 10/14] ARM: S3C24XX: transform s3c2412 irqs into new structure Contains only the new mapping structure. The special handling of the eint0 to eint3 interrupts still needs to be solved. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/irq.c | 126 +++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index 55a73c4d2c95..292f974c5294 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -627,9 +627,58 @@ void __init s3c24xx_init_irq(void) } #ifdef CONFIG_CPU_S3C2412 +static struct s3c_irq_data init_s3c2412base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_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 */ +}; -#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) -#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0)))) +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 */ +}; /* 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 @@ -698,72 +747,33 @@ static struct irq_chip s3c2412_irq_eint0t4 = { .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, -}; - void s3c2412_init_irq(void) { + struct s3c_irq_intc *main_intc; unsigned int irqno; - s3c24xx_init_irq(); + 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_eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018); + + /* special handling for eints 0 to 3 */ 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); - } } #endif From 5424f2188a76d006932bc6da67ed2ba1c2a72a8e Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:12:04 -0800 Subject: [PATCH 11/14] ARM: S3C24XX: include first 4 bits of the eint register in irq mapping This patch moves the irq numbers starting with EINT4 4 points down to enable the inclusion of the first 4 bits of EINT register into the mapping removing the need for special offset handling. For most S3C24XX architectures this will simply create 4 additional unused interrupts, but enables the S3C2412 to make use of the new infrastructure to realize its special handling of the EINT0 to EINT3 interrupts. All affected parts of the Samsung code (arch + drivers) seem to use the real interrupt defines (IRQ_something) and not any form of S3C2410_IRQ(x) whose numbering is changed here starting from S3C2410_IRQ(32). This patch was runtime-tested on a s3c2416 based board. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/include/mach/irqs.h | 54 +++++++++++------------ arch/arm/mach-s3c24xx/irq.c | 9 +--- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index b7a9f4d469e8..ea589e4f0d8b 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -59,49 +59,49 @@ #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_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 +136,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/irq.c b/arch/arm/mach-s3c24xx/irq.c index 292f974c5294..c2205eb78dc1 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -450,7 +450,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); @@ -474,7 +473,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"); @@ -482,7 +480,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"); @@ -491,7 +488,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"); @@ -499,9 +495,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"); @@ -512,7 +507,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"); From 9eecbe509607265d28d76b39bc479f01b6d55e01 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:12:06 -0800 Subject: [PATCH 12/14] ARM: S3C24XX: add soc_is_s3c2412 option Makes it possible to identify s3c2412 SoCs. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/cpu.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index e126644cadf4..0f6c47a6475b 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 From 1c8408e3137bcb78d9ab8af832111f455d11e99c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:12:09 -0800 Subject: [PATCH 13/14] ARM: S3C24XX: handle s3c2412 eints using new infrastructure The s3c2412 handles the eints 0 to 3 different than all the other SoCs of the 24xx range. These eints must be acked and masked in the regular bits as well as the bits 0 to 3 of the eint registers, which are unused on the other SoCs. This of course can be realized using the new infrastructure with the eint bits in the main register being the parent interrupts of the same bits in the eint register. The s3c2412 therefore gets its own IRQ_EINT0 to 4 constants that reside in the newly created gap before IRQ_EINT4. gpio-samsung, as the only user of these is modified to return the correct values when handling gpio_to_irq requests on s3c2412 based machines. Due to lack of hardware this is compile tested only, but should hopefully work as intended. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/include/mach/irqs.h | 4 + arch/arm/mach-s3c24xx/irq.c | 118 +++++++--------------- drivers/gpio/gpio-samsung.c | 5 +- 3 files changed, 44 insertions(+), 83 deletions(-) diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index ea589e4f0d8b..43cada8019b4 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -59,6 +59,10 @@ #define IRQ_ADCPARENT S3C2410_IRQ(31) /* interrupts generated from the external interrupts sources */ +#define IRQ_EINT0_2412 S3C2410_IRQ(32) +#define IRQ_EINT1_2412 S3C2410_IRQ(33) +#define IRQ_EINT2_2412 S3C2410_IRQ(34) +#define IRQ_EINT3_2412 S3C2410_IRQ(35) #define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */ #define IRQ_EINT5 S3C2410_IRQ(37) #define IRQ_EINT6 S3C2410_IRQ(38) diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index c2205eb78dc1..3f3de7492094 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -342,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 @@ -623,10 +626,10 @@ void __init s3c24xx_init_irq(void) #ifdef CONFIG_CPU_S3C2412 static struct s3c_irq_data init_s3c2412base[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, }, /* 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 */ @@ -657,6 +660,33 @@ static struct s3c_irq_data init_s3c2412base[32] = { { .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 */ @@ -675,77 +705,9 @@ static struct s3c_irq_data init_s3c2412subint[32] = { { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */ }; -/* 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, -}; - void s3c2412_init_irq(void) { struct s3c_irq_intc *main_intc; - unsigned int irqno; pr_info("S3C2412: IRQ Support\n"); @@ -759,16 +721,8 @@ void s3c2412_init_irq(void) return; } - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4); s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018); - - /* special handling for eints 0 to 3 */ - - 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); - } } #endif diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b3643ff007e4..db098cea3a55 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -1123,7 +1123,10 @@ int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) { if (offset < 4) - return IRQ_EINT0 + offset; + if (soc_is_s3c2412()) + return IRQ_EINT0_2412 + offset; + else + return IRQ_EINT0 + offset; if (offset < 8) return IRQ_EINT4 + offset - 4; From d97fedef912832611b668fa7ece8e8ff54a6a590 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 12 Feb 2013 21:01:38 -0800 Subject: [PATCH 14/14] gpio: samsung: fixes build warning with s3c2410_defconfig commit 7b45ed96 ("ARM: S3C24XX: handle s3c2412 eints using new infrastructure") introduced build warning and this patch fixes that: drivers/gpio/gpio-samsung.c: In function 's3c24xx_gpiolib_fbank_to_irq': drivers/gpio/gpio-samsung.c:1126:5: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses] Reported-by: kbuild test robot Cc: Heiko Stuebner Signed-off-by: Kukjin Kim --- drivers/gpio/gpio-samsung.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index db098cea3a55..58aa28fb5889 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -1122,11 +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) + 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;