mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	PCI: pciehp: Make pciehp_is_native() stricter
Previously pciehp_is_native() returned true for any PCI device in a hierarchy where _OSC says we can use pciehp. This is incorrect because bridges without PCI_EXP_SLTCAP_HPC capability should be managed by acpiphp instead. Improve pciehp_is_native() to return true only when PCI_EXP_SLTCAP_HPC is set and the pciehp driver is present. In any other case return false to let acpiphp handle those. Suggested-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> [bhelgaas: remove NULL pointer check] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
		
							parent
							
								
									9310f0dc1c
								
							
						
					
					
						commit
						5352a44a56
					
				
					 4 changed files with 18 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -370,26 +370,28 @@ EXPORT_SYMBOL_GPL(pci_get_hp_params);
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * pciehp_is_native - Check whether a hotplug port is handled by the OS
 | 
			
		||||
 * @pdev: Hotplug port to check
 | 
			
		||||
 * @bridge: Hotplug port to check
 | 
			
		||||
 *
 | 
			
		||||
 * Walk up from @pdev to the host bridge, obtain its cached _OSC Control Field
 | 
			
		||||
 * and return the value of the "PCI Express Native Hot Plug control" bit.
 | 
			
		||||
 * On failure to obtain the _OSC Control Field return %false.
 | 
			
		||||
 * Returns true if the given @bridge is handled by the native PCIe hotplug
 | 
			
		||||
 * driver.
 | 
			
		||||
 */
 | 
			
		||||
bool pciehp_is_native(struct pci_dev *pdev)
 | 
			
		||||
bool pciehp_is_native(struct pci_dev *bridge)
 | 
			
		||||
{
 | 
			
		||||
	struct acpi_pci_root *root;
 | 
			
		||||
	acpi_handle handle;
 | 
			
		||||
	const struct pci_host_bridge *host;
 | 
			
		||||
	u32 slot_cap;
 | 
			
		||||
 | 
			
		||||
	handle = acpi_find_root_bridge_handle(pdev);
 | 
			
		||||
	if (!handle)
 | 
			
		||||
	if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	root = acpi_pci_find_root(handle);
 | 
			
		||||
	if (!root)
 | 
			
		||||
	pcie_capability_read_dword(bridge, PCI_EXP_SLTCAP, &slot_cap);
 | 
			
		||||
	if (!(slot_cap & PCI_EXP_SLTCAP_HPC))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	return root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL;
 | 
			
		||||
	if (pcie_ports_native)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	host = pci_find_host_bridge(bridge->bus);
 | 
			
		||||
	return host->native_pcie_hotplug;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,6 @@
 | 
			
		|||
 | 
			
		||||
#include <linux/compiler.h>
 | 
			
		||||
 | 
			
		||||
extern bool pcie_ports_native;
 | 
			
		||||
 | 
			
		||||
/* Service Type */
 | 
			
		||||
#define PCIE_PORT_SERVICE_PME_SHIFT	0	/* Power Management Event */
 | 
			
		||||
#define PCIE_PORT_SERVICE_PME		(1 << PCIE_PORT_SERVICE_PME_SHIFT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1454,8 +1454,10 @@ static inline int pci_irqd_intx_xlate(struct irq_domain *d,
 | 
			
		|||
 | 
			
		||||
#ifdef CONFIG_PCIEPORTBUS
 | 
			
		||||
extern bool pcie_ports_disabled;
 | 
			
		||||
extern bool pcie_ports_native;
 | 
			
		||||
#else
 | 
			
		||||
#define pcie_ports_disabled	true
 | 
			
		||||
#define pcie_ports_native	false
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PCIEASPM
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -162,7 +162,7 @@ struct hotplug_params {
 | 
			
		|||
#ifdef CONFIG_ACPI
 | 
			
		||||
#include <linux/acpi.h>
 | 
			
		||||
int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp);
 | 
			
		||||
bool pciehp_is_native(struct pci_dev *pdev);
 | 
			
		||||
bool pciehp_is_native(struct pci_dev *bridge);
 | 
			
		||||
int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags);
 | 
			
		||||
int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
 | 
			
		||||
int acpi_pci_detect_ejectable(acpi_handle handle);
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +172,6 @@ static inline int pci_get_hp_params(struct pci_dev *dev,
 | 
			
		|||
{
 | 
			
		||||
	return -ENODEV;
 | 
			
		||||
}
 | 
			
		||||
static inline bool pciehp_is_native(struct pci_dev *pdev) { return true; }
 | 
			
		||||
static inline bool pciehp_is_native(struct pci_dev *bridge) { return true; }
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue