]>
Commit | Line | Data |
---|---|---|
c7f48656 RW |
1 | /* |
2 | * PCIe Native PME support, ACPI-related part | |
3 | * | |
4 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | |
5 | * | |
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 | */ | |
10 | ||
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> | |
17 | ||
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. | |
21 | * | |
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. | |
25 | */ | |
26 | int pcie_pme_acpi_setup(struct pcie_device *srv) | |
27 | { | |
28 | acpi_status status = AE_NOT_FOUND; | |
29 | struct pci_dev *port = srv->port; | |
30 | acpi_handle handle; | |
31 | int error = 0; | |
32 | ||
33 | if (acpi_pci_disabled) | |
34 | return -ENOSYS; | |
35 | ||
36 | dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n"); | |
37 | ||
38 | handle = acpi_find_root_bridge_handle(port); | |
39 | if (!handle) | |
40 | return -EINVAL; | |
41 | ||
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; | |
51 | } | |
52 | ||
53 | return error; | |
54 | } |