diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-06-09 09:16:21 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-07-08 03:58:53 -0400 |
commit | e27c72446bf09196d6d66f28389f00565273a13f (patch) | |
tree | 473530a0f10eee8d9dcae29afdc35c72b7a6a0ad /drivers/gpu/nvgpu | |
parent | 8417698b519be9dc8c1bd04714fc72ce4e0bc38f (diff) |
gpu: nvgpu: simplify power management
We currenlty initialize both runtime PM and pm_domains frameworks
and use pm_domain to control runtime power management of NvGPU
But since GPU has a separate rail, using pm_domain is not
strictly required
Hence remove pm_domain support and use runtime PM only for all
the power management
This also simplifies the code a lot
Initialization in gk20a_pm_init()
- if railgate_delay is set, set autosuspend delay of runtime PM
- try enabling runtime PM
- if runtime PM is now enabled, keep GPU railgated
- if runtime PM is not enabled, keep GPU unrailgated
- if can_railgate = false, disable runtime PM and keep
GPU unrailgated
Set gk20a_pm_ops with below callbacks for runtime PM
static const struct dev_pm_ops gk20a_pm_ops = {
.runtime_resume = gk20a_pm_runtime_resume,
.runtime_suspend = gk20a_pm_runtime_suspend,
.resume = gk20a_pm_resume,
.suspend = gk20a_pm_suspend,
}
Move gk20a_busy() to use runtime checks of pm_runtime_enabled()
instead of using compile time checks on CONFIG_PM
Clean up some pm_domain related code
Remove use of gk20a_pm_enable/disable_clk() since this
should be already done in platform specific unrailgate()/
railgate() APIs
Fix "railgate_delay" and "railgate_enable" sysfs to use
runtime PM calls
For VGPU, disable runtime PM during vgpu_pm_init()
With this, we will initialize vgpu with vgpu_pm_finalize_poweron()
upon first call to gk20a_busy()
Jira DNVGPU-57
Change-Id: I6013e33ae9bd28f35c25271af1239942a4fa0919
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1163216
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 378 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 40 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/platform_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/vgpu.c | 42 |
6 files changed, 123 insertions, 352 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 2ca89e9f..bcde6df3 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/debugfs.h> | 36 | #include <linux/debugfs.h> |
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/tegra-powergate.h> | 38 | #include <linux/tegra-powergate.h> |
39 | #include <linux/tegra_pm_domains.h> | ||
40 | #include <linux/clk/tegra.h> | 39 | #include <linux/clk/tegra.h> |
41 | #include <linux/kthread.h> | 40 | #include <linux/kthread.h> |
42 | #include <linux/platform/tegra/common.h> | 41 | #include <linux/platform/tegra/common.h> |
@@ -1130,41 +1129,31 @@ struct channel_gk20a *gk20a_get_channel_from_file(int fd) | |||
1130 | return ch; | 1129 | return ch; |
1131 | } | 1130 | } |
1132 | 1131 | ||
1133 | static int gk20a_pm_enable_clk(struct device *dev) | 1132 | static int gk20a_pm_railgate(struct device *dev) |
1134 | { | 1133 | { |
1135 | int index = 0; | 1134 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
1136 | struct gk20a_platform *platform; | 1135 | int ret = 0; |
1137 | |||
1138 | platform = dev_get_drvdata(dev); | ||
1139 | if (!platform) | ||
1140 | return -EINVAL; | ||
1141 | 1136 | ||
1142 | for (index = 0; index < platform->num_clks; index++) { | 1137 | if (platform->railgate) |
1143 | int err = 0; | 1138 | ret = platform->railgate(dev); |
1144 | if (platform->clk[index]) | ||
1145 | err = clk_prepare_enable(platform->clk[index]); | ||
1146 | if (err) | ||
1147 | return -EINVAL; | ||
1148 | } | ||
1149 | 1139 | ||
1150 | return 0; | 1140 | return ret; |
1151 | } | 1141 | } |
1152 | 1142 | ||
1153 | static int gk20a_pm_disable_clk(struct device *dev) | 1143 | static int gk20a_pm_unrailgate(struct device *dev) |
1154 | { | 1144 | { |
1155 | int index = 0; | 1145 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
1156 | struct gk20a_platform *platform; | 1146 | int ret = 0; |
1157 | 1147 | ||
1158 | platform = dev_get_drvdata(dev); | 1148 | trace_gk20a_pm_unrailgate(dev_name(dev)); |
1159 | if (!platform) | ||
1160 | return -EINVAL; | ||
1161 | 1149 | ||
1162 | for (index = 0; index < platform->num_clks; index++) { | 1150 | if (platform->unrailgate) { |
1163 | if (platform->clk[index]) | 1151 | mutex_lock(&platform->railgate_lock); |
1164 | clk_disable_unprepare(platform->clk[index]); | 1152 | ret = platform->unrailgate(dev); |
1153 | mutex_unlock(&platform->railgate_lock); | ||
1165 | } | 1154 | } |
1166 | 1155 | ||
1167 | return 0; | 1156 | return ret; |
1168 | } | 1157 | } |
1169 | 1158 | ||
1170 | static void gk20a_pm_shutdown(struct platform_device *pdev) | 1159 | static void gk20a_pm_shutdown(struct platform_device *pdev) |
@@ -1176,17 +1165,12 @@ static void gk20a_pm_shutdown(struct platform_device *pdev) | |||
1176 | /* If GPU is already railgated, | 1165 | /* If GPU is already railgated, |
1177 | * just prevent more requests, and return */ | 1166 | * just prevent more requests, and return */ |
1178 | if (platform->is_railgated && platform->is_railgated(&pdev->dev)) { | 1167 | if (platform->is_railgated && platform->is_railgated(&pdev->dev)) { |
1179 | #ifdef CONFIG_PM | ||
1180 | __pm_runtime_disable(&pdev->dev, false); | 1168 | __pm_runtime_disable(&pdev->dev, false); |
1181 | #endif | ||
1182 | return; | 1169 | return; |
1183 | } | 1170 | } |
1184 | 1171 | ||
1185 | |||
1186 | #ifdef CONFIG_PM | ||
1187 | /* Prevent more requests by disabling Runtime PM */ | 1172 | /* Prevent more requests by disabling Runtime PM */ |
1188 | __pm_runtime_disable(&pdev->dev, false); | 1173 | __pm_runtime_disable(&pdev->dev, false); |
1189 | #endif | ||
1190 | 1174 | ||
1191 | /* Be ready for rail-gate after this point */ | 1175 | /* Be ready for rail-gate after this point */ |
1192 | if (gk20a_gpu_is_virtual(&pdev->dev)) | 1176 | if (gk20a_gpu_is_virtual(&pdev->dev)) |
@@ -1194,63 +1178,55 @@ static void gk20a_pm_shutdown(struct platform_device *pdev) | |||
1194 | else | 1178 | else |
1195 | gk20a_pm_prepare_poweroff(&pdev->dev); | 1179 | gk20a_pm_prepare_poweroff(&pdev->dev); |
1196 | 1180 | ||
1181 | gk20a_pm_railgate(&pdev->dev); | ||
1182 | |||
1197 | dev_info(&pdev->dev, "shut down complete\n"); | 1183 | dev_info(&pdev->dev, "shut down complete\n"); |
1198 | } | 1184 | } |
1199 | 1185 | ||
1200 | #ifdef CONFIG_PM | 1186 | static int gk20a_pm_runtime_resume(struct device *dev) |
1201 | static const struct dev_pm_ops gk20a_pm_ops = { | ||
1202 | #if defined(CONFIG_PM) && !defined(CONFIG_PM_GENERIC_DOMAINS) | ||
1203 | .runtime_resume = gk20a_pm_enable_clk, | ||
1204 | .runtime_suspend = gk20a_pm_disable_clk, | ||
1205 | #endif | ||
1206 | }; | ||
1207 | #endif | ||
1208 | |||
1209 | static int _gk20a_pm_railgate(struct device *dev) | ||
1210 | { | 1187 | { |
1211 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 1188 | int err = 0; |
1212 | int ret = 0; | ||
1213 | if (platform->railgate) | ||
1214 | ret = platform->railgate(dev); | ||
1215 | return ret; | ||
1216 | } | ||
1217 | 1189 | ||
1218 | static int gk20a_pm_railgate(struct generic_pm_domain *domain) | 1190 | err = gk20a_pm_unrailgate(dev); |
1219 | { | 1191 | if (err) |
1220 | struct gk20a_domain_data *gk20a_domain = container_of(domain, | 1192 | goto fail; |
1221 | struct gk20a_domain_data, gpd); | 1193 | |
1222 | struct gk20a *g = gk20a_domain->gk20a; | 1194 | err = gk20a_pm_finalize_poweron(dev); |
1195 | if (err) | ||
1196 | goto fail_poweron; | ||
1223 | 1197 | ||
1224 | return _gk20a_pm_railgate(g->dev); | 1198 | return 0; |
1199 | |||
1200 | fail_poweron: | ||
1201 | gk20a_pm_railgate(dev); | ||
1202 | fail: | ||
1203 | return err; | ||
1225 | } | 1204 | } |
1226 | 1205 | ||
1227 | static int _gk20a_pm_unrailgate(struct device *dev) | 1206 | static int gk20a_pm_runtime_suspend(struct device *dev) |
1228 | { | 1207 | { |
1229 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 1208 | int err = 0; |
1230 | int ret = 0; | ||
1231 | 1209 | ||
1232 | if (platform->unrailgate) { | 1210 | err = gk20a_pm_prepare_poweroff(dev); |
1233 | mutex_lock(&platform->railgate_lock); | 1211 | if (err) |
1234 | ret = platform->unrailgate(dev); | 1212 | goto fail; |
1235 | mutex_unlock(&platform->railgate_lock); | ||
1236 | } | ||
1237 | 1213 | ||
1238 | return ret; | 1214 | err = gk20a_pm_railgate(dev); |
1239 | } | 1215 | if (err) |
1216 | goto fail_railgate; | ||
1240 | 1217 | ||
1241 | static int gk20a_pm_unrailgate(struct generic_pm_domain *domain) | 1218 | return 0; |
1242 | { | ||
1243 | struct gk20a_domain_data *gk20a_domain = container_of(domain, | ||
1244 | struct gk20a_domain_data, gpd); | ||
1245 | struct gk20a *g = gk20a_domain->gk20a; | ||
1246 | trace_gk20a_pm_unrailgate(dev_name(g->dev)); | ||
1247 | 1219 | ||
1248 | return _gk20a_pm_unrailgate(g->dev); | 1220 | fail_railgate: |
1221 | gk20a_pm_finalize_poweron(dev); | ||
1222 | fail: | ||
1223 | return err; | ||
1249 | } | 1224 | } |
1250 | 1225 | ||
1251 | static int gk20a_pm_suspend(struct device *dev) | 1226 | static int gk20a_pm_suspend(struct device *dev) |
1252 | { | 1227 | { |
1253 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 1228 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
1229 | struct gk20a *g = get_gk20a(dev); | ||
1254 | int ret = 0; | 1230 | int ret = 0; |
1255 | 1231 | ||
1256 | #ifdef CONFIG_PM | 1232 | #ifdef CONFIG_PM |
@@ -1258,86 +1234,43 @@ static int gk20a_pm_suspend(struct device *dev) | |||
1258 | return -EBUSY; | 1234 | return -EBUSY; |
1259 | #endif | 1235 | #endif |
1260 | 1236 | ||
1261 | ret = gk20a_pm_prepare_poweroff(dev); | 1237 | if (!g->power_on) |
1238 | return 0; | ||
1239 | |||
1240 | ret = gk20a_pm_runtime_suspend(dev); | ||
1262 | if (ret) | 1241 | if (ret) |
1263 | return ret; | 1242 | return ret; |
1264 | 1243 | ||
1265 | if (platform->suspend) | 1244 | if (platform->suspend) |
1266 | platform->suspend(dev); | 1245 | platform->suspend(dev); |
1267 | 1246 | ||
1247 | g->suspended = true; | ||
1248 | |||
1268 | return 0; | 1249 | return 0; |
1269 | } | 1250 | } |
1270 | 1251 | ||
1271 | static int gk20a_pm_resume(struct device *dev) | 1252 | static int gk20a_pm_resume(struct device *dev) |
1272 | { | 1253 | { |
1273 | return gk20a_pm_finalize_poweron(dev); | 1254 | struct gk20a *g = get_gk20a(dev); |
1274 | } | 1255 | int ret = 0; |
1275 | |||
1276 | #ifdef CONFIG_PM_GENERIC_DOMAINS_OF | ||
1277 | static int gk20a_pm_initialise_domain(struct device *dev) | ||
1278 | { | ||
1279 | struct gk20a_platform *platform = dev_get_drvdata(dev); | ||
1280 | struct dev_power_governor *pm_domain_gov = NULL; | ||
1281 | struct generic_pm_domain *domain = dev_to_genpd(dev); | ||
1282 | 1256 | ||
1283 | if (IS_ERR(domain)) | 1257 | if (!g->suspended) |
1284 | return 0; | 1258 | return 0; |
1285 | 1259 | ||
1286 | #ifdef CONFIG_PM | 1260 | ret = gk20a_pm_runtime_resume(dev); |
1287 | if (!platform->can_railgate) | ||
1288 | pm_domain_gov = &pm_domain_always_on_gov; | ||
1289 | #endif | ||
1290 | domain->gov = pm_domain_gov; | ||
1291 | 1261 | ||
1292 | if (platform->railgate_delay) | 1262 | g->suspended = false; |
1293 | pm_genpd_set_poweroff_delay(domain, platform->railgate_delay); | ||
1294 | 1263 | ||
1295 | device_set_wakeup_capable(dev, 0); | 1264 | return ret; |
1296 | return 0; | ||
1297 | } | 1265 | } |
1298 | 1266 | ||
1299 | #else | ||
1300 | static int gk20a_pm_initialise_domain(struct device *dev) | ||
1301 | { | ||
1302 | struct gk20a_platform *platform = dev_get_drvdata(dev); | ||
1303 | struct dev_power_governor *pm_domain_gov = NULL; | ||
1304 | struct generic_pm_domain *domain = NULL; | ||
1305 | int ret = 0; | ||
1306 | struct gk20a_domain_data *gpu_gpd_data = (struct gk20a_domain_data *) | ||
1307 | kzalloc(sizeof(struct gk20a_domain_data), GFP_KERNEL); | ||
1308 | |||
1309 | if (!gpu_gpd_data) | ||
1310 | return -ENOMEM; | ||
1311 | |||
1312 | gpu_gpd_data->gk20a = platform->g; | ||
1313 | domain = &gpu_gpd_data->gpd; | ||
1314 | |||
1315 | domain->name = "gpu"; | ||
1316 | |||
1317 | #ifdef CONFIG_PM | 1267 | #ifdef CONFIG_PM |
1318 | if (!platform->can_railgate) | 1268 | static const struct dev_pm_ops gk20a_pm_ops = { |
1319 | pm_domain_gov = &pm_domain_always_on_gov; | 1269 | .runtime_resume = gk20a_pm_runtime_resume, |
1320 | #endif | 1270 | .runtime_suspend = gk20a_pm_runtime_suspend, |
1321 | 1271 | .resume = gk20a_pm_resume, | |
1322 | pm_genpd_init(domain, pm_domain_gov, true); | 1272 | .suspend = gk20a_pm_suspend, |
1323 | 1273 | }; | |
1324 | domain->power_off = gk20a_pm_railgate; | ||
1325 | domain->power_on = gk20a_pm_unrailgate; | ||
1326 | domain->dev_ops.start = gk20a_pm_enable_clk; | ||
1327 | domain->dev_ops.stop = gk20a_pm_disable_clk; | ||
1328 | domain->dev_ops.save_state = gk20a_pm_prepare_poweroff; | ||
1329 | domain->dev_ops.restore_state = gk20a_pm_finalize_poweron; | ||
1330 | domain->dev_ops.suspend = gk20a_pm_suspend; | ||
1331 | domain->dev_ops.resume = gk20a_pm_resume; | ||
1332 | |||
1333 | device_set_wakeup_capable(dev, 0); | ||
1334 | ret = pm_genpd_add_device(domain, dev); | ||
1335 | |||
1336 | if (platform->railgate_delay) | ||
1337 | pm_genpd_set_poweroff_delay(domain, platform->railgate_delay); | ||
1338 | |||
1339 | return ret; | ||
1340 | } | ||
1341 | #endif | 1274 | #endif |
1342 | 1275 | ||
1343 | int gk20a_pm_init(struct device *dev) | 1276 | int gk20a_pm_init(struct device *dev) |
@@ -1350,24 +1283,20 @@ int gk20a_pm_init(struct device *dev) | |||
1350 | /* Initialise pm runtime */ | 1283 | /* Initialise pm runtime */ |
1351 | if (platform->railgate_delay) { | 1284 | if (platform->railgate_delay) { |
1352 | pm_runtime_set_autosuspend_delay(dev, | 1285 | pm_runtime_set_autosuspend_delay(dev, |
1353 | platform->railgate_delay); | 1286 | platform->railgate_delay); |
1354 | pm_runtime_use_autosuspend(dev); | 1287 | pm_runtime_use_autosuspend(dev); |
1355 | } | 1288 | } |
1356 | 1289 | ||
1357 | pm_runtime_enable(dev); | 1290 | if (platform->can_railgate) { |
1358 | if (!pm_runtime_enabled(dev)) | 1291 | pm_runtime_enable(dev); |
1359 | gk20a_pm_enable_clk(dev); | 1292 | if (!pm_runtime_enabled(dev)) |
1360 | 1293 | gk20a_pm_unrailgate(dev); | |
1361 | /* Enable runtime railgating if possible. If not, | 1294 | else |
1362 | * turn on the rail now. */ | 1295 | gk20a_pm_railgate(dev); |
1363 | if (platform->can_railgate && IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | 1296 | } else { |
1364 | _gk20a_pm_railgate(dev); | 1297 | __pm_runtime_disable(dev, false); |
1365 | else if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | 1298 | gk20a_pm_unrailgate(dev); |
1366 | _gk20a_pm_unrailgate(dev); | 1299 | } |
1367 | |||
1368 | /* genpd will take care of runtime power management if it is enabled */ | ||
1369 | if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
1370 | err = gk20a_pm_initialise_domain(dev); | ||
1371 | 1300 | ||
1372 | return err; | 1301 | return err; |
1373 | } | 1302 | } |
@@ -1386,24 +1315,12 @@ static int gk20a_secure_page_alloc(struct platform_device *pdev) | |||
1386 | return err; | 1315 | return err; |
1387 | } | 1316 | } |
1388 | 1317 | ||
1389 | static struct of_device_id tegra_gpu_domain_match[] = { | ||
1390 | {.compatible = "nvidia,tegra124-gpu-pd"}, | ||
1391 | {.compatible = "nvidia,tegra132-gpu-pd"}, | ||
1392 | {.compatible = "nvidia,tegra210-gpu-pd"}, | ||
1393 | {.compatible = "nvidia,tegra186-gpu-pd"}, | ||
1394 | {}, | ||
1395 | }; | ||
1396 | |||
1397 | static int gk20a_probe(struct platform_device *dev) | 1318 | static int gk20a_probe(struct platform_device *dev) |
1398 | { | 1319 | { |
1399 | struct gk20a *gk20a; | 1320 | struct gk20a *gk20a; |
1400 | int err; | 1321 | int err; |
1401 | struct gk20a_platform *platform = NULL; | 1322 | struct gk20a_platform *platform = NULL; |
1402 | 1323 | ||
1403 | #ifdef CONFIG_PM_GENERIC_DOMAINS_OF | ||
1404 | struct gk20a_domain_data *gk20a_domain; | ||
1405 | #endif | ||
1406 | |||
1407 | if (dev->dev.of_node) { | 1324 | if (dev->dev.of_node) { |
1408 | const struct of_device_id *match; | 1325 | const struct of_device_id *match; |
1409 | 1326 | ||
@@ -1434,12 +1351,6 @@ static int gk20a_probe(struct platform_device *dev) | |||
1434 | init_waitqueue_head(&gk20a->sw_irq_stall_last_handled_wq); | 1351 | init_waitqueue_head(&gk20a->sw_irq_stall_last_handled_wq); |
1435 | init_waitqueue_head(&gk20a->sw_irq_nonstall_last_handled_wq); | 1352 | init_waitqueue_head(&gk20a->sw_irq_nonstall_last_handled_wq); |
1436 | 1353 | ||
1437 | #ifdef CONFIG_PM_GENERIC_DOMAINS_OF | ||
1438 | gk20a_domain = container_of(dev_to_genpd(&dev->dev), | ||
1439 | struct gk20a_domain_data, gpd); | ||
1440 | gk20a_domain->gk20a = gk20a; | ||
1441 | #endif | ||
1442 | |||
1443 | set_gk20a(dev, gk20a); | 1354 | set_gk20a(dev, gk20a); |
1444 | gk20a->dev = &dev->dev; | 1355 | gk20a->dev = &dev->dev; |
1445 | 1356 | ||
@@ -1636,7 +1547,6 @@ static int __exit gk20a_remove(struct platform_device *pdev) | |||
1636 | struct device *dev = &pdev->dev; | 1547 | struct device *dev = &pdev->dev; |
1637 | struct gk20a *g = get_gk20a(dev); | 1548 | struct gk20a *g = get_gk20a(dev); |
1638 | struct gk20a_platform *platform = gk20a_get_platform(dev); | 1549 | struct gk20a_platform *platform = gk20a_get_platform(dev); |
1639 | struct gk20a_domain_data *gk20a_gpd; | ||
1640 | 1550 | ||
1641 | gk20a_dbg_fn(""); | 1551 | gk20a_dbg_fn(""); |
1642 | 1552 | ||
@@ -1665,14 +1575,8 @@ static int __exit gk20a_remove(struct platform_device *pdev) | |||
1665 | platform->secure_buffer.destroy(dev, | 1575 | platform->secure_buffer.destroy(dev, |
1666 | &platform->secure_buffer); | 1576 | &platform->secure_buffer); |
1667 | 1577 | ||
1668 | gk20a_gpd = container_of(&g, struct gk20a_domain_data, gk20a); | ||
1669 | gk20a_gpd->gk20a = NULL; | ||
1670 | kfree(gk20a_gpd); | ||
1671 | |||
1672 | if (pm_runtime_enabled(dev)) | 1578 | if (pm_runtime_enabled(dev)) |
1673 | pm_runtime_disable(dev); | 1579 | pm_runtime_disable(dev); |
1674 | else | ||
1675 | gk20a_pm_disable_clk(dev); | ||
1676 | 1580 | ||
1677 | if (platform->remove) | 1581 | if (platform->remove) |
1678 | platform->remove(dev); | 1582 | platform->remove(dev); |
@@ -1704,63 +1608,6 @@ static struct platform_driver gk20a_driver = { | |||
1704 | } | 1608 | } |
1705 | }; | 1609 | }; |
1706 | 1610 | ||
1707 | #ifdef CONFIG_PM_GENERIC_DOMAINS_OF | ||
1708 | |||
1709 | |||
1710 | static int _gk20a_init_domain(struct device_node *np, | ||
1711 | struct generic_pm_domain *gpd) | ||
1712 | { | ||
1713 | bool is_off = false; | ||
1714 | |||
1715 | gpd->name = (char *)np->name; | ||
1716 | |||
1717 | if (of_property_read_bool(np, "is_off")) | ||
1718 | is_off = true; | ||
1719 | |||
1720 | pm_genpd_init(gpd, NULL, is_off); | ||
1721 | |||
1722 | gpd->power_on = gk20a_pm_unrailgate; | ||
1723 | gpd->power_off = gk20a_pm_railgate; | ||
1724 | gpd->dev_ops.start = gk20a_pm_enable_clk; | ||
1725 | gpd->dev_ops.stop = gk20a_pm_disable_clk; | ||
1726 | gpd->dev_ops.save_state = gk20a_pm_prepare_poweroff; | ||
1727 | gpd->dev_ops.restore_state = gk20a_pm_finalize_poweron; | ||
1728 | gpd->dev_ops.suspend = gk20a_pm_suspend; | ||
1729 | gpd->dev_ops.resume = gk20a_pm_resume; | ||
1730 | |||
1731 | of_genpd_add_provider_simple(np, gpd); | ||
1732 | gpd->of_node = of_node_get(np); | ||
1733 | |||
1734 | genpd_pm_subdomain_attach(gpd); | ||
1735 | return 0; | ||
1736 | } | ||
1737 | |||
1738 | static int gk20a_domain_init(struct of_device_id *matches) | ||
1739 | { | ||
1740 | int ret = 0; | ||
1741 | struct device_node *np; | ||
1742 | struct gk20a_domain_data *gk20a_domain; | ||
1743 | |||
1744 | np = of_find_matching_node(NULL, matches); | ||
1745 | if (!np) | ||
1746 | return -ENOENT; | ||
1747 | |||
1748 | gk20a_domain = (struct gk20a_domain_data *)kzalloc | ||
1749 | (sizeof(struct gk20a_domain_data), GFP_KERNEL); | ||
1750 | if (!gk20a_domain) | ||
1751 | return -ENOMEM; | ||
1752 | |||
1753 | ret = _gk20a_init_domain(np, &gk20a_domain->gpd); | ||
1754 | |||
1755 | return ret; | ||
1756 | } | ||
1757 | #else | ||
1758 | static int gk20a_domain_init(struct of_device_id *matches) | ||
1759 | { | ||
1760 | return 0; | ||
1761 | } | ||
1762 | #endif | ||
1763 | |||
1764 | struct class nvgpu_class = { | 1611 | struct class nvgpu_class = { |
1765 | .owner = THIS_MODULE, | 1612 | .owner = THIS_MODULE, |
1766 | .name = CLASS_NAME, | 1613 | .name = CLASS_NAME, |
@@ -1775,10 +1622,6 @@ static int __init gk20a_init(void) | |||
1775 | if (ret) | 1622 | if (ret) |
1776 | return ret; | 1623 | return ret; |
1777 | 1624 | ||
1778 | ret = gk20a_domain_init(tegra_gpu_domain_match); | ||
1779 | if (ret) | ||
1780 | return ret; | ||
1781 | |||
1782 | ret = nvgpu_pci_init(); | 1625 | ret = nvgpu_pci_init(); |
1783 | if (ret) | 1626 | if (ret) |
1784 | return ret; | 1627 | return ret; |
@@ -1802,38 +1645,37 @@ int gk20a_busy(struct device *dev) | |||
1802 | { | 1645 | { |
1803 | int ret = 0; | 1646 | int ret = 0; |
1804 | struct gk20a *g = get_gk20a(dev); | 1647 | struct gk20a *g = get_gk20a(dev); |
1805 | #ifdef CONFIG_PM | ||
1806 | struct gk20a_platform *platform = gk20a_get_platform(dev); | 1648 | struct gk20a_platform *platform = gk20a_get_platform(dev); |
1807 | #endif | ||
1808 | 1649 | ||
1809 | down_read(&g->busy_lock); | 1650 | down_read(&g->busy_lock); |
1810 | 1651 | ||
1811 | #ifdef CONFIG_PM | 1652 | if (pm_runtime_enabled(dev)) { |
1812 | if (platform->busy) { | 1653 | if (platform->busy) { |
1813 | ret = platform->busy(dev); | 1654 | ret = platform->busy(dev); |
1655 | if (ret < 0) { | ||
1656 | dev_err(dev, "%s: failed to poweron platform dependency\n", | ||
1657 | __func__); | ||
1658 | goto fail; | ||
1659 | } | ||
1660 | } | ||
1661 | |||
1662 | ret = pm_runtime_get_sync(dev); | ||
1814 | if (ret < 0) { | 1663 | if (ret < 0) { |
1815 | dev_err(dev, "%s: failed to poweron platform dependency\n", | 1664 | pm_runtime_put_noidle(dev); |
1816 | __func__); | 1665 | if (platform->idle) |
1666 | platform->idle(dev); | ||
1817 | goto fail; | 1667 | goto fail; |
1818 | } | 1668 | } |
1669 | } else { | ||
1670 | if (!g->power_on) { | ||
1671 | ret = gk20a_gpu_is_virtual(dev) ? | ||
1672 | vgpu_pm_finalize_poweron(dev) | ||
1673 | : gk20a_pm_finalize_poweron(dev); | ||
1674 | if (ret) | ||
1675 | goto fail; | ||
1676 | } | ||
1819 | } | 1677 | } |
1820 | 1678 | ||
1821 | ret = pm_runtime_get_sync(dev); | ||
1822 | if (ret < 0) { | ||
1823 | pm_runtime_put_noidle(dev); | ||
1824 | if (platform->idle) | ||
1825 | platform->idle(dev); | ||
1826 | goto fail; | ||
1827 | } | ||
1828 | #else | ||
1829 | if (!g->power_on) { | ||
1830 | ret = gk20a_gpu_is_virtual(dev) ? | ||
1831 | vgpu_pm_finalize_poweron(dev) | ||
1832 | : gk20a_pm_finalize_poweron(dev); | ||
1833 | if (ret) | ||
1834 | goto fail; | ||
1835 | } | ||
1836 | #endif | ||
1837 | gk20a_scale_notify_busy(dev); | 1679 | gk20a_scale_notify_busy(dev); |
1838 | 1680 | ||
1839 | fail: | 1681 | fail: |
@@ -1844,18 +1686,22 @@ fail: | |||
1844 | 1686 | ||
1845 | void gk20a_idle(struct device *dev) | 1687 | void gk20a_idle(struct device *dev) |
1846 | { | 1688 | { |
1847 | #ifdef CONFIG_PM | ||
1848 | struct gk20a_platform *platform = gk20a_get_platform(dev); | 1689 | struct gk20a_platform *platform = gk20a_get_platform(dev); |
1849 | if (atomic_read(&dev->power.usage_count) == 1) | ||
1850 | gk20a_scale_notify_idle(dev); | ||
1851 | pm_runtime_mark_last_busy(dev); | ||
1852 | pm_runtime_put_sync_autosuspend(dev); | ||
1853 | 1690 | ||
1854 | if (platform->idle) | 1691 | if (pm_runtime_enabled(dev)) { |
1855 | platform->idle(dev); | 1692 | #ifdef CONFIG_PM |
1856 | #else | 1693 | if (atomic_read(&dev->power.usage_count) == 1) |
1857 | gk20a_scale_notify_idle(dev); | 1694 | gk20a_scale_notify_idle(dev); |
1858 | #endif | 1695 | #endif |
1696 | |||
1697 | pm_runtime_mark_last_busy(dev); | ||
1698 | pm_runtime_put_sync_autosuspend(dev); | ||
1699 | |||
1700 | if (platform->idle) | ||
1701 | platform->idle(dev); | ||
1702 | } else { | ||
1703 | gk20a_scale_notify_idle(dev); | ||
1704 | } | ||
1859 | } | 1705 | } |
1860 | 1706 | ||
1861 | void gk20a_disable(struct gk20a *g, u32 units) | 1707 | void gk20a_disable(struct gk20a *g, u32 units) |
@@ -1991,8 +1837,6 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) | |||
1991 | /* Save the GPU state */ | 1837 | /* Save the GPU state */ |
1992 | gk20a_pm_prepare_poweroff(dev); | 1838 | gk20a_pm_prepare_poweroff(dev); |
1993 | 1839 | ||
1994 | gk20a_pm_disable_clk(dev); | ||
1995 | |||
1996 | /* railgate GPU */ | 1840 | /* railgate GPU */ |
1997 | platform->railgate(dev); | 1841 | platform->railgate(dev); |
1998 | 1842 | ||
@@ -2044,8 +1888,6 @@ int __gk20a_do_unidle(struct device *dev) | |||
2044 | */ | 1888 | */ |
2045 | platform->unrailgate(dev); | 1889 | platform->unrailgate(dev); |
2046 | 1890 | ||
2047 | gk20a_pm_enable_clk(dev); | ||
2048 | |||
2049 | /* restore the GPU state */ | 1891 | /* restore the GPU state */ |
2050 | gk20a_pm_finalize_poweron(dev); | 1892 | gk20a_pm_finalize_poweron(dev); |
2051 | 1893 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index b8a2fc3e..949cd4a5 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -664,6 +664,7 @@ struct gk20a { | |||
664 | struct device *dev; | 664 | struct device *dev; |
665 | struct platform_device *host1x_dev; | 665 | struct platform_device *host1x_dev; |
666 | 666 | ||
667 | |||
667 | struct resource *reg_mem; | 668 | struct resource *reg_mem; |
668 | void __iomem *regs; | 669 | void __iomem *regs; |
669 | void __iomem *regs_saved; | 670 | void __iomem *regs_saved; |
@@ -673,6 +674,7 @@ struct gk20a { | |||
673 | void __iomem *bar1_saved; | 674 | void __iomem *bar1_saved; |
674 | 675 | ||
675 | bool power_on; | 676 | bool power_on; |
677 | bool suspended; | ||
676 | 678 | ||
677 | struct rw_semaphore busy_lock; | 679 | struct rw_semaphore busy_lock; |
678 | 680 | ||
@@ -882,11 +884,6 @@ struct gk20a_cyclestate_buffer_elem { | |||
882 | u64 data; | 884 | u64 data; |
883 | }; | 885 | }; |
884 | 886 | ||
885 | struct gk20a_domain_data { | ||
886 | struct generic_pm_domain gpd; | ||
887 | struct gk20a *gk20a; | ||
888 | }; | ||
889 | |||
890 | /* debug accessories */ | 887 | /* debug accessories */ |
891 | 888 | ||
892 | #ifdef CONFIG_DEBUG_FS | 889 | #ifdef CONFIG_DEBUG_FS |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index 127d0258..38d5a842 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | |||
@@ -276,49 +276,33 @@ static DEVICE_ATTR(ptimer_src_freq, | |||
276 | NULL); | 276 | NULL); |
277 | 277 | ||
278 | 278 | ||
279 | #if defined(CONFIG_PM) && defined(CONFIG_PM_GENERIC_DOMAINS) | 279 | #if defined(CONFIG_PM) |
280 | static ssize_t railgate_enable_store(struct device *dev, | 280 | static ssize_t railgate_enable_store(struct device *dev, |
281 | struct device_attribute *attr, const char *buf, size_t count) | 281 | struct device_attribute *attr, const char *buf, size_t count) |
282 | { | 282 | { |
283 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 283 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
284 | struct generic_pm_domain *genpd = dev_to_genpd(dev); | ||
285 | struct gk20a *g = get_gk20a(dev); | ||
286 | unsigned long railgate_enable = 0; | 284 | unsigned long railgate_enable = 0; |
287 | int err = 0; | 285 | int err = 0; |
288 | 286 | ||
289 | if (kstrtoul(buf, 10, &railgate_enable) < 0) | 287 | if (kstrtoul(buf, 10, &railgate_enable) < 0) |
290 | return -EINVAL; | 288 | return -EINVAL; |
289 | |||
291 | if (railgate_enable && !platform->can_railgate) { | 290 | if (railgate_enable && !platform->can_railgate) { |
292 | mutex_lock(&platform->railgate_lock); | 291 | /* release extra ref count */ |
292 | gk20a_idle(dev); | ||
293 | platform->can_railgate = true; | 293 | platform->can_railgate = true; |
294 | genpd->gov = NULL; | ||
295 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | ||
296 | /* release extra ref count:if power domains not enabled */ | ||
297 | if ((platform->railgate) && \ | ||
298 | !IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
299 | err = platform->railgate(dev); | ||
300 | mutex_unlock(&platform->railgate_lock); | ||
301 | } else if (railgate_enable == 0 && platform->can_railgate) { | 294 | } else if (railgate_enable == 0 && platform->can_railgate) { |
302 | mutex_lock(&platform->railgate_lock); | 295 | /* take extra ref count */ |
296 | err = gk20a_busy(dev); | ||
297 | if (err) | ||
298 | return err; | ||
303 | platform->can_railgate = false; | 299 | platform->can_railgate = false; |
304 | genpd->gov = &pm_domain_always_on_gov; | ||
305 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | ||
306 | /* take extra ref count - incase of power domains not enabled */ | ||
307 | if ((platform->unrailgate) && \ | ||
308 | !IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
309 | err = platform->unrailgate(dev); | ||
310 | mutex_unlock(&platform->railgate_lock); | ||
311 | } | 300 | } |
312 | if (err) | 301 | if (err) |
313 | return err; | 302 | return err; |
314 | 303 | ||
315 | dev_info(dev, "railgate is %s.\n", platform->can_railgate ? | 304 | dev_info(dev, "railgate is %s.\n", platform->can_railgate ? |
316 | "enabled" : "disabled"); | 305 | "enabled" : "disabled"); |
317 | /* wake-up system to make railgating_enable effective immediately */ | ||
318 | err = gk20a_busy(g->dev); | ||
319 | if (err) | ||
320 | return err; | ||
321 | gk20a_idle(g->dev); | ||
322 | 306 | ||
323 | return count; | 307 | return count; |
324 | } | 308 | } |
@@ -351,11 +335,11 @@ static ssize_t railgate_delay_store(struct device *dev, | |||
351 | 335 | ||
352 | ret = sscanf(buf, "%d", &railgate_delay); | 336 | ret = sscanf(buf, "%d", &railgate_delay); |
353 | if (ret == 1 && railgate_delay >= 0) { | 337 | if (ret == 1 && railgate_delay >= 0) { |
354 | struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); | ||
355 | platform->railgate_delay = railgate_delay; | 338 | platform->railgate_delay = railgate_delay; |
356 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | 339 | pm_runtime_set_autosuspend_delay(dev, platform->railgate_delay); |
357 | } else | 340 | } else |
358 | dev_err(dev, "Invalid powergate delay\n"); | 341 | dev_err(dev, "Invalid powergate delay\n"); |
342 | |||
359 | /* wake-up system to make rail-gating delay effective immediately */ | 343 | /* wake-up system to make rail-gating delay effective immediately */ |
360 | err = gk20a_busy(g->dev); | 344 | err = gk20a_busy(g->dev); |
361 | if (err) | 345 | if (err) |
@@ -782,10 +766,8 @@ void gk20a_remove_sysfs(struct device *dev) | |||
782 | device_remove_file(dev, &dev_attr_is_railgated); | 766 | device_remove_file(dev, &dev_attr_is_railgated); |
783 | #ifdef CONFIG_PM | 767 | #ifdef CONFIG_PM |
784 | device_remove_file(dev, &dev_attr_force_idle); | 768 | device_remove_file(dev, &dev_attr_force_idle); |
785 | #if defined(CONFIG_PM_GENERIC_DOMAINS) | ||
786 | device_remove_file(dev, &dev_attr_railgate_enable); | 769 | device_remove_file(dev, &dev_attr_railgate_enable); |
787 | #endif | 770 | #endif |
788 | #endif | ||
789 | device_remove_file(dev, &dev_attr_aelpg_param); | 771 | device_remove_file(dev, &dev_attr_aelpg_param); |
790 | device_remove_file(dev, &dev_attr_aelpg_enable); | 772 | device_remove_file(dev, &dev_attr_aelpg_enable); |
791 | device_remove_file(dev, &dev_attr_allow_all); | 773 | device_remove_file(dev, &dev_attr_allow_all); |
@@ -823,10 +805,8 @@ void gk20a_create_sysfs(struct device *dev) | |||
823 | error |= device_create_file(dev, &dev_attr_is_railgated); | 805 | error |= device_create_file(dev, &dev_attr_is_railgated); |
824 | #ifdef CONFIG_PM | 806 | #ifdef CONFIG_PM |
825 | error |= device_create_file(dev, &dev_attr_force_idle); | 807 | error |= device_create_file(dev, &dev_attr_force_idle); |
826 | #if defined(CONFIG_PM_GENERIC_DOMAINS) | ||
827 | error |= device_create_file(dev, &dev_attr_railgate_enable); | 808 | error |= device_create_file(dev, &dev_attr_railgate_enable); |
828 | #endif | 809 | #endif |
829 | #endif | ||
830 | error |= device_create_file(dev, &dev_attr_aelpg_param); | 810 | error |= device_create_file(dev, &dev_attr_aelpg_param); |
831 | error |= device_create_file(dev, &dev_attr_aelpg_enable); | 811 | error |= device_create_file(dev, &dev_attr_aelpg_enable); |
832 | error |= device_create_file(dev, &dev_attr_allow_all); | 812 | error |= device_create_file(dev, &dev_attr_allow_all); |
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h index a753201b..543f9873 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #define _GK20A_PLATFORM_H_ | 17 | #define _GK20A_PLATFORM_H_ |
18 | 18 | ||
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/pm_domain.h> | ||
21 | #include <linux/dma-attrs.h> | 20 | #include <linux/dma-attrs.h> |
22 | 21 | ||
23 | struct gk20a; | 22 | struct gk20a; |
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c index 25f9a8dd..cea82805 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <uapi/linux/nvgpu.h> | 22 | #include <uapi/linux/nvgpu.h> |
23 | #include <linux/dma-buf.h> | 23 | #include <linux/dma-buf.h> |
24 | #include <linux/nvmap.h> | 24 | #include <linux/nvmap.h> |
25 | #include <linux/tegra_pm_domains.h> | ||
26 | #include <linux/tegra_soctherm.h> | 25 | #include <linux/tegra_soctherm.h> |
27 | #include <linux/platform/tegra/clock.h> | 26 | #include <linux/platform/tegra/clock.h> |
28 | #include <linux/platform/tegra/dvfs.h> | 27 | #include <linux/platform/tegra/dvfs.h> |
@@ -780,9 +779,6 @@ static int gk20a_tegra_probe(struct device *dev) | |||
780 | 779 | ||
781 | static int gk20a_tegra_late_probe(struct device *dev) | 780 | static int gk20a_tegra_late_probe(struct device *dev) |
782 | { | 781 | { |
783 | /* Make gk20a power domain a subdomain of host1x */ | ||
784 | nvhost_register_client_domain(dev_to_genpd(dev)); | ||
785 | |||
786 | /* Initialise tegra specific scaling quirks */ | 782 | /* Initialise tegra specific scaling quirks */ |
787 | gk20a_tegra_scale_init(dev); | 783 | gk20a_tegra_scale_init(dev); |
788 | 784 | ||
@@ -791,9 +787,6 @@ static int gk20a_tegra_late_probe(struct device *dev) | |||
791 | 787 | ||
792 | static int gk20a_tegra_remove(struct device *dev) | 788 | static int gk20a_tegra_remove(struct device *dev) |
793 | { | 789 | { |
794 | /* remove gk20a power subdomain from host1x */ | ||
795 | nvhost_unregister_client_domain(dev_to_genpd(dev)); | ||
796 | |||
797 | /* deinitialise tegra specific scaling quirks */ | 790 | /* deinitialise tegra specific scaling quirks */ |
798 | gk20a_tegra_scale_exit(dev); | 791 | gk20a_tegra_scale_exit(dev); |
799 | 792 | ||
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index 6393ea50..c28130f2 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c | |||
@@ -430,48 +430,13 @@ done: | |||
430 | return err; | 430 | return err; |
431 | } | 431 | } |
432 | 432 | ||
433 | static int vgpu_pm_initialise_domain(struct device *dev) | ||
434 | { | ||
435 | struct gk20a_platform *platform = dev_get_drvdata(dev); | ||
436 | struct dev_power_governor *pm_domain_gov = NULL; | ||
437 | struct gk20a_domain_data *vgpu_pd_data; | ||
438 | struct generic_pm_domain *domain; | ||
439 | |||
440 | vgpu_pd_data = (struct gk20a_domain_data *)kzalloc | ||
441 | (sizeof(struct gk20a_domain_data), GFP_KERNEL); | ||
442 | |||
443 | if (!vgpu_pd_data) | ||
444 | return -ENOMEM; | ||
445 | |||
446 | domain = &vgpu_pd_data->gpd; | ||
447 | vgpu_pd_data->gk20a = platform->g; | ||
448 | |||
449 | domain->name = "gpu"; | ||
450 | |||
451 | #ifdef CONFIG_PM | ||
452 | pm_domain_gov = &pm_domain_always_on_gov; | ||
453 | #endif | ||
454 | |||
455 | pm_genpd_init(domain, pm_domain_gov, true); | ||
456 | |||
457 | domain->dev_ops.save_state = vgpu_pm_prepare_poweroff; | ||
458 | domain->dev_ops.restore_state = vgpu_pm_finalize_poweron; | ||
459 | |||
460 | device_set_wakeup_capable(dev, 0); | ||
461 | return pm_genpd_add_device(domain, dev); | ||
462 | } | ||
463 | |||
464 | static int vgpu_pm_init(struct device *dev) | 433 | static int vgpu_pm_init(struct device *dev) |
465 | { | 434 | { |
466 | int err = 0; | 435 | int err = 0; |
467 | 436 | ||
468 | gk20a_dbg_fn(""); | 437 | gk20a_dbg_fn(""); |
469 | 438 | ||
470 | pm_runtime_enable(dev); | 439 | __pm_runtime_disable(dev, false); |
471 | |||
472 | /* genpd will take care of runtime power management if it is enabled */ | ||
473 | if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
474 | err = vgpu_pm_initialise_domain(dev); | ||
475 | 440 | ||
476 | return err; | 441 | return err; |
477 | } | 442 | } |
@@ -567,16 +532,11 @@ int vgpu_remove(struct platform_device *pdev) | |||
567 | { | 532 | { |
568 | struct device *dev = &pdev->dev; | 533 | struct device *dev = &pdev->dev; |
569 | struct gk20a *g = get_gk20a(dev); | 534 | struct gk20a *g = get_gk20a(dev); |
570 | struct gk20a_domain_data *vgpu_gpd; | ||
571 | gk20a_dbg_fn(""); | 535 | gk20a_dbg_fn(""); |
572 | 536 | ||
573 | if (g->remove_support) | 537 | if (g->remove_support) |
574 | g->remove_support(dev); | 538 | g->remove_support(dev); |
575 | 539 | ||
576 | vgpu_gpd = container_of(&g, struct gk20a_domain_data, gk20a); | ||
577 | vgpu_gpd->gk20a = NULL; | ||
578 | kfree(vgpu_gpd); | ||
579 | |||
580 | vgpu_comm_deinit(); | 540 | vgpu_comm_deinit(); |
581 | gk20a_user_deinit(dev, &nvgpu_class); | 541 | gk20a_user_deinit(dev, &nvgpu_class); |
582 | gk20a_get_platform(dev)->g = NULL; | 542 | gk20a_get_platform(dev)->g = NULL; |