Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51dcdfec authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

parport: Use the PCI IRQ if offered



PCI parallel port devices can IRQ share so we should stop them hogging
the line and making a mess on modern PC systems.  We know the sharing
side works as the PCMCIA driver has shared the parallel port IRQ for
some time.

Signed-off-by: default avatarAlan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8e7d91c9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/interrupt.h>

#include <linux/parport.h>
#include <linux/parport_pc.h>
@@ -192,7 +193,7 @@ static int parport_config(struct pcmcia_device *link)

    p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
			      link->irq.AssignedIRQ, PARPORT_DMA_NONE,
			      &link->dev);
			      &link->dev, IRQF_SHARED);
    if (p == NULL) {
	printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
	       "0x%3x, irq %u failed\n", link->io.BasePort1,
+36 −21
Original line number Diff line number Diff line
@@ -2173,7 +2173,8 @@ static DEFINE_SPINLOCK(ports_lock);
struct parport *parport_pc_probe_port(unsigned long int base,
				      unsigned long int base_hi,
				      int irq, int dma,
				       struct device *dev)
				      struct device *dev,
				      int irqflags)
{
	struct parport_pc_private *priv;
	struct parport_operations *ops;
@@ -2326,7 +2327,7 @@ struct parport *parport_pc_probe_port (unsigned long int base,
	}
	if (p->irq != PARPORT_IRQ_NONE) {
		if (request_irq(p->irq, parport_irq_handler,
				 0, p->name, p)) {
				 irqflags, p->name, p)) {
			printk (KERN_WARNING "%s: irq %d in use, "
				"resorting to polled operation\n",
				p->name, p->irq);
@@ -2530,7 +2531,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
	 */
	release_resource(base_res);
	if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
				   irq, PARPORT_DMA_NONE, &pdev->dev)) {
				   irq, PARPORT_DMA_NONE, &pdev->dev, 0)) {
		printk (KERN_INFO
			"parport_pc: ITE 8872 parallel port: io=0x%X",
			ite8872_lpt);
@@ -2713,7 +2714,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
	}

	/* finally, do the probe with values obtained */
	if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
	if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev, 0)) {
		printk (KERN_INFO
			"parport_pc: VIA parallel port: io=0x%X", port1);
		if (irq != PARPORT_IRQ_NONE)
@@ -3018,6 +3019,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
	for (n = 0; n < cards[i].numports; n++) {
		int lo = cards[i].addr[n].lo;
		int hi = cards[i].addr[n].hi;
		int irq;
		unsigned long io_lo, io_hi;
		io_lo = pci_resource_start (dev, lo);
		io_hi = 0;
@@ -3028,13 +3030,25 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
                                        "hi" as an offset (see SYBA
                                        def.) */
		/* TODO: test if sharing interrupts works */
		printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
			"I/O at %#lx(%#lx)\n",
		irq = dev->irq;
		if (irq == IRQ_NONE) {
			printk (KERN_DEBUG
	"PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n",
				parport_pc_pci_tbl[i + last_sio].vendor,
			parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
				parport_pc_pci_tbl[i + last_sio].device,
				io_lo, io_hi);
			irq = PARPORT_IRQ_NONE;
		} else {
			printk (KERN_DEBUG
	"PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n",
				parport_pc_pci_tbl[i + last_sio].vendor,
				parport_pc_pci_tbl[i + last_sio].device,
				io_lo, io_hi, irq);
		}
		data->ports[count] =
			parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
					       PARPORT_DMA_NONE, &dev->dev);
			parport_pc_probe_port(io_lo, io_hi, irq,
					       PARPORT_DMA_NONE, &dev->dev,
					       IRQF_SHARED);
		if (data->ports[count])
			count++;
	}
@@ -3143,7 +3157,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id
		dma = PARPORT_DMA_NONE;

	dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
	if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
	if (!(pdata = parport_pc_probe_port(io_lo, io_hi,
					irq, dma, &dev->dev, 0)))
		return -ENODEV;

	pnp_set_drvdata(dev,pdata);
@@ -3192,11 +3207,11 @@ parport_pc_find_isa_ports (int autoirq, int autodma)
{
	int count = 0;

	if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL))
	if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL, 0))
		count++;
	if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL))
	if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL, 0))
		count++;
	if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL))
	if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL, 0))
		count++;

	return count;
@@ -3481,7 +3496,7 @@ static int __init parport_pc_init(void)
			if ((io_hi[i]) == PARPORT_IOHI_AUTO)
			       io_hi[i] = 0x400 + io[i];
			parport_pc_probe_port(io[i], io_hi[i],
						  irqval[i], dmaval[i], NULL);
					  irqval[i], dmaval[i], NULL, 0);
		}
	} else
		parport_pc_find_ports (irqval[0], dmaval[0]);
+16 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/8250_pci.h>
@@ -311,6 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev,
		int lo = card->addr[n].lo;
		int hi = card->addr[n].hi;
		unsigned long io_lo, io_hi;
		int irq;

		if (priv->num_par == ARRAY_SIZE (priv->port)) {
			printk (KERN_WARNING
@@ -329,10 +331,20 @@ static int __devinit parport_register (struct pci_dev *dev,
                                        "hi" as an offset (see SYBA
                                        def.) */
		/* TODO: test if sharing interrupts works */
		dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
			"%#lx(%#lx)\n", io_lo, io_hi);
		port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
					      PARPORT_DMA_NONE, &dev->dev);
		irq = dev->irq;
		if (irq == IRQ_NONE) {
			dev_dbg(&dev->dev,
			"PCI parallel port detected: I/O at %#lx(%#lx)\n",
				io_lo, io_hi);
			irq = PARPORT_IRQ_NONE;
		} else {
			dev_dbg(&dev->dev,
		"PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
				io_lo, io_hi, irq);
			irq = PARPORT_IRQ_NONE;
		}
		port = parport_pc_probe_port (io_lo, io_hi, irq,
			      PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
		if (port) {
			priv->port[priv->num_par++] = port;
			success = 1;
+6 −5
Original line number Diff line number Diff line
@@ -231,7 +231,8 @@ extern int parport_pc_claim_resources(struct parport *p);
extern struct parport *parport_pc_probe_port(unsigned long base,
					     unsigned long base_hi,
					     int irq, int dma,
					      struct device *dev);
					     struct device *dev,
					     int irqflags);
extern void parport_pc_unregister_port(struct parport *p);

#endif