diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-26 15:13:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-26 15:13:26 -0700 |
commit | fc00a6274b786f6863b32c79ff6f92aa0960b789 (patch) | |
tree | 7078e320ac34aa104f9adefaedf7add3173fe160 /arch | |
parent | 0983f0509480f95584f8e945e5b9c5310e9038f3 (diff) | |
parent | a8d11e3d0282e9607f65c73383c4030fd8f0e972 (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-s3c2410/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/clock.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/irq.c | 260 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/irq.h | 99 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/mach-bast.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/s3c2440-clock.c | 116 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/s3c2440-irq.c | 207 |
7 files changed, 434 insertions, 320 deletions
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index f99b689e439..55ed7c7e57d 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -23,6 +23,8 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o # S3C2440 support obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o +obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o +obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o # machine specific support diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index 8d986b8401c..9a66050e887 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c @@ -448,60 +448,3 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, return 0; } - -/* S3C2440 extended clock support */ - -#ifdef CONFIG_CPU_S3C2440 - -static struct clk s3c2440_clk_upll = { - .name = "upll", - .id = -1, -}; - -static struct clk s3c2440_clk_cam = { - .name = "camif", - .parent = &clk_h, - .id = -1, - .enable = s3c24xx_clkcon_enable, - .ctrlbit = S3C2440_CLKCON_CAMERA, -}; - -static struct clk s3c2440_clk_ac97 = { - .name = "ac97", - .parent = &clk_p, - .id = -1, - .enable = s3c24xx_clkcon_enable, - .ctrlbit = S3C2440_CLKCON_CAMERA, -}; - -static int s3c2440_clk_add(struct sys_device *sysdev) -{ - unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); - - s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate); - - printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", - print_mhz(s3c2440_clk_upll.rate)); - - s3c24xx_register_clock(&s3c2440_clk_ac97); - s3c24xx_register_clock(&s3c2440_clk_cam); - s3c24xx_register_clock(&s3c2440_clk_upll); - - clk_disable(&s3c2440_clk_ac97); - clk_disable(&s3c2440_clk_cam); - - return 0; -} - -static struct sysdev_driver s3c2440_clk_driver = { - .add = s3c2440_clk_add, -}; - -static int s3c24xx_clk_driver(void) -{ - return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); -} - -arch_initcall(s3c24xx_clk_driver); - -#endif /* CONFIG_CPU_S3C2440 */ diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index cf9f46d8806..973a5fe6769 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -45,6 +45,9 @@ * * 28-Jun-2005 Ben Dooks * Mark IRQ_LCD valid + * + * 25-Jul-2005 Ben Dooks + * Split the S3C2440 IRQ code to seperate file */ #include <linux/init.h> @@ -65,11 +68,7 @@ #include "cpu.h" #include "pm.h" - -#define irqdbf(x...) -#define irqdbf2(x...) - -#define EXTINT_OFF (IRQ_EINT4 - 4) +#include "irq.h" /* wakeup irq control */ @@ -181,7 +180,7 @@ s3c_irq_unmask(unsigned int irqno) __raw_writel(mask, S3C2410_INTMSK); } -static struct irqchip s3c_irq_level_chip = { +struct irqchip s3c_irq_level_chip = { .ack = s3c_irq_maskack, .mask = s3c_irq_mask, .unmask = s3c_irq_unmask, @@ -370,84 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) -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); - } -} /* UART0 */ @@ -794,174 +715,3 @@ void __init s3c24xx_init_irq(void) irqdbf("s3c2410: registered interrupt handlers\n"); } - -/* s3c2440 irq code -*/ - -#ifdef CONFIG_CPU_S3C2440 - -/* WDT/AC97 */ - -static void s3c_irq_demux_wdtac97(unsigned int irq, - struct irqdesc *desc, - struct pt_regs *regs) -{ - unsigned int subsrc, submsk; - struct irqdesc *mydesc; - - /* 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) { - mydesc = irq_desc + IRQ_S3C2440_WDT; - mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); - } - if (subsrc & 2) { - mydesc = irq_desc + IRQ_S3C2440_AC97; - mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); - } - } -} - - -#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) - -static void -s3c_irq_wdtac97_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13); -} - -static void -s3c_irq_wdtac97_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_WDT); -} - -static void -s3c_irq_wdtac97_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13); -} - -static struct irqchip s3c_irq_wdtac97 = { - .mask = s3c_irq_wdtac97_mask, - .unmask = s3c_irq_wdtac97_unmask, - .ack = s3c_irq_wdtac97_ack, -}; - -/* camera irq */ - -static void s3c_irq_demux_cam(unsigned int irq, - struct irqdesc *desc, - struct pt_regs *regs) -{ - unsigned int subsrc, submsk; - struct irqdesc *mydesc; - - /* 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) { - mydesc = irq_desc + IRQ_S3C2440_CAM_C; - mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); - } - if (subsrc & 2) { - mydesc = irq_desc + IRQ_S3C2440_CAM_P; - mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); - } - } -} - -#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) - -static void -s3c_irq_cam_mask(unsigned int irqno) -{ - s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11); -} - -static void -s3c_irq_cam_unmask(unsigned int irqno) -{ - s3c_irqsub_unmask(irqno, INTMSK_CAM); -} - -static void -s3c_irq_cam_ack(unsigned int irqno) -{ - s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); -} - -static struct irqchip s3c_irq_cam = { - .mask = s3c_irq_cam_mask, - .unmask = s3c_irq_cam_unmask, - .ack = s3c_irq_cam_ack, -}; - -static int s3c2440_irq_add(struct sys_device *sysdev) -{ - unsigned int irqno; - - printk("S3C2440: IRQ Support\n"); - - set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); - set_irq_handler(IRQ_NFCON, do_level_IRQ); - set_irq_flags(IRQ_NFCON, IRQF_VALID); - - /* add new chained handler for wdt, ac7 */ - - set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); - set_irq_handler(IRQ_WDT, do_level_IRQ); - set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); - - for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { - set_irq_chip(irqno, &s3c_irq_wdtac97); - set_irq_handler(irqno, do_level_IRQ); - set_irq_flags(irqno, IRQF_VALID); - } - - /* add chained handler for camera */ - - set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); - set_irq_handler(IRQ_CAM, do_level_IRQ); - set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); - - for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { - set_irq_chip(irqno, &s3c_irq_cam); - set_irq_handler(irqno, do_level_IRQ); - set_irq_flags(irqno, IRQF_VALID); - } - - return 0; -} - -static struct sysdev_driver s3c2440_irq_driver = { - .add = s3c2440_irq_add, -}; - -static int s3c24xx_irq_driver(void) -{ - return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver); -} - -arch_initcall(s3c24xx_irq_driver); - -#endif /* CONFIG_CPU_S3C2440 */ - diff --git a/arch/arm/mach-s3c2410/irq.h b/arch/arm/mach-s3c2410/irq.h new file mode 100644 index 00000000000..4abf0ca14e0 --- /dev/null +++ b/arch/arm/mach-s3c2410/irq.h @@ -0,0 +1,99 @@ +/* arch/arm/mach-s3c2410/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. + * + * Modifications: +*/ + +#define irqdbf(x...) +#define irqdbf2(x...) + +#define EXTINT_OFF (IRQ_EINT4 - 4) + +extern struct irqchip s3c_irq_level_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); + } +} diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 206778ebfce..1e7f343822d 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -25,10 +25,11 @@ * 14-Jan-2005 BJD Add support for muitlple NAND devices * 03-Mar-2005 BJD Ensured that bast-cpld.h is included * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA - * 14-Mar-2006 BJD Updated for __iomem changes - * 22-Jun-2006 BJD Added DM9000 platform information - * 28-Jun-2006 BJD Moved pm functionality out to common code - * 17-Jul-2006 BJD Changed to platform device for SuperIO 16550s + * 14-Mar-2005 BJD Updated for __iomem changes + * 22-Jun-2005 BJD Added DM9000 platform information + * 28-Jun-2005 BJD Moved pm functionality out to common code + * 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s + * 25-Jul-2005 BJD Removed ASIX static mappings */ #include <linux/kernel.h> @@ -116,7 +117,6 @@ static struct map_desc bast_iodesc[] __initdata = { /* slow, byte */ { VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, - { VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, { VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, { VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, @@ -126,7 +126,6 @@ static struct map_desc bast_iodesc[] __initdata = { /* slow, word */ { VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, - { VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, { VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, { VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, @@ -136,7 +135,6 @@ static struct map_desc bast_iodesc[] __initdata = { /* fast, byte */ { VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, - { VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, { VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, { VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, @@ -146,7 +144,6 @@ static struct map_desc bast_iodesc[] __initdata = { /* fast, word */ { VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, - { VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, { VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, { VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c new file mode 100644 index 00000000000..b018a1f680c --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2440-clock.c @@ -0,0 +1,116 @@ +/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2440 Clock support + * + * 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/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/hardware.h> +#include <asm/atomic.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/hardware/clock.h> +#include <asm/arch/regs-clock.h> + +#include "clock.h" +#include "cpu.h" + +/* S3C2440 extended clock support */ + +static struct clk s3c2440_clk_upll = { + .name = "upll", + .id = -1, +}; + +static struct clk s3c2440_clk_cam = { + .name = "camif", + .id = -1, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static struct clk s3c2440_clk_ac97 = { + .name = "ac97", + .id = -1, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static int s3c2440_clk_add(struct sys_device *sysdev) +{ + unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); + struct clk *clk_h; + struct clk *clk_p; + struct clk *clk_xtal; + + clk_xtal = clk_get(NULL, "xtal"); + if (IS_ERR(clk_xtal)) { + printk(KERN_ERR "S3C2440: Failed to get clk_xtal\n"); + return -EINVAL; + } + + s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal->rate); + + printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", + print_mhz(s3c2440_clk_upll.rate)); + + clk_p = clk_get(NULL, "pclk"); + clk_h = clk_get(NULL, "hclk"); + + if (IS_ERR(clk_p) || IS_ERR(clk_h)) { + printk(KERN_ERR "S3C2440: Failed to get parent clocks\n"); + return -EINVAL; + } + + s3c2440_clk_cam.parent = clk_h; + s3c2440_clk_ac97.parent = clk_p; + + s3c24xx_register_clock(&s3c2440_clk_ac97); + s3c24xx_register_clock(&s3c2440_clk_cam); + s3c24xx_register_clock(&s3c2440_clk_upll); + + clk_disable(&s3c2440_clk_ac97); + clk_disable(&s3c2440_clk_cam); + + return 0; +} + +static struct sysdev_driver s3c2440_clk_driver = { + .add = s3c2440_clk_add, +}; + +static __init int s3c24xx_clk_driver(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); +} + +arch_initcall(s3c24xx_clk_driver); diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c new file mode 100644 index 00000000000..7cb9912242a --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -0,0 +1,207 @@ +/* linux/arch/arm/mach-s3c2410/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 + * + * Changelog: + * 25-Jul-2005 BJD Split from irq.c + * +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/ptrace.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> + +#include <asm/arch/regs-irq.h> +#include <asm/arch/regs-gpio.h> + +#include "cpu.h" +#include "pm.h" +#include "irq.h" + +/* WDT/AC97 */ + +static void s3c_irq_demux_wdtac97(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int subsrc, submsk; + struct irqdesc *mydesc; + + /* 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) { + mydesc = irq_desc + IRQ_S3C2440_WDT; + mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); + } + if (subsrc & 2) { + mydesc = irq_desc + IRQ_S3C2440_AC97; + mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); + } + } +} + + +#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) + +static void +s3c_irq_wdtac97_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13); +} + +static void +s3c_irq_wdtac97_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_WDT); +} + +static void +s3c_irq_wdtac97_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13); +} + +static struct irqchip s3c_irq_wdtac97 = { + .mask = s3c_irq_wdtac97_mask, + .unmask = s3c_irq_wdtac97_unmask, + .ack = s3c_irq_wdtac97_ack, +}; + +/* camera irq */ + +static void s3c_irq_demux_cam(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int subsrc, submsk; + struct irqdesc *mydesc; + + /* 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) { + mydesc = irq_desc + IRQ_S3C2440_CAM_C; + mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); + } + if (subsrc & 2) { + mydesc = irq_desc + IRQ_S3C2440_CAM_P; + mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); + } + } +} + +#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) + +static void +s3c_irq_cam_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11); +} + +static void +s3c_irq_cam_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_CAM); +} + +static void +s3c_irq_cam_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); +} + +static struct irqchip s3c_irq_cam = { + .mask = s3c_irq_cam_mask, + .unmask = s3c_irq_cam_unmask, + .ack = s3c_irq_cam_ack, +}; + +static int s3c2440_irq_add(struct sys_device *sysdev) +{ + unsigned int irqno; + + printk("S3C2440: IRQ Support\n"); + + set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); + set_irq_handler(IRQ_NFCON, do_level_IRQ); + set_irq_flags(IRQ_NFCON, IRQF_VALID); + + /* add new chained handler for wdt, ac7 */ + + set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); + set_irq_handler(IRQ_WDT, do_level_IRQ); + set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); + + for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { + set_irq_chip(irqno, &s3c_irq_wdtac97); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + /* add chained handler for camera */ + + set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); + set_irq_handler(IRQ_CAM, do_level_IRQ); + set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); + + for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { + set_irq_chip(irqno, &s3c_irq_cam); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static struct sysdev_driver s3c2440_irq_driver = { + .add = s3c2440_irq_add, +}; + +static int s3c24xx_irq_driver(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver); +} + +arch_initcall(s3c24xx_irq_driver); + |