diff options
Diffstat (limited to 'arch/arm/mach-s3c2410/irq.c')
-rw-r--r-- | arch/arm/mach-s3c2410/irq.c | 260 |
1 files changed, 5 insertions, 255 deletions
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index cf9f46d88061..973a5fe6769c 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
@@ -45,6 +45,9 @@ | |||
45 | * | 45 | * |
46 | * 28-Jun-2005 Ben Dooks | 46 | * 28-Jun-2005 Ben Dooks |
47 | * Mark IRQ_LCD valid | 47 | * Mark IRQ_LCD valid |
48 | * | ||
49 | * 25-Jul-2005 Ben Dooks | ||
50 | * Split the S3C2440 IRQ code to seperate file | ||
48 | */ | 51 | */ |
49 | 52 | ||
50 | #include <linux/init.h> | 53 | #include <linux/init.h> |
@@ -65,11 +68,7 @@ | |||
65 | 68 | ||
66 | #include "cpu.h" | 69 | #include "cpu.h" |
67 | #include "pm.h" | 70 | #include "pm.h" |
68 | 71 | #include "irq.h" | |
69 | #define irqdbf(x...) | ||
70 | #define irqdbf2(x...) | ||
71 | |||
72 | #define EXTINT_OFF (IRQ_EINT4 - 4) | ||
73 | 72 | ||
74 | /* wakeup irq control */ | 73 | /* wakeup irq control */ |
75 | 74 | ||
@@ -181,7 +180,7 @@ s3c_irq_unmask(unsigned int irqno) | |||
181 | __raw_writel(mask, S3C2410_INTMSK); | 180 | __raw_writel(mask, S3C2410_INTMSK); |
182 | } | 181 | } |
183 | 182 | ||
184 | static struct irqchip s3c_irq_level_chip = { | 183 | struct irqchip s3c_irq_level_chip = { |
185 | .ack = s3c_irq_maskack, | 184 | .ack = s3c_irq_maskack, |
186 | .mask = s3c_irq_mask, | 185 | .mask = s3c_irq_mask, |
187 | .unmask = s3c_irq_unmask, | 186 | .unmask = s3c_irq_unmask, |
@@ -370,84 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { | |||
370 | #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) | 369 | #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) |
371 | #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) | 370 | #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) |
372 | 371 | ||
373 | static inline void | ||
374 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, | ||
375 | int subcheck) | ||
376 | { | ||
377 | unsigned long mask; | ||
378 | unsigned long submask; | ||
379 | |||
380 | submask = __raw_readl(S3C2410_INTSUBMSK); | ||
381 | mask = __raw_readl(S3C2410_INTMSK); | ||
382 | |||
383 | submask |= (1UL << (irqno - IRQ_S3CUART_RX0)); | ||
384 | |||
385 | /* check to see if we need to mask the parent IRQ */ | ||
386 | |||
387 | if ((submask & subcheck) == subcheck) { | ||
388 | __raw_writel(mask | parentbit, S3C2410_INTMSK); | ||
389 | } | ||
390 | |||
391 | /* write back masks */ | ||
392 | __raw_writel(submask, S3C2410_INTSUBMSK); | ||
393 | |||
394 | } | ||
395 | |||
396 | static inline void | ||
397 | s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit) | ||
398 | { | ||
399 | unsigned long mask; | ||
400 | unsigned long submask; | ||
401 | |||
402 | submask = __raw_readl(S3C2410_INTSUBMSK); | ||
403 | mask = __raw_readl(S3C2410_INTMSK); | ||
404 | |||
405 | submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0)); | ||
406 | mask &= ~parentbit; | ||
407 | |||
408 | /* write back masks */ | ||
409 | __raw_writel(submask, S3C2410_INTSUBMSK); | ||
410 | __raw_writel(mask, S3C2410_INTMSK); | ||
411 | } | ||
412 | |||
413 | |||
414 | static inline void | ||
415 | s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group) | ||
416 | { | ||
417 | unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); | ||
418 | |||
419 | s3c_irqsub_mask(irqno, parentmask, group); | ||
420 | |||
421 | __raw_writel(bit, S3C2410_SUBSRCPND); | ||
422 | |||
423 | /* only ack parent if we've got all the irqs (seems we must | ||
424 | * ack, all and hope that the irq system retriggers ok when | ||
425 | * the interrupt goes off again) | ||
426 | */ | ||
427 | |||
428 | if (1) { | ||
429 | __raw_writel(parentmask, S3C2410_SRCPND); | ||
430 | __raw_writel(parentmask, S3C2410_INTPND); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | static inline void | ||
435 | s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group) | ||
436 | { | ||
437 | unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); | ||
438 | |||
439 | __raw_writel(bit, S3C2410_SUBSRCPND); | ||
440 | |||
441 | /* only ack parent if we've got all the irqs (seems we must | ||
442 | * ack, all and hope that the irq system retriggers ok when | ||
443 | * the interrupt goes off again) | ||
444 | */ | ||
445 | |||
446 | if (1) { | ||
447 | __raw_writel(parentmask, S3C2410_SRCPND); | ||
448 | __raw_writel(parentmask, S3C2410_INTPND); | ||
449 | } | ||
450 | } | ||
451 | 372 | ||
452 | /* UART0 */ | 373 | /* UART0 */ |
453 | 374 | ||
@@ -794,174 +715,3 @@ void __init s3c24xx_init_irq(void) | |||
794 | 715 | ||
795 | irqdbf("s3c2410: registered interrupt handlers\n"); | 716 | irqdbf("s3c2410: registered interrupt handlers\n"); |
796 | } | 717 | } |
797 | |||
798 | /* s3c2440 irq code | ||
799 | */ | ||
800 | |||
801 | #ifdef CONFIG_CPU_S3C2440 | ||
802 | |||
803 | /* WDT/AC97 */ | ||
804 | |||
805 | static void s3c_irq_demux_wdtac97(unsigned int irq, | ||
806 | struct irqdesc *desc, | ||
807 | struct pt_regs *regs) | ||
808 | { | ||
809 | unsigned int subsrc, submsk; | ||
810 | struct irqdesc *mydesc; | ||
811 | |||
812 | /* read the current pending interrupts, and the mask | ||
813 | * for what it is available */ | ||
814 | |||
815 | subsrc = __raw_readl(S3C2410_SUBSRCPND); | ||
816 | submsk = __raw_readl(S3C2410_INTSUBMSK); | ||
817 | |||
818 | subsrc &= ~submsk; | ||
819 | subsrc >>= 13; | ||
820 | subsrc &= 3; | ||
821 | |||
822 | if (subsrc != 0) { | ||
823 | if (subsrc & 1) { | ||
824 | mydesc = irq_desc + IRQ_S3C2440_WDT; | ||
825 | mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); | ||
826 | } | ||
827 | if (subsrc & 2) { | ||
828 | mydesc = irq_desc + IRQ_S3C2440_AC97; | ||
829 | mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); | ||
830 | } | ||
831 | } | ||
832 | } | ||
833 | |||
834 | |||
835 | #define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) | ||
836 | |||
837 | static void | ||
838 | s3c_irq_wdtac97_mask(unsigned int irqno) | ||
839 | { | ||
840 | s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13); | ||
841 | } | ||
842 | |||
843 | static void | ||
844 | s3c_irq_wdtac97_unmask(unsigned int irqno) | ||
845 | { | ||
846 | s3c_irqsub_unmask(irqno, INTMSK_WDT); | ||
847 | } | ||
848 | |||
849 | static void | ||
850 | s3c_irq_wdtac97_ack(unsigned int irqno) | ||
851 | { | ||
852 | s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13); | ||
853 | } | ||
854 | |||
855 | static struct irqchip s3c_irq_wdtac97 = { | ||
856 | .mask = s3c_irq_wdtac97_mask, | ||
857 | .unmask = s3c_irq_wdtac97_unmask, | ||
858 | .ack = s3c_irq_wdtac97_ack, | ||
859 | }; | ||
860 | |||
861 | /* camera irq */ | ||
862 | |||
863 | static void s3c_irq_demux_cam(unsigned int irq, | ||
864 | struct irqdesc *desc, | ||
865 | struct pt_regs *regs) | ||
866 | { | ||
867 | unsigned int subsrc, submsk; | ||
868 | struct irqdesc *mydesc; | ||
869 | |||
870 | /* read the current pending interrupts, and the mask | ||
871 | * for what it is available */ | ||
872 | |||
873 | subsrc = __raw_readl(S3C2410_SUBSRCPND); | ||
874 | submsk = __raw_readl(S3C2410_INTSUBMSK); | ||
875 | |||
876 | subsrc &= ~submsk; | ||
877 | subsrc >>= 11; | ||
878 | subsrc &= 3; | ||
879 | |||
880 | if (subsrc != 0) { | ||
881 | if (subsrc & 1) { | ||
882 | mydesc = irq_desc + IRQ_S3C2440_CAM_C; | ||
883 | mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); | ||
884 | } | ||
885 | if (subsrc & 2) { | ||
886 | mydesc = irq_desc + IRQ_S3C2440_CAM_P; | ||
887 | mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); | ||
888 | } | ||
889 | } | ||
890 | } | ||
891 | |||
892 | #define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) | ||
893 | |||
894 | static void | ||
895 | s3c_irq_cam_mask(unsigned int irqno) | ||
896 | { | ||
897 | s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11); | ||
898 | } | ||
899 | |||
900 | static void | ||
901 | s3c_irq_cam_unmask(unsigned int irqno) | ||
902 | { | ||
903 | s3c_irqsub_unmask(irqno, INTMSK_CAM); | ||
904 | } | ||
905 | |||
906 | static void | ||
907 | s3c_irq_cam_ack(unsigned int irqno) | ||
908 | { | ||
909 | s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); | ||
910 | } | ||
911 | |||
912 | static struct irqchip s3c_irq_cam = { | ||
913 | .mask = s3c_irq_cam_mask, | ||
914 | .unmask = s3c_irq_cam_unmask, | ||
915 | .ack = s3c_irq_cam_ack, | ||
916 | }; | ||
917 | |||
918 | static int s3c2440_irq_add(struct sys_device *sysdev) | ||
919 | { | ||
920 | unsigned int irqno; | ||
921 | |||
922 | printk("S3C2440: IRQ Support\n"); | ||
923 | |||
924 | set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); | ||
925 | set_irq_handler(IRQ_NFCON, do_level_IRQ); | ||
926 | set_irq_flags(IRQ_NFCON, IRQF_VALID); | ||
927 | |||
928 | /* add new chained handler for wdt, ac7 */ | ||
929 | |||
930 | set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); | ||
931 | set_irq_handler(IRQ_WDT, do_level_IRQ); | ||
932 | set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); | ||
933 | |||
934 | for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { | ||
935 | set_irq_chip(irqno, &s3c_irq_wdtac97); | ||
936 | set_irq_handler(irqno, do_level_IRQ); | ||
937 | set_irq_flags(irqno, IRQF_VALID); | ||
938 | } | ||
939 | |||
940 | /* add chained handler for camera */ | ||
941 | |||
942 | set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); | ||
943 | set_irq_handler(IRQ_CAM, do_level_IRQ); | ||
944 | set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); | ||
945 | |||
946 | for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { | ||
947 | set_irq_chip(irqno, &s3c_irq_cam); | ||
948 | set_irq_handler(irqno, do_level_IRQ); | ||
949 | set_irq_flags(irqno, IRQF_VALID); | ||
950 | } | ||
951 | |||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | static struct sysdev_driver s3c2440_irq_driver = { | ||
956 | .add = s3c2440_irq_add, | ||
957 | }; | ||
958 | |||
959 | static int s3c24xx_irq_driver(void) | ||
960 | { | ||
961 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver); | ||
962 | } | ||
963 | |||
964 | arch_initcall(s3c24xx_irq_driver); | ||
965 | |||
966 | #endif /* CONFIG_CPU_S3C2440 */ | ||
967 | |||