diff options
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/module.c')
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/module.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 1fd7f544..955481c8 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
26 | #include <linux/reset.h> | 26 | #include <linux/reset.h> |
27 | #include <linux/reboot.h> | ||
28 | #include <linux/notifier.h> | ||
27 | #include <linux/platform/tegra/common.h> | 29 | #include <linux/platform/tegra/common.h> |
28 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
29 | 31 | ||
@@ -76,6 +78,14 @@ | |||
76 | #define CREATE_TRACE_POINTS | 78 | #define CREATE_TRACE_POINTS |
77 | #include <trace/events/gk20a.h> | 79 | #include <trace/events/gk20a.h> |
78 | 80 | ||
81 | static int nvgpu_kernel_shutdown_notification(struct notifier_block *nb, | ||
82 | unsigned long event, void *unused) | ||
83 | { | ||
84 | struct gk20a *g = container_of(nb, struct gk20a, nvgpu_reboot_nb); | ||
85 | |||
86 | __nvgpu_set_enabled(g, NVGPU_KERNEL_IS_DYING, true); | ||
87 | return NOTIFY_DONE; | ||
88 | } | ||
79 | 89 | ||
80 | struct device_node *nvgpu_get_node(struct gk20a *g) | 90 | struct device_node *nvgpu_get_node(struct gk20a *g) |
81 | { | 91 | { |
@@ -98,6 +108,22 @@ void gk20a_busy_noresume(struct gk20a *g) | |||
98 | pm_runtime_get_noresume(dev_from_gk20a(g)); | 108 | pm_runtime_get_noresume(dev_from_gk20a(g)); |
99 | } | 109 | } |
100 | 110 | ||
111 | /* | ||
112 | * Check if the device can go busy. | ||
113 | */ | ||
114 | static int nvgpu_can_busy(struct gk20a *g) | ||
115 | { | ||
116 | /* Can't do anything if the system is rebooting/shutting down. */ | ||
117 | if (nvgpu_is_enabled(g, NVGPU_KERNEL_IS_DYING)) | ||
118 | return 0; | ||
119 | |||
120 | /* Can't do anything if the driver is restarting. */ | ||
121 | if (nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING)) | ||
122 | return 0; | ||
123 | |||
124 | return 1; | ||
125 | } | ||
126 | |||
101 | int gk20a_busy(struct gk20a *g) | 127 | int gk20a_busy(struct gk20a *g) |
102 | { | 128 | { |
103 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | 129 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); |
@@ -111,7 +137,7 @@ int gk20a_busy(struct gk20a *g) | |||
111 | 137 | ||
112 | down_read(&l->busy_lock); | 138 | down_read(&l->busy_lock); |
113 | 139 | ||
114 | if (!gk20a_can_busy(g)) { | 140 | if (!nvgpu_can_busy(g)) { |
115 | ret = -ENODEV; | 141 | ret = -ENODEV; |
116 | atomic_dec(&g->usage_count.atomic_var); | 142 | atomic_dec(&g->usage_count.atomic_var); |
117 | goto fail; | 143 | goto fail; |
@@ -158,7 +184,7 @@ void gk20a_idle(struct gk20a *g) | |||
158 | 184 | ||
159 | dev = dev_from_gk20a(g); | 185 | dev = dev_from_gk20a(g); |
160 | 186 | ||
161 | if (!(dev && gk20a_can_busy(g))) | 187 | if (!(dev && nvgpu_can_busy(g))) |
162 | return; | 188 | return; |
163 | 189 | ||
164 | if (pm_runtime_enabled(dev)) { | 190 | if (pm_runtime_enabled(dev)) { |
@@ -1289,6 +1315,12 @@ static int gk20a_probe(struct platform_device *dev) | |||
1289 | goto return_err; | 1315 | goto return_err; |
1290 | } | 1316 | } |
1291 | 1317 | ||
1318 | gk20a->nvgpu_reboot_nb.notifier_call = | ||
1319 | nvgpu_kernel_shutdown_notification; | ||
1320 | err = register_reboot_notifier(&gk20a->nvgpu_reboot_nb); | ||
1321 | if (err) | ||
1322 | goto return_err; | ||
1323 | |||
1292 | return 0; | 1324 | return 0; |
1293 | 1325 | ||
1294 | return_err: | 1326 | return_err: |
@@ -1368,6 +1400,8 @@ static int __exit gk20a_remove(struct platform_device *pdev) | |||
1368 | 1400 | ||
1369 | err = nvgpu_remove(dev, &nvgpu_class); | 1401 | err = nvgpu_remove(dev, &nvgpu_class); |
1370 | 1402 | ||
1403 | unregister_reboot_notifier(&g->nvgpu_reboot_nb); | ||
1404 | |||
1371 | set_gk20a(pdev, NULL); | 1405 | set_gk20a(pdev, NULL); |
1372 | 1406 | ||
1373 | gk20a_put(g); | 1407 | gk20a_put(g); |