Commit 1ecf3020 authored by Dexuan Cui's avatar Dexuan Cui Committed by Sasha Levin
Browse files

video: hyperv_fb: Add the support of hibernation



This patch depends on the vmbus side change of the definition of
struct hv_driver.

Signed-off-by: default avatarDexuan Cui <decui@microsoft.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 56fb1058
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <linux/fb.h>
#include <linux/pci.h>
#include <linux/efi.h>
#include <linux/console.h>

#include <linux/hyperv.h>

@@ -211,6 +212,7 @@ struct hvfb_par {

	struct delayed_work dwork;
	bool update;
	bool update_saved; /* The value of 'update' before hibernation */

	u32 pseudo_palette[16];
	u8 init_buf[MAX_VMBUS_PKT_SIZE];
@@ -878,6 +880,61 @@ static int hvfb_remove(struct hv_device *hdev)
	return 0;
}

static int hvfb_suspend(struct hv_device *hdev)
{
	struct fb_info *info = hv_get_drvdata(hdev);
	struct hvfb_par *par = info->par;

	console_lock();

	/* 1 means do suspend */
	fb_set_suspend(info, 1);

	cancel_delayed_work_sync(&par->dwork);

	par->update_saved = par->update;
	par->update = false;
	par->fb_ready = false;

	vmbus_close(hdev->channel);

	console_unlock();

	return 0;
}

static int hvfb_resume(struct hv_device *hdev)
{
	struct fb_info *info = hv_get_drvdata(hdev);
	struct hvfb_par *par = info->par;
	int ret;

	console_lock();

	ret = synthvid_connect_vsp(hdev);
	if (ret != 0)
		goto out;

	ret = synthvid_send_config(hdev);
	if (ret != 0) {
		vmbus_close(hdev->channel);
		goto out;
	}

	par->fb_ready = true;
	par->update = par->update_saved;

	schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);

	/* 0 means do resume */
	fb_set_suspend(info, 0);

out:
	console_unlock();

	return ret;
}


static const struct pci_device_id pci_stub_id_table[] = {
	{
@@ -901,6 +958,8 @@ static struct hv_driver hvfb_drv = {
	.id_table = id_table,
	.probe = hvfb_probe,
	.remove = hvfb_remove,
	.suspend = hvfb_suspend,
	.resume = hvfb_resume,
	.driver = {
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},