Message ID | 1574234096-48767-1-git-send-email-decui@microsoft.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | af13f9ed6f9aa6801d020c48aeb19dca9f0d4f97 |
Delegated to: | Jiri Kosina |
Headers | show |
Series | [v2] HID: hyperv: Add the support of hibernation | expand |
On Tue, 19 Nov 2019, Dexuan Cui wrote: > During the suspend process and resume process, if there is any mouse > event, there is a small chance the suspend and the resume process can be > aborted because of mousevsc_on_receive() -> pm_wakeup_hard_event(). > > This behavior can be avoided by disabling the Hyper-V mouse device as > a wakeup source: > > echo disabled > /sys/bus/vmbus/drivers/hid_hyperv/XXX/power/wakeup > (XXX is the device's GUID). > > Signed-off-by: Dexuan Cui <decui@microsoft.com> > Acked-by: Jiri Kosina <jkosina@suse.cz> My Ack still holds for v2. Sasha, this is going to be merged through your tree, right? Thanks,
On Thu, Nov 21, 2019 at 03:34:10PM +0100, Jiri Kosina wrote: >On Tue, 19 Nov 2019, Dexuan Cui wrote: > >> During the suspend process and resume process, if there is any mouse >> event, there is a small chance the suspend and the resume process can be >> aborted because of mousevsc_on_receive() -> pm_wakeup_hard_event(). >> >> This behavior can be avoided by disabling the Hyper-V mouse device as >> a wakeup source: >> >> echo disabled > /sys/bus/vmbus/drivers/hid_hyperv/XXX/power/wakeup >> (XXX is the device's GUID). >> >> Signed-off-by: Dexuan Cui <decui@microsoft.com> >> Acked-by: Jiri Kosina <jkosina@suse.cz> > >My Ack still holds for v2. Sasha, this is going to be merged through your >tree, right? Yup, queued up for hyperv-next, thanks!
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 79a28fc91521..dddfca555df9 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c @@ -192,6 +192,9 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, if (desc->bLength == 0) goto cleanup; + /* The pointer is not NULL when we resume from hibernation */ + if (input_device->hid_desc != NULL) + kfree(input_device->hid_desc); input_device->hid_desc = kmemdup(desc, desc->bLength, GFP_ATOMIC); if (!input_device->hid_desc) @@ -203,6 +206,9 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, goto cleanup; } + /* The pointer is not NULL when we resume from hibernation */ + if (input_device->report_desc != NULL) + kfree(input_device->report_desc); input_device->report_desc = kzalloc(input_device->report_desc_size, GFP_ATOMIC); @@ -342,6 +348,8 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) struct mousevsc_prt_msg *request; struct mousevsc_prt_msg *response; + reinit_completion(&input_dev->wait_event); + request = &input_dev->protocol_req; memset(request, 0, sizeof(struct mousevsc_prt_msg)); @@ -541,6 +549,30 @@ static int mousevsc_remove(struct hv_device *dev) return 0; } +static int mousevsc_suspend(struct hv_device *dev) +{ + vmbus_close(dev->channel); + + return 0; +} + +static int mousevsc_resume(struct hv_device *dev) +{ + int ret; + + ret = vmbus_open(dev->channel, + INPUTVSC_SEND_RING_BUFFER_SIZE, + INPUTVSC_RECV_RING_BUFFER_SIZE, + NULL, 0, + mousevsc_on_channel_callback, + dev); + if (ret) + return ret; + + ret = mousevsc_connect_to_vsp(dev); + return ret; +} + static const struct hv_vmbus_device_id id_table[] = { /* Mouse guid */ { HV_MOUSE_GUID, }, @@ -554,6 +586,8 @@ static struct hv_driver mousevsc_drv = { .id_table = id_table, .probe = mousevsc_probe, .remove = mousevsc_remove, + .suspend = mousevsc_suspend, + .resume = mousevsc_resume, .driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, },