diff options
| -rw-r--r-- | arch/i386/kernel/acpi/boot.c | 4 | ||||
| -rw-r--r-- | arch/i386/kernel/io_apic.c | 6 | ||||
| -rw-r--r-- | arch/x86_64/kernel/io_apic.c | 6 | ||||
| -rw-r--r-- | drivers/acpi/bus.c | 5 | ||||
| -rw-r--r-- | drivers/acpi/pci_irq.c | 31 | ||||
| -rw-r--r-- | include/asm-i386/acpi.h | 9 | ||||
| -rw-r--r-- | include/asm-i386/system.h | 5 |
7 files changed, 37 insertions, 29 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index c4e2c06f10f2..f46ad9ac5aa7 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -67,6 +67,10 @@ int acpi_sci_override_gsi __initdata; static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #endif +#ifndef __HAVE_ARCH_CMPXCHG +#warning ACPI uses CMPXCHG, i486 and later hardware +#endif + /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 45a3600d4236..66a941542c81 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2440,7 +2440,11 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a entry.polarity = active_high_low; entry.mask = 1; - add_pin_to_irq(irq, ioapic, pin); + /* + * IRQs < 16 are already in the irq_2_pin[] map + */ + if (irq >= 16) + add_pin_to_irq(irq, ioapic, pin); entry.vector = assign_irq_vector(irq); diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 8f55252abdcb..0bfccaafb8bc 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1891,7 +1891,11 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a entry.polarity = active_high_low; entry.mask = 1; /* Disabled (masked) */ - add_pin_to_irq(irq, ioapic, pin); + /* + * IRQs < 16 are already in the irq_2_pin[] map + */ + if (irq >= 16) + add_pin_to_irq(irq, ioapic, pin); entry.vector = assign_irq_vector(irq); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 0b1e442c88cd..7d35c674d4ed 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -615,6 +615,11 @@ acpi_bus_init (void) #ifdef CONFIG_X86 if (!acpi_ioapic) { extern acpi_interrupt_flags acpi_sci_flags; + + /* compatible (0) means level (3) */ + if (acpi_sci_flags.trigger == 0) + acpi_sci_flags.trigger = 3; + /* Set PIC-mode SCI trigger type */ acpi_pic_sci_set_trigger(acpi_fadt.sci_int, acpi_sci_flags.trigger); } else { diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index a17f433c2a7a..8e991816632c 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -273,11 +273,6 @@ acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin) return_VALUE(entry->irq); } -/* - * current thinking is that acpi_pci_irq_derive() adds no value - * and should be deleted, so warn if it actually does something. - */ - static int acpi_pci_irq_derive ( struct pci_dev *dev, @@ -285,6 +280,7 @@ acpi_pci_irq_derive ( { struct pci_dev *bridge = dev; int irq = 0; + u8 bridge_pin = 0; ACPI_FUNCTION_TRACE("acpi_pci_irq_derive"); @@ -293,11 +289,25 @@ acpi_pci_irq_derive ( /* * Attempt to derive an IRQ for this device from a parent bridge's - * PCI interrupt routing entry (a.k.a. the "bridge swizzle"). + * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */ while (!irq && bridge->bus->self) { pin = (pin + PCI_SLOT(bridge->devfn)) % 4; bridge = bridge->bus->self; + + if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { + /* PC card has the same IRQ as its cardbridge */ + pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, &bridge_pin); + if (!bridge_pin) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "No interrupt pin configured for device %s\n", pci_name(bridge))); + return_VALUE(0); + } + /* Pin is from 0 to 3 */ + bridge_pin --; + pin = bridge_pin; + } + irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), pin); } @@ -307,7 +317,7 @@ acpi_pci_irq_derive ( return_VALUE(0); } - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Derive IRQ %d for device %s from %s\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n", irq, pci_name(dev), pci_name(bridge))); return_VALUE(irq); @@ -345,13 +355,6 @@ acpi_pci_irq_enable ( irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin); /* - * Check if the device has an IRQ, - * Hotplug devices may get IRQs by scanning - */ - if (!irq && dev->irq) - irq = dev->irq; - - /* * If no PRT entry was found, we'll try to derive an IRQ from the * device's parent bridge. */ diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index b303c70f8887..2a4b35f628fd 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h @@ -54,15 +54,6 @@ #define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() -/* - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in EAX ("=a") - * %1 and %2 are the input parameters in ECX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ static inline int __acpi_acquire_global_lock (unsigned int *lock) diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index 909ba6a3a9c8..6b1d2e84a20d 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -241,6 +241,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz #ifdef CONFIG_X86_CMPXCHG #define __HAVE_ARCH_CMPXCHG 1 +#endif static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) @@ -273,10 +274,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ (unsigned long)(n),sizeof(*(ptr)))) -#else -/* Compiling for a 386 proper. Is it worth implementing via cli/sti? */ -#endif - #ifdef __KERNEL__ struct alt_instr { __u8 *instr; /* original instruction */ |
