diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2008-07-06 21:34:48 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-07-07 19:26:28 -0400 |
commit | eb9d0fe40e313c0a74115ef456a2e43a6c8da72f (patch) | |
tree | 7a90a68b8dc152d49a38469fd6a6a7840954bac2 /drivers/pci/probe.c | |
parent | 0af4b8c4fb31193dc666f4893107a18fef82baab (diff) |
PCI ACPI: Rework PCI handling of wake-up
* Introduce function acpi_pm_device_sleep_wake() for enabling and
disabling the system wake-up capability of devices that are power
manageable by ACPI.
* Introduce function acpi_bus_can_wakeup() allowing other (dependent)
subsystems to check if ACPI is able to enable the system wake-up
capability of given device.
* Introduce callback .sleep_wake() in struct pci_platform_pm_ops and
for the ACPI PCI 'driver' make it use acpi_pm_device_sleep_wake().
* Introduce callback .can_wakeup() in struct pci_platform_pm_ops and
for the ACPI 'driver' make it use acpi_bus_can_wakeup().
* Move the PME# handlig code out of pci_enable_wake() and split it
into two functions, pci_pme_capable() and pci_pme_active(),
allowing the caller to check if given device is capable of
generating PME# from given power state and to enable/disable the
device's PME# functionality, respectively.
* Modify pci_enable_wake() to use the new ACPI callbacks and the new
PME#-related functions.
* Drop the generic .platform_enable_wakeup() callback that is not
used any more.
* Introduce device_set_wakeup_capable() that will set the
power.can_wakeup flag of given device.
* Rework PCI device PM initialization so that, if given device is
capable of generating wake-up events, either natively through the
PME# mechanism, or with the help of the platform, its
power.can_wakeup flag is set and its power.should_wakeup flag is
unset as appropriate.
* Make ACPI set the power.can_wakeup flag for devices found to be
wake-up capable by it.
* Make the ACPI wake-up code enable/disable GPEs for devices that
have the wakeup.flags.prepared flag set (which means that their
wake-up power has been enabled).
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 47 |
1 files changed, 3 insertions, 44 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2f0ae70710d6..b1724cf31b66 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -860,49 +860,6 @@ int pci_cfg_space_size_ext(struct pci_dev *dev) | |||
860 | return PCI_CFG_SPACE_SIZE; | 860 | return PCI_CFG_SPACE_SIZE; |
861 | } | 861 | } |
862 | 862 | ||
863 | /** | ||
864 | * pci_disable_pme - Disable the PME function of PCI device | ||
865 | * @dev: PCI device affected | ||
866 | * -EINVAL is returned if PCI device doesn't support PME. | ||
867 | * Zero is returned if the PME is supported and can be disabled. | ||
868 | */ | ||
869 | static int pci_disable_pme(struct pci_dev *dev) | ||
870 | { | ||
871 | int pm; | ||
872 | u16 value; | ||
873 | |||
874 | /* find PCI PM capability in list */ | ||
875 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | ||
876 | |||
877 | /* If device doesn't support PM Capabilities, it means that PME is | ||
878 | * not supported. | ||
879 | */ | ||
880 | if (!pm) | ||
881 | return -EINVAL; | ||
882 | /* Check device's ability to generate PME# */ | ||
883 | pci_read_config_word(dev, pm + PCI_PM_PMC, &value); | ||
884 | |||
885 | value &= PCI_PM_CAP_PME_MASK; | ||
886 | /* Check if it can generate PME# */ | ||
887 | if (!value) { | ||
888 | /* | ||
889 | * If it is zero, it means that PME is still unsupported | ||
890 | * although there exists the PM capability. | ||
891 | */ | ||
892 | return -EINVAL; | ||
893 | } | ||
894 | |||
895 | pci_read_config_word(dev, pm + PCI_PM_CTRL, &value); | ||
896 | |||
897 | /* Clear PME_Status by writing 1 to it */ | ||
898 | value |= PCI_PM_CTRL_PME_STATUS ; | ||
899 | /* Disable PME enable bit */ | ||
900 | value &= ~PCI_PM_CTRL_PME_ENABLE; | ||
901 | pci_write_config_word(dev, pm + PCI_PM_CTRL, value); | ||
902 | |||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | int pci_cfg_space_size(struct pci_dev *dev) | 863 | int pci_cfg_space_size(struct pci_dev *dev) |
907 | { | 864 | { |
908 | int pos; | 865 | int pos; |
@@ -1010,7 +967,6 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | |||
1010 | } | 967 | } |
1011 | 968 | ||
1012 | pci_vpd_pci22_init(dev); | 969 | pci_vpd_pci22_init(dev); |
1013 | pci_disable_pme(dev); | ||
1014 | 970 | ||
1015 | return dev; | 971 | return dev; |
1016 | } | 972 | } |
@@ -1031,6 +987,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1031 | /* Fix up broken headers */ | 987 | /* Fix up broken headers */ |
1032 | pci_fixup_device(pci_fixup_header, dev); | 988 | pci_fixup_device(pci_fixup_header, dev); |
1033 | 989 | ||
990 | /* Initialize power management of the device */ | ||
991 | pci_pm_init(dev); | ||
992 | |||
1034 | /* | 993 | /* |
1035 | * Add the device to our list of discovered devices | 994 | * Add the device to our list of discovered devices |
1036 | * and the bus list for fixup functions, etc. | 995 | * and the bus list for fixup functions, etc. |