From: Dexuan Cui <decui@microsoft.com>
To: KY Srinivasan <kys@microsoft.com>,
Haiyang Zhang <haiyangz@microsoft.com>,
Stephen Hemminger <sthemmin@microsoft.com>,
"sashal@kernel.org" <sashal@kernel.org>,
"dmitry.torokhov@gmail.com" <dmitry.torokhov@gmail.com>,
"linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
"linux-input@vger.kernel.org" <linux-input@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Michael Kelley <mikelley@microsoft.com>
Cc: Dexuan Cui <decui@microsoft.com>
Subject: [PATCH] Input: hyperv-keyboard: Add the support of hibernation
Date: Wed, 11 Sep 2019 23:36:20 +0000 [thread overview]
Message-ID: <1568244975-66795-1-git-send-email-decui@microsoft.com> (raw)
We need hv_kbd_pm_notify() to make sure the pm_wakeup_hard_event() call
does not prevent the system from entering hibernation: the hibernation
is a relatively long process, which can be aborted by the call
pm_wakeup_hard_event(), which is invoked upon keyboard events.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---
This patch is basically a pure Hyper-V specific change and it has a
build dependency on the commit 271b2224d42f ("Drivers: hv: vmbus: Implement
suspend/resume for VSC drivers for hibernation"), which is on Sasha Levin's
Hyper-V tree's hyperv-next branch:
https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git/log/?h=hyperv-next
I request this patch should go through Sasha's tree rather than the
input subsystemi's tree.
Hi Dmitry, can you please Ack?
drivers/input/serio/hyperv-keyboard.c | 68 ++++++++++++++++++++++++++++++++---
1 file changed, 63 insertions(+), 5 deletions(-)
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index 88ae7c2..277dc4c 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -10,6 +10,7 @@
#include <linux/hyperv.h>
#include <linux/serio.h>
#include <linux/slab.h>
+#include <linux/suspend.h>
/*
* Current version 1.0
@@ -95,6 +96,9 @@ struct hv_kbd_dev {
struct completion wait_event;
spinlock_t lock; /* protects 'started' field */
bool started;
+
+ struct notifier_block pm_nb;
+ bool hibernation_in_progress;
};
static void hv_kbd_on_receive(struct hv_device *hv_dev,
@@ -168,7 +172,7 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
* "echo freeze > /sys/power/state" can't really enter the
* state because the Enter-UP can trigger a wakeup at once.
*/
- if (!(info & IS_BREAK))
+ if (!(info & IS_BREAK) && !kbd_dev->hibernation_in_progress)
pm_wakeup_hard_event(&hv_dev->device);
break;
@@ -179,10 +183,10 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
}
}
-static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,
- struct vmpacket_descriptor *desc,
- u32 bytes_recvd,
- u64 req_id)
+static void
+hv_kbd_handle_received_packet(struct hv_device *hv_dev,
+ const struct vmpacket_descriptor *desc,
+ u32 bytes_recvd, u64 req_id)
{
struct synth_kbd_msg *msg;
u32 msg_sz;
@@ -282,6 +286,8 @@ static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev)
u32 proto_status;
int error;
+ reinit_completion(&kbd_dev->wait_event);
+
request = &kbd_dev->protocol_req;
memset(request, 0, sizeof(struct synth_kbd_protocol_request));
request->header.type = __cpu_to_le32(SYNTH_KBD_PROTOCOL_REQUEST);
@@ -332,6 +338,29 @@ static void hv_kbd_stop(struct serio *serio)
spin_unlock_irqrestore(&kbd_dev->lock, flags);
}
+static int hv_kbd_pm_notify(struct notifier_block *nb,
+ unsigned long val, void *ign)
+{
+ struct hv_kbd_dev *kbd_dev;
+
+ kbd_dev = container_of(nb, struct hv_kbd_dev, pm_nb);
+
+ switch (val) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_RESTORE_PREPARE:
+ kbd_dev->hibernation_in_progress = true;
+ return NOTIFY_OK;
+
+ case PM_POST_HIBERNATION:
+ case PM_POST_RESTORE:
+ kbd_dev->hibernation_in_progress = false;
+ return NOTIFY_OK;
+
+ default:
+ return NOTIFY_DONE;
+ }
+}
+
static int hv_kbd_probe(struct hv_device *hv_dev,
const struct hv_vmbus_device_id *dev_id)
{
@@ -380,6 +409,9 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
device_init_wakeup(&hv_dev->device, true);
+ kbd_dev->pm_nb.notifier_call = hv_kbd_pm_notify;
+ register_pm_notifier(&kbd_dev->pm_nb);
+
return 0;
err_close_vmbus:
@@ -394,6 +426,7 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
{
struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
+ unregister_pm_notifier(&kbd_dev->pm_nb);
serio_unregister_port(kbd_dev->hv_serio);
vmbus_close(hv_dev->channel);
kfree(kbd_dev);
@@ -403,6 +436,29 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
return 0;
}
+static int hv_kbd_suspend(struct hv_device *hv_dev)
+{
+ vmbus_close(hv_dev->channel);
+
+ return 0;
+}
+
+static int hv_kbd_resume(struct hv_device *hv_dev)
+{
+ int ret;
+
+ ret = vmbus_open(hv_dev->channel,
+ KBD_VSC_SEND_RING_BUFFER_SIZE,
+ KBD_VSC_RECV_RING_BUFFER_SIZE,
+ NULL, 0,
+ hv_kbd_on_channel_callback,
+ hv_dev);
+ if (ret == 0)
+ ret = hv_kbd_connect_to_vsp(hv_dev);
+
+ return ret;
+}
+
static const struct hv_vmbus_device_id id_table[] = {
/* Keyboard guid */
{ HV_KBD_GUID, },
@@ -416,6 +472,8 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
.id_table = id_table,
.probe = hv_kbd_probe,
.remove = hv_kbd_remove,
+ .suspend = hv_kbd_suspend,
+ .resume = hv_kbd_resume,
.driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
--
1.8.3.1
next reply other threads:[~2019-09-11 23:36 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-11 23:36 Dexuan Cui [this message]
2019-09-19 16:17 ` [PATCH] Input: hyperv-keyboard: Add the support of hibernation dmitry.torokhov
2019-09-21 6:56 ` Dexuan Cui
2019-09-25 19:49 ` Dexuan Cui
2019-09-28 0:31 ` dmitry.torokhov
2019-09-30 22:09 ` Dexuan Cui
2019-09-30 23:06 ` dmitry.torokhov
2019-10-03 5:35 ` Dexuan Cui
2019-10-03 6:44 ` Dexuan Cui
2019-10-03 17:45 ` dmitry.torokhov
2019-10-03 18:18 ` Dexuan Cui
2019-11-05 5:18 ` Dexuan Cui
2019-11-05 5:43 ` Dexuan Cui
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1568244975-66795-1-git-send-email-decui@microsoft.com \
--to=decui@microsoft.com \
--cc=dmitry.torokhov@gmail.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mikelley@microsoft.com \
--cc=sashal@kernel.org \
--cc=sthemmin@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).