[PATCH] Quirk to fix suspend/resume on another Lenovo ThinkPad Edge, model 030246G.

Stefan Bader stefan.bader at canonical.com
Thu Feb 24 16:30:36 UTC 2011


On 02/24/2011 03:56 PM, Andreas Herrmann wrote:
> On Wed, Feb 23, 2011 at 03:58:40PM +0100, Andreas Herrmann wrote:
>> On Wed, Feb 16, 2011 at 04:17:02AM -0500, Stefan Bader wrote:
>>> Hi Andreas,
>>>
>>> I know there probably are already enough people poking you about when there
>>> might be a generic fix. Just wanted to point out that Thomas reported a SB880
>>> (in case that makes a difference to SB800 that seemed to be reported before).
>>
>> Hi Stefan,
>>
>> patch is prepared.
>> Just want to have verified it on one known buggy system here.
>> I'll send it out by end of today or tomorrow.
> 
> I've just submitted below patch to LKML
> (http://marc.info/?i=20110224145346.GD3658@alberich.amd.com)
> 
> 
> Andreas
> 

Cool. Thanks.

/me ponders whether this might be something to have a cmdline quirking for...

> ---
> 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
> 
> Cc: stable at kernel.org # 37.x, 32.x
> Tested-by: Manoj Iyer <manoj.iyer at canonical.com>
> Tested-by: Andre Przywara <andre.przywara at amd.com>
> Signed-off-by: Andreas Herrmann <andreas.herrmann3 at amd.com>
> ---
>  arch/x86/include/asm/acpi.h    |    1 +
>  arch/x86/kernel/acpi/boot.c    |   16 ++++++++++++----
>  arch/x86/kernel/early-quirks.c |   16 +++++++---------
>  3 files changed, 20 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
> index 211ca3f..4ea15ca 100644
> --- a/arch/x86/include/asm/acpi.h
> +++ b/arch/x86/include/asm/acpi.h
> @@ -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;
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index b3a7113..ff25db6 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -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;
> @@ -415,10 +416,17 @@ 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,
> diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
> index 76b8cd9..9efbdcc 100644
> --- a/arch/x86/kernel/early-quirks.c
> +++ b/arch/x86/kernel/early-quirks.c
> @@ -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;
>  }
> @@ -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)))





More information about the kernel-team mailing list