From patchwork Fri May 28 10:09:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Kivilinna X-Patchwork-Id: 102856 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4SA96Kj014353 for ; Fri, 28 May 2010 10:09:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755261Ab0E1KJE (ORCPT ); Fri, 28 May 2010 06:09:04 -0400 Received: from saarni.dnainternet.net ([83.102.40.136]:56175 "EHLO saarni.dnainternet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754467Ab0E1KJD (ORCPT ); Fri, 28 May 2010 06:09:03 -0400 Received: from localhost (localhost [127.0.0.1]) by saarni.dnainternet.net (Postfix) with ESMTP id 92ED057CB4; Fri, 28 May 2010 13:09:01 +0300 (EEST) X-Virus-Scanned: DNA Postiturva at dnainternet.net X-Spam-Flag: NO X-Spam-Score: -1.36 X-Spam-Level: X-Spam-Status: No, score=-1.36 tagged_above=-9999 required=6 tests=[ALL_TRUSTED=-1.36] Received: from saarni.dnainternet.net ([83.102.40.136]) by localhost (saarni.dnainternet.net [127.0.0.1]) (amavisd-new, port 10041) with ESMTP id Y0OMzjpMutVB; Fri, 28 May 2010 13:09:01 +0300 (EEST) Received: from oliivipuu.dnainternet.net (oliivipuu.dnainternet.net [83.102.40.215]) by saarni.dnainternet.net (Postfix) with ESMTP id 65D2957CB7; Fri, 28 May 2010 13:09:01 +0300 (EEST) Received: from fate.lan (dyn2-85-23-163-72.psoas.suomi.net [85.23.163.72]) by oliivipuu.dnainternet.net (Postfix) with ESMTP id 4F4267F008; Fri, 28 May 2010 13:09:01 +0300 (EEST) Subject: [PATCH] ath5k: disable ASPM To: ath5k-devel@venema.h4ckr.net From: Jussi Kivilinna Cc: linux-wireless@vger.kernel.org Date: Fri, 28 May 2010 13:09:01 +0300 Message-ID: <20100528100901.14580.1322.stgit@fate.lan> User-Agent: StGit/0.15 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Fri, 28 May 2010 10:09:06 +0000 (UTC) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cc6d41d..ce9c983 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -195,6 +196,8 @@ static const struct ieee80211_rate ath5k_rates[] = { static int __devinit ath5k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void __devexit ath5k_pci_remove(struct pci_dev *pdev); +static void __ath5k_disable_aspm(struct pci_dev *pdev, u16 state); +static void ath5k_disable_aspm(struct pci_dev *pdev, u16 state); #ifdef CONFIG_PM static int ath5k_pci_suspend(struct device *dev); static int ath5k_pci_resume(struct device *dev); @@ -424,6 +427,47 @@ module_exit(exit_ath5k_pci); * PCI Initialization * \********************/ +#ifdef CONFIG_PCIEASPM +static void __ath5k_disable_aspm(struct pci_dev *pdev, u16 state) +{ + pci_disable_link_state(pdev, state); +} +#else +static void __ath5k_disable_aspm(struct pci_dev *pdev, u16 state) +{ + int pos; + u16 reg16; + + /* + * Both device and parent should have the same ASPM setting. + * Disable ASPM in downstream component first and then upstream. + */ + pos = pci_pcie_cap(pdev); + pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~state; + pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); + + if (!pdev->bus->self) + return; + + pos = pci_pcie_cap(pdev->bus->self); + pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~state; + pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); +} +#endif +static void ath5k_disable_aspm(struct pci_dev *pdev, u16 state) +{ + if (!pdev->is_pcie) + return; + + dev_info(&pdev->dev, "Disabling ASPM %s%s\n", + (state & PCIE_LINK_STATE_L0S) ? "L0s " : "", + (state & PCIE_LINK_STATE_L1) ? "L1" : ""); + + __ath5k_disable_aspm(pdev, state); +} + static const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) { @@ -473,6 +517,8 @@ ath5k_pci_probe(struct pci_dev *pdev, int ret; u8 csz; + ath5k_disable_aspm(pdev, PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L0S); + ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "can't enable device\n"); @@ -725,6 +771,8 @@ static int ath5k_pci_resume(struct device *dev) struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath5k_softc *sc = hw->priv; + ath5k_disable_aspm(pdev, PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L0S); + /* * Suspend/Resume resets the PCI configuration space, so we have to * re-disable the RETRY_TIMEOUT register (0x41) to keep