^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)