diff options
-rw-r--r-- | arch/arm/mach-s3c24xx/include/mach/irqs.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/irq.c | 118 | ||||
-rw-r--r-- | drivers/gpio/gpio-samsung.c | 5 |
3 files changed, 44 insertions, 83 deletions
diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index ea589e4f0d8b..43cada8019b4 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h | |||
@@ -59,6 +59,10 @@ | |||
59 | #define IRQ_ADCPARENT S3C2410_IRQ(31) | 59 | #define IRQ_ADCPARENT S3C2410_IRQ(31) |
60 | 60 | ||
61 | /* interrupts generated from the external interrupts sources */ | 61 | /* interrupts generated from the external interrupts sources */ |
62 | #define IRQ_EINT0_2412 S3C2410_IRQ(32) | ||
63 | #define IRQ_EINT1_2412 S3C2410_IRQ(33) | ||
64 | #define IRQ_EINT2_2412 S3C2410_IRQ(34) | ||
65 | #define IRQ_EINT3_2412 S3C2410_IRQ(35) | ||
62 | #define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */ | 66 | #define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */ |
63 | #define IRQ_EINT5 S3C2410_IRQ(37) | 67 | #define IRQ_EINT5 S3C2410_IRQ(37) |
64 | #define IRQ_EINT6 S3C2410_IRQ(38) | 68 | #define IRQ_EINT6 S3C2410_IRQ(38) |
diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index c2205eb78dc1..3f3de7492094 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c | |||
@@ -342,7 +342,10 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, | |||
342 | case S3C_IRQTYPE_NONE: | 342 | case S3C_IRQTYPE_NONE: |
343 | return 0; | 343 | return 0; |
344 | case S3C_IRQTYPE_EINT: | 344 | case S3C_IRQTYPE_EINT: |
345 | if (irq_data->parent_irq) | 345 | /* On the S3C2412, the EINT0to3 have a parent irq |
346 | * but need the s3c_irq_eint0t4 chip | ||
347 | */ | ||
348 | if (irq_data->parent_irq && (!soc_is_s3c2412() || hw >= 4)) | ||
346 | irq_set_chip_and_handler(virq, &s3c_irqext_chip, | 349 | irq_set_chip_and_handler(virq, &s3c_irqext_chip, |
347 | handle_edge_irq); | 350 | handle_edge_irq); |
348 | else | 351 | else |
@@ -623,10 +626,10 @@ void __init s3c24xx_init_irq(void) | |||
623 | 626 | ||
624 | #ifdef CONFIG_CPU_S3C2412 | 627 | #ifdef CONFIG_CPU_S3C2412 |
625 | static struct s3c_irq_data init_s3c2412base[32] = { | 628 | static struct s3c_irq_data init_s3c2412base[32] = { |
626 | { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ | 629 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */ |
627 | { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ | 630 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */ |
628 | { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ | 631 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */ |
629 | { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ | 632 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */ |
630 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ | 633 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ |
631 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ | 634 | { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ |
632 | { .type = S3C_IRQTYPE_NONE, }, /* reserved */ | 635 | { .type = S3C_IRQTYPE_NONE, }, /* reserved */ |
@@ -657,6 +660,33 @@ static struct s3c_irq_data init_s3c2412base[32] = { | |||
657 | { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ | 660 | { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ |
658 | }; | 661 | }; |
659 | 662 | ||
663 | static struct s3c_irq_data init_s3c2412eint[32] = { | ||
664 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */ | ||
665 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */ | ||
666 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */ | ||
667 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */ | ||
668 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */ | ||
669 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */ | ||
670 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */ | ||
671 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */ | ||
672 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */ | ||
673 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */ | ||
674 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */ | ||
675 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */ | ||
676 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */ | ||
677 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */ | ||
678 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */ | ||
679 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */ | ||
680 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */ | ||
681 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */ | ||
682 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */ | ||
683 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */ | ||
684 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */ | ||
685 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */ | ||
686 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */ | ||
687 | { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */ | ||
688 | }; | ||
689 | |||
660 | static struct s3c_irq_data init_s3c2412subint[32] = { | 690 | static struct s3c_irq_data init_s3c2412subint[32] = { |
661 | { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ | 691 | { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ |
662 | { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ | 692 | { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ |
@@ -675,77 +705,9 @@ static struct s3c_irq_data init_s3c2412subint[32] = { | |||
675 | { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */ | 705 | { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */ |
676 | }; | 706 | }; |
677 | 707 | ||
678 | /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by | ||
679 | * having them turn up in both the INT* and the EINT* registers. Whilst | ||
680 | * both show the status, they both now need to be acked when the IRQs | ||
681 | * go off. | ||
682 | */ | ||
683 | |||
684 | static void | ||
685 | s3c2412_irq_mask(struct irq_data *data) | ||
686 | { | ||
687 | unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); | ||
688 | unsigned long mask; | ||
689 | |||
690 | mask = __raw_readl(S3C2410_INTMSK); | ||
691 | __raw_writel(mask | bitval, S3C2410_INTMSK); | ||
692 | |||
693 | mask = __raw_readl(S3C2412_EINTMASK); | ||
694 | __raw_writel(mask | bitval, S3C2412_EINTMASK); | ||
695 | } | ||
696 | |||
697 | static inline void | ||
698 | s3c2412_irq_ack(struct irq_data *data) | ||
699 | { | ||
700 | unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); | ||
701 | |||
702 | __raw_writel(bitval, S3C2412_EINTPEND); | ||
703 | __raw_writel(bitval, S3C2410_SRCPND); | ||
704 | __raw_writel(bitval, S3C2410_INTPND); | ||
705 | } | ||
706 | |||
707 | static inline void | ||
708 | s3c2412_irq_maskack(struct irq_data *data) | ||
709 | { | ||
710 | unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); | ||
711 | unsigned long mask; | ||
712 | |||
713 | mask = __raw_readl(S3C2410_INTMSK); | ||
714 | __raw_writel(mask|bitval, S3C2410_INTMSK); | ||
715 | |||
716 | mask = __raw_readl(S3C2412_EINTMASK); | ||
717 | __raw_writel(mask | bitval, S3C2412_EINTMASK); | ||
718 | |||
719 | __raw_writel(bitval, S3C2412_EINTPEND); | ||
720 | __raw_writel(bitval, S3C2410_SRCPND); | ||
721 | __raw_writel(bitval, S3C2410_INTPND); | ||
722 | } | ||
723 | |||
724 | static void | ||
725 | s3c2412_irq_unmask(struct irq_data *data) | ||
726 | { | ||
727 | unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); | ||
728 | unsigned long mask; | ||
729 | |||
730 | mask = __raw_readl(S3C2412_EINTMASK); | ||
731 | __raw_writel(mask & ~bitval, S3C2412_EINTMASK); | ||
732 | |||
733 | mask = __raw_readl(S3C2410_INTMSK); | ||
734 | __raw_writel(mask & ~bitval, S3C2410_INTMSK); | ||
735 | } | ||
736 | |||
737 | static struct irq_chip s3c2412_irq_eint0t4 = { | ||
738 | .irq_ack = s3c2412_irq_ack, | ||
739 | .irq_mask = s3c2412_irq_mask, | ||
740 | .irq_unmask = s3c2412_irq_unmask, | ||
741 | .irq_set_wake = s3c_irq_wake, | ||
742 | .irq_set_type = s3c_irqext_type, | ||
743 | }; | ||
744 | |||
745 | void s3c2412_init_irq(void) | 708 | void s3c2412_init_irq(void) |
746 | { | 709 | { |
747 | struct s3c_irq_intc *main_intc; | 710 | struct s3c_irq_intc *main_intc; |
748 | unsigned int irqno; | ||
749 | 711 | ||
750 | pr_info("S3C2412: IRQ Support\n"); | 712 | pr_info("S3C2412: IRQ Support\n"); |
751 | 713 | ||
@@ -759,16 +721,8 @@ void s3c2412_init_irq(void) | |||
759 | return; | 721 | return; |
760 | } | 722 | } |
761 | 723 | ||
762 | s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); | 724 | s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4); |
763 | s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018); | 725 | s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018); |
764 | |||
765 | /* special handling for eints 0 to 3 */ | ||
766 | |||
767 | for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { | ||
768 | irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4, | ||
769 | handle_edge_irq); | ||
770 | set_irq_flags(irqno, IRQF_VALID); | ||
771 | } | ||
772 | } | 726 | } |
773 | #endif | 727 | #endif |
774 | 728 | ||
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b3643ff007e4..db098cea3a55 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -1123,7 +1123,10 @@ int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) | |||
1123 | static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) | 1123 | static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) |
1124 | { | 1124 | { |
1125 | if (offset < 4) | 1125 | if (offset < 4) |
1126 | return IRQ_EINT0 + offset; | 1126 | if (soc_is_s3c2412()) |
1127 | return IRQ_EINT0_2412 + offset; | ||
1128 | else | ||
1129 | return IRQ_EINT0 + offset; | ||
1127 | 1130 | ||
1128 | if (offset < 8) | 1131 | if (offset < 8) |
1129 | return IRQ_EINT4 + offset - 4; | 1132 | return IRQ_EINT4 + offset - 4; |