diff options
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c')
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 6fa15421..271c5d92 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
20 | #include <linux/anon_inodes.h> | 20 | #include <linux/anon_inodes.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/pm_runtime.h> | ||
22 | #include <uapi/linux/nvgpu.h> | 23 | #include <uapi/linux/nvgpu.h> |
23 | 24 | ||
24 | #include <nvgpu/bitops.h> | 25 | #include <nvgpu/bitops.h> |
@@ -596,19 +597,46 @@ static int gk20a_ctrl_get_fbp_l2_masks( | |||
596 | static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, | 597 | static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, |
597 | struct nvgpu_gpu_l2_fb_args *args) | 598 | struct nvgpu_gpu_l2_fb_args *args) |
598 | { | 599 | { |
599 | int err = 0; | 600 | int ret; |
601 | bool always_poweron; | ||
600 | 602 | ||
601 | if ((!args->l2_flush && !args->fb_flush) || | 603 | if ((!args->l2_flush && !args->fb_flush) || |
602 | (!args->l2_flush && args->l2_invalidate)) | 604 | (!args->l2_flush && args->l2_invalidate)) |
603 | return -EINVAL; | 605 | return -EINVAL; |
604 | 606 | ||
607 | /* Handle this case for joint rails or DGPU */ | ||
608 | always_poweron = (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE) || | ||
609 | !pm_runtime_enabled(dev_from_gk20a(g))); | ||
610 | |||
611 | /* In case of not always power_on, exit if g->power_on is false */ | ||
612 | if (!always_poweron && !gk20a_check_poweron(g)) { | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /* There is a small window between a call to gk20a_idle() has occured | ||
617 | * and railgate being actually triggered(setting g->power_on = false), | ||
618 | * when l2_flush can race with railgate. Its better to take a busy_lock | ||
619 | * to prevent the gk20a_idle() from proceeding. There is a very small | ||
620 | * chance that gk20a_idle() might begin before gk20a_busy(). Having | ||
621 | * a locked access to g->power_on further reduces the probability of | ||
622 | * gk20a_idle() being triggered before gk20a_busy() | ||
623 | */ | ||
624 | ret = gk20a_busy(g); | ||
625 | |||
626 | if (ret != 0) { | ||
627 | nvgpu_err(g, "failed to take power ref"); | ||
628 | return ret; | ||
629 | } | ||
630 | |||
605 | if (args->l2_flush) | 631 | if (args->l2_flush) |
606 | g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); | 632 | g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); |
607 | 633 | ||
608 | if (args->fb_flush) | 634 | if (args->fb_flush) |
609 | g->ops.mm.fb_flush(g); | 635 | g->ops.mm.fb_flush(g); |
610 | 636 | ||
611 | return err; | 637 | gk20a_idle(g); |
638 | |||
639 | return 0; | ||
612 | } | 640 | } |
613 | 641 | ||
614 | static int nvgpu_gpu_ioctl_set_mmu_debug_mode( | 642 | static int nvgpu_gpu_ioctl_set_mmu_debug_mode( |