Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
[linux/fpc-iii.git] / drivers / pci / pcie / pme / pcie_pme_acpi.c
blob83ab2287ae3f86bc501ddf64b2a7d1f09991e1f5
1 /*
2 * PCIe Native PME support, ACPI-related part
4 * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License V2. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
11 #include <linux/pci.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/acpi.h>
15 #include <linux/pci-acpi.h>
16 #include <linux/pcieport_if.h>
18 /**
19 * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME.
20 * @srv - PCIe PME service for a root port or event collector.
22 * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid
23 * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME
24 * control to the kernel.
26 int pcie_pme_acpi_setup(struct pcie_device *srv)
28 acpi_status status = AE_NOT_FOUND;
29 struct pci_dev *port = srv->port;
30 acpi_handle handle;
31 int error = 0;
33 if (acpi_pci_disabled)
34 return -ENOSYS;
36 dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n");
38 handle = acpi_find_root_bridge_handle(port);
39 if (!handle)
40 return -EINVAL;
42 status = acpi_pci_osc_control_set(handle,
43 OSC_PCI_EXPRESS_PME_CONTROL |
44 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
45 if (ACPI_FAILURE(status)) {
46 dev_info(&port->dev,
47 "Failed to receive control of PCIe PME service: %s\n",
48 (status == AE_SUPPORT || status == AE_NOT_FOUND) ?
49 "no _OSC support" : "ACPI _OSC failed");
50 error = -ENODEV;
53 return error;