Skip to content

Commit

Permalink
x86 quirk: Fix polarity for IRQ0 pin2 override on SB800 systems
Browse files Browse the repository at this point in the history
On some SB800 systems polarity for IOAPIC pin2 is wrongly
specified as low active by BIOS. This caused system hangs after
resume from S3 when HPET was used in one-shot mode on such
systems because a timer interrupt was missed (HPET signal is
high active).

For more details see:

  http://marc.info/?l=linux-kernel&m=129623757413868

Tested-by: Manoj Iyer <manoj.iyer@canonical.com>
Tested-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: stable@kernel.org # 37.x, 32.x
LKML-Reference: <20110224145346.GD3658@alberich.amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Andreas Herrmann authored and Ingo Molnar committed Feb 24, 2011
1 parent 7b62dbe commit 7f74f8f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ extern int acpi_disabled;
extern int acpi_pci_disabled;
extern int acpi_skip_timer_override;
extern int acpi_use_timer_override;
extern int acpi_fix_pin2_polarity;

extern u8 acpi_sci_flags;
extern int acpi_sci_override_gsi;
Expand Down
14 changes: 10 additions & 4 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ u8 acpi_sci_flags __initdata;
int acpi_sci_override_gsi __initdata;
int acpi_skip_timer_override __initdata;
int acpi_use_timer_override __initdata;
int acpi_fix_pin2_polarity __initdata;

#ifdef CONFIG_X86_LOCAL_APIC
static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
Expand Down Expand Up @@ -415,10 +416,15 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
return 0;
}

if (acpi_skip_timer_override &&
intsrc->source_irq == 0 && intsrc->global_irq == 2) {
printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
return 0;
if (intsrc->source_irq == 0 && intsrc->global_irq == 2) {
if (acpi_skip_timer_override) {
printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
return 0;
}
if (acpi_fix_pin2_polarity && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) {
intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK;
printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n");
}
}

mp_override_legacy_irq(intsrc->source_irq,
Expand Down
16 changes: 7 additions & 9 deletions arch/x86/kernel/early-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,10 @@ static void __init ati_bugs(int num, int slot, int func)

static u32 __init ati_sbx00_rev(int num, int slot, int func)
{
u32 old, d;
u32 d;

d = read_pci_config(num, slot, func, 0x70);
old = d;
d &= ~(1<<8);
write_pci_config(num, slot, func, 0x70, d);
d = read_pci_config(num, slot, func, 0x8);
d &= 0xff;
write_pci_config(num, slot, func, 0x70, old);

return d;
}
Expand All @@ -160,13 +155,16 @@ static void __init ati_bugs_contd(int num, int slot, int func)
{
u32 d, rev;

if (acpi_use_timer_override)
return;

rev = ati_sbx00_rev(num, slot, func);
if (rev >= 0x40)
acpi_fix_pin2_polarity = 1;

if (rev > 0x13)
return;

if (acpi_use_timer_override)
return;

/* check for IRQ0 interrupt swap */
d = read_pci_config(num, slot, func, 0x64);
if (!(d & (1<<14)))
Expand Down

0 comments on commit 7f74f8f

Please sign in to comment.