diff options
author | Lukas Wunner <lukas@wunner.de> | 2018-07-19 18:27:57 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2018-07-31 12:09:36 -0400 |
commit | 4417aa45c185376ece278430e33b6a1891a1dc36 (patch) | |
tree | 0e498444068e5ba5e4d8a280d972faabd2ff1e22 | |
parent | 8350307454240abeebe52ff5a73810d9ba93dd60 (diff) |
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>
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 14 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 7 |
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 3e73b12ed656..01fcf1fa0f66 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | 28 | ||
29 | #include "../pci.h" | ||
30 | |||
29 | /* Global variables */ | 31 | /* Global variables */ |
30 | bool pciehp_debug; | 32 | bool pciehp_debug; |
31 | bool pciehp_poll_mode; | 33 | bool pciehp_poll_mode; |
@@ -126,8 +128,11 @@ static void cleanup_slot(struct controller *ctrl) | |||
126 | static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | 128 | static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) |
127 | { | 129 | { |
128 | struct slot *slot = hotplug_slot->private; | 130 | struct slot *slot = hotplug_slot->private; |
131 | struct pci_dev *pdev = slot->ctrl->pcie->port; | ||
129 | 132 | ||
133 | pci_config_pm_runtime_get(pdev); | ||
130 | pciehp_set_attention_status(slot, status); | 134 | pciehp_set_attention_status(slot, status); |
135 | pci_config_pm_runtime_put(pdev); | ||
131 | return 0; | 136 | return 0; |
132 | } | 137 | } |
133 | 138 | ||
@@ -150,8 +155,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
150 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) | 155 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) |
151 | { | 156 | { |
152 | struct slot *slot = hotplug_slot->private; | 157 | struct slot *slot = hotplug_slot->private; |
158 | struct pci_dev *pdev = slot->ctrl->pcie->port; | ||
153 | 159 | ||
160 | pci_config_pm_runtime_get(pdev); | ||
154 | pciehp_get_power_status(slot, value); | 161 | pciehp_get_power_status(slot, value); |
162 | pci_config_pm_runtime_put(pdev); | ||
155 | return 0; | 163 | return 0; |
156 | } | 164 | } |
157 | 165 | ||
@@ -166,16 +174,22 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
166 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) | 174 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) |
167 | { | 175 | { |
168 | struct slot *slot = hotplug_slot->private; | 176 | struct slot *slot = hotplug_slot->private; |
177 | struct pci_dev *pdev = slot->ctrl->pcie->port; | ||
169 | 178 | ||
179 | pci_config_pm_runtime_get(pdev); | ||
170 | pciehp_get_latch_status(slot, value); | 180 | pciehp_get_latch_status(slot, value); |
181 | pci_config_pm_runtime_put(pdev); | ||
171 | return 0; | 182 | return 0; |
172 | } | 183 | } |
173 | 184 | ||
174 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | 185 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) |
175 | { | 186 | { |
176 | struct slot *slot = hotplug_slot->private; | 187 | struct slot *slot = hotplug_slot->private; |
188 | struct pci_dev *pdev = slot->ctrl->pcie->port; | ||
177 | 189 | ||
190 | pci_config_pm_runtime_get(pdev); | ||
178 | pciehp_get_adapter_status(slot, value); | 191 | pciehp_get_adapter_status(slot, value); |
192 | pci_config_pm_runtime_put(pdev); | ||
179 | return 0; | 193 | return 0; |
180 | } | 194 | } |
181 | 195 | ||
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 6e9b4330ad82..6f7de0819c88 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -322,7 +322,9 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot, | |||
322 | struct pci_dev *pdev = ctrl_dev(slot->ctrl); | 322 | struct pci_dev *pdev = ctrl_dev(slot->ctrl); |
323 | u16 slot_ctrl; | 323 | u16 slot_ctrl; |
324 | 324 | ||
325 | pci_config_pm_runtime_get(pdev); | ||
325 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); | 326 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); |
327 | pci_config_pm_runtime_put(pdev); | ||
326 | *status = (slot_ctrl & (PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC)) >> 6; | 328 | *status = (slot_ctrl & (PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC)) >> 6; |
327 | return 0; | 329 | return 0; |
328 | } | 330 | } |
@@ -333,7 +335,9 @@ void pciehp_get_attention_status(struct slot *slot, u8 *status) | |||
333 | struct pci_dev *pdev = ctrl_dev(ctrl); | 335 | struct pci_dev *pdev = ctrl_dev(ctrl); |
334 | u16 slot_ctrl; | 336 | u16 slot_ctrl; |
335 | 337 | ||
338 | pci_config_pm_runtime_get(pdev); | ||
336 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); | 339 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); |
340 | pci_config_pm_runtime_put(pdev); | ||
337 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, | 341 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, |
338 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); | 342 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
339 | 343 | ||
@@ -408,9 +412,12 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot, | |||
408 | { | 412 | { |
409 | struct slot *slot = hotplug_slot->private; | 413 | struct slot *slot = hotplug_slot->private; |
410 | struct controller *ctrl = slot->ctrl; | 414 | struct controller *ctrl = slot->ctrl; |
415 | struct pci_dev *pdev = ctrl_dev(ctrl); | ||
411 | 416 | ||
417 | pci_config_pm_runtime_get(pdev); | ||
412 | pcie_write_cmd_nowait(ctrl, status << 6, | 418 | pcie_write_cmd_nowait(ctrl, status << 6, |
413 | PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC); | 419 | PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC); |
420 | pci_config_pm_runtime_put(pdev); | ||
414 | return 0; | 421 | return 0; |
415 | } | 422 | } |
416 | 423 | ||