495 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* National Semiconductor NS87560UBD Super I/O controller used in3 * HP [BCJ]x000 workstations.4 *5 * This chip is a horrid piece of engineering, and National6 * denies any knowledge of its existence. Thus no datasheet is7 * available off www.national.com. 8 *9 * (C) Copyright 2000 Linuxcare, Inc.10 * (C) Copyright 2000 Linuxcare Canada, Inc.11 * (C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com>12 * (C) Copyright 2000 Alex deVries <alex@onefishtwo.ca>13 * (C) Copyright 2001 John Marvin <jsm fc hp com>14 * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org>15 * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>16 * (C) Copyright 2006 Helge Deller <deller@gmx.de>17 *18 * The initial version of this is by Martin Peterson. Alex deVries19 * has spent a bit of time trying to coax it into working.20 *21 * Major changes to get basic interrupt infrastructure working to22 * hopefully be able to support all SuperIO devices. Currently23 * works with serial. -- John Marvin <jsm@fc.hp.com>24 *25 * Converted superio_init() to be a PCI_FIXUP_FINAL callee.26 * -- Kyle McMartin <kyle@parisc-linux.org>27 */28 29 30/* NOTES:31 * 32 * Function 0 is an IDE controller. It is identical to a PC87415 IDE33 * controller (and identifies itself as such).34 *35 * Function 1 is a "Legacy I/O" controller. Under this function is a36 * whole mess of legacy I/O peripherals. Of course, HP hasn't enabled37 * all the functionality in hardware, but the following is available:38 *39 * Two 16550A compatible serial controllers40 * An IEEE 1284 compatible parallel port41 * A floppy disk controller42 *43 * Function 2 is a USB controller.44 *45 * We must be incredibly careful during initialization. Since all46 * interrupts are routed through function 1 (which is not allowed by47 * the PCI spec), we need to program the PICs on the legacy I/O port48 * *before* we attempt to set up IDE and USB. @#$!&49 *50 * According to HP, devices are only enabled by firmware if they have51 * a physical device connected.52 *53 * Configuration register bits:54 * 0x5A: FDC, SP1, IDE1, SP2, IDE2, PAR, Reserved, P9255 * 0x5B: RTC, 8259, 8254, DMA1, DMA2, KBC, P61, APM56 *57 */58 59#include <linux/errno.h>60#include <linux/init.h>61#include <linux/module.h>62#include <linux/types.h>63#include <linux/interrupt.h>64#include <linux/ioport.h>65#include <linux/serial.h>66#include <linux/pci.h>67#include <linux/parport.h>68#include <linux/parport_pc.h>69#include <linux/termios.h>70#include <linux/tty.h>71#include <linux/serial_core.h>72#include <linux/serial_8250.h>73#include <linux/delay.h>74 75#include <asm/io.h>76#include <asm/hardware.h>77#include <asm/superio.h>78 79static struct superio_device sio_dev;80 81 82#undef DEBUG_SUPERIO_INIT83 84#ifdef DEBUG_SUPERIO_INIT85#define DBG_INIT(x...) printk(x)86#else87#define DBG_INIT(x...)88#endif89 90#define SUPERIO "SuperIO"91#define PFX SUPERIO ": "92 93static irqreturn_t94superio_interrupt(int parent_irq, void *devp)95{96 u8 results;97 u8 local_irq;98 99 /* Poll the 8259 to see if there's an interrupt. */100 outb (OCW3_POLL,IC_PIC1+0);101 102 results = inb(IC_PIC1+0);103 104 /*105 * Bit 7: 1 = active Interrupt; 0 = no Interrupt pending106 * Bits 6-3: zero107 * Bits 2-0: highest priority, active requesting interrupt ID (0-7)108 */109 if ((results & 0x80) == 0) {110 /* I suspect "spurious" interrupts are from unmasking an IRQ.111 * We don't know if an interrupt was/is pending and thus112 * just call the handler for that IRQ as if it were pending.113 */114 return IRQ_NONE;115 }116 117 /* Check to see which device is interrupting */118 local_irq = results & 0x0f;119 120 if (local_irq == 2 || local_irq > 7) {121 printk(KERN_ERR PFX "slave interrupted!\n");122 return IRQ_HANDLED;123 }124 125 if (local_irq == 7) {126 127 /* Could be spurious. Check in service bits */128 129 outb(OCW3_ISR,IC_PIC1+0);130 results = inb(IC_PIC1+0);131 if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */132 printk(KERN_WARNING PFX "spurious interrupt!\n");133 return IRQ_HANDLED;134 }135 }136 137 /* Call the appropriate device's interrupt */138 generic_handle_irq(local_irq);139 140 /* set EOI - forces a new interrupt if a lower priority device141 * still needs service.142 */143 outb((OCW2_SEOI|local_irq),IC_PIC1 + 0);144 return IRQ_HANDLED;145}146 147/* Initialize Super I/O device */148static void149superio_init(struct pci_dev *pcidev)150{151 struct superio_device *sio = &sio_dev;152 struct pci_dev *pdev = sio->lio_pdev;153 u16 word;154 int ret;155 156 if (sio->suckyio_irq_enabled)157 return;158 159 BUG_ON(!pdev);160 BUG_ON(!sio->usb_pdev);161 162 /* use the IRQ iosapic found for USB INT D... */163 pdev->irq = sio->usb_pdev->irq;164 165 /* ...then properly fixup the USB to point at suckyio PIC */166 sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);167 168 printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n",169 pci_name(pdev), pdev->irq);170 171 pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);172 sio->sp1_base &= ~1;173 printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base);174 175 pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base);176 sio->sp2_base &= ~1;177 printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base);178 179 pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base);180 sio->pp_base &= ~1;181 printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base);182 183 pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base);184 sio->fdc_base &= ~1;185 printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base);186 pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base);187 sio->acpi_base &= ~1;188 printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base);189 190 request_region (IC_PIC1, 0x1f, "pic1");191 request_region (IC_PIC2, 0x1f, "pic2");192 request_region (sio->acpi_base, 0x1f, "acpi");193 194 /* Enable the legacy I/O function */195 pci_read_config_word (pdev, PCI_COMMAND, &word);196 word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;197 pci_write_config_word (pdev, PCI_COMMAND, word);198 199 pci_set_master (pdev);200 ret = pci_enable_device(pdev);201 BUG_ON(ret < 0); /* not too much we can do about this... */202 203 /*204 * Next project is programming the onboard interrupt controllers.205 * PDC hasn't done this for us, since it's using polled I/O.206 *207 * XXX Use dword writes to avoid bugs in Elroy or Suckyio Config208 * space access. PCI is by nature a 32-bit bus and config209 * space can be sensitive to that.210 */211 212 /* 0x64 - 0x67 :213 DMA Rtg 2214 DMA Rtg 3215 DMA Chan Ctl216 TRIGGER_1 == 0x82 USB & IDE level triggered, rest to edge217 */218 pci_write_config_dword (pdev, 0x64, 0x82000000U);219 220 /* 0x68 - 0x6b :221 TRIGGER_2 == 0x00 all edge triggered (not used)222 CFG_IR_SER == 0x43 SerPort1 = IRQ3, SerPort2 = IRQ4223 CFG_IR_PF == 0x65 ParPort = IRQ5, FloppyCtlr = IRQ6224 CFG_IR_IDE == 0x07 IDE1 = IRQ7, reserved225 */226 pci_write_config_dword (pdev, TRIGGER_2, 0x07654300U);227 228 /* 0x6c - 0x6f :229 CFG_IR_INTAB == 0x00230 CFG_IR_INTCD == 0x10 USB = IRQ1231 CFG_IR_PS2 == 0x00232 CFG_IR_FXBUS == 0x00233 */234 pci_write_config_dword (pdev, CFG_IR_INTAB, 0x00001000U);235 236 /* 0x70 - 0x73 :237 CFG_IR_USB == 0x00 not used. USB is connected to INTD.238 CFG_IR_ACPI == 0x00 not used.239 DMA Priority == 0x4c88 Power on default value. NFC.240 */241 pci_write_config_dword (pdev, CFG_IR_USB, 0x4c880000U);242 243 /* PIC1 Initialization Command Word register programming */244 outb (0x11,IC_PIC1+0); /* ICW1: ICW4 write req | ICW1 */245 outb (0x00,IC_PIC1+1); /* ICW2: interrupt vector table - not used */246 outb (0x04,IC_PIC1+1); /* ICW3: Cascade */247 outb (0x01,IC_PIC1+1); /* ICW4: x86 mode */248 249 /* PIC1 Program Operational Control Words */250 outb (0xff,IC_PIC1+1); /* OCW1: Mask all interrupts */251 outb (0xc2,IC_PIC1+0); /* OCW2: priority (3-7,0-2) */252 253 /* PIC2 Initialization Command Word register programming */254 outb (0x11,IC_PIC2+0); /* ICW1: ICW4 write req | ICW1 */255 outb (0x00,IC_PIC2+1); /* ICW2: N/A */256 outb (0x02,IC_PIC2+1); /* ICW3: Slave ID code */257 outb (0x01,IC_PIC2+1); /* ICW4: x86 mode */258 259 /* Program Operational Control Words */260 outb (0xff,IC_PIC1+1); /* OCW1: Mask all interrupts */261 outb (0x68,IC_PIC1+0); /* OCW3: OCW3 select | ESMM | SMM */262 263 /* Write master mask reg */264 outb (0xff,IC_PIC1+1);265 266 /* Setup USB power regulation */267 outb(1, sio->acpi_base + USB_REG_CR);268 if (inb(sio->acpi_base + USB_REG_CR) & 1)269 printk(KERN_INFO PFX "USB regulator enabled\n");270 else271 printk(KERN_ERR PFX "USB regulator not initialized!\n");272 273 if (request_irq(pdev->irq, superio_interrupt, 0,274 SUPERIO, (void *)sio)) {275 276 printk(KERN_ERR PFX "could not get irq\n");277 BUG();278 return;279 }280 281 sio->suckyio_irq_enabled = 1;282}283DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);284 285static void superio_mask_irq(struct irq_data *d)286{287 unsigned int irq = d->irq;288 u8 r8;289 290 if ((irq < 1) || (irq == 2) || (irq > 7)) {291 printk(KERN_ERR PFX "Illegal irq number.\n");292 BUG();293 return;294 }295 296 /* Mask interrupt */297 298 r8 = inb(IC_PIC1+1);299 r8 |= (1 << irq);300 outb (r8,IC_PIC1+1);301}302 303static void superio_unmask_irq(struct irq_data *d)304{305 unsigned int irq = d->irq;306 u8 r8;307 308 if ((irq < 1) || (irq == 2) || (irq > 7)) {309 printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq);310 BUG();311 return;312 }313 314 /* Unmask interrupt */315 r8 = inb(IC_PIC1+1);316 r8 &= ~(1 << irq);317 outb (r8,IC_PIC1+1);318}319 320static struct irq_chip superio_interrupt_type = {321 .name = SUPERIO,322 .irq_unmask = superio_unmask_irq,323 .irq_mask = superio_mask_irq,324};325 326#ifdef DEBUG_SUPERIO_INIT327static unsigned short expected_device[3] = {328 PCI_DEVICE_ID_NS_87415,329 PCI_DEVICE_ID_NS_87560_LIO,330 PCI_DEVICE_ID_NS_87560_USB331};332#endif333 334int superio_fixup_irq(struct pci_dev *pcidev)335{336 int local_irq, i;337 338#ifdef DEBUG_SUPERIO_INIT339 int fn;340 fn = PCI_FUNC(pcidev->devfn);341 342 /* Verify the function number matches the expected device id. */343 if (expected_device[fn] != pcidev->device) {344 BUG();345 return -1;346 }347 printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n",348 pci_name(pcidev),349 pcidev->vendor, pcidev->device,350 __builtin_return_address(0));351#endif352 353 for (i = 0; i < 16; i++) {354 irq_set_chip_and_handler(i, &superio_interrupt_type,355 handle_simple_irq);356 }357 358 /*359 * We don't allocate a SuperIO irq for the legacy IO function,360 * since it is a "bridge". Instead, we will allocate irq's for361 * each legacy device as they are initialized.362 */363 364 switch(pcidev->device) {365 case PCI_DEVICE_ID_NS_87415: /* Function 0 */366 local_irq = IDE_IRQ;367 break;368 case PCI_DEVICE_ID_NS_87560_LIO: /* Function 1 */369 sio_dev.lio_pdev = pcidev; /* save for superio_init() */370 return -1;371 case PCI_DEVICE_ID_NS_87560_USB: /* Function 2 */372 sio_dev.usb_pdev = pcidev; /* save for superio_init() */373 local_irq = USB_IRQ;374 break;375 default:376 local_irq = -1;377 BUG();378 break;379 }380 381 return local_irq;382}383 384static void __init superio_serial_init(void)385{386#ifdef CONFIG_SERIAL_8250387 int retval;388 struct uart_port serial_port;389 390 memset(&serial_port, 0, sizeof(serial_port));391 serial_port.iotype = UPIO_PORT;392 serial_port.type = PORT_16550A;393 serial_port.uartclk = 115200*16;394 serial_port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE |395 UPF_BOOT_AUTOCONF;396 397 /* serial port #1 */398 serial_port.iobase = sio_dev.sp1_base;399 serial_port.irq = SP1_IRQ;400 serial_port.line = 0;401 retval = early_serial_setup(&serial_port);402 if (retval < 0) {403 printk(KERN_WARNING PFX "Register Serial #0 failed.\n");404 return;405 }406 407 /* serial port #2 */408 serial_port.iobase = sio_dev.sp2_base;409 serial_port.irq = SP2_IRQ;410 serial_port.line = 1;411 retval = early_serial_setup(&serial_port);412 if (retval < 0)413 printk(KERN_WARNING PFX "Register Serial #1 failed.\n");414#endif /* CONFIG_SERIAL_8250 */415}416 417 418static void __init superio_parport_init(void)419{420#ifdef CONFIG_PARPORT_PC421 if (!parport_pc_probe_port(sio_dev.pp_base,422 0 /*base_hi*/,423 PAR_IRQ, 424 PARPORT_DMA_NONE /* dma */,425 NULL /*struct pci_dev* */,426 0 /* shared irq flags */))427 428 printk(KERN_WARNING PFX "Probing parallel port failed.\n");429#endif /* CONFIG_PARPORT_PC */430}431 432 433static void superio_fixup_pci(struct pci_dev *pdev)434{435 u8 prog;436 437 pdev->class |= 0x5;438 pci_write_config_byte(pdev, PCI_CLASS_PROG, pdev->class);439 440 pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);441 printk("PCI: Enabled native mode for NS87415 (pif=0x%x)\n", prog);442}443DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);444 445 446static int __init447superio_probe(struct pci_dev *dev, const struct pci_device_id *id)448{449 struct superio_device *sio = &sio_dev;450 451 /*452 ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a453 ** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000454 ** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310455 */456 DBG_INIT("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n",457 pci_name(dev),458 dev->vendor, dev->device,459 dev->subsystem_vendor, dev->subsystem_device,460 dev->class);461 462 BUG_ON(!sio->suckyio_irq_enabled); /* Enabled by PCI_FIXUP_FINAL */463 464 if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */465 superio_parport_init();466 superio_serial_init();467 /* REVISIT XXX : superio_fdc_init() ? */468 return 0;469 } else if (dev->device == PCI_DEVICE_ID_NS_87415) { /* Function 0 */470 DBG_INIT("superio_probe: ignoring IDE 87415\n");471 } else if (dev->device == PCI_DEVICE_ID_NS_87560_USB) { /* Function 2 */472 DBG_INIT("superio_probe: ignoring USB OHCI controller\n");473 } else {474 DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");475 }476 477 /* Let appropriate other driver claim this device. */478 return -ENODEV;479}480 481static const struct pci_device_id superio_tbl[] __initconst = {482 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },483 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },484 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },485 { 0, }486};487 488static struct pci_driver superio_driver __refdata = {489 .name = SUPERIO,490 .id_table = superio_tbl,491 .probe = superio_probe,492};493 494module_pci_driver(superio_driver);495