Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*      National Semiconductor NS87560UBD Super I/O controller used in
0003  *      HP [BCJ]x000 workstations.
0004  *
0005  *      This chip is a horrid piece of engineering, and National
0006  *      denies any knowledge of its existence. Thus no datasheet is
0007  *      available off www.national.com. 
0008  *
0009  *  (C) Copyright 2000 Linuxcare, Inc.
0010  *  (C) Copyright 2000 Linuxcare Canada, Inc.
0011  *  (C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com>
0012  *  (C) Copyright 2000 Alex deVries <alex@onefishtwo.ca>
0013  *      (C) Copyright 2001 John Marvin <jsm fc hp com>
0014  *      (C) Copyright 2003 Grant Grundler <grundler parisc-linux org>
0015  *  (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>
0016  *  (C) Copyright 2006 Helge Deller <deller@gmx.de>
0017  *
0018  *  The initial version of this is by Martin Peterson.  Alex deVries
0019  *  has spent a bit of time trying to coax it into working.
0020  *
0021  *      Major changes to get basic interrupt infrastructure working to
0022  *      hopefully be able to support all SuperIO devices. Currently
0023  *      works with serial. -- John Marvin <jsm@fc.hp.com>
0024  *
0025  *  Converted superio_init() to be a PCI_FIXUP_FINAL callee.
0026  *         -- Kyle McMartin <kyle@parisc-linux.org>
0027  */
0028 
0029 
0030 /* NOTES:
0031  * 
0032  * Function 0 is an IDE controller. It is identical to a PC87415 IDE
0033  * controller (and identifies itself as such).
0034  *
0035  * Function 1 is a "Legacy I/O" controller. Under this function is a
0036  * whole mess of legacy I/O peripherals. Of course, HP hasn't enabled
0037  * all the functionality in hardware, but the following is available:
0038  *
0039  *      Two 16550A compatible serial controllers
0040  *      An IEEE 1284 compatible parallel port
0041  *      A floppy disk controller
0042  *
0043  * Function 2 is a USB controller.
0044  *
0045  * We must be incredibly careful during initialization.  Since all
0046  * interrupts are routed through function 1 (which is not allowed by
0047  * the PCI spec), we need to program the PICs on the legacy I/O port
0048  * *before* we attempt to set up IDE and USB.  @#$!&
0049  *
0050  * According to HP, devices are only enabled by firmware if they have
0051  * a physical device connected.
0052  *
0053  * Configuration register bits:
0054  *     0x5A: FDC, SP1, IDE1, SP2, IDE2, PAR, Reserved, P92
0055  *     0x5B: RTC, 8259, 8254, DMA1, DMA2, KBC, P61, APM
0056  *
0057  */
0058 
0059 #include <linux/errno.h>
0060 #include <linux/init.h>
0061 #include <linux/module.h>
0062 #include <linux/types.h>
0063 #include <linux/interrupt.h>
0064 #include <linux/ioport.h>
0065 #include <linux/serial.h>
0066 #include <linux/pci.h>
0067 #include <linux/parport.h>
0068 #include <linux/parport_pc.h>
0069 #include <linux/termios.h>
0070 #include <linux/tty.h>
0071 #include <linux/serial_core.h>
0072 #include <linux/serial_8250.h>
0073 #include <linux/delay.h>
0074 
0075 #include <asm/io.h>
0076 #include <asm/hardware.h>
0077 #include <asm/superio.h>
0078 
0079 static struct superio_device sio_dev;
0080 
0081 
0082 #undef DEBUG_SUPERIO_INIT
0083 
0084 #ifdef DEBUG_SUPERIO_INIT
0085 #define DBG_INIT(x...)  printk(x)
0086 #else
0087 #define DBG_INIT(x...)
0088 #endif
0089 
0090 #define SUPERIO "SuperIO"
0091 #define PFX SUPERIO ": "
0092 
0093 static irqreturn_t
0094 superio_interrupt(int parent_irq, void *devp)
0095 {
0096     u8 results;
0097     u8 local_irq;
0098 
0099     /* Poll the 8259 to see if there's an interrupt. */
0100     outb (OCW3_POLL,IC_PIC1+0);
0101 
0102     results = inb(IC_PIC1+0);
0103 
0104     /*
0105      * Bit    7:    1 = active Interrupt; 0 = no Interrupt pending
0106      * Bits 6-3:    zero
0107      * Bits 2-0:    highest priority, active requesting interrupt ID (0-7)
0108      */
0109     if ((results & 0x80) == 0) {
0110         /* I suspect "spurious" interrupts are from unmasking an IRQ.
0111          * We don't know if an interrupt was/is pending and thus
0112          * just call the handler for that IRQ as if it were pending.
0113          */
0114         return IRQ_NONE;
0115     }
0116 
0117     /* Check to see which device is interrupting */
0118     local_irq = results & 0x0f;
0119 
0120     if (local_irq == 2 || local_irq > 7) {
0121         printk(KERN_ERR PFX "slave interrupted!\n");
0122         return IRQ_HANDLED;
0123     }
0124 
0125     if (local_irq == 7) {
0126 
0127         /* Could be spurious. Check in service bits */
0128 
0129         outb(OCW3_ISR,IC_PIC1+0);
0130         results = inb(IC_PIC1+0);
0131         if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */
0132             printk(KERN_WARNING PFX "spurious interrupt!\n");
0133             return IRQ_HANDLED;
0134         }
0135     }
0136 
0137     /* Call the appropriate device's interrupt */
0138     generic_handle_irq(local_irq);
0139 
0140     /* set EOI - forces a new interrupt if a lower priority device
0141      * still needs service.
0142      */
0143     outb((OCW2_SEOI|local_irq),IC_PIC1 + 0);
0144     return IRQ_HANDLED;
0145 }
0146 
0147 /* Initialize Super I/O device */
0148 static void
0149 superio_init(struct pci_dev *pcidev)
0150 {
0151     struct superio_device *sio = &sio_dev;
0152     struct pci_dev *pdev = sio->lio_pdev;
0153     u16 word;
0154     int ret;
0155 
0156     if (sio->suckyio_irq_enabled)
0157         return;
0158 
0159     BUG_ON(!pdev);
0160     BUG_ON(!sio->usb_pdev);
0161 
0162     /* use the IRQ iosapic found for USB INT D... */
0163     pdev->irq = sio->usb_pdev->irq;
0164 
0165     /* ...then properly fixup the USB to point at suckyio PIC */
0166     sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
0167 
0168     printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n",
0169            pci_name(pdev), pdev->irq);
0170 
0171     pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
0172     sio->sp1_base &= ~1;
0173     printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base);
0174 
0175     pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base);
0176     sio->sp2_base &= ~1;
0177     printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base);
0178 
0179     pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base);
0180     sio->pp_base &= ~1;
0181     printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base);
0182 
0183     pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base);
0184     sio->fdc_base &= ~1;
0185     printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base);
0186     pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base);
0187     sio->acpi_base &= ~1;
0188     printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base);
0189 
0190     request_region (IC_PIC1, 0x1f, "pic1");
0191     request_region (IC_PIC2, 0x1f, "pic2");
0192     request_region (sio->acpi_base, 0x1f, "acpi");
0193 
0194     /* Enable the legacy I/O function */
0195     pci_read_config_word (pdev, PCI_COMMAND, &word);
0196     word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;
0197     pci_write_config_word (pdev, PCI_COMMAND, word);
0198 
0199     pci_set_master (pdev);
0200     ret = pci_enable_device(pdev);
0201     BUG_ON(ret < 0);    /* not too much we can do about this... */
0202 
0203     /*
0204      * Next project is programming the onboard interrupt controllers.
0205      * PDC hasn't done this for us, since it's using polled I/O.
0206      *
0207      * XXX Use dword writes to avoid bugs in Elroy or Suckyio Config
0208      *     space access.  PCI is by nature a 32-bit bus and config
0209      *     space can be sensitive to that.
0210      */
0211 
0212     /* 0x64 - 0x67 :
0213         DMA Rtg 2
0214         DMA Rtg 3
0215         DMA Chan Ctl
0216         TRIGGER_1    == 0x82   USB & IDE level triggered, rest to edge
0217     */
0218     pci_write_config_dword (pdev, 0x64,         0x82000000U);
0219 
0220     /* 0x68 - 0x6b :
0221         TRIGGER_2    == 0x00   all edge triggered (not used)
0222         CFG_IR_SER   == 0x43   SerPort1 = IRQ3, SerPort2 = IRQ4
0223         CFG_IR_PF    == 0x65   ParPort  = IRQ5, FloppyCtlr = IRQ6
0224         CFG_IR_IDE   == 0x07   IDE1 = IRQ7, reserved
0225     */
0226     pci_write_config_dword (pdev, TRIGGER_2,    0x07654300U);
0227 
0228     /* 0x6c - 0x6f :
0229         CFG_IR_INTAB == 0x00
0230         CFG_IR_INTCD == 0x10   USB = IRQ1
0231         CFG_IR_PS2   == 0x00
0232         CFG_IR_FXBUS == 0x00
0233     */
0234     pci_write_config_dword (pdev, CFG_IR_INTAB, 0x00001000U);
0235 
0236     /* 0x70 - 0x73 :
0237         CFG_IR_USB   == 0x00  not used. USB is connected to INTD.
0238         CFG_IR_ACPI  == 0x00  not used.
0239         DMA Priority == 0x4c88  Power on default value. NFC.
0240     */
0241     pci_write_config_dword (pdev, CFG_IR_USB, 0x4c880000U);
0242 
0243     /* PIC1 Initialization Command Word register programming */
0244     outb (0x11,IC_PIC1+0);  /* ICW1: ICW4 write req | ICW1 */
0245     outb (0x00,IC_PIC1+1);  /* ICW2: interrupt vector table - not used */
0246     outb (0x04,IC_PIC1+1);  /* ICW3: Cascade */
0247     outb (0x01,IC_PIC1+1);  /* ICW4: x86 mode */
0248 
0249     /* PIC1 Program Operational Control Words */
0250     outb (0xff,IC_PIC1+1);  /* OCW1: Mask all interrupts */
0251     outb (0xc2,IC_PIC1+0);  /* OCW2: priority (3-7,0-2) */
0252 
0253     /* PIC2 Initialization Command Word register programming */
0254     outb (0x11,IC_PIC2+0);  /* ICW1: ICW4 write req | ICW1 */
0255     outb (0x00,IC_PIC2+1);  /* ICW2: N/A */
0256     outb (0x02,IC_PIC2+1);  /* ICW3: Slave ID code */
0257     outb (0x01,IC_PIC2+1);  /* ICW4: x86 mode */
0258         
0259     /* Program Operational Control Words */
0260     outb (0xff,IC_PIC1+1);  /* OCW1: Mask all interrupts */
0261     outb (0x68,IC_PIC1+0);  /* OCW3: OCW3 select | ESMM | SMM */
0262 
0263     /* Write master mask reg */
0264     outb (0xff,IC_PIC1+1);
0265 
0266     /* Setup USB power regulation */
0267     outb(1, sio->acpi_base + USB_REG_CR);
0268     if (inb(sio->acpi_base + USB_REG_CR) & 1)
0269         printk(KERN_INFO PFX "USB regulator enabled\n");
0270     else
0271         printk(KERN_ERR PFX "USB regulator not initialized!\n");
0272 
0273     if (request_irq(pdev->irq, superio_interrupt, 0,
0274             SUPERIO, (void *)sio)) {
0275 
0276         printk(KERN_ERR PFX "could not get irq\n");
0277         BUG();
0278         return;
0279     }
0280 
0281     sio->suckyio_irq_enabled = 1;
0282 }
0283 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
0284 
0285 static void superio_mask_irq(struct irq_data *d)
0286 {
0287     unsigned int irq = d->irq;
0288     u8 r8;
0289 
0290     if ((irq < 1) || (irq == 2) || (irq > 7)) {
0291         printk(KERN_ERR PFX "Illegal irq number.\n");
0292         BUG();
0293         return;
0294     }
0295 
0296     /* Mask interrupt */
0297 
0298     r8 = inb(IC_PIC1+1);
0299     r8 |= (1 << irq);
0300     outb (r8,IC_PIC1+1);
0301 }
0302 
0303 static void superio_unmask_irq(struct irq_data *d)
0304 {
0305     unsigned int irq = d->irq;
0306     u8 r8;
0307 
0308     if ((irq < 1) || (irq == 2) || (irq > 7)) {
0309         printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq);
0310         BUG();
0311         return;
0312     }
0313 
0314     /* Unmask interrupt */
0315     r8 = inb(IC_PIC1+1);
0316     r8 &= ~(1 << irq);
0317     outb (r8,IC_PIC1+1);
0318 }
0319 
0320 static struct irq_chip superio_interrupt_type = {
0321     .name       =   SUPERIO,
0322     .irq_unmask =   superio_unmask_irq,
0323     .irq_mask   =   superio_mask_irq,
0324 };
0325 
0326 #ifdef DEBUG_SUPERIO_INIT
0327 static unsigned short expected_device[3] = {
0328     PCI_DEVICE_ID_NS_87415,
0329     PCI_DEVICE_ID_NS_87560_LIO,
0330     PCI_DEVICE_ID_NS_87560_USB
0331 };
0332 #endif
0333 
0334 int superio_fixup_irq(struct pci_dev *pcidev)
0335 {
0336     int local_irq, i;
0337 
0338 #ifdef DEBUG_SUPERIO_INIT
0339     int fn;
0340     fn = PCI_FUNC(pcidev->devfn);
0341 
0342     /* Verify the function number matches the expected device id. */
0343     if (expected_device[fn] != pcidev->device) {
0344         BUG();
0345         return -1;
0346     }
0347     printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n",
0348         pci_name(pcidev),
0349         pcidev->vendor, pcidev->device,
0350         __builtin_return_address(0));
0351 #endif
0352 
0353     for (i = 0; i < 16; i++) {
0354         irq_set_chip_and_handler(i, &superio_interrupt_type,
0355                      handle_simple_irq);
0356     }
0357 
0358     /*
0359      * We don't allocate a SuperIO irq for the legacy IO function,
0360      * since it is a "bridge". Instead, we will allocate irq's for
0361      * each legacy device as they are initialized.
0362      */
0363 
0364     switch(pcidev->device) {
0365     case PCI_DEVICE_ID_NS_87415:        /* Function 0 */
0366         local_irq = IDE_IRQ;
0367         break;
0368     case PCI_DEVICE_ID_NS_87560_LIO:    /* Function 1 */
0369         sio_dev.lio_pdev = pcidev;  /* save for superio_init() */
0370         return -1;
0371     case PCI_DEVICE_ID_NS_87560_USB:    /* Function 2 */
0372         sio_dev.usb_pdev = pcidev;  /* save for superio_init() */
0373         local_irq = USB_IRQ;
0374         break;
0375     default:
0376         local_irq = -1;
0377         BUG();
0378         break;
0379     }
0380 
0381     return local_irq;
0382 }
0383 
0384 static void __init superio_serial_init(void)
0385 {
0386 #ifdef CONFIG_SERIAL_8250
0387     int retval;
0388     struct uart_port serial_port;
0389 
0390     memset(&serial_port, 0, sizeof(serial_port));
0391     serial_port.iotype  = UPIO_PORT;
0392     serial_port.type    = PORT_16550A;
0393     serial_port.uartclk = 115200*16;
0394     serial_port.flags   = UPF_FIXED_PORT | UPF_FIXED_TYPE |
0395                   UPF_BOOT_AUTOCONF;
0396 
0397     /* serial port #1 */
0398     serial_port.iobase  = sio_dev.sp1_base;
0399     serial_port.irq     = SP1_IRQ;
0400     serial_port.line    = 0;
0401     retval = early_serial_setup(&serial_port);
0402     if (retval < 0) {
0403         printk(KERN_WARNING PFX "Register Serial #0 failed.\n");
0404         return;
0405     }
0406 
0407     /* serial port #2 */
0408     serial_port.iobase  = sio_dev.sp2_base;
0409     serial_port.irq     = SP2_IRQ;
0410     serial_port.line    = 1;
0411     retval = early_serial_setup(&serial_port);
0412     if (retval < 0)
0413         printk(KERN_WARNING PFX "Register Serial #1 failed.\n");
0414 #endif /* CONFIG_SERIAL_8250 */
0415 }
0416 
0417 
0418 static void __init superio_parport_init(void)
0419 {
0420 #ifdef CONFIG_PARPORT_PC
0421     if (!parport_pc_probe_port(sio_dev.pp_base,
0422             0 /*base_hi*/,
0423             PAR_IRQ, 
0424             PARPORT_DMA_NONE /* dma */,
0425             NULL /*struct pci_dev* */,
0426             0 /* shared irq flags */))
0427 
0428         printk(KERN_WARNING PFX "Probing parallel port failed.\n");
0429 #endif  /* CONFIG_PARPORT_PC */
0430 }
0431 
0432 
0433 static void superio_fixup_pci(struct pci_dev *pdev)
0434 {
0435     u8 prog;
0436 
0437     pdev->class |= 0x5;
0438     pci_write_config_byte(pdev, PCI_CLASS_PROG, pdev->class);
0439 
0440     pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
0441     printk("PCI: Enabled native mode for NS87415 (pif=0x%x)\n", prog);
0442 }
0443 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
0444 
0445 
0446 static int __init
0447 superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
0448 {
0449     struct superio_device *sio = &sio_dev;
0450 
0451     /*
0452     ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
0453     ** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000
0454     ** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310
0455     */
0456     DBG_INIT("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n",
0457         pci_name(dev),
0458         dev->vendor, dev->device,
0459         dev->subsystem_vendor, dev->subsystem_device,
0460         dev->class);
0461 
0462     BUG_ON(!sio->suckyio_irq_enabled);  /* Enabled by PCI_FIXUP_FINAL */
0463 
0464     if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) {    /* Function 1 */
0465         superio_parport_init();
0466         superio_serial_init();
0467         /* REVISIT XXX : superio_fdc_init() ? */
0468         return 0;
0469     } else if (dev->device == PCI_DEVICE_ID_NS_87415) { /* Function 0 */
0470         DBG_INIT("superio_probe: ignoring IDE 87415\n");
0471     } else if (dev->device == PCI_DEVICE_ID_NS_87560_USB) { /* Function 2 */
0472         DBG_INIT("superio_probe: ignoring USB OHCI controller\n");
0473     } else {
0474         DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");
0475     }
0476 
0477     /* Let appropriate other driver claim this device. */
0478     return -ENODEV;
0479 }
0480 
0481 static const struct pci_device_id superio_tbl[] __initconst = {
0482     { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
0483     { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
0484     { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
0485     { 0, }
0486 };
0487 
0488 static struct pci_driver superio_driver __refdata = {
0489     .name =         SUPERIO,
0490     .id_table =     superio_tbl,
0491     .probe =        superio_probe,
0492 };
0493 
0494 module_pci_driver(superio_driver);