aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-s3c24xx/irq.c289
1 files changed, 75 insertions, 214 deletions
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index f9ce39cdf618..cb9f5e011e73 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -732,230 +732,91 @@ void __init s3c2416_init_irq(void)
732#endif 732#endif
733 733
734#ifdef CONFIG_CPU_S3C2443 734#ifdef CONFIG_CPU_S3C2443
735#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) 735static struct s3c_irq_data init_s3c2443base[32] = {
736 736 { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
737static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len) 737 { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
738{ 738 { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
739 unsigned int subsrc, submsk; 739 { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
740 unsigned int end; 740 { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
741 741 { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
742 /* read the current pending interrupts, and the mask 742 { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
743 * for what it is available */ 743 { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
744 744 { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
745 subsrc = __raw_readl(S3C2410_SUBSRCPND); 745 { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
746 submsk = __raw_readl(S3C2410_INTSUBMSK); 746 { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
747 747 { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
748 subsrc &= ~submsk; 748 { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
749 subsrc >>= (irq - S3C2410_IRQSUB(0)); 749 { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
750 subsrc &= (1 << len)-1; 750 { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
751 751 { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
752 end = len + irq; 752 { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
753 753 { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
754 for (; irq < end && subsrc; irq++) { 754 { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
755 if (subsrc & 1) 755 { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
756 generic_handle_irq(irq); 756 { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
757 757 { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
758 subsrc >>= 1; 758 { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
759 } 759 { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
760} 760 { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
761 761 { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
762/* WDT/AC97 sub interrupts */ 762 { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
763 763 { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
764static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc) 764 { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
765{ 765 { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
766 s3c2443_irq_demux(IRQ_S3C2443_WDT, 4); 766 { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
767} 767 { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
768
769#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
770#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
771
772static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
773{
774 s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
775}
776
777static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
778{
779 s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
780}
781
782static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
783{
784 s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
785}
786
787static struct irq_chip s3c2443_irq_wdtac97 = {
788 .irq_mask = s3c2443_irq_wdtac97_mask,
789 .irq_unmask = s3c2443_irq_wdtac97_unmask,
790 .irq_ack = s3c2443_irq_wdtac97_ack,
791};
792
793/* LCD sub interrupts */
794
795static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
796{
797 s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
798}
799
800#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
801#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
802
803static void s3c2443_irq_lcd_mask(struct irq_data *data)
804{
805 s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
806}
807
808static void s3c2443_irq_lcd_unmask(struct irq_data *data)
809{
810 s3c_irqsub_unmask(data->irq, INTMSK_LCD);
811}
812
813static void s3c2443_irq_lcd_ack(struct irq_data *data)
814{
815 s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
816}
817
818static struct irq_chip s3c2443_irq_lcd = {
819 .irq_mask = s3c2443_irq_lcd_mask,
820 .irq_unmask = s3c2443_irq_lcd_unmask,
821 .irq_ack = s3c2443_irq_lcd_ack,
822};
823
824/* DMA sub interrupts */
825
826static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
827{
828 s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
829}
830
831#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
832#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
833
834static void s3c2443_irq_dma_mask(struct irq_data *data)
835{
836 s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
837}
838
839static void s3c2443_irq_dma_unmask(struct irq_data *data)
840{
841 s3c_irqsub_unmask(data->irq, INTMSK_DMA);
842}
843
844static void s3c2443_irq_dma_ack(struct irq_data *data)
845{
846 s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
847}
848
849static struct irq_chip s3c2443_irq_dma = {
850 .irq_mask = s3c2443_irq_dma_mask,
851 .irq_unmask = s3c2443_irq_dma_unmask,
852 .irq_ack = s3c2443_irq_dma_ack,
853};
854
855/* UART3 sub interrupts */
856
857static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
858{
859 s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
860}
861
862#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
863#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
864
865static void s3c2443_irq_uart3_mask(struct irq_data *data)
866{
867 s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
868}
869
870static void s3c2443_irq_uart3_unmask(struct irq_data *data)
871{
872 s3c_irqsub_unmask(data->irq, INTMSK_UART3);
873}
874
875static void s3c2443_irq_uart3_ack(struct irq_data *data)
876{
877 s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
878}
879
880static struct irq_chip s3c2443_irq_uart3 = {
881 .irq_mask = s3c2443_irq_uart3_mask,
882 .irq_unmask = s3c2443_irq_uart3_unmask,
883 .irq_ack = s3c2443_irq_uart3_ack,
884}; 768};
885 769
886/* CAM sub interrupts */
887 770
888static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc) 771static struct s3c_irq_data init_s3c2443subint[32] = {
889{ 772 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
890 s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4); 773 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
891} 774 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
892 775 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
893#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) 776 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
894#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P) 777 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
895 778 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
896static void s3c2443_irq_cam_mask(struct irq_data *data) 779 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
897{ 780 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
898 s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM); 781 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
899} 782 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
900 783 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
901static void s3c2443_irq_cam_unmask(struct irq_data *data) 784 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
902{ 785 { .type = S3C_IRQTYPE_NONE }, /* reserved */
903 s3c_irqsub_unmask(data->irq, INTMSK_CAM); 786 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
904} 787 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
905 788 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
906static void s3c2443_irq_cam_ack(struct irq_data *data) 789 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
907{ 790 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
908 s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM); 791 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
909} 792 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
910 793 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
911static struct irq_chip s3c2443_irq_cam = { 794 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
912 .irq_mask = s3c2443_irq_cam_mask, 795 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
913 .irq_unmask = s3c2443_irq_cam_unmask, 796 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
914 .irq_ack = s3c2443_irq_cam_ack, 797 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
798 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
799 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
800 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
915}; 801};
916 802
917/* IRQ initialisation code */
918
919static int s3c2443_add_sub(unsigned int base,
920 void (*demux)(unsigned int,
921 struct irq_desc *),
922 struct irq_chip *chip,
923 unsigned int start, unsigned int end)
924{
925 unsigned int irqno;
926
927 irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
928 irq_set_chained_handler(base, demux);
929
930 for (irqno = start; irqno <= end; irqno++) {
931 irq_set_chip_and_handler(irqno, chip, handle_level_irq);
932 set_irq_flags(irqno, IRQF_VALID);
933 }
934
935 return 0;
936}
937
938void __init s3c2443_init_irq(void) 803void __init s3c2443_init_irq(void)
939{ 804{
940 pr_info("S3C2443: IRQ Support\n"); 805 struct s3c_irq_intc *main_intc;
941
942 s3c24xx_init_irq();
943
944 s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
945 IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
946 806
947 s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd, 807 pr_info("S3C2443: IRQ Support\n");
948 IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
949 808
950 s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma, 809#ifdef CONFIG_FIQ
951 &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5); 810 init_FIQ(FIQ_START);
811#endif
952 812
953 s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3, 813 main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
954 &s3c2443_irq_uart3, 814 if (IS_ERR(main_intc)) {
955 IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3); 815 pr_err("irq: could not create main interrupt controller\n");
816 return;
817 }
956 818
957 s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97, 819 s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
958 &s3c2443_irq_wdtac97, 820 s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
959 IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
960} 821}
961#endif 822#endif