xref: /openbmc/linux/arch/arm/mach-rpc/irq.c (revision 63a0666b)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds #include <linux/init.h>
31da177e4SLinus Torvalds #include <linux/list.h>
4fced80c7SRussell King #include <linux/io.h>
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds #include <asm/mach/irq.h>
71da177e4SLinus Torvalds #include <asm/hardware/iomd.h>
81da177e4SLinus Torvalds #include <asm/irq.h>
978cbaacaSRob Herring #include <asm/fiq.h>
101da177e4SLinus Torvalds 
119a364da7SLennert Buytenhek static void iomd_ack_irq_a(struct irq_data *d)
121da177e4SLinus Torvalds {
131da177e4SLinus Torvalds 	unsigned int val, mask;
141da177e4SLinus Torvalds 
159a364da7SLennert Buytenhek 	mask = 1 << d->irq;
161da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKA);
171da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
181da177e4SLinus Torvalds 	iomd_writeb(mask, IOMD_IRQCLRA);
191da177e4SLinus Torvalds }
201da177e4SLinus Torvalds 
219a364da7SLennert Buytenhek static void iomd_mask_irq_a(struct irq_data *d)
221da177e4SLinus Torvalds {
231da177e4SLinus Torvalds 	unsigned int val, mask;
241da177e4SLinus Torvalds 
259a364da7SLennert Buytenhek 	mask = 1 << d->irq;
261da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKA);
271da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
281da177e4SLinus Torvalds }
291da177e4SLinus Torvalds 
309a364da7SLennert Buytenhek static void iomd_unmask_irq_a(struct irq_data *d)
311da177e4SLinus Torvalds {
321da177e4SLinus Torvalds 	unsigned int val, mask;
331da177e4SLinus Torvalds 
349a364da7SLennert Buytenhek 	mask = 1 << d->irq;
351da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKA);
361da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_IRQMASKA);
371da177e4SLinus Torvalds }
381da177e4SLinus Torvalds 
3910dd5ce2SRussell King static struct irq_chip iomd_a_chip = {
409a364da7SLennert Buytenhek 	.irq_ack	= iomd_ack_irq_a,
419a364da7SLennert Buytenhek 	.irq_mask	= iomd_mask_irq_a,
429a364da7SLennert Buytenhek 	.irq_unmask	= iomd_unmask_irq_a,
431da177e4SLinus Torvalds };
441da177e4SLinus Torvalds 
459a364da7SLennert Buytenhek static void iomd_mask_irq_b(struct irq_data *d)
461da177e4SLinus Torvalds {
471da177e4SLinus Torvalds 	unsigned int val, mask;
481da177e4SLinus Torvalds 
499a364da7SLennert Buytenhek 	mask = 1 << (d->irq & 7);
501da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKB);
511da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
521da177e4SLinus Torvalds }
531da177e4SLinus Torvalds 
549a364da7SLennert Buytenhek static void iomd_unmask_irq_b(struct irq_data *d)
551da177e4SLinus Torvalds {
561da177e4SLinus Torvalds 	unsigned int val, mask;
571da177e4SLinus Torvalds 
589a364da7SLennert Buytenhek 	mask = 1 << (d->irq & 7);
591da177e4SLinus Torvalds 	val = iomd_readb(IOMD_IRQMASKB);
601da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_IRQMASKB);
611da177e4SLinus Torvalds }
621da177e4SLinus Torvalds 
6310dd5ce2SRussell King static struct irq_chip iomd_b_chip = {
649a364da7SLennert Buytenhek 	.irq_ack	= iomd_mask_irq_b,
659a364da7SLennert Buytenhek 	.irq_mask	= iomd_mask_irq_b,
669a364da7SLennert Buytenhek 	.irq_unmask	= iomd_unmask_irq_b,
671da177e4SLinus Torvalds };
681da177e4SLinus Torvalds 
699a364da7SLennert Buytenhek static void iomd_mask_irq_dma(struct irq_data *d)
701da177e4SLinus Torvalds {
711da177e4SLinus Torvalds 	unsigned int val, mask;
721da177e4SLinus Torvalds 
739a364da7SLennert Buytenhek 	mask = 1 << (d->irq & 7);
741da177e4SLinus Torvalds 	val = iomd_readb(IOMD_DMAMASK);
751da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_DMAMASK);
761da177e4SLinus Torvalds }
771da177e4SLinus Torvalds 
789a364da7SLennert Buytenhek static void iomd_unmask_irq_dma(struct irq_data *d)
791da177e4SLinus Torvalds {
801da177e4SLinus Torvalds 	unsigned int val, mask;
811da177e4SLinus Torvalds 
829a364da7SLennert Buytenhek 	mask = 1 << (d->irq & 7);
831da177e4SLinus Torvalds 	val = iomd_readb(IOMD_DMAMASK);
841da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_DMAMASK);
851da177e4SLinus Torvalds }
861da177e4SLinus Torvalds 
8710dd5ce2SRussell King static struct irq_chip iomd_dma_chip = {
889a364da7SLennert Buytenhek 	.irq_ack	= iomd_mask_irq_dma,
899a364da7SLennert Buytenhek 	.irq_mask	= iomd_mask_irq_dma,
909a364da7SLennert Buytenhek 	.irq_unmask	= iomd_unmask_irq_dma,
911da177e4SLinus Torvalds };
921da177e4SLinus Torvalds 
939a364da7SLennert Buytenhek static void iomd_mask_irq_fiq(struct irq_data *d)
941da177e4SLinus Torvalds {
951da177e4SLinus Torvalds 	unsigned int val, mask;
961da177e4SLinus Torvalds 
979a364da7SLennert Buytenhek 	mask = 1 << (d->irq & 7);
981da177e4SLinus Torvalds 	val = iomd_readb(IOMD_FIQMASK);
991da177e4SLinus Torvalds 	iomd_writeb(val & ~mask, IOMD_FIQMASK);
1001da177e4SLinus Torvalds }
1011da177e4SLinus Torvalds 
1029a364da7SLennert Buytenhek static void iomd_unmask_irq_fiq(struct irq_data *d)
1031da177e4SLinus Torvalds {
1041da177e4SLinus Torvalds 	unsigned int val, mask;
1051da177e4SLinus Torvalds 
1069a364da7SLennert Buytenhek 	mask = 1 << (d->irq & 7);
1071da177e4SLinus Torvalds 	val = iomd_readb(IOMD_FIQMASK);
1081da177e4SLinus Torvalds 	iomd_writeb(val | mask, IOMD_FIQMASK);
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds 
11110dd5ce2SRussell King static struct irq_chip iomd_fiq_chip = {
1129a364da7SLennert Buytenhek 	.irq_ack	= iomd_mask_irq_fiq,
1139a364da7SLennert Buytenhek 	.irq_mask	= iomd_mask_irq_fiq,
1149a364da7SLennert Buytenhek 	.irq_unmask	= iomd_unmask_irq_fiq,
1151da177e4SLinus Torvalds };
1161da177e4SLinus Torvalds 
11778cbaacaSRob Herring extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
11878cbaacaSRob Herring 
1191da177e4SLinus Torvalds void __init rpc_init_irq(void)
1201da177e4SLinus Torvalds {
12163a0666bSRussell King 	unsigned int irq, clr, set;
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_IRQMASKA);
1241da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_IRQMASKB);
1251da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_FIQMASK);
1261da177e4SLinus Torvalds 	iomd_writeb(0, IOMD_DMAMASK);
1271da177e4SLinus Torvalds 
12878cbaacaSRob Herring 	set_fiq_handler(&rpc_default_fiq_start,
12978cbaacaSRob Herring 		&rpc_default_fiq_end - &rpc_default_fiq_start);
13078cbaacaSRob Herring 
1311da177e4SLinus Torvalds 	for (irq = 0; irq < NR_IRQS; irq++) {
132e8d36d5dSRob Herring 		clr = IRQ_NOREQUEST;
13363a0666bSRussell King 		set = 0;
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 		if (irq <= 6 || (irq >= 9 && irq <= 15))
136e8d36d5dSRob Herring 			clr |= IRQ_NOPROBE;
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds 		if (irq == 21 || (irq >= 16 && irq <= 19) ||
1391da177e4SLinus Torvalds 		    irq == IRQ_KEYBOARDTX)
140e8d36d5dSRob Herring 			set |= IRQ_NOAUTOEN;
1411da177e4SLinus Torvalds 
1421da177e4SLinus Torvalds 		switch (irq) {
1431da177e4SLinus Torvalds 		case 0 ... 7:
144f38c02f3SThomas Gleixner 			irq_set_chip_and_handler(irq, &iomd_a_chip,
145f38c02f3SThomas Gleixner 						 handle_level_irq);
146e8d36d5dSRob Herring 			irq_modify_status(irq, clr, set);
1471da177e4SLinus Torvalds 			break;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 		case 8 ... 15:
150f38c02f3SThomas Gleixner 			irq_set_chip_and_handler(irq, &iomd_b_chip,
151f38c02f3SThomas Gleixner 						 handle_level_irq);
152e8d36d5dSRob Herring 			irq_modify_status(irq, clr, set);
1531da177e4SLinus Torvalds 			break;
1541da177e4SLinus Torvalds 
1551da177e4SLinus Torvalds 		case 16 ... 21:
156f38c02f3SThomas Gleixner 			irq_set_chip_and_handler(irq, &iomd_dma_chip,
157f38c02f3SThomas Gleixner 						 handle_level_irq);
158e8d36d5dSRob Herring 			irq_modify_status(irq, clr, set);
1591da177e4SLinus Torvalds 			break;
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds 		case 64 ... 71:
1626845664aSThomas Gleixner 			irq_set_chip(irq, &iomd_fiq_chip);
163e8d36d5dSRob Herring 			irq_modify_status(irq, clr, set);
1641da177e4SLinus Torvalds 			break;
1651da177e4SLinus Torvalds 		}
1661da177e4SLinus Torvalds 	}
1671da177e4SLinus Torvalds 
168bc89663aSShawn Guo 	init_FIQ(FIQ_START);
1691da177e4SLinus Torvalds }
1701da177e4SLinus Torvalds 
171