xref: /openbmc/linux/arch/arm/mach-rpc/irq.c (revision fced80c7)
11da177e4SLinus Torvalds #include <linux/init.h>
21da177e4SLinus Torvalds #include <linux/list.h>
3fced80c7SRussell King #include <linux/io.h>
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds #include <asm/mach/irq.h>
61da177e4SLinus Torvalds #include <asm/hardware/iomd.h>
71da177e4SLinus Torvalds #include <asm/irq.h>
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds static void iomd_ack_irq_a(unsigned int irq)
101da177e4SLinus Torvalds {
111da177e4SLinus Torvalds 	unsigned int val, mask;
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds 	mask = 1 << irq;
141da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKA);
151da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
161da177e4SLinus Torvalds 	iomd_writeb(mask, IOMD_IRQCLRA);
171da177e4SLinus Torvalds }
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds static void iomd_mask_irq_a(unsigned int irq)
201da177e4SLinus Torvalds {
211da177e4SLinus Torvalds 	unsigned int val, mask;
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds 	mask = 1 << irq;
241da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKA);
251da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
261da177e4SLinus Torvalds }
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds static void iomd_unmask_irq_a(unsigned int irq)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds 	unsigned int val, mask;
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds 	mask = 1 << irq;
331da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKA);
341da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_IRQMASKA);
351da177e4SLinus Torvalds }
361da177e4SLinus Torvalds 
3710dd5ce2SRussell King static struct irq_chip iomd_a_chip = {
381da177e4SLinus Torvalds 	.ack	= iomd_ack_irq_a,
391da177e4SLinus Torvalds 	.mask	= iomd_mask_irq_a,
401da177e4SLinus Torvalds 	.unmask = iomd_unmask_irq_a,
411da177e4SLinus Torvalds };
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds static void iomd_mask_irq_b(unsigned int irq)
441da177e4SLinus Torvalds {
451da177e4SLinus Torvalds 	unsigned int val, mask;
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds 	mask = 1 << (irq & 7);
481da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKB);
491da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
501da177e4SLinus Torvalds }
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds static void iomd_unmask_irq_b(unsigned int irq)
531da177e4SLinus Torvalds {
541da177e4SLinus Torvalds 	unsigned int val, mask;
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds 	mask = 1 << (irq & 7);
571da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKB);
581da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_IRQMASKB);
591da177e4SLinus Torvalds }
601da177e4SLinus Torvalds 
6110dd5ce2SRussell King static struct irq_chip iomd_b_chip = {
621da177e4SLinus Torvalds 	.ack	= iomd_mask_irq_b,
631da177e4SLinus Torvalds 	.mask	= iomd_mask_irq_b,
641da177e4SLinus Torvalds 	.unmask = iomd_unmask_irq_b,
651da177e4SLinus Torvalds };
661da177e4SLinus Torvalds 
671da177e4SLinus Torvalds static void iomd_mask_irq_dma(unsigned int irq)
681da177e4SLinus Torvalds {
691da177e4SLinus Torvalds 	unsigned int val, mask;
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds 	mask = 1 << (irq & 7);
721da177e4SLinus Torvalds 	val = iomd_readb(IOMD_DMAMASK);
731da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_DMAMASK);
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds static void iomd_unmask_irq_dma(unsigned int irq)
771da177e4SLinus Torvalds {
781da177e4SLinus Torvalds 	unsigned int val, mask;
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds 	mask = 1 << (irq & 7);
811da177e4SLinus Torvalds 	val = iomd_readb(IOMD_DMAMASK);
821da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_DMAMASK);
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds 
8510dd5ce2SRussell King static struct irq_chip iomd_dma_chip = {
861da177e4SLinus Torvalds 	.ack	= iomd_mask_irq_dma,
871da177e4SLinus Torvalds 	.mask	= iomd_mask_irq_dma,
881da177e4SLinus Torvalds 	.unmask = iomd_unmask_irq_dma,
891da177e4SLinus Torvalds };
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds static void iomd_mask_irq_fiq(unsigned int irq)
921da177e4SLinus Torvalds {
931da177e4SLinus Torvalds 	unsigned int val, mask;
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds 	mask = 1 << (irq & 7);
961da177e4SLinus Torvalds 	val = iomd_readb(IOMD_FIQMASK);
971da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_FIQMASK);
981da177e4SLinus Torvalds }
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds static void iomd_unmask_irq_fiq(unsigned int irq)
1011da177e4SLinus Torvalds {
1021da177e4SLinus Torvalds 	unsigned int val, mask;
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 	mask = 1 << (irq & 7);
1051da177e4SLinus Torvalds 	val = iomd_readb(IOMD_FIQMASK);
1061da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_FIQMASK);
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
10910dd5ce2SRussell King static struct irq_chip iomd_fiq_chip = {
1101da177e4SLinus Torvalds 	.ack	= iomd_mask_irq_fiq,
1111da177e4SLinus Torvalds 	.mask	= iomd_mask_irq_fiq,
1121da177e4SLinus Torvalds 	.unmask = iomd_unmask_irq_fiq,
1131da177e4SLinus Torvalds };
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds void __init rpc_init_irq(void)
1161da177e4SLinus Torvalds {
1171da177e4SLinus Torvalds 	unsigned int irq, flags;
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_IRQMASKA);
1201da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_IRQMASKB);
1211da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_FIQMASK);
1221da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_DMAMASK);
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 	for (irq = 0; irq < NR_IRQS; irq++) {
1251da177e4SLinus Torvalds 		flags = IRQF_VALID;
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 		if (irq <= 6 || (irq >= 9 && irq <= 15))
1281da177e4SLinus Torvalds 			flags |= IRQF_PROBE;
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds 		if (irq == 21 || (irq >= 16 && irq <= 19) ||
1311da177e4SLinus Torvalds 		    irq == IRQ_KEYBOARDTX)
1321da177e4SLinus Torvalds 			flags |= IRQF_NOAUTOEN;
1331da177e4SLinus Torvalds 
1341da177e4SLinus Torvalds 		switch (irq) {
1351da177e4SLinus Torvalds 		case 0 ... 7:
1361da177e4SLinus Torvalds 			set_irq_chip(irq, &iomd_a_chip);
13710dd5ce2SRussell King 			set_irq_handler(irq, handle_level_irq);
1381da177e4SLinus Torvalds 			set_irq_flags(irq, flags);
1391da177e4SLinus Torvalds 			break;
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 		case 8 ... 15:
1421da177e4SLinus Torvalds 			set_irq_chip(irq, &iomd_b_chip);
14310dd5ce2SRussell King 			set_irq_handler(irq, handle_level_irq);
1441da177e4SLinus Torvalds 			set_irq_flags(irq, flags);
1451da177e4SLinus Torvalds 			break;
1461da177e4SLinus Torvalds 
1471da177e4SLinus Torvalds 		case 16 ... 21:
1481da177e4SLinus Torvalds 			set_irq_chip(irq, &iomd_dma_chip);
14910dd5ce2SRussell King 			set_irq_handler(irq, handle_level_irq);
1501da177e4SLinus Torvalds 			set_irq_flags(irq, flags);
1511da177e4SLinus Torvalds 			break;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 		case 64 ... 71:
1541da177e4SLinus Torvalds 			set_irq_chip(irq, &iomd_fiq_chip);
1551da177e4SLinus Torvalds 			set_irq_flags(irq, IRQF_VALID);
1561da177e4SLinus Torvalds 			break;
1571da177e4SLinus Torvalds 		}
1581da177e4SLinus Torvalds 	}
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	init_FIQ();
1611da177e4SLinus Torvalds }
1621da177e4SLinus Torvalds 
163