diff options
| -rw-r--r-- | arch/arm/mach-s3c2412/irq.c | 58 | ||||
| -rw-r--r-- | arch/arm/mach-s3c2412/s3c2412.c | 5 | ||||
| -rw-r--r-- | include/asm-arm/arch-s3c2410/irqs.h | 7 |
3 files changed, 70 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c index f0d66828f965..e9d0c769f5da 100644 --- a/arch/arm/mach-s3c2412/irq.c +++ b/arch/arm/mach-s3c2412/irq.c | |||
| @@ -38,6 +38,9 @@ | |||
| 38 | #include <asm/plat-s3c24xx/irq.h> | 38 | #include <asm/plat-s3c24xx/irq.h> |
| 39 | #include <asm/plat-s3c24xx/pm.h> | 39 | #include <asm/plat-s3c24xx/pm.h> |
| 40 | 40 | ||
| 41 | #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) | ||
| 42 | #define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0)))) | ||
| 43 | |||
| 41 | /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by | 44 | /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by |
| 42 | * having them turn up in both the INT* and the EINT* registers. Whilst | 45 | * having them turn up in both the INT* and the EINT* registers. Whilst |
| 43 | * both show the status, they both now need to be acked when the IRQs | 46 | * both show the status, they both now need to be acked when the IRQs |
| @@ -105,6 +108,51 @@ static struct irq_chip s3c2412_irq_eint0t4 = { | |||
| 105 | .set_type = s3c_irqext_type, | 108 | .set_type = s3c_irqext_type, |
| 106 | }; | 109 | }; |
| 107 | 110 | ||
| 111 | #define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0))) | ||
| 112 | |||
| 113 | /* CF and SDI sub interrupts */ | ||
| 114 | |||
| 115 | static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc) | ||
| 116 | { | ||
| 117 | unsigned int subsrc, submsk; | ||
| 118 | |||
| 119 | subsrc = __raw_readl(S3C2410_SUBSRCPND); | ||
| 120 | submsk = __raw_readl(S3C2410_INTSUBMSK); | ||
| 121 | |||
| 122 | subsrc &= ~submsk; | ||
| 123 | |||
| 124 | if (subsrc & INTBIT(IRQ_S3C2412_SDI)) | ||
| 125 | desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI); | ||
| 126 | |||
| 127 | if (subsrc & INTBIT(IRQ_S3C2412_CF)) | ||
| 128 | desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF); | ||
| 129 | } | ||
| 130 | |||
| 131 | #define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0)) | ||
| 132 | #define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF) | ||
| 133 | |||
| 134 | static void s3c2412_irq_cfsdi_mask(unsigned int irqno) | ||
| 135 | { | ||
| 136 | s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); | ||
| 137 | } | ||
| 138 | |||
| 139 | static void s3c2412_irq_cfsdi_unmask(unsigned int irqno) | ||
| 140 | { | ||
| 141 | s3c_irqsub_unmask(irqno, INTMSK_CFSDI); | ||
| 142 | } | ||
| 143 | |||
| 144 | static void s3c2412_irq_cfsdi_ack(unsigned int irqno) | ||
| 145 | { | ||
| 146 | s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); | ||
| 147 | } | ||
| 148 | |||
| 149 | static struct irq_chip s3c2412_irq_cfsdi = { | ||
| 150 | .name = "s3c2412-cfsdi", | ||
| 151 | .ack = s3c2412_irq_cfsdi_ack, | ||
| 152 | .mask = s3c2412_irq_cfsdi_mask, | ||
| 153 | .unmask = s3c2412_irq_cfsdi_unmask, | ||
| 154 | }; | ||
| 155 | |||
| 108 | static int s3c2412_irq_add(struct sys_device *sysdev) | 156 | static int s3c2412_irq_add(struct sys_device *sysdev) |
| 109 | { | 157 | { |
| 110 | unsigned int irqno; | 158 | unsigned int irqno; |
| @@ -115,6 +163,16 @@ static int s3c2412_irq_add(struct sys_device *sysdev) | |||
| 115 | set_irq_flags(irqno, IRQF_VALID); | 163 | set_irq_flags(irqno, IRQF_VALID); |
| 116 | } | 164 | } |
| 117 | 165 | ||
| 166 | /* add demux support for CF/SDI */ | ||
| 167 | |||
| 168 | set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi); | ||
| 169 | |||
| 170 | for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) { | ||
| 171 | set_irq_chip(irqno, &s3c2412_irq_cfsdi); | ||
| 172 | set_irq_handler(irqno, handle_level_irq); | ||
| 173 | set_irq_flags(irqno, IRQF_VALID); | ||
| 174 | } | ||
| 175 | |||
| 118 | return 0; | 176 | return 0; |
| 119 | } | 177 | } |
| 120 | 178 | ||
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index e0ccb404623f..4f92a1562d77 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c | |||
| @@ -78,6 +78,11 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) | |||
| 78 | s3c_device_lcd.name = "s3c2412-lcd"; | 78 | s3c_device_lcd.name = "s3c2412-lcd"; |
| 79 | s3c_device_nand.name = "s3c2412-nand"; | 79 | s3c_device_nand.name = "s3c2412-nand"; |
| 80 | 80 | ||
| 81 | /* alter IRQ of SDI controller */ | ||
| 82 | |||
| 83 | s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI; | ||
| 84 | s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI; | ||
| 85 | |||
| 81 | /* spi channel related changes, s3c2412/13 specific */ | 86 | /* spi channel related changes, s3c2412/13 specific */ |
| 82 | s3c_device_spi0.name = "s3c2412-spi"; | 87 | s3c_device_spi0.name = "s3c2412-spi"; |
| 83 | s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24; | 88 | s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24; |
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h index 3b49cd1c345c..996f65488d2d 100644 --- a/include/asm-arm/arch-s3c2410/irqs.h +++ b/include/asm-arm/arch-s3c2410/irqs.h | |||
| @@ -112,6 +112,13 @@ | |||
| 112 | #define IRQ_TC S3C2410_IRQSUB(9) | 112 | #define IRQ_TC S3C2410_IRQSUB(9) |
| 113 | #define IRQ_ADC S3C2410_IRQSUB(10) | 113 | #define IRQ_ADC S3C2410_IRQSUB(10) |
| 114 | 114 | ||
| 115 | /* extra irqs for s3c2412 */ | ||
| 116 | |||
| 117 | #define IRQ_S3C2412_CFSDI S3C2410_IRQ(21) | ||
| 118 | |||
| 119 | #define IRQ_S3C2412_SDI S3C2410_IRQSUB(13) | ||
| 120 | #define IRQ_S3C2412_CF S3C2410_IRQSUB(14) | ||
| 121 | |||
| 115 | /* extra irqs for s3c2440 */ | 122 | /* extra irqs for s3c2440 */ |
| 116 | 123 | ||
| 117 | #define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ | 124 | #define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ |
