X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fpci%2Fpci-acpi.c;h=6917c6cb091287a407a6274fa7ebdd382237bed5;hb=650eec5e04468d0611a60e6098464b7c43981552;hp=f94c86fbc6695cb0e8662d253c23341c3977559f;hpb=84df749f364209c9623304b7a94ddb954dc343bb;p=powerpc.git diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index f94c86fbc6..6917c6cb09 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -17,6 +17,7 @@ #include #include +#include "pci.h" static u32 ctrlset_buf[3] = {0, 0, 0}; static u32 global_ctrlsets = 0; @@ -90,9 +91,7 @@ acpi_query_osc ( static acpi_status acpi_run_osc ( acpi_handle handle, - u32 level, - void *context, - void **retval ) + void *context) { acpi_status status; struct acpi_object_list input; @@ -179,11 +178,12 @@ EXPORT_SYMBOL(pci_osc_support_set); /** * pci_osc_control_set - commit requested control to Firmware + * @handle: acpi_handle for the target ACPI object * @flags: driver's requested control bits * * Attempt to take control from Firmware on requested control bits. **/ -acpi_status pci_osc_control_set(u32 flags) +acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) { acpi_status status; u32 ctrlset; @@ -197,10 +197,7 @@ acpi_status pci_osc_control_set(u32 flags) return AE_SUPPORT; } ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; - status = acpi_get_devices ( PCI_ROOT_HID_STRING, - acpi_run_osc, - ctrlset_buf, - NULL ); + status = acpi_run_osc(handle, ctrlset_buf); if (ACPI_FAILURE (status)) { ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; } @@ -209,6 +206,56 @@ acpi_status pci_osc_control_set(u32 flags) } EXPORT_SYMBOL(pci_osc_control_set); +/* + * _SxD returns the D-state with the highest power + * (lowest D-state number) supported in the S-state "x". + * + * If the devices does not have a _PRW + * (Power Resources for Wake) supporting system wakeup from "x" + * then the OS is free to choose a lower power (higher number + * D-state) than the return value from _SxD. + * + * But if _PRW is enabled at S-state "x", the OS + * must not choose a power lower than _SxD -- + * unless the device has an _SxW method specifying + * the lowest power (highest D-state number) the device + * may enter while still able to wake the system. + * + * ie. depending on global OS policy: + * + * if (_PRW at S-state x) + * choose from highest power _SxD to lowest power _SxW + * else // no _PRW at S-state x + * choose highest power _SxD or any lower power + * + * currently we simply return _SxD, if present. + */ + +static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state) +{ + /* TBD */ + + return -ENODEV; +} + +static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) +{ + acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); + static int state_conv[] = { + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 3, + [4] = 3 + }; + int acpi_state = state_conv[(int __force) state]; + + if (!handle) + return -ENODEV; + return acpi_bus_set_power(handle, acpi_state); +} + + /* ACPI bus type */ static int pci_acpi_find_device(struct device *dev, acpi_handle *handle) { @@ -255,6 +302,8 @@ static int __init pci_acpi_init(void) ret = register_acpi_bus_type(&pci_acpi_bus); if (ret) return 0; + platform_pci_choose_state = acpi_pci_choose_state; + platform_pci_set_power_state = acpi_pci_set_power_state; return 0; } arch_initcall(pci_acpi_init);