aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2009-04-07 10:30:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:44:06 -0400
commit51dcdfec6a274afc1c6fce180d582add9ff512c0 (patch)
tree51442c7adc06f36977859e8133b645c6c42ea0c9
parent8e7d91c97570ba1a16c0b4f984c04f04f039a231 (diff)
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: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/parport/parport_cs.c3
-rw-r--r--drivers/parport/parport_pc.c57
-rw-r--r--drivers/parport/parport_serial.c20
-rw-r--r--include/linux/parport_pc.h11
4 files changed, 60 insertions, 31 deletions
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 0cd5fbc7f2c2..8fdfa4f537a6 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -43,6 +43,7 @@
43#include <linux/timer.h> 43#include <linux/timer.h>
44#include <linux/ioport.h> 44#include <linux/ioport.h>
45#include <linux/major.h> 45#include <linux/major.h>
46#include <linux/interrupt.h>
46 47
47#include <linux/parport.h> 48#include <linux/parport.h>
48#include <linux/parport_pc.h> 49#include <linux/parport_pc.h>
@@ -192,7 +193,7 @@ static int parport_config(struct pcmcia_device *link)
192 193
193 p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, 194 p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
194 link->irq.AssignedIRQ, PARPORT_DMA_NONE, 195 link->irq.AssignedIRQ, PARPORT_DMA_NONE,
195 &link->dev); 196 &link->dev, IRQF_SHARED);
196 if (p == NULL) { 197 if (p == NULL) {
197 printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " 198 printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
198 "0x%3x, irq %u failed\n", link->io.BasePort1, 199 "0x%3x, irq %u failed\n", link->io.BasePort1,
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 96f3bdf0ec4b..4e63cc9e2778 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2170,10 +2170,11 @@ static int parport_dma_probe (struct parport *p)
2170static LIST_HEAD(ports_list); 2170static LIST_HEAD(ports_list);
2171static DEFINE_SPINLOCK(ports_lock); 2171static DEFINE_SPINLOCK(ports_lock);
2172 2172
2173struct parport *parport_pc_probe_port (unsigned long int base, 2173struct parport *parport_pc_probe_port(unsigned long int base,
2174 unsigned long int base_hi, 2174 unsigned long int base_hi,
2175 int irq, int dma, 2175 int irq, int dma,
2176 struct device *dev) 2176 struct device *dev,
2177 int irqflags)
2177{ 2178{
2178 struct parport_pc_private *priv; 2179 struct parport_pc_private *priv;
2179 struct parport_operations *ops; 2180 struct parport_operations *ops;
@@ -2194,11 +2195,11 @@ struct parport *parport_pc_probe_port (unsigned long int base,
2194 dev = &pdev->dev; 2195 dev = &pdev->dev;
2195 } 2196 }
2196 2197
2197 ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); 2198 ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
2198 if (!ops) 2199 if (!ops)
2199 goto out1; 2200 goto out1;
2200 2201
2201 priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL); 2202 priv = kmalloc(sizeof(struct parport_pc_private), GFP_KERNEL);
2202 if (!priv) 2203 if (!priv)
2203 goto out2; 2204 goto out2;
2204 2205
@@ -2325,8 +2326,8 @@ struct parport *parport_pc_probe_port (unsigned long int base,
2325 EPP_res = NULL; 2326 EPP_res = NULL;
2326 } 2327 }
2327 if (p->irq != PARPORT_IRQ_NONE) { 2328 if (p->irq != PARPORT_IRQ_NONE) {
2328 if (request_irq (p->irq, parport_irq_handler, 2329 if (request_irq(p->irq, parport_irq_handler,
2329 0, p->name, p)) { 2330 irqflags, p->name, p)) {
2330 printk (KERN_WARNING "%s: irq %d in use, " 2331 printk (KERN_WARNING "%s: irq %d in use, "
2331 "resorting to polled operation\n", 2332 "resorting to polled operation\n",
2332 p->name, p->irq); 2333 p->name, p->irq);
@@ -2530,7 +2531,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
2530 */ 2531 */
2531 release_resource(base_res); 2532 release_resource(base_res);
2532 if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi, 2533 if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
2533 irq, PARPORT_DMA_NONE, &pdev->dev)) { 2534 irq, PARPORT_DMA_NONE, &pdev->dev, 0)) {
2534 printk (KERN_INFO 2535 printk (KERN_INFO
2535 "parport_pc: ITE 8872 parallel port: io=0x%X", 2536 "parport_pc: ITE 8872 parallel port: io=0x%X",
2536 ite8872_lpt); 2537 ite8872_lpt);
@@ -2713,7 +2714,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
2713 } 2714 }
2714 2715
2715 /* finally, do the probe with values obtained */ 2716 /* finally, do the probe with values obtained */
2716 if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) { 2717 if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev, 0)) {
2717 printk (KERN_INFO 2718 printk (KERN_INFO
2718 "parport_pc: VIA parallel port: io=0x%X", port1); 2719 "parport_pc: VIA parallel port: io=0x%X", port1);
2719 if (irq != PARPORT_IRQ_NONE) 2720 if (irq != PARPORT_IRQ_NONE)
@@ -3018,6 +3019,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
3018 for (n = 0; n < cards[i].numports; n++) { 3019 for (n = 0; n < cards[i].numports; n++) {
3019 int lo = cards[i].addr[n].lo; 3020 int lo = cards[i].addr[n].lo;
3020 int hi = cards[i].addr[n].hi; 3021 int hi = cards[i].addr[n].hi;
3022 int irq;
3021 unsigned long io_lo, io_hi; 3023 unsigned long io_lo, io_hi;
3022 io_lo = pci_resource_start (dev, lo); 3024 io_lo = pci_resource_start (dev, lo);
3023 io_hi = 0; 3025 io_hi = 0;
@@ -3028,13 +3030,25 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
3028 "hi" as an offset (see SYBA 3030 "hi" as an offset (see SYBA
3029 def.) */ 3031 def.) */
3030 /* TODO: test if sharing interrupts works */ 3032 /* TODO: test if sharing interrupts works */
3031 printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, " 3033 irq = dev->irq;
3032 "I/O at %#lx(%#lx)\n", 3034 if (irq == IRQ_NONE) {
3033 parport_pc_pci_tbl[i + last_sio].vendor, 3035 printk (KERN_DEBUG
3034 parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi); 3036 "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n",
3037 parport_pc_pci_tbl[i + last_sio].vendor,
3038 parport_pc_pci_tbl[i + last_sio].device,
3039 io_lo, io_hi);
3040 irq = PARPORT_IRQ_NONE;
3041 } else {
3042 printk (KERN_DEBUG
3043 "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n",
3044 parport_pc_pci_tbl[i + last_sio].vendor,
3045 parport_pc_pci_tbl[i + last_sio].device,
3046 io_lo, io_hi, irq);
3047 }
3035 data->ports[count] = 3048 data->ports[count] =
3036 parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, 3049 parport_pc_probe_port(io_lo, io_hi, irq,
3037 PARPORT_DMA_NONE, &dev->dev); 3050 PARPORT_DMA_NONE, &dev->dev,
3051 IRQF_SHARED);
3038 if (data->ports[count]) 3052 if (data->ports[count])
3039 count++; 3053 count++;
3040 } 3054 }
@@ -3143,7 +3157,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id
3143 dma = PARPORT_DMA_NONE; 3157 dma = PARPORT_DMA_NONE;
3144 3158
3145 dev_info(&dev->dev, "reported by %s\n", dev->protocol->name); 3159 dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
3146 if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev))) 3160 if (!(pdata = parport_pc_probe_port(io_lo, io_hi,
3161 irq, dma, &dev->dev, 0)))
3147 return -ENODEV; 3162 return -ENODEV;
3148 3163
3149 pnp_set_drvdata(dev,pdata); 3164 pnp_set_drvdata(dev,pdata);
@@ -3192,11 +3207,11 @@ parport_pc_find_isa_ports (int autoirq, int autodma)
3192{ 3207{
3193 int count = 0; 3208 int count = 0;
3194 3209
3195 if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL)) 3210 if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL, 0))
3196 count++; 3211 count++;
3197 if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL)) 3212 if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL, 0))
3198 count++; 3213 count++;
3199 if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL)) 3214 if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL, 0))
3200 count++; 3215 count++;
3201 3216
3202 return count; 3217 return count;
@@ -3481,7 +3496,7 @@ static int __init parport_pc_init(void)
3481 if ((io_hi[i]) == PARPORT_IOHI_AUTO) 3496 if ((io_hi[i]) == PARPORT_IOHI_AUTO)
3482 io_hi[i] = 0x400 + io[i]; 3497 io_hi[i] = 0x400 + io[i];
3483 parport_pc_probe_port(io[i], io_hi[i], 3498 parport_pc_probe_port(io[i], io_hi[i],
3484 irqval[i], dmaval[i], NULL); 3499 irqval[i], dmaval[i], NULL, 0);
3485 } 3500 }
3486 } else 3501 } else
3487 parport_pc_find_ports (irqval[0], dmaval[0]); 3502 parport_pc_find_ports (irqval[0], dmaval[0]);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index f3492110b1ad..c3bb84ac931e 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -21,6 +21,7 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/interrupt.h>
24#include <linux/parport.h> 25#include <linux/parport.h>
25#include <linux/parport_pc.h> 26#include <linux/parport_pc.h>
26#include <linux/8250_pci.h> 27#include <linux/8250_pci.h>
@@ -311,6 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev,
311 int lo = card->addr[n].lo; 312 int lo = card->addr[n].lo;
312 int hi = card->addr[n].hi; 313 int hi = card->addr[n].hi;
313 unsigned long io_lo, io_hi; 314 unsigned long io_lo, io_hi;
315 int irq;
314 316
315 if (priv->num_par == ARRAY_SIZE (priv->port)) { 317 if (priv->num_par == ARRAY_SIZE (priv->port)) {
316 printk (KERN_WARNING 318 printk (KERN_WARNING
@@ -329,10 +331,20 @@ static int __devinit parport_register (struct pci_dev *dev,
329 "hi" as an offset (see SYBA 331 "hi" as an offset (see SYBA
330 def.) */ 332 def.) */
331 /* TODO: test if sharing interrupts works */ 333 /* TODO: test if sharing interrupts works */
332 dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " 334 irq = dev->irq;
333 "%#lx(%#lx)\n", io_lo, io_hi); 335 if (irq == IRQ_NONE) {
334 port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, 336 dev_dbg(&dev->dev,
335 PARPORT_DMA_NONE, &dev->dev); 337 "PCI parallel port detected: I/O at %#lx(%#lx)\n",
338 io_lo, io_hi);
339 irq = PARPORT_IRQ_NONE;
340 } else {
341 dev_dbg(&dev->dev,
342 "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
343 io_lo, io_hi, irq);
344 irq = PARPORT_IRQ_NONE;
345 }
346 port = parport_pc_probe_port (io_lo, io_hi, irq,
347 PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
336 if (port) { 348 if (port) {
337 priv->port[priv->num_par++] = port; 349 priv->port[priv->num_par++] = port;
338 success = 1; 350 success = 1;
diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h
index ea8c6d84996d..cc1767f5cca8 100644
--- a/include/linux/parport_pc.h
+++ b/include/linux/parport_pc.h
@@ -228,10 +228,11 @@ extern void parport_pc_release_resources(struct parport *p);
228extern int parport_pc_claim_resources(struct parport *p); 228extern int parport_pc_claim_resources(struct parport *p);
229 229
230/* PCMCIA code will want to get us to look at a port. Provide a mechanism. */ 230/* PCMCIA code will want to get us to look at a port. Provide a mechanism. */
231extern struct parport *parport_pc_probe_port (unsigned long base, 231extern struct parport *parport_pc_probe_port(unsigned long base,
232 unsigned long base_hi, 232 unsigned long base_hi,
233 int irq, int dma, 233 int irq, int dma,
234 struct device *dev); 234 struct device *dev,
235extern void parport_pc_unregister_port (struct parport *p); 235 int irqflags);
236extern void parport_pc_unregister_port(struct parport *p);
236 237
237#endif 238#endif