git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vserver 1.9.5.x5
[linux-2.6.git]
/
arch
/
i386
/
pci
/
irq.c
diff --git
a/arch/i386/pci/irq.c
b/arch/i386/pci/irq.c
index
6aa9e5f
..
9882a43
100644
(file)
--- a/
arch/i386/pci/irq.c
+++ b/
arch/i386/pci/irq.c
@@
-17,6
+17,7
@@
#include <asm/smp.h>
#include <asm/io_apic.h>
#include <asm/hw_irq.h>
#include <asm/smp.h>
#include <asm/io_apic.h>
#include <asm/hw_irq.h>
+#include <linux/acpi.h>
#include "pci.h"
#include "pci.h"
@@
-28,6
+29,8
@@
static int acer_tm360_irqrouting;
static struct irq_routing_table *pirq_table;
static struct irq_routing_table *pirq_table;
+static int pirq_enable_irq(struct pci_dev *dev);
+
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
@@
-127,8
+130,15
@@
void eisa_set_level_irq(unsigned int irq)
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
- unsigned char val = inb(port);
+ unsigned char val;
+ static u16 eisa_irq_mask;
+
+ if (irq >= 16 || (1 << irq) & eisa_irq_mask)
+ return;
+ eisa_irq_mask |= (1 << irq);
+ printk("PCI: setting IRQ %u as level-triggered\n", irq);
+ val = inb(port);
if (!(val & mask)) {
DBG(" -> edge");
outb(val | mask, port);
if (!(val & mask)) {
DBG(" -> edge");
outb(val | mask, port);
@@
-452,14
+462,16
@@
static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
#endif
#endif
-
static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
+ static struct pci_device_id pirq_440gx[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
+ { },
+ };
+
/* 440GX has a proprietary PIRQ router -- don't use it */
/* 440GX has a proprietary PIRQ router -- don't use it */
- if ( pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82443GX_0, NULL) ||
- pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82443GX_2, NULL))
+ if (pci_dev_present(pirq_440gx))
return 0;
switch(device)
return 0;
switch(device)
@@
-481,6
+493,8
@@
static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ESB_1:
case PCI_DEVICE_ID_INTEL_ICH6_0:
case PCI_DEVICE_ID_INTEL_ICH6_1:
case PCI_DEVICE_ID_INTEL_ESB_1:
case PCI_DEVICE_ID_INTEL_ICH6_0:
case PCI_DEVICE_ID_INTEL_ICH6_1:
+ case PCI_DEVICE_ID_INTEL_ICH7_0:
+ case PCI_DEVICE_ID_INTEL_ICH7_1:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
@@
-723,7
+737,7
@@
static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
if (!pirq_table)
return 0;
if (!pirq_table)
return 0;
- DBG("IRQ for %s
:%d", pci_name(dev),
pin);
+ DBG("IRQ for %s
[%c]", pci_name(dev), 'A' +
pin);
info = pirq_get_info(dev);
if (!info) {
DBG(" -> not found in routing table\n");
info = pirq_get_info(dev);
if (!info) {
DBG(" -> not found in routing table\n");
@@
-804,7
+818,7
@@
static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev));
/* Update IRQ for all devices with the same pirq value */
printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev));
/* Update IRQ for all devices with the same pirq value */
- while ((dev2 = pci_
find
_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
+ while ((dev2 = pci_
get
_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
if (!pin)
continue;
pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
if (!pin)
continue;
@@
-838,7
+852,7
@@
static void __init pcibios_fixup_irqs(void)
u8 pin;
DBG("PCI: IRQ fixup\n");
u8 pin;
DBG("PCI: IRQ fixup\n");
- while ((dev = pci_
find
_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ while ((dev = pci_
get
_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
@@
-854,7
+868,7
@@
static void __init pcibios_fixup_irqs(void)
}
dev = NULL;
}
dev = NULL;
- while ((dev = pci_
find
_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ while ((dev = pci_
get
_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
#ifdef CONFIG_X86_IO_APIC
/*
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
#ifdef CONFIG_X86_IO_APIC
/*
@@
-880,16
+894,16
@@
static void __init pcibios_fixup_irqs(void)
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
- printk(KERN_WARNING "PCI: using PPB
(B%d,I%d,P%d) to get irq %d\n",
-
bridge->bus->number, PCI_SLOT(bridge->devfn),
pin, irq);
+ printk(KERN_WARNING "PCI: using PPB
%s[%c] to get irq %d\n",
+
pci_name(bridge), 'A' +
pin, irq);
}
if (irq >= 0) {
if (use_pci_vector() &&
!platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
}
if (irq >= 0) {
if (use_pci_vector() &&
!platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
- printk(KERN_INFO "PCI->APIC IRQ transform:
(B%d,I%d,P%d) ->
%d\n",
-
dev->bus->number, PCI_SLOT(dev->devfn),
pin, irq);
+ printk(KERN_INFO "PCI->APIC IRQ transform:
%s[%c] -> IRQ
%d\n",
+
pci_name(dev), 'A' +
pin, irq);
dev->irq = irq;
}
}
dev->irq = irq;
}
}
@@
-989,19
+1003,30
@@
static int __init pcibios_irq_init(void)
subsys_initcall(pcibios_irq_init);
subsys_initcall(pcibios_irq_init);
-
void pcibios
_penalize_isa_irq(int irq)
+
static void pirq
_penalize_isa_irq(int irq)
{
/*
* If any ISAPnP device reports an IRQ in its list of possible
* IRQ's, we try to avoid assigning it to PCI devices.
*/
{
/*
* If any ISAPnP device reports an IRQ in its list of possible
* IRQ's, we try to avoid assigning it to PCI devices.
*/
- pirq_penalty[irq] += 100;
+ if (irq < 16)
+ pirq_penalty[irq] += 100;
+}
+
+void pcibios_penalize_isa_irq(int irq)
+{
+#ifdef CONFIG_ACPI_PCI
+ if (!acpi_noirq)
+ acpi_penalize_isa_irq(irq);
+ else
+#endif
+ pirq_penalize_isa_irq(irq);
}
}
-int pirq_enable_irq(struct pci_dev *dev)
+
static
int pirq_enable_irq(struct pci_dev *dev)
{
u8 pin;
{
u8 pin;
- extern int interrupt_line_quirk;
+ extern int
via_
interrupt_line_quirk;
struct pci_dev *temp_dev;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
struct pci_dev *temp_dev;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@
-1028,8
+1053,8
@@
int pirq_enable_irq(struct pci_dev *dev)
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
- printk(KERN_WARNING "PCI: using PPB
(B%d,I%d,P%d) to get irq %d\n",
-
bridge->bus->number, PCI_SLOT(bridge->devfn),
pin, irq);
+ printk(KERN_WARNING "PCI: using PPB
%s[%c] to get irq %d\n",
+
pci_name(bridge), 'A' +
pin, irq);
dev = bridge;
}
dev = temp_dev;
dev = bridge;
}
dev = temp_dev;
@@
-1038,8
+1063,8
@@
int pirq_enable_irq(struct pci_dev *dev)
if (!platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
#endif
if (!platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
#endif
- printk(KERN_INFO "PCI->APIC IRQ transform:
(B%d,I%d,P%d) ->
%d\n",
-
dev->bus->number, PCI_SLOT(dev->devfn),
pin, irq);
+ printk(KERN_INFO "PCI->APIC IRQ transform:
%s[%c] -> IRQ
%d\n",
+
pci_name(dev), 'A' +
pin, irq);
dev->irq = irq;
return 0;
} else
dev->irq = irq;
return 0;
} else
@@
-1059,7
+1084,7
@@
int pirq_enable_irq(struct pci_dev *dev)
}
/* VIA bridges use interrupt line for apic/pci steering across
the V-Link */
}
/* VIA bridges use interrupt line for apic/pci steering across
the V-Link */
- else if (interrupt_line_quirk)
+ else if (
via_
interrupt_line_quirk)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
return 0;
}
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
return 0;
}