From b938a229c85a567de7dba2d806d9f63a7c90483e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:05:54 -0600 Subject: ACPI: Rename OSC_QUERY_TYPE to OSC_QUERY_DWORD OSC_QUERY_TYPE isn't a "type"; it's an index into the _OSC Capabilities Buffer of DWORDs. Rename OSC_QUERY_TYPE, OSC_SUPPORT_TYPE, and OSC_CONTROL_TYPE to OSC_QUERY_DWORD, etc., to make this clear. No functional change. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d3874f42565..323afd7ccfb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -158,14 +158,14 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, support &= OSC_PCI_SUPPORT_MASKS; support |= root->osc_support_set; - capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; - capbuf[OSC_SUPPORT_TYPE] = support; + capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; + capbuf[OSC_SUPPORT_DWORD] = support; if (control) { *control &= OSC_PCI_CONTROL_MASKS; - capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; + capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; } else { /* Run _OSC query only with existing controls. */ - capbuf[OSC_CONTROL_TYPE] = root->osc_control_set; + capbuf[OSC_CONTROL_DWORD] = root->osc_control_set; } status = acpi_pci_run_osc(root->device->handle, capbuf, &result); @@ -357,9 +357,9 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) goto out; } - capbuf[OSC_QUERY_TYPE] = 0; - capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; - capbuf[OSC_CONTROL_TYPE] = ctrl; + capbuf[OSC_QUERY_DWORD] = 0; + capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set; + capbuf[OSC_CONTROL_DWORD] = ctrl; status = acpi_pci_run_osc(handle, capbuf, mask); if (ACPI_SUCCESS(status)) root->osc_control_set = *mask; -- cgit v1.2.3-70-g09d2 From 7dab9ef4f0823072a3c9afdb3b373c9f2f38848b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:39 -0600 Subject: PCI/ACPI: Name _OSC #defines more consistently Make PCI Host Bridge _OSC #defines more consistent. No functional change. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 19 +++++++++---------- drivers/pci/hotplug/acpi_pcihp.c | 2 +- drivers/pci/hotplug/shpchp.h | 2 +- include/linux/acpi.h | 12 ++++++------ 4 files changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 323afd7ccfb..28dd5550978 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -49,10 +49,10 @@ static int acpi_pci_root_add(struct acpi_device *device, const struct acpi_device_id *not_used); static void acpi_pci_root_remove(struct acpi_device *device); -#define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ - | OSC_ACTIVE_STATE_PWR_SUPPORT \ - | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \ - | OSC_MSI_SUPPORT) +#define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \ + | OSC_PCI_ASPM_SUPPORT \ + | OSC_PCI_CLOCK_PM_SUPPORT \ + | OSC_PCI_MSI_SUPPORT) static const struct acpi_device_id root_device_ids[] = { {"PNP0A03", 0}, @@ -439,13 +439,12 @@ static int acpi_pci_root_add(struct acpi_device *device, acpi_pci_osc_support(root, flags); if (pci_ext_cfg_avail()) - flags |= OSC_EXT_PCI_CONFIG_SUPPORT; + flags |= OSC_PCI_EXT_CONFIG_SUPPORT; if (pcie_aspm_support_enabled()) { - flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | - OSC_CLOCK_PWR_CAPABILITY_SUPPORT; + flags |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; } if (pci_msi_enabled()) - flags |= OSC_MSI_SUPPORT; + flags |= OSC_PCI_MSI_SUPPORT; if (flags != base_flags) { status = acpi_pci_osc_support(root, flags); if (ACPI_FAILURE(status)) { @@ -458,7 +457,7 @@ static int acpi_pci_root_add(struct acpi_device *device, if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { - flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL + flags = OSC_PCI_EXPRESS_CAPABILITY_CONTROL | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | OSC_PCI_EXPRESS_PME_CONTROL; @@ -474,7 +473,7 @@ static int acpi_pci_root_add(struct acpi_device *device, "Requesting ACPI _OSC control (0x%02x)\n", flags); status = acpi_pci_osc_control_set(handle, &flags, - OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + OSC_PCI_EXPRESS_CAPABILITY_CONTROL); if (ACPI_SUCCESS(status)) { dev_info(&device->dev, "ACPI _OSC control (0x%02x) granted\n", flags); diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 2a47e82821d..f8140164ec0 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -338,7 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) acpi_handle chandle, handle; struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; - flags &= OSC_SHPC_NATIVE_HP_CONTROL; + flags &= OSC_PCI_SHPC_NATIVE_HP_CONTROL; if (!flags) { err("Invalid flags %u specified!\n", flags); return -EINVAL; diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index e260f207a90..d876e4b3c6a 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -191,7 +191,7 @@ static inline const char *slot_name(struct slot *slot) #include static inline int get_hp_hw_control_from_firmware(struct pci_dev *dev) { - u32 flags = OSC_SHPC_NATIVE_HP_CONTROL; + u32 flags = OSC_PCI_SHPC_NATIVE_HP_CONTROL; return acpi_get_hp_hw_control_from_firmware(dev, flags); } #else diff --git a/include/linux/acpi.h b/include/linux/acpi.h index bb4e7701b26..e2e52cf5322 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -325,19 +325,19 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); extern bool osc_sb_apei_support_acked; /* PCI Host Bridge _OSC: Capabilities DWORD 2: Support Field */ -#define OSC_EXT_PCI_CONFIG_SUPPORT 0x00000001 -#define OSC_ACTIVE_STATE_PWR_SUPPORT 0x00000002 -#define OSC_CLOCK_PWR_CAPABILITY_SUPPORT 0x00000004 +#define OSC_PCI_EXT_CONFIG_SUPPORT 0x00000001 +#define OSC_PCI_ASPM_SUPPORT 0x00000002 +#define OSC_PCI_CLOCK_PM_SUPPORT 0x00000004 #define OSC_PCI_SEGMENT_GROUPS_SUPPORT 0x00000008 -#define OSC_MSI_SUPPORT 0x00000010 +#define OSC_PCI_MSI_SUPPORT 0x00000010 #define OSC_PCI_SUPPORT_MASKS 0x0000001f /* PCI Host Bridge _OSC: Capabilities DWORD 3: Control Field */ #define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 0x00000001 -#define OSC_SHPC_NATIVE_HP_CONTROL 0x00000002 +#define OSC_PCI_SHPC_NATIVE_HP_CONTROL 0x00000002 #define OSC_PCI_EXPRESS_PME_CONTROL 0x00000004 #define OSC_PCI_EXPRESS_AER_CONTROL 0x00000008 -#define OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL 0x00000010 +#define OSC_PCI_EXPRESS_CAPABILITY_CONTROL 0x00000010 #define OSC_PCI_CONTROL_MASKS 0x0000001f extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, -- cgit v1.2.3-70-g09d2 From 4ffe6e54b0ce259d254e7740a7a4a99dad14a484 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:41 -0600 Subject: PCI/ACPI: Drop unnecessary _OSC existence tests There's no need to check whether _OSC exists here; we eventually call acpi_evaluate_object(..., "_OSC", ...), and that will fail gracefully if _OSC doesn't exist. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 28dd5550978..cc87cc4fea0 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -180,11 +180,7 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) { acpi_status status; - acpi_handle tmp; - status = acpi_get_handle(root->device->handle, "_OSC", &tmp); - if (ACPI_FAILURE(status)) - return status; mutex_lock(&osc_lock); status = acpi_pci_query_osc(root, flags, NULL); mutex_unlock(&osc_lock); @@ -316,9 +312,8 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev); acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) { struct acpi_pci_root *root; - acpi_status status; + acpi_status status = AE_OK; u32 ctrl, capbuf[3]; - acpi_handle tmp; if (!mask) return AE_BAD_PARAMETER; @@ -331,10 +326,6 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) if (!root) return AE_NOT_EXIST; - status = acpi_get_handle(handle, "_OSC", &tmp); - if (ACPI_FAILURE(status)) - return status; - mutex_lock(&osc_lock); *mask = ctrl | root->osc_control_set; -- cgit v1.2.3-70-g09d2 From 3e43abb012d45dc284ef9a0fb0cea0fb004b5607 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:41 -0600 Subject: PCI/ACPI: Move _OSC stuff from acpi_pci_root_add() to negotiate_os_control() This doesn't change any of the _OSC code; it just moves it out into a new function so it doesn't clutter acpi_pci_root_add() so much. This also enables future simplifications. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 132 ++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 61 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index cc87cc4fea0..3e57f104e09 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -360,67 +360,13 @@ out: } EXPORT_SYMBOL(acpi_pci_osc_control_set); -static int acpi_pci_root_add(struct acpi_device *device, - const struct acpi_device_id *not_used) +static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, + int *clear_aspm) { - unsigned long long segment, bus; - acpi_status status; - int result; - struct acpi_pci_root *root; u32 flags, base_flags; + acpi_status status; + struct acpi_device *device = root->device; acpi_handle handle = device->handle; - bool no_aspm = false, clear_aspm = false; - - root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); - if (!root) - return -ENOMEM; - - segment = 0; - status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, - &segment); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - dev_err(&device->dev, "can't evaluate _SEG\n"); - result = -ENODEV; - goto end; - } - - /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ - root->secondary.flags = IORESOURCE_BUS; - status = try_get_root_bridge_busnr(handle, &root->secondary); - if (ACPI_FAILURE(status)) { - /* - * We need both the start and end of the downstream bus range - * to interpret _CBA (MMCONFIG base address), so it really is - * supposed to be in _CRS. If we don't find it there, all we - * can do is assume [_BBN-0xFF] or [0-0xFF]. - */ - root->secondary.end = 0xFF; - dev_warn(&device->dev, - FW_BUG "no secondary bus range in _CRS\n"); - status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, - NULL, &bus); - if (ACPI_SUCCESS(status)) - root->secondary.start = bus; - else if (status == AE_NOT_FOUND) - root->secondary.start = 0; - else { - dev_err(&device->dev, "can't evaluate _BBN\n"); - result = -ENODEV; - goto end; - } - } - - root->device = device; - root->segment = segment & 0xFFFF; - strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); - device->driver_data = root; - - pr_info(PREFIX "%s [%s] (domain %04x %pR)\n", - acpi_device_name(device), acpi_device_bid(device), - root->segment, &root->secondary); - - root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); /* * All supported architectures that use ACPI have support for @@ -441,7 +387,7 @@ static int acpi_pci_root_add(struct acpi_device *device, if (ACPI_FAILURE(status)) { dev_info(&device->dev, "ACPI _OSC support " "notification failed, disabling PCIe ASPM\n"); - no_aspm = true; + *no_aspm = 1; flags = base_flags; } } @@ -473,7 +419,7 @@ static int acpi_pci_root_add(struct acpi_device *device, * We have ASPM control, but the FADT indicates * that it's unsupported. Clear it. */ - clear_aspm = true; + *clear_aspm = 1; } } else { dev_info(&device->dev, @@ -489,13 +435,77 @@ static int acpi_pci_root_add(struct acpi_device *device, * flag here, to defer the action until after the ACPI * root scan. */ - no_aspm = true; + *no_aspm = 1; } } else { dev_info(&device->dev, "Unable to request _OSC control " "(_OSC support mask: 0x%02x)\n", flags); } +} + +static int acpi_pci_root_add(struct acpi_device *device, + const struct acpi_device_id *not_used) +{ + unsigned long long segment, bus; + acpi_status status; + int result; + struct acpi_pci_root *root; + acpi_handle handle = device->handle; + int no_aspm = 0, clear_aspm = 0; + + root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + if (!root) + return -ENOMEM; + + segment = 0; + status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, + &segment); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + dev_err(&device->dev, "can't evaluate _SEG\n"); + result = -ENODEV; + goto end; + } + + /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ + root->secondary.flags = IORESOURCE_BUS; + status = try_get_root_bridge_busnr(handle, &root->secondary); + if (ACPI_FAILURE(status)) { + /* + * We need both the start and end of the downstream bus range + * to interpret _CBA (MMCONFIG base address), so it really is + * supposed to be in _CRS. If we don't find it there, all we + * can do is assume [_BBN-0xFF] or [0-0xFF]. + */ + root->secondary.end = 0xFF; + dev_warn(&device->dev, + FW_BUG "no secondary bus range in _CRS\n"); + status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, + NULL, &bus); + if (ACPI_SUCCESS(status)) + root->secondary.start = bus; + else if (status == AE_NOT_FOUND) + root->secondary.start = 0; + else { + dev_err(&device->dev, "can't evaluate _BBN\n"); + result = -ENODEV; + goto end; + } + } + + root->device = device; + root->segment = segment & 0xFFFF; + strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); + device->driver_data = root; + + pr_info(PREFIX "%s [%s] (domain %04x %pR)\n", + acpi_device_name(device), acpi_device_bid(device), + root->segment, &root->secondary); + + root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); + + negotiate_os_control(root, &no_aspm, &clear_aspm); /* * TBD: Need PCI interface for enumeration/configuration of roots. -- cgit v1.2.3-70-g09d2 From b8eb67fcc4548b9f0d00bbfd1c0c8f72d8018900 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:42 -0600 Subject: PCI/ACPI: Split _OSC "support" and "control" flags into separate variables Previously we used "flags" for both: - the bitmask of features we support (segments, ASPM, MSI, etc.), and - the bitmask of features we want to control (native hotplug, AER, etc.) To reduce confusion, this patch splits this into two variables: "support" is the bitmask of features we support, and "control" is the bitmask of features we want to control. No functional change. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 3e57f104e09..3e06d4e179e 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -363,7 +363,7 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, int *clear_aspm) { - u32 flags, base_flags; + u32 support, base_support, control; acpi_status status; struct acpi_device *device = root->device; acpi_handle handle = device->handle; @@ -372,29 +372,29 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, * All supported architectures that use ACPI have support for * PCI domains, so we indicate this in _OSC support capabilities. */ - flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; - acpi_pci_osc_support(root, flags); + support = base_support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; + acpi_pci_osc_support(root, support); if (pci_ext_cfg_avail()) - flags |= OSC_PCI_EXT_CONFIG_SUPPORT; + support |= OSC_PCI_EXT_CONFIG_SUPPORT; if (pcie_aspm_support_enabled()) { - flags |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; + support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; } if (pci_msi_enabled()) - flags |= OSC_PCI_MSI_SUPPORT; - if (flags != base_flags) { - status = acpi_pci_osc_support(root, flags); + support |= OSC_PCI_MSI_SUPPORT; + if (support != base_support) { + status = acpi_pci_osc_support(root, support); if (ACPI_FAILURE(status)) { dev_info(&device->dev, "ACPI _OSC support " "notification failed, disabling PCIe ASPM\n"); *no_aspm = 1; - flags = base_flags; + support = base_support; } } if (!pcie_ports_disabled - && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { - flags = OSC_PCI_EXPRESS_CAPABILITY_CONTROL + && (support & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { + control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | OSC_PCI_EXPRESS_PME_CONTROL; @@ -403,17 +403,18 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, dev_dbg(&device->dev, "PCIe errors handled by BIOS.\n"); else - flags |= OSC_PCI_EXPRESS_AER_CONTROL; + control |= OSC_PCI_EXPRESS_AER_CONTROL; } dev_info(&device->dev, - "Requesting ACPI _OSC control (0x%02x)\n", flags); + "Requesting ACPI _OSC control (0x%02x)\n", control); - status = acpi_pci_osc_control_set(handle, &flags, + status = acpi_pci_osc_control_set(handle, &control, OSC_PCI_EXPRESS_CAPABILITY_CONTROL); if (ACPI_SUCCESS(status)) { dev_info(&device->dev, - "ACPI _OSC control (0x%02x) granted\n", flags); + "ACPI _OSC control (0x%02x) granted\n", + control); if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { /* * We have ASPM control, but the FADT indicates @@ -425,7 +426,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, dev_info(&device->dev, "ACPI _OSC request failed (%s), " "returned control mask: 0x%02x\n", - acpi_format_exception(status), flags); + acpi_format_exception(status), control); dev_info(&device->dev, "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); /* @@ -440,7 +441,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, } else { dev_info(&device->dev, "Unable to request _OSC control " - "(_OSC support mask: 0x%02x)\n", flags); + "(_OSC support mask: 0x%02x)\n", support); } } -- cgit v1.2.3-70-g09d2 From 1b2a7be60eaaf17bc88368d748471dd70e40befd Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:42 -0600 Subject: PCI/ACPI: Run _OSC only once for OSPM feature support Previously, we ran _OSC once to tell the platform that we support PCI Segment Groups, then we ran it again if we supported any additional features (ASPM, MSI, or extended config space). I don't think it's necessary to run it twice, since we can easily build the complete mask of features we support before running _OSC the first time. We run _OSC again later when requesting control of PCIe features; that's unaffected by this change. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 3e06d4e179e..0e2004100c4 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -373,23 +373,18 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, * PCI domains, so we indicate this in _OSC support capabilities. */ support = base_support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; - acpi_pci_osc_support(root, support); - if (pci_ext_cfg_avail()) support |= OSC_PCI_EXT_CONFIG_SUPPORT; - if (pcie_aspm_support_enabled()) { + if (pcie_aspm_support_enabled()) support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; - } if (pci_msi_enabled()) support |= OSC_PCI_MSI_SUPPORT; - if (support != base_support) { - status = acpi_pci_osc_support(root, support); - if (ACPI_FAILURE(status)) { - dev_info(&device->dev, "ACPI _OSC support " - "notification failed, disabling PCIe ASPM\n"); - *no_aspm = 1; - support = base_support; - } + status = acpi_pci_osc_support(root, support); + if (ACPI_FAILURE(status)) { + dev_info(&device->dev, "ACPI _OSC support " + "notification failed, disabling PCIe ASPM\n"); + *no_aspm = 1; + support = base_support; } if (!pcie_ports_disabled -- cgit v1.2.3-70-g09d2 From 65afe91622c456560e20d57a779b807c20822e81 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:43 -0600 Subject: PCI/ACPI: Skip _OSC control tests if _OSC support call failed If the _OSC support notification fails, we will never request control (because "support == OSC_PCI_SEGMENT_GROUPS_SUPPORT", which doesn't include all the features in ACPI_PCIE_REQ_SUPPORT), so we can return early to simplify the code. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0e2004100c4..67cc43a134a 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -363,7 +363,7 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, int *clear_aspm) { - u32 support, base_support, control; + u32 support, control; acpi_status status; struct acpi_device *device = root->device; acpi_handle handle = device->handle; @@ -372,7 +372,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, * All supported architectures that use ACPI have support for * PCI domains, so we indicate this in _OSC support capabilities. */ - support = base_support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; + support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; if (pci_ext_cfg_avail()) support |= OSC_PCI_EXT_CONFIG_SUPPORT; if (pcie_aspm_support_enabled()) @@ -381,10 +381,10 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, support |= OSC_PCI_MSI_SUPPORT; status = acpi_pci_osc_support(root, support); if (ACPI_FAILURE(status)) { - dev_info(&device->dev, "ACPI _OSC support " - "notification failed, disabling PCIe ASPM\n"); + dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n", + acpi_format_exception(status)); *no_aspm = 1; - support = base_support; + return; } if (!pcie_ports_disabled -- cgit v1.2.3-70-g09d2 From 43613a1fac0eec78de14fecc9de184e1052abac7 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:43 -0600 Subject: PCI/ACPI: Separate out _OSC "PCIe port services disabled" path Test "pcie_ports_disabled" separately so we can give a better message. Previously we said "Unable to request _OSC control..."; now we'll say "PCIe port services disabled; not requesting _OSC control". "pcie_ports_disabled" is true when CONFIG_PCIEPORTBUS=n or we boot with "pcie_ports=compat". Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 67cc43a134a..68e5a187e78 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -387,8 +387,12 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, return; } - if (!pcie_ports_disabled - && (support & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { + if (pcie_ports_disabled) { + dev_info(&device->dev, "PCIe port services disabled; not requesting _OSC control\n"); + return; + } + + if ((support & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | OSC_PCI_EXPRESS_PME_CONTROL; -- cgit v1.2.3-70-g09d2 From de18966228ed4b42393ecbe83ba20ff3db78bfdc Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:50:52 -0600 Subject: PCI/ACPI: Separate out _OSC "we don't support enough services" path Test the services we support (extended config space, ASPM, MSI) separately so we can give a better message. Previously we said "Unable to request _OSC control..."; now we'll say "we support %#02x but %#02x are required". Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 84 ++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 68e5a187e78..65aefcf7855 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -392,55 +392,55 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, return; } - if ((support & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { - control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL - | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL - | OSC_PCI_EXPRESS_PME_CONTROL; - - if (pci_aer_available()) { - if (aer_acpi_firmware_first()) - dev_dbg(&device->dev, - "PCIe errors handled by BIOS.\n"); - else - control |= OSC_PCI_EXPRESS_AER_CONTROL; - } + if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { + dev_info(&device->dev, "Not requesting _OSC control (we support %#02x but %#02x are required)\n", + support, ACPI_PCIE_REQ_SUPPORT); + return; + } + + control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL + | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL + | OSC_PCI_EXPRESS_PME_CONTROL; + + if (pci_aer_available()) { + if (aer_acpi_firmware_first()) + dev_dbg(&device->dev, + "PCIe errors handled by BIOS.\n"); + else + control |= OSC_PCI_EXPRESS_AER_CONTROL; + } + dev_info(&device->dev, + "Requesting ACPI _OSC control (0x%02x)\n", control); + + status = acpi_pci_osc_control_set(handle, &control, + OSC_PCI_EXPRESS_CAPABILITY_CONTROL); + if (ACPI_SUCCESS(status)) { dev_info(&device->dev, - "Requesting ACPI _OSC control (0x%02x)\n", control); - - status = acpi_pci_osc_control_set(handle, &control, - OSC_PCI_EXPRESS_CAPABILITY_CONTROL); - if (ACPI_SUCCESS(status)) { - dev_info(&device->dev, - "ACPI _OSC control (0x%02x) granted\n", - control); - if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { - /* - * We have ASPM control, but the FADT indicates - * that it's unsupported. Clear it. - */ - *clear_aspm = 1; - } - } else { - dev_info(&device->dev, - "ACPI _OSC request failed (%s), " - "returned control mask: 0x%02x\n", - acpi_format_exception(status), control); - dev_info(&device->dev, - "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); + "ACPI _OSC control (0x%02x) granted\n", + control); + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { /* - * We want to disable ASPM here, but aspm_disabled - * needs to remain in its state from boot so that we - * properly handle PCIe 1.1 devices. So we set this - * flag here, to defer the action until after the ACPI - * root scan. + * We have ASPM control, but the FADT indicates + * that it's unsupported. Clear it. */ - *no_aspm = 1; + *clear_aspm = 1; } } else { dev_info(&device->dev, - "Unable to request _OSC control " - "(_OSC support mask: 0x%02x)\n", support); + "ACPI _OSC request failed (%s), " + "returned control mask: 0x%02x\n", + acpi_format_exception(status), control); + dev_info(&device->dev, + "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); + /* + * We want to disable ASPM here, but aspm_disabled + * needs to remain in its state from boot so that we + * properly handle PCIe 1.1 devices. So we set this + * flag here, to defer the action until after the ACPI + * root scan. + */ + *no_aspm = 1; } } -- cgit v1.2.3-70-g09d2 From 955f14b4ed0648da12f0a7011f94150b8982a5c2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 5 Sep 2013 15:07:45 -0600 Subject: PCI/ACPI: Decode _OSC bitmasks symbolically This updates _OSC-related messages to be more human-readable. We now always show the features we declare support for (this was previously invisible) as well as the features we are granted control of. Typical changes: -acpi PNP0A08:00: Requesting ACPI _OSC control (0x1d) -acpi PNP0A08:00: ACPI _OSC control (0x1d) granted +acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI] +acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug PME AER PCIeCapability] Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 84 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 17 deletions(-) (limited to 'drivers/acpi/pci_root.c') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 65aefcf7855..924ad92852c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -127,6 +127,55 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, return AE_OK; } +struct pci_osc_bit_struct { + u32 bit; + char *desc; +}; + +static struct pci_osc_bit_struct pci_osc_support_bit[] = { + { OSC_PCI_EXT_CONFIG_SUPPORT, "ExtendedConfig" }, + { OSC_PCI_ASPM_SUPPORT, "ASPM" }, + { OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM" }, + { OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments" }, + { OSC_PCI_MSI_SUPPORT, "MSI" }, +}; + +static struct pci_osc_bit_struct pci_osc_control_bit[] = { + { OSC_PCI_EXPRESS_NATIVE_HP_CONTROL, "PCIeHotplug" }, + { OSC_PCI_SHPC_NATIVE_HP_CONTROL, "SHPCHotplug" }, + { OSC_PCI_EXPRESS_PME_CONTROL, "PME" }, + { OSC_PCI_EXPRESS_AER_CONTROL, "AER" }, + { OSC_PCI_EXPRESS_CAPABILITY_CONTROL, "PCIeCapability" }, +}; + +static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word, + struct pci_osc_bit_struct *table, int size) +{ + char buf[80]; + int i, len = 0; + struct pci_osc_bit_struct *entry; + + buf[0] = '\0'; + for (i = 0, entry = table; i < size; i++, entry++) + if (word & entry->bit) + len += snprintf(buf + len, sizeof(buf) - len, "%s%s", + len ? " " : "", entry->desc); + + dev_info(&root->device->dev, "_OSC: %s [%s]\n", msg, buf); +} + +static void decode_osc_support(struct acpi_pci_root *root, char *msg, u32 word) +{ + decode_osc_bits(root, msg, word, pci_osc_support_bit, + ARRAY_SIZE(pci_osc_support_bit)); +} + +static void decode_osc_control(struct acpi_pci_root *root, char *msg, u32 word) +{ + decode_osc_bits(root, msg, word, pci_osc_control_bit, + ARRAY_SIZE(pci_osc_control_bit)); +} + static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; static acpi_status acpi_pci_run_osc(acpi_handle handle, @@ -340,10 +389,14 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) goto out; if (ctrl == *mask) break; + decode_osc_control(root, "platform does not support", + ctrl & ~(*mask)); ctrl = *mask; } if ((ctrl & req) != req) { + decode_osc_control(root, "not requesting control; platform does not support", + req & ~(ctrl)); status = AE_SUPPORT; goto out; } @@ -363,7 +416,7 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, int *clear_aspm) { - u32 support, control; + u32 support, control, requested; acpi_status status; struct acpi_device *device = root->device; acpi_handle handle = device->handle; @@ -379,6 +432,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; if (pci_msi_enabled()) support |= OSC_PCI_MSI_SUPPORT; + + decode_osc_support(root, "OS supports", support); status = acpi_pci_osc_support(root, support); if (ACPI_FAILURE(status)) { dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n", @@ -393,8 +448,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, } if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { - dev_info(&device->dev, "Not requesting _OSC control (we support %#02x but %#02x are required)\n", - support, ACPI_PCIE_REQ_SUPPORT); + decode_osc_support(root, "not requesting OS control; OS requires", + ACPI_PCIE_REQ_SUPPORT); return; } @@ -404,21 +459,17 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, if (pci_aer_available()) { if (aer_acpi_firmware_first()) - dev_dbg(&device->dev, - "PCIe errors handled by BIOS.\n"); + dev_info(&device->dev, + "PCIe AER handled by firmware\n"); else control |= OSC_PCI_EXPRESS_AER_CONTROL; } - dev_info(&device->dev, - "Requesting ACPI _OSC control (0x%02x)\n", control); - + requested = control; status = acpi_pci_osc_control_set(handle, &control, OSC_PCI_EXPRESS_CAPABILITY_CONTROL); if (ACPI_SUCCESS(status)) { - dev_info(&device->dev, - "ACPI _OSC control (0x%02x) granted\n", - control); + decode_osc_control(root, "OS now controls", control); if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { /* * We have ASPM control, but the FADT indicates @@ -427,12 +478,11 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, *clear_aspm = 1; } } else { - dev_info(&device->dev, - "ACPI _OSC request failed (%s), " - "returned control mask: 0x%02x\n", - acpi_format_exception(status), control); - dev_info(&device->dev, - "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); + decode_osc_control(root, "OS requested", requested); + decode_osc_control(root, "platform willing to grant", control); + dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n", + acpi_format_exception(status)); + /* * We want to disable ASPM here, but aspm_disabled * needs to remain in its state from boot so that we -- cgit v1.2.3-70-g09d2