mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 08:34:20 +08:00
PCI: let pci_disable_link_state propagate errors
Drivers may rely on pci_disable_link_state() having disabled certain ASPM link states. If OS can't control ASPM then pci_disable_link_state() turns into a no-op w/o informing the caller. The driver therefore may falsely assume the respective ASPM link states are disabled. Let pci_disable_link_state() propagate errors to the caller, enabling the caller to react accordingly. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
dca73a65a6
commit
4cfd218855
@ -1062,18 +1062,18 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
|
||||
up_read(&pci_bus_sem);
|
||||
}
|
||||
|
||||
static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
{
|
||||
struct pci_dev *parent = pdev->bus->self;
|
||||
struct pcie_link_state *link;
|
||||
|
||||
if (!pci_is_pcie(pdev))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (pdev->has_secondary_link)
|
||||
parent = pdev;
|
||||
if (!parent || !parent->link_state)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* A driver requested that ASPM be disabled on this device, but
|
||||
@ -1085,7 +1085,7 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
*/
|
||||
if (aspm_disabled) {
|
||||
pci_warn(pdev, "can't disable ASPM; OS doesn't have ASPM control\n");
|
||||
return;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (sem)
|
||||
@ -1105,11 +1105,13 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
mutex_unlock(&aspm_lock);
|
||||
if (sem)
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
|
||||
int pci_disable_link_state_locked(struct pci_dev *pdev, int state)
|
||||
{
|
||||
__pci_disable_link_state(pdev, state, false);
|
||||
return __pci_disable_link_state(pdev, state, false);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_link_state_locked);
|
||||
|
||||
@ -1117,14 +1119,14 @@ EXPORT_SYMBOL(pci_disable_link_state_locked);
|
||||
* pci_disable_link_state - Disable device's link state, so the link will
|
||||
* never enter specific states. Note that if the BIOS didn't grant ASPM
|
||||
* control to the OS, this does nothing because we can't touch the LNKCTL
|
||||
* register.
|
||||
* register. Returns 0 or a negative errno.
|
||||
*
|
||||
* @pdev: PCI device
|
||||
* @state: ASPM link state to disable
|
||||
*/
|
||||
void pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
int pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
{
|
||||
__pci_disable_link_state(pdev, state, true);
|
||||
return __pci_disable_link_state(pdev, state, true);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_link_state);
|
||||
|
||||
|
@ -24,11 +24,12 @@
|
||||
#define PCIE_LINK_STATE_CLKPM 4
|
||||
|
||||
#ifdef CONFIG_PCIEASPM
|
||||
void pci_disable_link_state(struct pci_dev *pdev, int state);
|
||||
void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
|
||||
int pci_disable_link_state(struct pci_dev *pdev, int state);
|
||||
int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
|
||||
void pcie_no_aspm(void);
|
||||
#else
|
||||
static inline void pci_disable_link_state(struct pci_dev *pdev, int state) { }
|
||||
static inline int pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
{ return 0; }
|
||||
static inline void pcie_no_aspm(void) { }
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user