// SPDX-License-Identifier: GPL-2.0-or-later /* National Semiconductor NS87560UBD Super I/O controller used in * HP [BCJ]x000 workstations. * * This chip is a horrid piece of engineering, and National * denies any knowledge of its existence. Thus no datasheet is * available off www.national.com. * * (C) Copyright 2000 Linuxcare, Inc. * (C) Copyright 2000 Linuxcare Canada, Inc. * (C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com> * (C) Copyright 2000 Alex deVries <alex@onefishtwo.ca> * (C) Copyright 2001 John Marvin <jsm fc hp com> * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org> * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> * (C) Copyright 2006 Helge Deller <deller@gmx.de> * * The initial version of this is by Martin Peterson. Alex deVries * has spent a bit of time trying to coax it into working. * * Major changes to get basic interrupt infrastructure working to * hopefully be able to support all SuperIO devices. Currently * works with serial. -- John Marvin <jsm@fc.hp.com> * * Converted superio_init() to be a PCI_FIXUP_FINAL callee. * -- Kyle McMartin <kyle@parisc-linux.org>
*/
/* NOTES: * * Function 0 is an IDE controller. It is identical to a PC87415 IDE * controller (and identifies itself as such). * * Function 1 is a "Legacy I/O" controller. Under this function is a * whole mess of legacy I/O peripherals. Of course, HP hasn't enabled * all the functionality in hardware, but the following is available: * * Two 16550A compatible serial controllers * An IEEE 1284 compatible parallel port * A floppy disk controller * * Function 2 is a USB controller. * * We must be incredibly careful during initialization. Since all * interrupts are routed through function 1 (which is not allowed by * the PCI spec), we need to program the PICs on the legacy I/O port * *before* we attempt to set up IDE and USB. @#$!& * * According to HP, devices are only enabled by firmware if they have * a physical device connected. * * Configuration register bits: * 0x5A: FDC, SP1, IDE1, SP2, IDE2, PAR, Reserved, P92 * 0x5B: RTC, 8259, 8254, DMA1, DMA2, KBC, P61, APM *
*/
/* Poll the 8259 to see if there's an interrupt. */
outb (OCW3_POLL,IC_PIC1+0);
results = inb(IC_PIC1+0);
/* * Bit 7: 1 = active Interrupt; 0 = no Interrupt pending * Bits 6-3: zero * Bits 2-0: highest priority, active requesting interrupt ID (0-7)
*/ if ((results & 0x80) == 0) { /* I suspect "spurious" interrupts are from unmasking an IRQ. * We don't know if an interrupt was/is pending and thus * just call the handler for that IRQ as if it were pending.
*/ return IRQ_NONE;
}
/* Check to see which device is interrupting */
local_irq = results & 0x0f;
outb(OCW3_ISR,IC_PIC1+0);
results = inb(IC_PIC1+0); if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */
printk(KERN_WARNING PFX "spurious interrupt!\n"); return IRQ_HANDLED;
}
}
/* Call the appropriate device's interrupt */
generic_handle_irq(local_irq);
/* set EOI - forces a new interrupt if a lower priority device * still needs service.
*/
outb((OCW2_SEOI|local_irq),IC_PIC1 + 0); return IRQ_HANDLED;
}
/* Enable the legacy I/O function */
pci_read_config_word (pdev, PCI_COMMAND, &word);
word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;
pci_write_config_word (pdev, PCI_COMMAND, word);
pci_set_master (pdev);
ret = pci_enable_device(pdev);
BUG_ON(ret < 0); /* not too much we can do about this... */
/* * Next project is programming the onboard interrupt controllers. * PDC hasn't done this for us, since it's using polled I/O. * * XXX Use dword writes to avoid bugs in Elroy or Suckyio Config * space access. PCI is by nature a 32-bit bus and config * space can be sensitive to that.
*/
/* 0x64 - 0x67 : DMA Rtg 2 DMA Rtg 3 DMA Chan Ctl TRIGGER_1 == 0x82 USB & IDE level triggered, rest to edge
*/
pci_write_config_dword (pdev, 0x64, 0x82000000U);
/* 0x70 - 0x73 : CFG_IR_USB == 0x00 not used. USB is connected to INTD. CFG_IR_ACPI == 0x00 not used. DMA Priority == 0x4c88 Power on default value. NFC.
*/
pci_write_config_dword (pdev, CFG_IR_USB, 0x4c880000U);
int superio_fixup_irq(struct pci_dev *pcidev)
{ int local_irq, i;
#ifdef DEBUG_SUPERIO_INIT int fn;
fn = PCI_FUNC(pcidev->devfn);
/* Verify the function number matches the expected device id. */ if (expected_device[fn] != pcidev->device) {
BUG(); return -1;
}
printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n",
pci_name(pcidev),
pcidev->vendor, pcidev->device,
__builtin_return_address(0)); #endif
for (i = 0; i < 16; i++) {
irq_set_chip_and_handler(i, &superio_interrupt_type,
handle_simple_irq);
}
/* * We don't allocate a SuperIO irq for the legacy IO function, * since it is a "bridge". Instead, we will allocate irq's for * each legacy device as they are initialized.
*/
switch(pcidev->device) { case PCI_DEVICE_ID_NS_87415: /* Function 0 */
local_irq = IDE_IRQ; break; case PCI_DEVICE_ID_NS_87560_LIO: /* Function 1 */
sio_dev.lio_pdev = pcidev; /* save for superio_init() */ return -1; case PCI_DEVICE_ID_NS_87560_USB: /* Function 2 */
sio_dev.usb_pdev = pcidev; /* save for superio_init() */
local_irq = USB_IRQ; break; default:
local_irq = -1;
BUG(); break;
}
/* ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a ** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000 ** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310
*/
DBG_INIT("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n",
pci_name(dev),
dev->vendor, dev->device,
dev->subsystem_vendor, dev->subsystem_device,
dev->class);
BUG_ON(!sio->suckyio_irq_enabled); /* Enabled by PCI_FIXUP_FINAL */
if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */
superio_parport_init();
superio_serial_init(); /* REVISIT XXX : superio_fdc_init() ? */ return 0;
} elseif (dev->device == PCI_DEVICE_ID_NS_87415) { /* Function 0 */
DBG_INIT("superio_probe: ignoring IDE 87415\n");
} elseif (dev->device == PCI_DEVICE_ID_NS_87560_USB) { /* Function 2 */
DBG_INIT("superio_probe: ignoring USB OHCI controller\n");
} else {
DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");
}
/* Let appropriate other driver claim this device. */ return -ENODEV;
}
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.