Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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