Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bd50dd8 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Jesse Barnes
Browse files

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: default avatarRafael J. Wysocki <rjw@sisk.pl>
Reviewed-by: default avatarHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 28eb5f27
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -259,20 +259,43 @@ static int get_port_device_capability(struct pci_dev *dev)
	/* Hot-Plug Capable */
	if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
		pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
		if (reg32 & PCI_EXP_SLTCAP_HPC)
		if (reg32 & PCI_EXP_SLTCAP_HPC) {
			services |= PCIE_PORT_SERVICE_HP;
			/*
			 * Disable hot-plug interrupts in case they have been
			 * enabled by the BIOS and the hot-plug service driver
			 * is not loaded.
			 */
			pos += PCI_EXP_SLTCTL;
			pci_read_config_word(dev, pos, &reg16);
			reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
			pci_write_config_word(dev, pos, reg16);
		}
	}
	/* AER capable */
	if ((cap_mask & PCIE_PORT_SERVICE_AER)
	    && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
	    && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
		services |= PCIE_PORT_SERVICE_AER;
		/*
		 * Disable AER on this port in case it's been enabled by the
		 * BIOS (the AER service driver will enable it when necessary).
		 */
		pci_disable_pcie_error_reporting(dev);
	}
	/* VC support */
	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
		services |= PCIE_PORT_SERVICE_VC;
	/* Root ports are capable of generating PME too */
	if ((cap_mask & PCIE_PORT_SERVICE_PME)
	    && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
	    && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
		services |= PCIE_PORT_SERVICE_PME;
		/*
		 * Disable PME interrupt on this port in case it's been enabled
		 * by the BIOS (the PME service driver will enable it when
		 * necessary).
		 */
		pcie_pme_interrupt_enable(dev, false);
	}

	return services;
}