^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright 2003-2005 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // http://www.simtec.co.uk/products/EB2410ITX/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/mach-types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/mach/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "regs-irq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <mach/irqs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "bast.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define irqdbf(x...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define irqdbf2(x...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* handle PC104 ISA interrupts from the system CPLD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* table of ISA irq nos to the relevant mask... zero means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * the irq is not implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const unsigned char bast_pc104_irqmasks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 0, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 0, /* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 0, /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 1, /* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 0, /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 2, /* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 0, /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 4, /* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 0, /* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 0, /* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 8, /* 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 0, /* 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 0, /* 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 0, /* 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 0, /* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 0, /* 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static const unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) bast_pc104_mask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) temp = __raw_readb(BAST_VA_PC104_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) temp &= ~bast_pc104_irqmasks[data->irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bast_pc104_maskack(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct irq_desc *desc = irq_to_desc(BAST_IRQ_ISA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) bast_pc104_mask(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) desc->irq_data.chip->irq_ack(&desc->irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) bast_pc104_unmask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned long temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) temp = __raw_readb(BAST_VA_PC104_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) temp |= bast_pc104_irqmasks[data->irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static struct irq_chip bast_pc104_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .irq_mask = bast_pc104_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .irq_unmask = bast_pc104_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .irq_ack = bast_pc104_maskack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void bast_irq_pc104_demux(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned int irqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (unlikely(stat == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* ack if we get an irq with nothing (ie, startup) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) desc->irq_data.chip->irq_ack(&desc->irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* handle the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) for (i = 0; stat != 0; i++, stat >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (stat & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) irqno = bast_pc104_irqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) generic_handle_irq(irqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static __init int bast_irq_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (machine_is_bast()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* zap all the IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) __raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) irq_set_chained_handler(BAST_IRQ_ISA, bast_irq_pc104_demux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* register our IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int irqno = bast_pc104_irqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) irq_set_chip_and_handler(irqno, &bast_pc104_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) irq_clear_status_flags(irqno, IRQ_NOREQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) arch_initcall(bast_irq_init);