aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorTobias Diedrich <ranma+kernel@tdiedrich.de>2008-05-31 19:20:05 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-06-28 10:23:36 -0400
commitf5ccbcfacaae57e3312e623432a79d5f1f079cf5 (patch)
tree6ef160abded88049606225a73dbdd3bbbabc6a9a /drivers/pci
parent9a60a82600822d34dcbc4df0866ec6ce643c0e79 (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.c20
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
319static 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
320static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) 339static 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;