PCI: pciehp: Resume parent to D0 on config space access
Ensure accessibility of a hotplug port's config space when accessed via sysfs by resuming its parent to D0. Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Cc: Mika Westerberg <mika.westerberg@linux.intel.com> Cc: Ashok Raj <ashok.raj@intel.com> Cc: Keith Busch <keith.busch@intel.com> Cc: Yinghai Lu <yinghai@kernel.org>
This commit is contained in:
Родитель
8350307454
Коммит
4417aa45c1
|
@ -26,6 +26,8 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include "../pci.h"
|
||||
|
||||
/* Global variables */
|
||||
bool pciehp_debug;
|
||||
bool pciehp_poll_mode;
|
||||
|
@ -126,8 +128,11 @@ static void cleanup_slot(struct controller *ctrl)
|
|||
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
|
||||
{
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
struct pci_dev *pdev = slot->ctrl->pcie->port;
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pciehp_set_attention_status(slot, status);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -150,8 +155,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
|
|||
static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
|
||||
{
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
struct pci_dev *pdev = slot->ctrl->pcie->port;
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pciehp_get_power_status(slot, value);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -166,16 +174,22 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
|
|||
static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
|
||||
{
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
struct pci_dev *pdev = slot->ctrl->pcie->port;
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pciehp_get_latch_status(slot, value);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
|
||||
{
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
struct pci_dev *pdev = slot->ctrl->pcie->port;
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pciehp_get_adapter_status(slot, value);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -322,7 +322,9 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot,
|
|||
struct pci_dev *pdev = ctrl_dev(slot->ctrl);
|
||||
u16 slot_ctrl;
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
*status = (slot_ctrl & (PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC)) >> 6;
|
||||
return 0;
|
||||
}
|
||||
|
@ -333,7 +335,9 @@ void pciehp_get_attention_status(struct slot *slot, u8 *status)
|
|||
struct pci_dev *pdev = ctrl_dev(ctrl);
|
||||
u16 slot_ctrl;
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,
|
||||
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
|
||||
|
||||
|
@ -408,9 +412,12 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
|
|||
{
|
||||
struct slot *slot = hotplug_slot->private;
|
||||
struct controller *ctrl = slot->ctrl;
|
||||
struct pci_dev *pdev = ctrl_dev(ctrl);
|
||||
|
||||
pci_config_pm_runtime_get(pdev);
|
||||
pcie_write_cmd_nowait(ctrl, status << 6,
|
||||
PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC);
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче