aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-s3c24xx/irq.c118
-rw-r--r--drivers/gpio/gpio-samsung.c5
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
625static struct s3c_irq_data init_s3c2412base[32] = { 628static 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
663static 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
660static struct s3c_irq_data init_s3c2412subint[32] = { 690static 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
684static void
685s3c2412_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
697static inline void
698s3c2412_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
707static inline void
708s3c2412_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
724static void
725s3c2412_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
737static 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
745void s3c2412_init_irq(void) 708void 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)
1123static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) 1123static 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;