From patchwork Wed Jul 4 08:34:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1155001 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id AF8DF3FE4F for ; Wed, 4 Jul 2012 08:34:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754212Ab2GDIeS (ORCPT ); Wed, 4 Jul 2012 04:34:18 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:58680 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753541Ab2GDIeQ (ORCPT ); Wed, 4 Jul 2012 04:34:16 -0400 Received: by pbbrp8 with SMTP id rp8so10694040pbb.19 for ; Wed, 04 Jul 2012 01:34:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:x-mailer; bh=YUeDnI/fF6/zIGVbE6vG0nWm0cyzKl5KYzEKyjSJ+RU=; b=inUxIv6r+Jm+309qZ1stgC8aqaRiMy2MMwHJCkb58/DmPTVHQ3AXwyPE5373ijDlAl fBQMSVfPOhE/aBy2s6bcp2Ys9SY39sSOhTzJ4UZCU/DjhkivIPHlUybRAG+5LZVD+JhU U7rJ18IUmOhP30ASV/iNhCcZaiK8MXMu2zuiufTLGQyh+eLkDyjUmBqATsCBhXfomyDR lQPCP42yLzOS9nmmkTP0Yb9nzAlHAN3MaCrLsWMh25Bd2Gu0ptmHH5HPx73LfiUyeZW/ VmmWpwoZAbYfvaIXwjRI8FcORN0hmmKEGf9BUbp180StO6+IonGpRCgK5Yuk+opDFiZz T4wA== Received: by 10.68.203.40 with SMTP id kn8mr15951838pbc.162.1341390855821; Wed, 04 Jul 2012 01:34:15 -0700 (PDT) Received: from localhost ([210.242.151.101]) by mx.google.com with ESMTPS id vz9sm17306577pbc.12.2012.07.04.01.34.13 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 04 Jul 2012 01:34:14 -0700 (PDT) From: AceLan Kao To: linux-pci@vger.kernel.org, Bjorn Helgaas Subject: [PATCH] PCI: Quirk for ASUS S3 issue Date: Wed, 4 Jul 2012 16:34:11 +0800 Message-Id: <1341390851-22099-1-git-send-email-acelan.kao@canonical.com> X-Mailer: git-send-email 1.7.9.5 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Attempt to suspend some ASUS systems causes hang. Power cycle required to recover. The root cause of this issue is result from the the BIOS will try to disable USB which is already disabled by the driver. BIOS will check the EHCI controller's PCI COMMAND register, if it's not zero, then BIOS will think the USB is not disabled yet, so it will try to disable USB again, and then hang in the BIOS code. To resolve this, we should clear the EHCI controller's PCI COMMAND register before entering S3. And this does no harm to the system, since it'll switch off the power after enter S3, and the value in the register will be reset by BIOS after wakeup. Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=43064 BugLink: http://bugs.launchpad.net/bugs/951143 Signed-off-by: AceLan Kao --- drivers/pci/quirks.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 194b243a..d1bb4db 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2955,6 +2955,25 @@ static void __devinit asus_ehci_no_d3(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); +/* + * ASUS BIOS will check the EHCI controller's PCI COMMAND register to see + * if the value is all zero. If not, BIOS will think the USB is not disabled + * and will try to disable USB. But, actually, USB is disabled by the driver + * while entering S3, so it'll hang in BIOS when it try to disable USB. + * Since it's going to enter S3, so it does no harm to clear the EHCI + * controller's PCI COMMAND register. And the value of the PCI COMMAND + * register value will be restored correctly after S3. + */ +static void asus_clear_pci_command(struct pci_dev *dev) +{ + if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) + return; + + pci_write_config_word(dev, PCI_COMMAND, 0); +} +DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x7808, asus_clear_memory_bit); +DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_ATI, 0x4396, asus_clear_memory_bit); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) {