|
@@ -532,3 +532,145 @@ void __init s3c24xx_init_irq(void)
|
|
int irqno;
|
|
int irqno;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_FIQ
|
|
|
|
+ init_FIQ(FIQ_START);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
|
|
|
|
+
|
|
|
|
+ /* first, clear all interrupts pending... */
|
|
|
|
+
|
|
|
|
+ last = 0;
|
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
|
+ pend = __raw_readl(S3C24XX_EINTPEND);
|
|
|
|
+
|
|
|
|
+ if (pend == 0 || pend == last)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ __raw_writel(pend, S3C24XX_EINTPEND);
|
|
|
|
+ printk("irq: clearing pending ext status %08x\n", (int)pend);
|
|
|
|
+ last = pend;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ last = 0;
|
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
|
+ pend = __raw_readl(S3C2410_INTPND);
|
|
|
|
+
|
|
|
|
+ if (pend == 0 || pend == last)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ __raw_writel(pend, S3C2410_SRCPND);
|
|
|
|
+ __raw_writel(pend, S3C2410_INTPND);
|
|
|
|
+ printk("irq: clearing pending status %08x\n", (int)pend);
|
|
|
|
+ last = pend;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ last = 0;
|
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
|
+ pend = __raw_readl(S3C2410_SUBSRCPND);
|
|
|
|
+
|
|
|
|
+ if (pend == 0 || pend == last)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ printk("irq: clearing subpending status %08x\n", (int)pend);
|
|
|
|
+ __raw_writel(pend, S3C2410_SUBSRCPND);
|
|
|
|
+ last = pend;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* register the main interrupts */
|
|
|
|
+
|
|
|
|
+ irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
|
|
|
|
+ /* set all the s3c2410 internal irqs */
|
|
|
|
+
|
|
|
|
+ switch (irqno) {
|
|
|
|
+ /* deal with the special IRQs (cascaded) */
|
|
|
|
+
|
|
|
|
+ case IRQ_EINT4t7:
|
|
|
|
+ case IRQ_EINT8t23:
|
|
|
|
+ case IRQ_UART0:
|
|
|
|
+ case IRQ_UART1:
|
|
|
|
+ case IRQ_UART2:
|
|
|
|
+ case IRQ_ADCPARENT:
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_level_chip,
|
|
|
|
+ handle_level_irq);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case IRQ_RESERVED6:
|
|
|
|
+ case IRQ_RESERVED24:
|
|
|
|
+ /* no IRQ here */
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ //irqdbf("registering irq %d (s3c irq)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_chip,
|
|
|
|
+ handle_edge_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* setup the cascade irq handlers */
|
|
|
|
+
|
|
|
|
+ irq_set_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
|
|
|
|
+ irq_set_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
|
|
|
|
+
|
|
|
|
+ irq_set_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
|
|
|
|
+ irq_set_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
|
|
|
|
+ irq_set_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
|
|
|
|
+ irq_set_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
|
|
|
|
+
|
|
|
|
+ /* external interrupts */
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
|
|
|
|
+ irqdbf("registering irq %d (ext int)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4,
|
|
|
|
+ handle_edge_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
|
|
|
|
+ irqdbf("registering irq %d (extended s3c irq)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irqext_chip,
|
|
|
|
+ handle_edge_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* register the uart interrupts */
|
|
|
|
+
|
|
|
|
+ irqdbf("s3c2410: registering external interrupts\n");
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
|
|
|
|
+ irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart0,
|
|
|
|
+ handle_level_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
|
|
|
|
+ irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart1,
|
|
|
|
+ handle_level_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
|
|
|
|
+ irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart2,
|
|
|
|
+ handle_level_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
|
|
|
|
+ irqdbf("registering irq %d (s3c adc irq)\n", irqno);
|
|
|
|
+ irq_set_chip_and_handler(irqno, &s3c_irq_adc, handle_edge_irq);
|
|
|
|
+ set_irq_flags(irqno, IRQF_VALID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ irqdbf("s3c2410: registered interrupt handlers\n");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+struct syscore_ops s3c24xx_irq_syscore_ops = {
|
|
|
|
+ .suspend = s3c24xx_irq_suspend,
|
|
|
|
+ .resume = s3c24xx_irq_resume,
|
|
|
|
+};
|