// SPDX-License-Identifier: GPL-2.0-or-later /* * eisa.c - provide support for EISA adapters in PA-RISC machines * * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard * Copyright (c) 2001 Daniel Engstrom <5116@telia.com> * * There are two distinct EISA adapters. Mongoose is found in machines * before the 712; then the Wax ASIC is used. To complicate matters, the * Wax ASIC also includes a PS/2 and RS-232 controller, but those are * dealt with elsewhere; this file is concerned only with the EISA portions * of Wax. * * HINT: * ----- * To allow an ISA card to work properly in the EISA slot you need to * set an edge trigger level. This may be done on the palo command line * by adding the kernel parameter "eisa_irq_edge=n,n2,[...]]", with * n and n2 as the irq levels you want to use. * * Example: "eisa_irq_edge=10,11" allows ISA cards to operate at * irq levels 10 and 11.
*/
/* We can only have one EISA adapter in the system because neither * implementation can be flexed.
*/ staticstruct eisa_ba { struct pci_hba_data hba; unsignedlong eeprom_addr; struct eisa_root_device root;
} eisa_dev;
#ifndef CONFIG_PCI /* We call these directly without PCI. See asm/io.h. */
EXPORT_SYMBOL(eisa_in8);
EXPORT_SYMBOL(eisa_in16);
EXPORT_SYMBOL(eisa_in32);
EXPORT_SYMBOL(eisa_out8);
EXPORT_SYMBOL(eisa_out16);
EXPORT_SYMBOL(eisa_out32); #endif
/* the trig level can be set with the * eisa_irq_edge=n,n,n commandline parameter * We should really read this from the EEPROM * in the furure.
*/ /* irq 13,8,2,1,0 must be edge */ staticunsignedint eisa_irq_level __read_mostly; /* default to edge triggered */
/* called by free irq */ staticvoid eisa_mask_irq(struct irq_data *d)
{ unsignedint irq = d->irq; unsignedlong flags;
eisa_dev.hba.lmmio_space.name = "EISA";
eisa_dev.hba.lmmio_space.start = F_EXTEND(0xfc000000);
eisa_dev.hba.lmmio_space.end = F_EXTEND(0xffbfffff);
eisa_dev.hba.lmmio_space.flags = IORESOURCE_MEM;
result = ccio_request_resource(dev, &eisa_dev.hba.lmmio_space); if (result < 0) {
printk(KERN_ERR "EISA: failed to claim EISA Bus address space!\n"); return result;
}
eisa_dev.hba.io_space.name = "EISA";
eisa_dev.hba.io_space.start = 0;
eisa_dev.hba.io_space.end = 0xffff;
eisa_dev.hba.lmmio_space.flags = IORESOURCE_IO;
result = request_resource(&ioport_resource, &eisa_dev.hba.io_space); if (result < 0) {
printk(KERN_ERR "EISA: failed to claim EISA Bus port space!\n"); return result;
}
pcibios_register_hba(&eisa_dev.hba);
result = request_irq(dev->irq, eisa_irq, IRQF_SHARED, "EISA", &eisa_dev); if (result) {
printk(KERN_ERR "EISA: request_irq failed!\n"); goto error_release;
}
/* Reserve IRQ2 */ if (request_irq(2, dummy_irq2_handler, 0, "cascade", NULL))
pr_err("Failed to request irq 2 (cascade)\n"); for (i = 0; i < 16; i++) {
irq_set_chip_and_handler(i, &eisa_interrupt_type,
handle_simple_irq);
}
EISA_bus = 1;
if (dev->num_addrs) { /* newer firmware hand out the eeprom address */
eisa_dev.eeprom_addr = dev->addr[0];
} else { /* old firmware, need to figure out the box */ if (is_mongoose(dev)) {
eisa_dev.eeprom_addr = SNAKES_EEPROM_BASE_ADDR;
} else {
eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR;
}
}
eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); if (!eisa_eeprom_addr) {
result = -ENOMEM;
printk(KERN_ERR "EISA: ioremap failed!\n"); goto error_free_irq;
}
result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space,
&eisa_dev.hba.lmmio_space);
init_eisa_pic();
if (result >= 0) { /* FIXME : Don't enumerate the bus twice. */
eisa_dev.root.dev = &dev->dev;
dev_set_drvdata(&dev->dev, &eisa_dev.root);
eisa_dev.root.bus_base_addr = 0;
eisa_dev.root.res = &eisa_dev.hba.io_space;
eisa_dev.root.slots = result;
eisa_dev.root.dma_mask = 0xffffffff; /* wild guess */ if (eisa_root_register (&eisa_dev.root)) {
printk(KERN_ERR "EISA: Failed to register EISA root\n");
result = -ENOMEM; goto error_iounmap;
}
}
staticunsignedint eisa_irq_configured; void eisa_make_irq_level(int num)
{ if (eisa_irq_configured& (1<<num)) {
printk(KERN_WARNING "IRQ %d polarity configured twice (last to level)\n",
num);
}
eisa_irq_level |= (1<<num); /* set the corresponding bit */
eisa_irq_configured |= (1<<num); /* set the corresponding bit */
}
void eisa_make_irq_edge(int num)
{ if (eisa_irq_configured& (1<<num)) {
printk(KERN_WARNING "IRQ %d polarity configured twice (last to edge)\n",
num);
}
eisa_irq_level &= ~(1<<num); /* clear the corresponding bit */
eisa_irq_configured |= (1<<num); /* set the corresponding bit */
}
EISA_DBG("IRQ setup\n"); while (cur != NULL) { char *pe;
val = (int) simple_strtoul(cur, &pe, 0); if (val > 15 || val < 0) {
printk(KERN_ERR "eisa: EISA irq value are 0-15\n"); continue;
} if (val == 2) {
val = 9;
}
eisa_make_irq_edge(val); /* clear the corresponding bit */
EISA_DBG("setting IRQ %d to edge-triggered mode\n", val);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.