diff options
author | Heiko Stuebner <heiko@sntech.de> | 2013-01-29 13:25:23 -0500 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2013-02-03 18:52:50 -0500 |
commit | f44ddba3635e35317057e976888d4a12dcb0f842 (patch) | |
tree | 082fb806a84367816f7402282c72b99e74d6932f | |
parent | b499b7a87117c6ec45f5d4f73ac6a643b1709292 (diff) |
ARM: S3C24XX: transform s3c2443 subirqs into new structure
Share the common irq code by simply defining a correct mapping declaration
for the s3c2443.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r-- | arch/arm/plat-s3c24xx/irq.c | 289 |
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) | 735 | static struct s3c_irq_data init_s3c2443base[32] = { |
736 | 736 | { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ | |
737 | static 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 */ | |
764 | static 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 | |||
772 | static void s3c2443_irq_wdtac97_mask(struct irq_data *data) | ||
773 | { | ||
774 | s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97); | ||
775 | } | ||
776 | |||
777 | static void s3c2443_irq_wdtac97_unmask(struct irq_data *data) | ||
778 | { | ||
779 | s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97); | ||
780 | } | ||
781 | |||
782 | static void s3c2443_irq_wdtac97_ack(struct irq_data *data) | ||
783 | { | ||
784 | s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97); | ||
785 | } | ||
786 | |||
787 | static 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 | |||
795 | static 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 | |||
803 | static void s3c2443_irq_lcd_mask(struct irq_data *data) | ||
804 | { | ||
805 | s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD); | ||
806 | } | ||
807 | |||
808 | static void s3c2443_irq_lcd_unmask(struct irq_data *data) | ||
809 | { | ||
810 | s3c_irqsub_unmask(data->irq, INTMSK_LCD); | ||
811 | } | ||
812 | |||
813 | static void s3c2443_irq_lcd_ack(struct irq_data *data) | ||
814 | { | ||
815 | s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD); | ||
816 | } | ||
817 | |||
818 | static 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 | |||
826 | static 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 | |||
834 | static void s3c2443_irq_dma_mask(struct irq_data *data) | ||
835 | { | ||
836 | s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA); | ||
837 | } | ||
838 | |||
839 | static void s3c2443_irq_dma_unmask(struct irq_data *data) | ||
840 | { | ||
841 | s3c_irqsub_unmask(data->irq, INTMSK_DMA); | ||
842 | } | ||
843 | |||
844 | static void s3c2443_irq_dma_ack(struct irq_data *data) | ||
845 | { | ||
846 | s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA); | ||
847 | } | ||
848 | |||
849 | static 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 | |||
857 | static 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 | |||
865 | static void s3c2443_irq_uart3_mask(struct irq_data *data) | ||
866 | { | ||
867 | s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3); | ||
868 | } | ||
869 | |||
870 | static void s3c2443_irq_uart3_unmask(struct irq_data *data) | ||
871 | { | ||
872 | s3c_irqsub_unmask(data->irq, INTMSK_UART3); | ||
873 | } | ||
874 | |||
875 | static void s3c2443_irq_uart3_ack(struct irq_data *data) | ||
876 | { | ||
877 | s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3); | ||
878 | } | ||
879 | |||
880 | static 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 | ||
888 | static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc) | 771 | static 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 */ | |
896 | static 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 */ | |
901 | static 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 */ | |
906 | static 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 */ | |
911 | static 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 | |||
919 | static 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 | |||
938 | void __init s3c2443_init_irq(void) | 803 | void __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 |