diff options
author | Tobias Diedrich <ranma+kernel@tdiedrich.de> | 2008-05-31 19:20:05 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-06-28 10:23:36 -0400 |
commit | f5ccbcfacaae57e3312e623432a79d5f1f079cf5 (patch) | |
tree | 6ef160abded88049606225a73dbdd3bbbabc6a9a /drivers/pci | |
parent | 9a60a82600822d34dcbc4df0866ec6ce643c0e79 (diff) |
Fix forcedeth hibernate/wake-on-lan problems
This patch is the minimal amount of code needed to support
wake-on-lan in platform mode properly (i.e. "ethtool -s eth0 wol g"
is sufficient, no additional magic needed) for me.
This is derived from David Brownells patch
(http://lists.laptop.org/pipermail/devel/2007-April/004691.html).
However I decided to move the hook into pci-acpi.c since the other
two pci hooks also live there and pci and acpi are the only users of
the platform_enable_wakeup-hook.
As a 'side-effect' this also makes wake on usb activity work for me
and I had to disable usb wakeup (which is enabled by default) using
the power/wakeup sysfs functionality ("echo disabled >
${sysfs_path_to_device}/power/wakeup").
(BTW I first thought the 'immediate reboot because of usb wake' effect is
caused by the optical mouse generating a wake event, but it rather
seems to be a problem with a flaky secondary usb host controller,
which sees a connected device where nothing is attached)
Signed-off-by: Tobias Diedrich <ranma+kernel@tdiedrich.de>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-acpi.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 9d6fc8e6285d..f7904ff2ace0 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -315,6 +315,25 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev, | |||
315 | } | 315 | } |
316 | return PCI_POWER_ERROR; | 316 | return PCI_POWER_ERROR; |
317 | } | 317 | } |
318 | |||
319 | static int acpi_platform_enable_wakeup(struct device *dev, int is_on) | ||
320 | { | ||
321 | struct acpi_device *adev; | ||
322 | int status; | ||
323 | |||
324 | if (!device_can_wakeup(dev)) | ||
325 | return -EINVAL; | ||
326 | |||
327 | if (is_on && !device_may_wakeup(dev)) | ||
328 | return -EINVAL; | ||
329 | |||
330 | status = acpi_bus_get_device(DEVICE_ACPI_HANDLE(dev), &adev); | ||
331 | if (status < 0) | ||
332 | return status; | ||
333 | |||
334 | adev->wakeup.state.enabled = !!is_on; | ||
335 | return 0; | ||
336 | } | ||
318 | #endif | 337 | #endif |
319 | 338 | ||
320 | static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | 339 | static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) |
@@ -399,6 +418,7 @@ static int __init acpi_pci_init(void) | |||
399 | return 0; | 418 | return 0; |
400 | #ifdef CONFIG_ACPI_SLEEP | 419 | #ifdef CONFIG_ACPI_SLEEP |
401 | platform_pci_choose_state = acpi_pci_choose_state; | 420 | platform_pci_choose_state = acpi_pci_choose_state; |
421 | platform_enable_wakeup = acpi_platform_enable_wakeup; | ||
402 | #endif | 422 | #endif |
403 | platform_pci_set_power_state = acpi_pci_set_power_state; | 423 | platform_pci_set_power_state = acpi_pci_set_power_state; |
404 | return 0; | 424 | return 0; |