diff options
-rw-r--r-- | arch/arm/mach-exynos/common.c | 147 | ||||
-rw-r--r-- | arch/arm/mach-exynos/include/mach/regs-gpio.h | 20 |
2 files changed, 105 insertions, 62 deletions
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 4ef0cb513c83..cbbaca54966a 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c | |||
@@ -665,10 +665,60 @@ static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no) | |||
665 | s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no); | 665 | s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no); |
666 | } | 666 | } |
667 | 667 | ||
668 | static void __iomem *exynos_eint_base; | ||
669 | |||
668 | static DEFINE_SPINLOCK(eint_lock); | 670 | static DEFINE_SPINLOCK(eint_lock); |
669 | 671 | ||
670 | static unsigned int eint0_15_data[16]; | 672 | static unsigned int eint0_15_data[16]; |
671 | 673 | ||
674 | static inline int exynos4_irq_to_gpio(unsigned int irq) | ||
675 | { | ||
676 | if (irq < IRQ_EINT(0)) | ||
677 | return -EINVAL; | ||
678 | |||
679 | irq -= IRQ_EINT(0); | ||
680 | if (irq < 8) | ||
681 | return EXYNOS4_GPX0(irq); | ||
682 | |||
683 | irq -= 8; | ||
684 | if (irq < 8) | ||
685 | return EXYNOS4_GPX1(irq); | ||
686 | |||
687 | irq -= 8; | ||
688 | if (irq < 8) | ||
689 | return EXYNOS4_GPX2(irq); | ||
690 | |||
691 | irq -= 8; | ||
692 | if (irq < 8) | ||
693 | return EXYNOS4_GPX3(irq); | ||
694 | |||
695 | return -EINVAL; | ||
696 | } | ||
697 | |||
698 | static inline int exynos5_irq_to_gpio(unsigned int irq) | ||
699 | { | ||
700 | if (irq < IRQ_EINT(0)) | ||
701 | return -EINVAL; | ||
702 | |||
703 | irq -= IRQ_EINT(0); | ||
704 | if (irq < 8) | ||
705 | return EXYNOS5_GPX0(irq); | ||
706 | |||
707 | irq -= 8; | ||
708 | if (irq < 8) | ||
709 | return EXYNOS5_GPX1(irq); | ||
710 | |||
711 | irq -= 8; | ||
712 | if (irq < 8) | ||
713 | return EXYNOS5_GPX2(irq); | ||
714 | |||
715 | irq -= 8; | ||
716 | if (irq < 8) | ||
717 | return EXYNOS5_GPX3(irq); | ||
718 | |||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
672 | static unsigned int exynos4_eint0_15_src_int[16] = { | 722 | static unsigned int exynos4_eint0_15_src_int[16] = { |
673 | EXYNOS4_IRQ_EINT0, | 723 | EXYNOS4_IRQ_EINT0, |
674 | EXYNOS4_IRQ_EINT1, | 724 | EXYNOS4_IRQ_EINT1, |
@@ -706,41 +756,41 @@ static unsigned int exynos5_eint0_15_src_int[16] = { | |||
706 | EXYNOS5_IRQ_EINT14, | 756 | EXYNOS5_IRQ_EINT14, |
707 | EXYNOS5_IRQ_EINT15, | 757 | EXYNOS5_IRQ_EINT15, |
708 | }; | 758 | }; |
709 | static inline void exynos4_irq_eint_mask(struct irq_data *data) | 759 | static inline void exynos_irq_eint_mask(struct irq_data *data) |
710 | { | 760 | { |
711 | u32 mask; | 761 | u32 mask; |
712 | 762 | ||
713 | spin_lock(&eint_lock); | 763 | spin_lock(&eint_lock); |
714 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | 764 | mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq)); |
715 | mask |= eint_irq_to_bit(data->irq); | 765 | mask |= EINT_OFFSET_BIT(data->irq); |
716 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | 766 | __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq)); |
717 | spin_unlock(&eint_lock); | 767 | spin_unlock(&eint_lock); |
718 | } | 768 | } |
719 | 769 | ||
720 | static void exynos4_irq_eint_unmask(struct irq_data *data) | 770 | static void exynos_irq_eint_unmask(struct irq_data *data) |
721 | { | 771 | { |
722 | u32 mask; | 772 | u32 mask; |
723 | 773 | ||
724 | spin_lock(&eint_lock); | 774 | spin_lock(&eint_lock); |
725 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | 775 | mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq)); |
726 | mask &= ~(eint_irq_to_bit(data->irq)); | 776 | mask &= ~(EINT_OFFSET_BIT(data->irq)); |
727 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | 777 | __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq)); |
728 | spin_unlock(&eint_lock); | 778 | spin_unlock(&eint_lock); |
729 | } | 779 | } |
730 | 780 | ||
731 | static inline void exynos4_irq_eint_ack(struct irq_data *data) | 781 | static inline void exynos_irq_eint_ack(struct irq_data *data) |
732 | { | 782 | { |
733 | __raw_writel(eint_irq_to_bit(data->irq), | 783 | __raw_writel(EINT_OFFSET_BIT(data->irq), |
734 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | 784 | EINT_PEND(exynos_eint_base, data->irq)); |
735 | } | 785 | } |
736 | 786 | ||
737 | static void exynos4_irq_eint_maskack(struct irq_data *data) | 787 | static void exynos_irq_eint_maskack(struct irq_data *data) |
738 | { | 788 | { |
739 | exynos4_irq_eint_mask(data); | 789 | exynos_irq_eint_mask(data); |
740 | exynos4_irq_eint_ack(data); | 790 | exynos_irq_eint_ack(data); |
741 | } | 791 | } |
742 | 792 | ||
743 | static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) | 793 | static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type) |
744 | { | 794 | { |
745 | int offs = EINT_OFFSET(data->irq); | 795 | int offs = EINT_OFFSET(data->irq); |
746 | int shift; | 796 | int shift; |
@@ -777,39 +827,27 @@ static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) | |||
777 | mask = 0x7 << shift; | 827 | mask = 0x7 << shift; |
778 | 828 | ||
779 | spin_lock(&eint_lock); | 829 | spin_lock(&eint_lock); |
780 | ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); | 830 | ctrl = __raw_readl(EINT_CON(exynos_eint_base, data->irq)); |
781 | ctrl &= ~mask; | 831 | ctrl &= ~mask; |
782 | ctrl |= newvalue << shift; | 832 | ctrl |= newvalue << shift; |
783 | __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); | 833 | __raw_writel(ctrl, EINT_CON(exynos_eint_base, data->irq)); |
784 | spin_unlock(&eint_lock); | 834 | spin_unlock(&eint_lock); |
785 | 835 | ||
786 | switch (offs) { | 836 | if (soc_is_exynos5250()) |
787 | case 0 ... 7: | 837 | s3c_gpio_cfgpin(exynos5_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf)); |
788 | s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); | 838 | else |
789 | break; | 839 | s3c_gpio_cfgpin(exynos4_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf)); |
790 | case 8 ... 15: | ||
791 | s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); | ||
792 | break; | ||
793 | case 16 ... 23: | ||
794 | s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); | ||
795 | break; | ||
796 | case 24 ... 31: | ||
797 | s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); | ||
798 | break; | ||
799 | default: | ||
800 | printk(KERN_ERR "No such irq number %d", offs); | ||
801 | } | ||
802 | 840 | ||
803 | return 0; | 841 | return 0; |
804 | } | 842 | } |
805 | 843 | ||
806 | static struct irq_chip exynos4_irq_eint = { | 844 | static struct irq_chip exynos_irq_eint = { |
807 | .name = "exynos4-eint", | 845 | .name = "exynos-eint", |
808 | .irq_mask = exynos4_irq_eint_mask, | 846 | .irq_mask = exynos_irq_eint_mask, |
809 | .irq_unmask = exynos4_irq_eint_unmask, | 847 | .irq_unmask = exynos_irq_eint_unmask, |
810 | .irq_mask_ack = exynos4_irq_eint_maskack, | 848 | .irq_mask_ack = exynos_irq_eint_maskack, |
811 | .irq_ack = exynos4_irq_eint_ack, | 849 | .irq_ack = exynos_irq_eint_ack, |
812 | .irq_set_type = exynos4_irq_eint_set_type, | 850 | .irq_set_type = exynos_irq_eint_set_type, |
813 | #ifdef CONFIG_PM | 851 | #ifdef CONFIG_PM |
814 | .irq_set_wake = s3c_irqext_wake, | 852 | .irq_set_wake = s3c_irqext_wake, |
815 | #endif | 853 | #endif |
@@ -824,12 +862,12 @@ static struct irq_chip exynos4_irq_eint = { | |||
824 | * | 862 | * |
825 | * Each EINT pend/mask registers handle eight of them. | 863 | * Each EINT pend/mask registers handle eight of them. |
826 | */ | 864 | */ |
827 | static inline void exynos4_irq_demux_eint(unsigned int start) | 865 | static inline void exynos_irq_demux_eint(unsigned int start) |
828 | { | 866 | { |
829 | unsigned int irq; | 867 | unsigned int irq; |
830 | 868 | ||
831 | u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); | 869 | u32 status = __raw_readl(EINT_PEND(exynos_eint_base, start)); |
832 | u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); | 870 | u32 mask = __raw_readl(EINT_MASK(exynos_eint_base, start)); |
833 | 871 | ||
834 | status &= ~mask; | 872 | status &= ~mask; |
835 | status &= 0xff; | 873 | status &= 0xff; |
@@ -841,12 +879,12 @@ static inline void exynos4_irq_demux_eint(unsigned int start) | |||
841 | } | 879 | } |
842 | } | 880 | } |
843 | 881 | ||
844 | static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | 882 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) |
845 | { | 883 | { |
846 | struct irq_chip *chip = irq_get_chip(irq); | 884 | struct irq_chip *chip = irq_get_chip(irq); |
847 | chained_irq_enter(chip, desc); | 885 | chained_irq_enter(chip, desc); |
848 | exynos4_irq_demux_eint(IRQ_EINT(16)); | 886 | exynos_irq_demux_eint(IRQ_EINT(16)); |
849 | exynos4_irq_demux_eint(IRQ_EINT(24)); | 887 | exynos_irq_demux_eint(IRQ_EINT(24)); |
850 | chained_irq_exit(chip, desc); | 888 | chained_irq_exit(chip, desc); |
851 | } | 889 | } |
852 | 890 | ||
@@ -867,20 +905,27 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | |||
867 | chained_irq_exit(chip, desc); | 905 | chained_irq_exit(chip, desc); |
868 | } | 906 | } |
869 | 907 | ||
870 | static int __init exynos4_init_irq_eint(void) | 908 | static int __init exynos_init_irq_eint(void) |
871 | { | 909 | { |
872 | int irq; | 910 | int irq; |
873 | 911 | ||
874 | if (soc_is_exynos5250()) | 912 | if (soc_is_exynos5250()) |
875 | return 0; | 913 | exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); |
914 | else | ||
915 | exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); | ||
916 | |||
917 | if (exynos_eint_base == NULL) { | ||
918 | pr_err("unable to ioremap for EINT base address\n"); | ||
919 | return -ENOMEM; | ||
920 | } | ||
876 | 921 | ||
877 | for (irq = 0 ; irq <= 31 ; irq++) { | 922 | for (irq = 0 ; irq <= 31 ; irq++) { |
878 | irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint, | 923 | irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint, |
879 | handle_level_irq); | 924 | handle_level_irq); |
880 | set_irq_flags(IRQ_EINT(irq), IRQF_VALID); | 925 | set_irq_flags(IRQ_EINT(irq), IRQF_VALID); |
881 | } | 926 | } |
882 | 927 | ||
883 | irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos4_irq_demux_eint16_31); | 928 | irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31); |
884 | 929 | ||
885 | for (irq = 0 ; irq <= 15 ; irq++) { | 930 | for (irq = 0 ; irq <= 15 ; irq++) { |
886 | eint0_15_data[irq] = IRQ_EINT(irq); | 931 | eint0_15_data[irq] = IRQ_EINT(irq); |
@@ -900,4 +945,4 @@ static int __init exynos4_init_irq_eint(void) | |||
900 | 945 | ||
901 | return 0; | 946 | return 0; |
902 | } | 947 | } |
903 | arch_initcall(exynos4_init_irq_eint); | 948 | arch_initcall(exynos_init_irq_eint); |
diff --git a/arch/arm/mach-exynos/include/mach/regs-gpio.h b/arch/arm/mach-exynos/include/mach/regs-gpio.h index 1401b21663a5..e4b5b60dcb85 100644 --- a/arch/arm/mach-exynos/include/mach/regs-gpio.h +++ b/arch/arm/mach-exynos/include/mach/regs-gpio.h | |||
@@ -16,6 +16,15 @@ | |||
16 | #include <mach/map.h> | 16 | #include <mach/map.h> |
17 | #include <mach/irqs.h> | 17 | #include <mach/irqs.h> |
18 | 18 | ||
19 | #define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3) | ||
20 | #define EINT_CON(b, x) (b + 0xE00 + (EINT_REG_NR(x) * 4)) | ||
21 | #define EINT_FLTCON(b, x) (b + 0xE80 + (EINT_REG_NR(x) * 4)) | ||
22 | #define EINT_MASK(b, x) (b + 0xF00 + (EINT_REG_NR(x) * 4)) | ||
23 | #define EINT_PEND(b, x) (b + 0xF40 + (EINT_REG_NR(x) * 4)) | ||
24 | |||
25 | #define EINT_OFFSET_BIT(x) (1 << (EINT_OFFSET(x) & 0x7)) | ||
26 | |||
27 | /* compatibility for plat-s5p/irq-pm.c */ | ||
19 | #define EXYNOS4_EINT40CON (S5P_VA_GPIO2 + 0xE00) | 28 | #define EXYNOS4_EINT40CON (S5P_VA_GPIO2 + 0xE00) |
20 | #define S5P_EINT_CON(x) (EXYNOS4_EINT40CON + ((x) * 0x4)) | 29 | #define S5P_EINT_CON(x) (EXYNOS4_EINT40CON + ((x) * 0x4)) |
21 | 30 | ||
@@ -28,15 +37,4 @@ | |||
28 | #define EXYNOS4_EINT40PEND (S5P_VA_GPIO2 + 0xF40) | 37 | #define EXYNOS4_EINT40PEND (S5P_VA_GPIO2 + 0xF40) |
29 | #define S5P_EINT_PEND(x) (EXYNOS4_EINT40PEND + ((x) * 0x4)) | 38 | #define S5P_EINT_PEND(x) (EXYNOS4_EINT40PEND + ((x) * 0x4)) |
30 | 39 | ||
31 | #define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3) | ||
32 | |||
33 | #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) | ||
34 | |||
35 | #define EINT_MODE S3C_GPIO_SFN(0xf) | ||
36 | |||
37 | #define EINT_GPIO_0(x) EXYNOS4_GPX0(x) | ||
38 | #define EINT_GPIO_1(x) EXYNOS4_GPX1(x) | ||
39 | #define EINT_GPIO_2(x) EXYNOS4_GPX2(x) | ||
40 | #define EINT_GPIO_3(x) EXYNOS4_GPX3(x) | ||
41 | |||
42 | #endif /* __ASM_ARCH_REGS_GPIO_H */ | 40 | #endif /* __ASM_ARCH_REGS_GPIO_H */ |