Skip to content

Commit 1ecf302

Browse files
dcuiSasha Levin
authored andcommitted
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: Dexuan Cui <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 56fb105 commit 1ecf302

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

drivers/video/fbdev/hyperv_fb.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/fb.h>
3535
#include <linux/pci.h>
3636
#include <linux/efi.h>
37+
#include <linux/console.h>
3738

3839
#include <linux/hyperv.h>
3940

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

212213
struct delayed_work dwork;
213214
bool update;
215+
bool update_saved; /* The value of 'update' before hibernation */
214216

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

883+
static int hvfb_suspend(struct hv_device *hdev)
884+
{
885+
struct fb_info *info = hv_get_drvdata(hdev);
886+
struct hvfb_par *par = info->par;
887+
888+
console_lock();
889+
890+
/* 1 means do suspend */
891+
fb_set_suspend(info, 1);
892+
893+
cancel_delayed_work_sync(&par->dwork);
894+
895+
par->update_saved = par->update;
896+
par->update = false;
897+
par->fb_ready = false;
898+
899+
vmbus_close(hdev->channel);
900+
901+
console_unlock();
902+
903+
return 0;
904+
}
905+
906+
static int hvfb_resume(struct hv_device *hdev)
907+
{
908+
struct fb_info *info = hv_get_drvdata(hdev);
909+
struct hvfb_par *par = info->par;
910+
int ret;
911+
912+
console_lock();
913+
914+
ret = synthvid_connect_vsp(hdev);
915+
if (ret != 0)
916+
goto out;
917+
918+
ret = synthvid_send_config(hdev);
919+
if (ret != 0) {
920+
vmbus_close(hdev->channel);
921+
goto out;
922+
}
923+
924+
par->fb_ready = true;
925+
par->update = par->update_saved;
926+
927+
schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
928+
929+
/* 0 means do resume */
930+
fb_set_suspend(info, 0);
931+
932+
out:
933+
console_unlock();
934+
935+
return ret;
936+
}
937+
881938

882939
static const struct pci_device_id pci_stub_id_table[] = {
883940
{
@@ -901,6 +958,8 @@ static struct hv_driver hvfb_drv = {
901958
.id_table = id_table,
902959
.probe = hvfb_probe,
903960
.remove = hvfb_remove,
961+
.suspend = hvfb_suspend,
962+
.resume = hvfb_resume,
904963
.driver = {
905964
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
906965
},

0 commit comments

Comments
 (0)