67 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| commit 885c252ffb059dc493200bdb981bdd21cabe4442
 | |
| Author: Matthew Garrett <mjg@redhat.com>
 | |
| Date:   Thu Dec 9 18:31:59 2010 -0500
 | |
| 
 | |
|     PCI: _OSC "supported" field should contain supported features, not enabled ones
 | |
|     
 | |
|     From testing with Windows, the call to the PCI root _OSC method includes
 | |
|     the full set of features supported by the operating system even if the
 | |
|     hardware has already indicated that it doesn't support ASPM or MSI.
 | |
|     https://bugzilla.redhat.com/show_bug.cgi?id=638912 is a case where making
 | |
|     the _OSC call will incorrectly configure the chipset unless the supported
 | |
|     field has bits 1, 2 and 4 set. Rework the functionality to ensure that
 | |
|     we match this behaviour.
 | |
|     
 | |
|     Signed-off-by: Matthew Garrett <mjg@redhat.com>
 | |
| 
 | |
| diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
 | |
| index 96668ad..afb5d08 100644
 | |
| --- a/drivers/acpi/pci_root.c
 | |
| +++ b/drivers/acpi/pci_root.c
 | |
| @@ -450,7 +450,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
 | |
|  	struct acpi_pci_root *root;
 | |
|  	acpi_handle handle;
 | |
|  	struct acpi_device *child;
 | |
| -	u32 flags, base_flags;
 | |
| +	u32 flags;
 | |
|  
 | |
|  	root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
 | |
|  	if (!root)
 | |
| @@ -498,10 +498,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
 | |
|  	device->driver_data = root;
 | |
|  
 | |
|  	/*
 | |
| -	 * All supported architectures that use ACPI have support for
 | |
| -	 * PCI domains, so we indicate this in _OSC support capabilities.
 | |
| +	 * Indicate support for various _OSC capabilities. These match
 | |
| +	 * what the operating system supports, not what the hardware supports,
 | |
| +	 * so they shouldn't be conditional on functionality that's been
 | |
| +	 * blacklisted
 | |
|  	 */
 | |
| -	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
 | |
| +	flags = OSC_EXT_PCI_CONFIG_SUPPORT | OSC_ACTIVE_STATE_PWR_SUPPORT |
 | |
| +		OSC_CLOCK_PWR_CAPABILITY_SUPPORT |
 | |
| +		OSC_PCI_SEGMENT_GROUPS_SUPPORT | OSC_MSI_SUPPORT;
 | |
| +
 | |
|  	acpi_pci_osc_support(root, flags);
 | |
|  
 | |
|  	/*
 | |
| @@ -555,17 +560,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
 | |
|  	list_for_each_entry(child, &device->children, node)
 | |
|  		acpi_pci_bridge_scan(child);
 | |
|  
 | |
| -	/* Indicate support for various _OSC capabilities. */
 | |
| -	if (pci_ext_cfg_avail(root->bus->self))
 | |
| -		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
 | |
| -	if (pcie_aspm_enabled())
 | |
| -		flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
 | |
| -			OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
 | |
| -	if (pci_msi_enabled())
 | |
| -		flags |= OSC_MSI_SUPPORT;
 | |
| -	if (flags != base_flags)
 | |
| -		acpi_pci_osc_support(root, flags);
 | |
| -
 | |
|  	pci_acpi_add_bus_pm_notifier(device, root->bus);
 | |
|  	if (device->wakeup.flags.run_wake)
 | |
|  		device_set_run_wake(root->bus->bridge, true);
 |