From: Tobias Diedrich Date: Sat, 31 May 2008 23:20:05 +0000 (+0200) Subject: Fix forcedeth hibernate/wake-on-lan problems X-Git-Tag: v2.6.27-rc1~969^2~255^2~3 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=f5ccbcfacaae57e3312e623432a79d5f1f079cf5;p=karo-tx-linux.git 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 Signed-off-by: Jeff Garzik --- 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, } return PCI_POWER_ERROR; } + +static int acpi_platform_enable_wakeup(struct device *dev, int is_on) +{ + struct acpi_device *adev; + int status; + + if (!device_can_wakeup(dev)) + return -EINVAL; + + if (is_on && !device_may_wakeup(dev)) + return -EINVAL; + + status = acpi_bus_get_device(DEVICE_ACPI_HANDLE(dev), &adev); + if (status < 0) + return status; + + adev->wakeup.state.enabled = !!is_on; + return 0; +} #endif 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) return 0; #ifdef CONFIG_ACPI_SLEEP platform_pci_choose_state = acpi_pci_choose_state; + platform_enable_wakeup = acpi_platform_enable_wakeup; #endif platform_pci_set_power_state = acpi_pci_set_power_state; return 0;