aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c97
1 files changed, 56 insertions, 41 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 1f67057af2a5..3ba8d1f44a73 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -33,7 +33,6 @@
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/pci-acpi.h> 35#include <linux/pci-acpi.h>
36#include <linux/pci-aspm.h>
37#include <linux/acpi.h> 36#include <linux/acpi.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
39#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -226,22 +225,31 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle,
226 return status; 225 return status;
227} 226}
228 227
229static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) 228static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
229 u32 support,
230 u32 *control)
230{ 231{
231 acpi_status status; 232 acpi_status status;
232 u32 support_set, result, capbuf[3]; 233 u32 result, capbuf[3];
234
235 support &= OSC_PCI_SUPPORT_MASKS;
236 support |= root->osc_support_set;
233 237
234 /* do _OSC query for all possible controls */
235 support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS);
236 capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; 238 capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
237 capbuf[OSC_SUPPORT_TYPE] = support_set; 239 capbuf[OSC_SUPPORT_TYPE] = support;
238 capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; 240 if (control) {
241 *control &= OSC_PCI_CONTROL_MASKS;
242 capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
243 } else {
244 /* Run _OSC query for all possible controls. */
245 capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
246 }
239 247
240 status = acpi_pci_run_osc(root->device->handle, capbuf, &result); 248 status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
241 if (ACPI_SUCCESS(status)) { 249 if (ACPI_SUCCESS(status)) {
242 root->osc_support_set = support_set; 250 root->osc_support_set = support;
243 root->osc_control_qry = result; 251 if (control)
244 root->osc_queried = 1; 252 *control = result;
245 } 253 }
246 return status; 254 return status;
247} 255}
@@ -255,7 +263,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
255 if (ACPI_FAILURE(status)) 263 if (ACPI_FAILURE(status))
256 return status; 264 return status;
257 mutex_lock(&osc_lock); 265 mutex_lock(&osc_lock);
258 status = acpi_pci_query_osc(root, flags); 266 status = acpi_pci_query_osc(root, flags, NULL);
259 mutex_unlock(&osc_lock); 267 mutex_unlock(&osc_lock);
260 return status; 268 return status;
261} 269}
@@ -365,55 +373,70 @@ out:
365EXPORT_SYMBOL_GPL(acpi_get_pci_dev); 373EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
366 374
367/** 375/**
368 * acpi_pci_osc_control_set - commit requested control to Firmware 376 * acpi_pci_osc_control_set - Request control of PCI root _OSC features.
369 * @handle: acpi_handle for the target ACPI object 377 * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
370 * @flags: driver's requested control bits 378 * @mask: Mask of _OSC bits to request control of, place to store control mask.
379 * @req: Mask of _OSC bits the control of is essential to the caller.
380 *
381 * Run _OSC query for @mask and if that is successful, compare the returned
382 * mask of control bits with @req. If all of the @req bits are set in the
383 * returned mask, run _OSC request for it.
371 * 384 *
372 * Attempt to take control from Firmware on requested control bits. 385 * The variable at the @mask address may be modified regardless of whether or
386 * not the function returns success. On success it will contain the mask of
387 * _OSC bits the BIOS has granted control of, but its contents are meaningless
388 * on failure.
373 **/ 389 **/
374acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags) 390acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
375{ 391{
392 struct acpi_pci_root *root;
376 acpi_status status; 393 acpi_status status;
377 u32 control_req, result, capbuf[3]; 394 u32 ctrl, capbuf[3];
378 acpi_handle tmp; 395 acpi_handle tmp;
379 struct acpi_pci_root *root;
380 396
381 status = acpi_get_handle(handle, "_OSC", &tmp); 397 if (!mask)
382 if (ACPI_FAILURE(status)) 398 return AE_BAD_PARAMETER;
383 return status;
384 399
385 control_req = (flags & OSC_PCI_CONTROL_MASKS); 400 ctrl = *mask & OSC_PCI_CONTROL_MASKS;
386 if (!control_req) 401 if ((ctrl & req) != req)
387 return AE_TYPE; 402 return AE_TYPE;
388 403
389 root = acpi_pci_find_root(handle); 404 root = acpi_pci_find_root(handle);
390 if (!root) 405 if (!root)
391 return AE_NOT_EXIST; 406 return AE_NOT_EXIST;
392 407
408 status = acpi_get_handle(handle, "_OSC", &tmp);
409 if (ACPI_FAILURE(status))
410 return status;
411
393 mutex_lock(&osc_lock); 412 mutex_lock(&osc_lock);
413
414 *mask = ctrl | root->osc_control_set;
394 /* No need to evaluate _OSC if the control was already granted. */ 415 /* No need to evaluate _OSC if the control was already granted. */
395 if ((root->osc_control_set & control_req) == control_req) 416 if ((root->osc_control_set & ctrl) == ctrl)
396 goto out; 417 goto out;
397 418
398 /* Need to query controls first before requesting them */ 419 /* Need to check the available controls bits before requesting them. */
399 if (!root->osc_queried) { 420 while (*mask) {
400 status = acpi_pci_query_osc(root, root->osc_support_set); 421 status = acpi_pci_query_osc(root, root->osc_support_set, mask);
401 if (ACPI_FAILURE(status)) 422 if (ACPI_FAILURE(status))
402 goto out; 423 goto out;
424 if (ctrl == *mask)
425 break;
426 ctrl = *mask;
403 } 427 }
404 if ((root->osc_control_qry & control_req) != control_req) { 428
405 printk(KERN_DEBUG 429 if ((ctrl & req) != req) {
406 "Firmware did not grant requested _OSC control\n");
407 status = AE_SUPPORT; 430 status = AE_SUPPORT;
408 goto out; 431 goto out;
409 } 432 }
410 433
411 capbuf[OSC_QUERY_TYPE] = 0; 434 capbuf[OSC_QUERY_TYPE] = 0;
412 capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; 435 capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
413 capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req; 436 capbuf[OSC_CONTROL_TYPE] = ctrl;
414 status = acpi_pci_run_osc(handle, capbuf, &result); 437 status = acpi_pci_run_osc(handle, capbuf, mask);
415 if (ACPI_SUCCESS(status)) 438 if (ACPI_SUCCESS(status))
416 root->osc_control_set = result; 439 root->osc_control_set = *mask;
417out: 440out:
418 mutex_unlock(&osc_lock); 441 mutex_unlock(&osc_lock);
419 return status; 442 return status;
@@ -544,14 +567,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
544 if (flags != base_flags) 567 if (flags != base_flags)
545 acpi_pci_osc_support(root, flags); 568 acpi_pci_osc_support(root, flags);
546 569
547 status = acpi_pci_osc_control_set(root->device->handle,
548 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
549
550 if (ACPI_FAILURE(status)) {
551 printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
552 pcie_no_aspm();
553 }
554
555 pci_acpi_add_bus_pm_notifier(device, root->bus); 570 pci_acpi_add_bus_pm_notifier(device, root->bus);
556 if (device->wakeup.flags.run_wake) 571 if (device->wakeup.flags.run_wake)
557 device_set_run_wake(root->bus->bridge, true); 572 device_set_run_wake(root->bus->bridge, true);