diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-12-17 15:10:05 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-01-07 14:13:07 -0500 |
commit | eb9c39d031bbcfd4005bd7e0337c3fd3909c1bf7 (patch) | |
tree | 1549b3fb7eb08296b7f7fe72582d7067098059db /drivers/pci | |
parent | 876e501ab25dcd683574a5d3d56d8fe450083ed6 (diff) |
PCI: set device wakeup capable flag if platform support is present
When PCI devices are initialized, we check whether they support PCI PM
caps and set the device can_wakeup flag if so. However, some devices
may have platform provided wakeup events rather than PCI PME signals, so
we need to set can_wakeup in that case too. Doing so should allow
wakeups from many more devices, especially on cost constrained systems.
Reported-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Joseph Chan <JosephChan@via.com.tw>
Acked-by: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci.c | 20 | ||||
-rw-r--r-- | drivers/pci/pci.h | 1 | ||||
-rw-r--r-- | drivers/pci/probe.c | 1 |
3 files changed, 22 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7e9c0f3936dd..1b807330e500 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1286,6 +1286,26 @@ void pci_pm_init(struct pci_dev *dev) | |||
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | /** | 1288 | /** |
1289 | * platform_pci_wakeup_init - init platform wakeup if present | ||
1290 | * @dev: PCI device | ||
1291 | * | ||
1292 | * Some devices don't have PCI PM caps but can still generate wakeup | ||
1293 | * events through platform methods (like ACPI events). If @dev supports | ||
1294 | * platform wakeup events, set the device flag to indicate as much. This | ||
1295 | * may be redundant if the device also supports PCI PM caps, but double | ||
1296 | * initialization should be safe in that case. | ||
1297 | */ | ||
1298 | void platform_pci_wakeup_init(struct pci_dev *dev) | ||
1299 | { | ||
1300 | if (!platform_pci_can_wakeup(dev)) | ||
1301 | return; | ||
1302 | |||
1303 | device_set_wakeup_capable(&dev->dev, true); | ||
1304 | device_set_wakeup_enable(&dev->dev, false); | ||
1305 | platform_pci_sleep_wake(dev, false); | ||
1306 | } | ||
1307 | |||
1308 | /** | ||
1289 | * pci_add_save_buffer - allocate buffer for saving given capability registers | 1309 | * pci_add_save_buffer - allocate buffer for saving given capability registers |
1290 | * @dev: the PCI device | 1310 | * @dev: the PCI device |
1291 | * @cap: the capability to allocate the buffer for | 1311 | * @cap: the capability to allocate the buffer for |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d1e92d83aa06..65deed8bfc06 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -45,6 +45,7 @@ struct pci_platform_pm_ops { | |||
45 | 45 | ||
46 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 46 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
47 | extern void pci_pm_init(struct pci_dev *dev); | 47 | extern void pci_pm_init(struct pci_dev *dev); |
48 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | ||
48 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 49 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
49 | 50 | ||
50 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); | 51 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2ee00962734b..303644614eea 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -965,6 +965,7 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
965 | 965 | ||
966 | /* Power Management */ | 966 | /* Power Management */ |
967 | pci_pm_init(dev); | 967 | pci_pm_init(dev); |
968 | platform_pci_wakeup_init(dev); | ||
968 | 969 | ||
969 | /* Vital Product Data */ | 970 | /* Vital Product Data */ |
970 | pci_vpd_pci22_init(dev); | 971 | pci_vpd_pci22_init(dev); |