summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c
index 5627abfd..807df2ca 100644
--- a/drivers/gpu/nvgpu/os/linux/module.c
+++ b/drivers/gpu/nvgpu/os/linux/module.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * GK20A Graphics 2 * GK20A Graphics
3 * 3 *
4 * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2020, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -1058,11 +1058,13 @@ static int gk20a_pm_suspend(struct device *dev)
1058 struct gk20a_platform *platform = dev_get_drvdata(dev); 1058 struct gk20a_platform *platform = dev_get_drvdata(dev);
1059 struct gk20a *g = get_gk20a(dev); 1059 struct gk20a *g = get_gk20a(dev);
1060 int ret = 0; 1060 int ret = 0;
1061 int idle_usage_count = 0; 1061 int usage_count;
1062 struct nvgpu_timeout timeout;
1062 1063
1063 if (!g->power_on) { 1064 if (!g->power_on) {
1064 if (platform->suspend) 1065 if (platform->suspend)
1065 ret = platform->suspend(dev); 1066 ret = platform->suspend(dev);
1067
1066 if (ret) 1068 if (ret)
1067 return ret; 1069 return ret;
1068 1070
@@ -1072,20 +1074,43 @@ static int gk20a_pm_suspend(struct device *dev)
1072 return ret; 1074 return ret;
1073 } 1075 }
1074 1076
1075 if (nvgpu_atomic_read(&g->usage_count) > idle_usage_count) 1077 nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS,
1076 return -EBUSY; 1078 NVGPU_TIMER_CPU_TIMER);
1079 /*
1080 * Hold back deterministic submits and changes to deterministic
1081 * channels - this must be outside the power busy locks.
1082 */
1083 gk20a_channel_deterministic_idle(g);
1084
1085 /* check and wait until GPU is idle (with a timeout) */
1086 do {
1087 nvgpu_usleep_range(1000, 1100);
1088 usage_count = nvgpu_atomic_read(&g->usage_count);
1089 } while (usage_count != 0 && !nvgpu_timeout_expired(&timeout));
1090
1091 if (usage_count != 0) {
1092 nvgpu_err(g, "failed to idle - usage_count %d", usage_count);
1093 ret = -EINVAL;
1094 goto fail_idle;
1095 }
1077 1096
1078 ret = gk20a_pm_runtime_suspend(dev); 1097 ret = gk20a_pm_runtime_suspend(dev);
1079 if (ret) 1098 if (ret)
1080 return ret; 1099 goto fail_idle;
1081 1100
1082 if (platform->suspend) 1101 if (platform->suspend)
1083 ret = platform->suspend(dev); 1102 ret = platform->suspend(dev);
1084 if (ret) 1103 if (ret)
1085 return ret; 1104 goto fail_suspend;
1086 1105
1087 g->suspended = true; 1106 g->suspended = true;
1088 1107
1108 return 0;
1109
1110fail_suspend:
1111 gk20a_pm_runtime_resume(dev);
1112fail_idle:
1113 gk20a_channel_deterministic_unidle(g);
1089 return ret; 1114 return ret;
1090} 1115}
1091 1116
@@ -1118,6 +1143,8 @@ static int gk20a_pm_resume(struct device *dev)
1118 1143
1119 g->suspended = false; 1144 g->suspended = false;
1120 1145
1146 gk20a_channel_deterministic_unidle(g);
1147
1121 return ret; 1148 return ret;
1122} 1149}
1123 1150