aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-08-20 19:57:39 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-08-24 16:47:47 -0400
commit2bd50dd800b52245294cfceb56be62020cdc7515 (patch)
treeffefb8e50f9e454f332f318c415085ca2911991b
parent28eb5f274a305bf3a13b2c80c4804d4515d05c64 (diff)
PCI: PCIe: Disable PCIe port services during port initialization
In principle PCIe port services may be enabled by the BIOS, so it's better to disable them during port initialization to avoid spurious events from being generated. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/pcie/portdrv_core.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index d0245c83b621..a9c222d79ebc 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -259,20 +259,43 @@ static int get_port_device_capability(struct pci_dev *dev)
259 /* Hot-Plug Capable */ 259 /* Hot-Plug Capable */
260 if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) { 260 if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
261 pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32); 261 pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
262 if (reg32 & PCI_EXP_SLTCAP_HPC) 262 if (reg32 & PCI_EXP_SLTCAP_HPC) {
263 services |= PCIE_PORT_SERVICE_HP; 263 services |= PCIE_PORT_SERVICE_HP;
264 /*
265 * Disable hot-plug interrupts in case they have been
266 * enabled by the BIOS and the hot-plug service driver
267 * is not loaded.
268 */
269 pos += PCI_EXP_SLTCTL;
270 pci_read_config_word(dev, pos, &reg16);
271 reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
272 pci_write_config_word(dev, pos, reg16);
273 }
264 } 274 }
265 /* AER capable */ 275 /* AER capable */
266 if ((cap_mask & PCIE_PORT_SERVICE_AER) 276 if ((cap_mask & PCIE_PORT_SERVICE_AER)
267 && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) 277 && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
268 services |= PCIE_PORT_SERVICE_AER; 278 services |= PCIE_PORT_SERVICE_AER;
279 /*
280 * Disable AER on this port in case it's been enabled by the
281 * BIOS (the AER service driver will enable it when necessary).
282 */
283 pci_disable_pcie_error_reporting(dev);
284 }
269 /* VC support */ 285 /* VC support */
270 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) 286 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
271 services |= PCIE_PORT_SERVICE_VC; 287 services |= PCIE_PORT_SERVICE_VC;
272 /* Root ports are capable of generating PME too */ 288 /* Root ports are capable of generating PME too */
273 if ((cap_mask & PCIE_PORT_SERVICE_PME) 289 if ((cap_mask & PCIE_PORT_SERVICE_PME)
274 && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) 290 && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
275 services |= PCIE_PORT_SERVICE_PME; 291 services |= PCIE_PORT_SERVICE_PME;
292 /*
293 * Disable PME interrupt on this port in case it's been enabled
294 * by the BIOS (the PME service driver will enable it when
295 * necessary).
296 */
297 pcie_pme_interrupt_enable(dev, false);
298 }
276 299
277 return services; 300 return services;
278} 301}