Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * eisa.c - provide support for EISA adapters in PA-RISC machines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (c) 2001 Daniel Engstrom <5116@telia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * There are two distinct EISA adapters.  Mongoose is found in machines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * before the 712; then the Wax ASIC is used.  To complicate matters, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Wax ASIC also includes a PS/2 and RS-232 controller, but those are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * dealt with elsewhere; this file is concerned only with the EISA portions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * of Wax.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * HINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * To allow an ISA card to work properly in the EISA slot you need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * set an edge trigger level. This may be done on the palo command line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * by adding the kernel parameter "eisa_irq_edge=n,n2,[...]]", with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * n and n2 as the irq levels you want to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Example: "eisa_irq_edge=10,11" allows ISA cards to operate at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * irq levels 10 and 11.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/eisa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <asm/hardware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <asm/parisc-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <asm/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <asm/eisa_bus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <asm/eisa_eeprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include "iommu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define EISA_DBG(msg, arg...) printk(KERN_DEBUG "eisa: " msg, ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define EISA_DBG(msg, arg...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define SNAKES_EEPROM_BASE_ADDR 0xF0810400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define MIRAGE_EEPROM_BASE_ADDR 0xF00C0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static DEFINE_SPINLOCK(eisa_irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) void __iomem *eisa_eeprom_addr __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /* We can only have one EISA adapter in the system because neither
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * implementation can be flexed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static struct eisa_ba {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct pci_hba_data	hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	unsigned long eeprom_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct eisa_root_device root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) } eisa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) /* Port ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static inline unsigned long eisa_permute(unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (port & 0x300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		return 0xfc000000 | ((port & 0xfc00) >> 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			| ((port & 0x3f8) << 9) | (port & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return 0xfc000000 | port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) unsigned char eisa_in8(unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (EISA_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return gsc_readb(eisa_permute(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) unsigned short eisa_in16(unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (EISA_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		return le16_to_cpu(gsc_readw(eisa_permute(port)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) unsigned int eisa_in32(unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (EISA_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		return le32_to_cpu(gsc_readl(eisa_permute(port)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void eisa_out8(unsigned char data, unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (EISA_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		gsc_writeb(data, eisa_permute(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void eisa_out16(unsigned short data, unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (EISA_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		gsc_writew(cpu_to_le16(data), eisa_permute(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void eisa_out32(unsigned int data, unsigned short port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (EISA_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		gsc_writel(cpu_to_le32(data), eisa_permute(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #ifndef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* We call these directly without PCI.  See asm/io.h. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) EXPORT_SYMBOL(eisa_in8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) EXPORT_SYMBOL(eisa_in16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) EXPORT_SYMBOL(eisa_in32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) EXPORT_SYMBOL(eisa_out8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) EXPORT_SYMBOL(eisa_out16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) EXPORT_SYMBOL(eisa_out32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Interrupt handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* cached interrupt mask registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int master_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int slave_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* the trig level can be set with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * eisa_irq_edge=n,n,n commandline parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * We should really read this from the EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * in the furure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* irq 13,8,2,1,0 must be edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* called by free irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void eisa_mask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	unsigned int irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	EISA_DBG("disable irq %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/* just mask for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	spin_lock_irqsave(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)         if (irq & 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		slave_mask |= (1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		eisa_out8(slave_mask, 0xa1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		master_mask |= (1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		eisa_out8(master_mask, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* called by request irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void eisa_unmask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	unsigned int irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	EISA_DBG("enable irq %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	spin_lock_irqsave(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)         if (irq & 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		slave_mask &= ~(1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		eisa_out8(slave_mask, 0xa1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		master_mask &= ~(1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		eisa_out8(master_mask, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct irq_chip eisa_interrupt_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	.name		=	"EISA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	.irq_unmask	=	eisa_unmask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	.irq_mask	=	eisa_mask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	spin_lock_irqsave(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	/* read IRR command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	eisa_out8(0x0a, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	eisa_out8(0x0a, 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	EISA_DBG("irq IAR %02x 8259-1 irr %02x 8259-2 irr %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		   irq, eisa_in8(0x20), eisa_in8(0xa0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/* read ISR command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	eisa_out8(0x0a, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	eisa_out8(0x0a, 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	EISA_DBG("irq 8259-1 isr %02x imr %02x 8259-2 isr %02x imr %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		 eisa_in8(0x20), eisa_in8(0x21), eisa_in8(0xa0), eisa_in8(0xa1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	irq &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* mask irq and write eoi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (irq & 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		slave_mask |= (1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		eisa_out8(slave_mask, 0xa1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		eisa_out8(0x60 | (irq&7),0xa0);/* 'Specific EOI' to slave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		eisa_out8(0x62, 0x20);	/* 'Specific EOI' to master-IRQ2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		master_mask |= (1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		eisa_out8(master_mask, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		eisa_out8(0x60|irq, 0x20);	/* 'Specific EOI' to master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	spin_lock_irqsave(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	/* unmask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)         if (irq & 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		slave_mask &= ~(1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		eisa_out8(slave_mask, 0xa1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		master_mask &= ~(1 << (irq&7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		eisa_out8(master_mask, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static irqreturn_t dummy_irq2_handler(int _, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	printk(KERN_ALERT "eisa: uhh, irq2?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void init_eisa_pic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	spin_lock_irqsave(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	eisa_out8(0xff, 0x21); /* mask during init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	eisa_out8(0xff, 0xa1); /* mask during init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/* master pic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	eisa_out8(0x11, 0x20); /* ICW1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	eisa_out8(0x00, 0x21); /* ICW2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	eisa_out8(0x04, 0x21); /* ICW3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	eisa_out8(0x01, 0x21); /* ICW4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	eisa_out8(0x40, 0x20); /* OCW2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	/* slave pic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	eisa_out8(0x11, 0xa0); /* ICW1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	eisa_out8(0x08, 0xa1); /* ICW2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	eisa_out8(0x02, 0xa1); /* ICW3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	eisa_out8(0x01, 0xa1); /* ICW4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	eisa_out8(0x40, 0xa0); /* OCW2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	slave_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	master_mask = 0xfb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	eisa_out8(slave_mask, 0xa1); /* OCW1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	eisa_out8(master_mask, 0x21); /* OCW1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	/* setup trig level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	EISA_DBG("EISA edge/level %04x\n", eisa_irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	eisa_out8(eisa_irq_level&0xff, 0x4d0); /* Set all irq's to edge  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	eisa_out8((eisa_irq_level >> 8) & 0xff, 0x4d1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	EISA_DBG("pic0 edge/level %02x\n", eisa_in8(0x4d0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	EISA_DBG("pic1 edge/level %02x\n", eisa_in8(0x4d1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Device initialisation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #define is_mongoose(dev) (dev->id.sversion == 0x00076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int __init eisa_probe(struct parisc_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int i, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		name, (unsigned long)dev->hpa.start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	eisa_dev.hba.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	eisa_dev.hba.lmmio_space.name = "EISA";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	eisa_dev.hba.lmmio_space.start = F_EXTEND(0xfc000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	eisa_dev.hba.lmmio_space.end = F_EXTEND(0xffbfffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	eisa_dev.hba.lmmio_space.flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	result = ccio_request_resource(dev, &eisa_dev.hba.lmmio_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		printk(KERN_ERR "EISA: failed to claim EISA Bus address space!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	eisa_dev.hba.io_space.name = "EISA";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	eisa_dev.hba.io_space.start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	eisa_dev.hba.io_space.end = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	eisa_dev.hba.lmmio_space.flags = IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	result = request_resource(&ioport_resource, &eisa_dev.hba.io_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		printk(KERN_ERR "EISA: failed to claim EISA Bus port space!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	pcibios_register_hba(&eisa_dev.hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	result = request_irq(dev->irq, eisa_irq, IRQF_SHARED, "EISA", &eisa_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		printk(KERN_ERR "EISA: request_irq failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		goto error_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	/* Reserve IRQ2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (request_irq(2, dummy_irq2_handler, 0, "cascade", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		pr_err("Failed to request irq 2 (cascade)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		irq_set_chip_and_handler(i, &eisa_interrupt_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 					 handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	EISA_bus = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (dev->num_addrs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		/* newer firmware hand out the eeprom address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		eisa_dev.eeprom_addr = dev->addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		/* old firmware, need to figure out the box */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		if (is_mongoose(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			eisa_dev.eeprom_addr = SNAKES_EEPROM_BASE_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (!eisa_eeprom_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		result = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		printk(KERN_ERR "EISA: ioremap failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		goto error_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			&eisa_dev.hba.lmmio_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	init_eisa_pic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	if (result >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		/* FIXME : Don't enumerate the bus twice. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		eisa_dev.root.dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		dev_set_drvdata(&dev->dev, &eisa_dev.root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		eisa_dev.root.bus_base_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		eisa_dev.root.res = &eisa_dev.hba.io_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		eisa_dev.root.slots = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		eisa_dev.root.dma_mask = 0xffffffff; /* wild guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		if (eisa_root_register (&eisa_dev.root)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			printk(KERN_ERR "EISA: Failed to register EISA root\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			result = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) error_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	iounmap(eisa_eeprom_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) error_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	free_irq(dev->irq, &eisa_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) error_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	release_resource(&eisa_dev.hba.io_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static const struct parisc_device_id eisa_tbl[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00076 }, /* Mongoose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00090 }, /* Wax EISA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) MODULE_DEVICE_TABLE(parisc, eisa_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static struct parisc_driver eisa_driver __refdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	.name =		"eisa_ba",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	.id_table =	eisa_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	.probe =	eisa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) void __init eisa_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	register_parisc_driver(&eisa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static unsigned int eisa_irq_configured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) void eisa_make_irq_level(int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	if (eisa_irq_configured& (1<<num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		       "IRQ %d polarity configured twice (last to level)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		       num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	eisa_irq_level |= (1<<num); /* set the corresponding bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	eisa_irq_configured |= (1<<num); /* set the corresponding bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) void eisa_make_irq_edge(int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	if (eisa_irq_configured& (1<<num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		       "IRQ %d polarity configured twice (last to edge)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		       num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	eisa_irq_level &= ~(1<<num); /* clear the corresponding bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	eisa_irq_configured |= (1<<num); /* set the corresponding bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int __init eisa_irq_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	char *cur = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	EISA_DBG("IRQ setup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	while (cur != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		char *pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		val = (int) simple_strtoul(cur, &pe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		if (val > 15 || val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			printk(KERN_ERR "eisa: EISA irq value are 0-15\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		if (val == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			val = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		eisa_make_irq_edge(val); /* clear the corresponding bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		EISA_DBG("setting IRQ %d to edge-triggered mode\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		if ((cur = strchr(cur, ','))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			cur++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) __setup("eisa_irq_edge=", eisa_irq_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)