[patch] USB after second suspend/resume on ThinkPads.
Edward Tomasz Napierała
trasz at FreeBSD.org
Mon Jun 16 19:22:00 UTC 2014
Hi. Patch below should fix a problem where USB stops working after
_second_ suspend/resume, which happens on various ThinkPad models.
Please test, and report both success stories and failures. If nothing
comes up, I'll commit it in a week or so.
(Btw, has anyone encountered the problem on hardware other than ThinkPads?)
Index: sys/dev/acpi_support/acpi_ibm.c
===================================================================
--- sys/dev/acpi_support/acpi_ibm.c (revision 267417)
+++ sys/dev/acpi_support/acpi_ibm.c (working copy)
@@ -169,6 +169,9 @@ struct acpi_ibm_softc {
int light_get_supported;
int light_set_supported;
+ /* USB power workaround */
+ ACPI_HANDLE power_handle;
+
/* led(4) interface */
struct cdev *led_dev;
int led_busy;
@@ -365,6 +368,7 @@ acpi_ibm_attach(device_t dev)
{
struct acpi_ibm_softc *sc;
devclass_t ec_devclass;
+ ACPI_STATUS status;
ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
@@ -448,6 +452,17 @@ acpi_ibm_attach(device_t dev)
if (sc->light_set_supported)
sc->led_dev = led_create_state(ibm_led, sc, "thinklight", sc->light_val);
+ /*
+ * Obtain a handle to the power resource available on many models.
+ * This must be turned on manually upon resume. Otherwise the system
+ * may, for instance, resume from S3 with usb(4) powered down.
+ */
+ status = AcpiGetHandle(sc->handle, "\\_SB.PCI0.LPC.EC.PUBS", &sc->power_handle);
+ if (ACPI_FAILURE(status)) {
+ device_printf(dev, "Failed to get power handle\n");
+ return (status);
+ }
+
return (0);
}
@@ -476,6 +491,7 @@ static int
acpi_ibm_resume(device_t dev)
{
struct acpi_ibm_softc *sc = device_get_softc(dev);
+ ACPI_STATUS status;
ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
@@ -495,6 +511,15 @@ acpi_ibm_resume(device_t dev)
acpi_ibm_sysctl_set(sc, i, val);
}
+ if (sc->power_handle != NULL) {
+ status = AcpiEvaluateObject(sc->power_handle,
+ "_ON", NULL, NULL);
+ if (ACPI_FAILURE(status)) {
+ device_printf(dev, "failed to switch %s on - %s\n",
+ acpi_name(sc->power_handle),
+ AcpiFormatException(status));
+ }
+ }
ACPI_SERIAL_END(ibm);
return (0);
More information about the freebsd-current
mailing list