mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-28 10:15:32 -05:00
Merge branch 'pci/pm'
- If a device has already been disconnected, e.g., by a hotplug removal, don't bother trying to resume it to D0 when detaching the driver (Mario Limonciello) - Ensure devices are powered up before config reads for 'max_link_width', 'current_link_speed', 'current_link_width', 'secondary_bus_number', and 'subordinate_bus_number' sysfs files (Brian Norris) * pci/pm: PCI/sysfs: Ensure devices are powered for config reads PCI/PM: Skip resuming to D0 if device is disconnected
This commit is contained in:
@@ -201,8 +201,14 @@ static ssize_t max_link_width_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
ssize_t ret;
|
||||
|
||||
return sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev));
|
||||
/* We read PCI_EXP_LNKCAP, so we need the device to be accessible. */
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
ret = sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev));
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static DEVICE_ATTR_RO(max_link_width);
|
||||
|
||||
@@ -214,7 +220,10 @@ static ssize_t current_link_speed_show(struct device *dev,
|
||||
int err;
|
||||
enum pci_bus_speed speed;
|
||||
|
||||
pci_config_pm_runtime_get(pci_dev);
|
||||
err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat);
|
||||
pci_config_pm_runtime_put(pci_dev);
|
||||
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -231,7 +240,10 @@ static ssize_t current_link_width_show(struct device *dev,
|
||||
u16 linkstat;
|
||||
int err;
|
||||
|
||||
pci_config_pm_runtime_get(pci_dev);
|
||||
err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat);
|
||||
pci_config_pm_runtime_put(pci_dev);
|
||||
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -247,7 +259,10 @@ static ssize_t secondary_bus_number_show(struct device *dev,
|
||||
u8 sec_bus;
|
||||
int err;
|
||||
|
||||
pci_config_pm_runtime_get(pci_dev);
|
||||
err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, &sec_bus);
|
||||
pci_config_pm_runtime_put(pci_dev);
|
||||
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -263,7 +278,10 @@ static ssize_t subordinate_bus_number_show(struct device *dev,
|
||||
u8 sub_bus;
|
||||
int err;
|
||||
|
||||
pci_config_pm_runtime_get(pci_dev);
|
||||
err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, &sub_bus);
|
||||
pci_config_pm_runtime_put(pci_dev);
|
||||
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -1374,6 +1374,11 @@ int pci_power_up(struct pci_dev *dev)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (pci_dev_is_disconnected(dev)) {
|
||||
dev->current_state = PCI_D3cold;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
|
||||
if (PCI_POSSIBLE_ERROR(pmcsr)) {
|
||||
pci_err(dev, "Unable to change power state from %s to D0, device inaccessible\n",
|
||||
|
||||
Reference in New Issue
Block a user