Blame view

drivers/parisc/superio.c 13.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*      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>
7efe1611b   Kyle McMartin   [PARISC] Initiali...
14
   *	(C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>
5076c1586   Helge Deller   [PARISC] I/O-Spac...
15
   *	(C) Copyright 2006 Helge Deller <deller@gmx.de>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
20
21
22
23
24
25
26
27
   *
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License as
   *	published by the Free Software Foundation; either version 2 of
   *	the License, or (at your option) any later version.  
   *
   *	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>
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
28
29
30
   *
   *	Converted superio_init() to be a PCI_FIXUP_FINAL callee.
   *         -- Kyle McMartin <kyle@parisc-linux.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
   */
  
  
  /* 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
   *
   */
  
  #include <linux/errno.h>
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/interrupt.h>
  #include <linux/ioport.h>
  #include <linux/serial.h>
  #include <linux/pci.h>
  #include <linux/parport.h>
  #include <linux/parport_pc.h>
  #include <linux/termios.h>
  #include <linux/tty.h>
  #include <linux/serial_core.h>
b187f180c   Yinghai Lu   serial: add early...
76
  #include <linux/serial_8250.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  #include <linux/delay.h>
  
  #include <asm/io.h>
  #include <asm/hardware.h>
  #include <asm/superio.h>
  
  static struct superio_device sio_dev;
  
  
  #undef DEBUG_SUPERIO_INIT
  
  #ifdef DEBUG_SUPERIO_INIT
  #define DBG_INIT(x...)  printk(x)
  #else
  #define DBG_INIT(x...)
  #endif
16541c874   Kyle McMartin   [PARISC] Clean up...
93
94
  #define SUPERIO	"SuperIO"
  #define PFX	SUPERIO ": "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
  static irqreturn_t
7d12e780e   David Howells   IRQ: Maintain reg...
96
  superio_interrupt(int parent_irq, void *devp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  {
  	u8 results;
  	u8 local_irq;
  
  	/* 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;
  
  	if (local_irq == 2 || local_irq > 7) {
16541c874   Kyle McMartin   [PARISC] Clean up...
123
124
  		printk(KERN_ERR PFX "slave interrupted!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
129
130
131
132
133
134
  		return IRQ_HANDLED;
  	}
  
  	if (local_irq == 7) {
  
  		/* Could be spurious. Check in service bits */
  
  		outb(OCW3_ISR,IC_PIC1+0);
  		results = inb(IC_PIC1+0);
  		if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */
16541c874   Kyle McMartin   [PARISC] Clean up...
135
136
  			printk(KERN_WARNING PFX "spurious interrupt!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
141
  			return IRQ_HANDLED;
  		}
  	}
  
  	/* Call the appropriate device's interrupt */
ba20085c2   Kyle McMartin   parisc: lay groun...
142
  	generic_handle_irq(local_irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
145
146
147
148
149
150
151
  
  	/* 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;
  }
  
  /* Initialize Super I/O device */
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
152
153
  static void
  superio_init(struct pci_dev *pcidev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  {
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
155
  	struct superio_device *sio = &sio_dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
  	struct pci_dev *pdev = sio->lio_pdev;
  	u16 word;
19c4d5664   Kyle McMartin   [PARISC] Squelch ...
158
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

67a5a59d3   Helge Deller   [PARISC] Misc. ja...
160
  	if (sio->suckyio_irq_enabled)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  		return;
b74945547   Eric Sesterhenn   BUG_ON() Conversi...
162
163
  	BUG_ON(!pdev);
  	BUG_ON(!sio->usb_pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
168
169
  
  	/* use the IRQ iosapic found for USB INT D... */
  	pdev->irq = sio->usb_pdev->irq;
  
  	/* ...then properly fixup the USB to point at suckyio PIC */
  	sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
a3bee03e7   Frans Pop   parisc: remove tr...
170
171
  	printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)
  ",
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
172
  	       pci_name(pdev), pdev->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
175
  
  	pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
  	sio->sp1_base &= ~1;
16541c874   Kyle McMartin   [PARISC] Clean up...
176
177
  	printk(KERN_INFO PFX "Serial port 1 at 0x%x
  ", sio->sp1_base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
  
  	pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base);
  	sio->sp2_base &= ~1;
16541c874   Kyle McMartin   [PARISC] Clean up...
181
182
  	printk(KERN_INFO PFX "Serial port 2 at 0x%x
  ", sio->sp2_base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
  
  	pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base);
  	sio->pp_base &= ~1;
16541c874   Kyle McMartin   [PARISC] Clean up...
186
187
  	printk(KERN_INFO PFX "Parallel port at 0x%x
  ", sio->pp_base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
  
  	pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base);
  	sio->fdc_base &= ~1;
16541c874   Kyle McMartin   [PARISC] Clean up...
191
192
  	printk(KERN_INFO PFX "Floppy controller at 0x%x
  ", sio->fdc_base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
  	pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base);
  	sio->acpi_base &= ~1;
16541c874   Kyle McMartin   [PARISC] Clean up...
195
196
  	printk(KERN_INFO PFX "ACPI at 0x%x
  ", sio->acpi_base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
199
200
201
202
  
  	request_region (IC_PIC1, 0x1f, "pic1");
  	request_region (IC_PIC2, 0x1f, "pic2");
  	request_region (sio->acpi_base, 0x1f, "acpi");
  
  	/* Enable the legacy I/O function */
67a5a59d3   Helge Deller   [PARISC] Misc. ja...
203
  	pci_read_config_word (pdev, PCI_COMMAND, &word);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
  	word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;
  	pci_write_config_word (pdev, PCI_COMMAND, word);
  
  	pci_set_master (pdev);
19c4d5664   Kyle McMartin   [PARISC] Squelch ...
208
209
  	ret = pci_enable_device(pdev);
  	BUG_ON(ret < 0);	/* not too much we can do about this... */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  
  	/*
  	 * 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);
  
  	/* 0x68 - 0x6b :
  		TRIGGER_2    == 0x00   all edge triggered (not used)
  		CFG_IR_SER   == 0x43   SerPort1 = IRQ3, SerPort2 = IRQ4
  		CFG_IR_PF    == 0x65   ParPort  = IRQ5, FloppyCtlr = IRQ6
  		CFG_IR_IDE   == 0x07   IDE1 = IRQ7, reserved
  	*/
  	pci_write_config_dword (pdev, TRIGGER_2,    0x07654300U);
  
  	/* 0x6c - 0x6f :
  		CFG_IR_INTAB == 0x00
  		CFG_IR_INTCD == 0x10   USB = IRQ1
  		CFG_IR_PS2   == 0x00
  		CFG_IR_FXBUS == 0x00
  	*/
  	pci_write_config_dword (pdev, CFG_IR_INTAB, 0x00001000U);
  
  	/* 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);
  
  	/* PIC1 Initialization Command Word register programming */
  	outb (0x11,IC_PIC1+0);	/* ICW1: ICW4 write req | ICW1 */
  	outb (0x00,IC_PIC1+1);	/* ICW2: interrupt vector table - not used */
  	outb (0x04,IC_PIC1+1);	/* ICW3: Cascade */
  	outb (0x01,IC_PIC1+1);	/* ICW4: x86 mode */
  
  	/* PIC1 Program Operational Control Words */
  	outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
  	outb (0xc2,IC_PIC1+0);  /* OCW2: priority (3-7,0-2) */
  
  	/* PIC2 Initialization Command Word register programming */
  	outb (0x11,IC_PIC2+0);	/* ICW1: ICW4 write req | ICW1 */
  	outb (0x00,IC_PIC2+1);	/* ICW2: N/A */
  	outb (0x02,IC_PIC2+1);	/* ICW3: Slave ID code */
  	outb (0x01,IC_PIC2+1);	/* ICW4: x86 mode */
  		
  	/* Program Operational Control Words */
  	outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
  	outb (0x68,IC_PIC1+0);	/* OCW3: OCW3 select | ESMM | SMM */
  
  	/* Write master mask reg */
  	outb (0xff,IC_PIC1+1);
  
  	/* Setup USB power regulation */
  	outb(1, sio->acpi_base + USB_REG_CR);
  	if (inb(sio->acpi_base + USB_REG_CR) & 1)
16541c874   Kyle McMartin   [PARISC] Clean up...
277
278
  		printk(KERN_INFO PFX "USB regulator enabled
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  	else
16541c874   Kyle McMartin   [PARISC] Clean up...
280
281
  		printk(KERN_ERR PFX "USB regulator not initialized!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282

b54cb2332   Peter Zijlstra   parisc: remove IR...
283
  	if (request_irq(pdev->irq, superio_interrupt, 0,
16541c874   Kyle McMartin   [PARISC] Clean up...
284
  			SUPERIO, (void *)sio)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285

16541c874   Kyle McMartin   [PARISC] Clean up...
286
287
  		printk(KERN_ERR PFX "could not get irq
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
290
291
292
293
  		BUG();
  		return;
  	}
  
  	sio->suckyio_irq_enabled = 1;
  }
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
294
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295

4c4231ea2   Thomas Gleixner   [PARISC] Convert ...
296
  static void superio_mask_irq(struct irq_data *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  {
4c4231ea2   Thomas Gleixner   [PARISC] Convert ...
298
  	unsigned int irq = d->irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
301
  	u8 r8;
  
  	if ((irq < 1) || (irq == 2) || (irq > 7)) {
16541c874   Kyle McMartin   [PARISC] Clean up...
302
303
  		printk(KERN_ERR PFX "Illegal irq number.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
309
310
311
312
313
  		BUG();
  		return;
  	}
  
  	/* Mask interrupt */
  
  	r8 = inb(IC_PIC1+1);
  	r8 |= (1 << irq);
  	outb (r8,IC_PIC1+1);
  }
4c4231ea2   Thomas Gleixner   [PARISC] Convert ...
314
  static void superio_unmask_irq(struct irq_data *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  {
4c4231ea2   Thomas Gleixner   [PARISC] Convert ...
316
  	unsigned int irq = d->irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
  	u8 r8;
  
  	if ((irq < 1) || (irq == 2) || (irq > 7)) {
16541c874   Kyle McMartin   [PARISC] Clean up...
320
321
  		printk(KERN_ERR PFX "Illegal irq number (%d).
  ", irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
326
327
328
329
330
  		BUG();
  		return;
  	}
  
  	/* Unmask interrupt */
  	r8 = inb(IC_PIC1+1);
  	r8 &= ~(1 << irq);
  	outb (r8,IC_PIC1+1);
  }
dfe075650   Thomas Gleixner   parisc: remove ob...
331
  static struct irq_chip superio_interrupt_type = {
4c4231ea2   Thomas Gleixner   [PARISC] Convert ...
332
333
334
  	.name		=	SUPERIO,
  	.irq_unmask	=	superio_unmask_irq,
  	.irq_mask	=	superio_mask_irq,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  };
  
  #ifdef DEBUG_SUPERIO_INIT
  static unsigned short expected_device[3] = {
  	PCI_DEVICE_ID_NS_87415,
  	PCI_DEVICE_ID_NS_87560_LIO,
  	PCI_DEVICE_ID_NS_87560_USB
  };
  #endif
  
  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;
  	}
4deb508e9   Joe Perches   parisc: Use vspri...
358
359
  	printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
362
363
364
365
  		pci_name(pcidev),
  		pcidev->vendor, pcidev->device,
  		__builtin_return_address(0));
  #endif
  
  	for (i = 0; i < 16; i++) {
e2f571d29   Thomas Gleixner   parisc: Convert i...
366
367
  		irq_set_chip_and_handler(i, &superio_interrupt_type,
  					 handle_simple_irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  	}
  
  	/*
  	 * 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;
  	}
  
  	return local_irq;
  }
8c678b101   Helge Deller   [PARISC] fix sect...
395
  static void __init superio_serial_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
397
398
  {
  #ifdef CONFIG_SERIAL_8250
  	int retval;
5076c1586   Helge Deller   [PARISC] I/O-Spac...
399
400
401
402
403
404
405
  	struct uart_port serial_port;
  
  	memset(&serial_port, 0, sizeof(serial_port));
  	serial_port.iotype	= UPIO_PORT;
  	serial_port.type	= PORT_16550A;
  	serial_port.uartclk	= 115200*16;
  	serial_port.fifosize	= 16;
5076c1586   Helge Deller   [PARISC] I/O-Spac...
406
407
408
409
410
411
  
  	/* serial port #1 */
  	serial_port.iobase	= sio_dev.sp1_base;
  	serial_port.irq		= SP1_IRQ;
  	serial_port.line	= 0;
  	retval = early_serial_setup(&serial_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
  	if (retval < 0) {
16541c874   Kyle McMartin   [PARISC] Clean up...
413
414
  		printk(KERN_WARNING PFX "Register Serial #0 failed.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
416
  		return;
  	}
5076c1586   Helge Deller   [PARISC] I/O-Spac...
417
418
419
420
421
  	/* serial port #2 */
  	serial_port.iobase	= sio_dev.sp2_base;
  	serial_port.irq		= SP2_IRQ;
  	serial_port.line	= 1;
  	retval = early_serial_setup(&serial_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422
  	if (retval < 0)
16541c874   Kyle McMartin   [PARISC] Clean up...
423
424
  		printk(KERN_WARNING PFX "Register Serial #1 failed.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
426
  #endif /* CONFIG_SERIAL_8250 */
  }
8c678b101   Helge Deller   [PARISC] fix sect...
427
  static void __init superio_parport_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
430
431
432
433
  {
  #ifdef CONFIG_PARPORT_PC
  	if (!parport_pc_probe_port(sio_dev.pp_base,
  			0 /*base_hi*/,
  			PAR_IRQ, 
  			PARPORT_DMA_NONE /* dma */,
0c5cb7919   Alexander Beregalov   parisc: superio: ...
434
435
  			NULL /*struct pci_dev* */,
  			0 /* shared irq flags */))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436

16541c874   Kyle McMartin   [PARISC] Clean up...
437
438
  		printk(KERN_WARNING PFX "Probing parallel port failed.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  #endif	/* CONFIG_PARPORT_PC */
  }
  
  
  static void superio_fixup_pci(struct pci_dev *pdev)
  {
  	u8 prog;
  
  	pdev->class |= 0x5;
  	pci_write_config_byte(pdev, PCI_CLASS_PROG, pdev->class);
  
  	pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
  	printk("PCI: Enabled native mode for NS87415 (pif=0x%x)
  ", prog);
  }
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
8c678b101   Helge Deller   [PARISC] fix sect...
455
  static int __init
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
456
  superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
  {
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
458
  	struct superio_device *sio = &sio_dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
460
461
462
463
464
465
466
467
468
469
470
  
  	/*
  	** 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
  ",
  		pci_name(dev),
  		dev->vendor, dev->device,
  		dev->subsystem_vendor, dev->subsystem_device,
  		dev->class);
b74945547   Eric Sesterhenn   BUG_ON() Conversi...
471
  	BUG_ON(!sio->suckyio_irq_enabled);	/* Enabled by PCI_FIXUP_FINAL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
  
  	if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) {	/* Function 1 */
  		superio_parport_init();
  		superio_serial_init();
  		/* REVISIT XXX : superio_fdc_init() ? */
  		return 0;
  	} else if (dev->device == PCI_DEVICE_ID_NS_87415) {	/* Function 0 */
  		DBG_INIT("superio_probe: ignoring IDE 87415
  ");
  	} else if (dev->device == PCI_DEVICE_ID_NS_87560_USB) {	/* Function 2 */
  		DBG_INIT("superio_probe: ignoring USB OHCI controller
  ");
  	} else {
  		DBG_INIT("superio_probe: WTF? Fire Extinguisher?
  ");
  	}
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
488
  	/* Let appropriate other driver claim this device. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
  	return -ENODEV;
  }
8c678b101   Helge Deller   [PARISC] fix sect...
491
  static const struct pci_device_id superio_tbl[] = {
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
492
493
494
  	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
497
498
  	{ 0, }
  };
  
  static struct pci_driver superio_driver = {
16541c874   Kyle McMartin   [PARISC] Clean up...
499
  	.name =         SUPERIO,
a39cf72ce   Kyle McMartin   [PARISC] Make sup...
500
501
  	.id_table =     superio_tbl,
  	.probe =        superio_probe,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
  };
2c2d32bed   Peter Huewe   parisc/superio: U...
503
  module_pci_driver(superio_driver);