aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-exynos/common.c147
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-gpio.h20
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
668static void __iomem *exynos_eint_base;
669
668static DEFINE_SPINLOCK(eint_lock); 670static DEFINE_SPINLOCK(eint_lock);
669 671
670static unsigned int eint0_15_data[16]; 672static unsigned int eint0_15_data[16];
671 673
674static 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
698static 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
672static unsigned int exynos4_eint0_15_src_int[16] = { 722static 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};
709static inline void exynos4_irq_eint_mask(struct irq_data *data) 759static 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
720static void exynos4_irq_eint_unmask(struct irq_data *data) 770static 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
731static inline void exynos4_irq_eint_ack(struct irq_data *data) 781static 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
737static void exynos4_irq_eint_maskack(struct irq_data *data) 787static 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
743static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) 793static 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
806static struct irq_chip exynos4_irq_eint = { 844static 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 */
827static inline void exynos4_irq_demux_eint(unsigned int start) 865static 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
844static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) 882static 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
870static int __init exynos4_init_irq_eint(void) 908static 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}
903arch_initcall(exynos4_init_irq_eint); 948arch_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 */