From 8d69ac3dcfb4c7f9493330c8ac9b407ddbd088f7 Mon Sep 17 00:00:00 2001 From: Shuangjie Lin Date: Tue, 16 Apr 2024 10:30:13 +0800 Subject: [PATCH] driver: rknpu: add power get/put for drm free memory Signed-off-by: Shuangjie Lin Change-Id: I2adc5888babf323372a6bd967576c693c7414b8d --- drivers/rknpu/include/rknpu_drv.h | 1 + drivers/rknpu/rknpu_drv.c | 21 +++++++++++++++++---- drivers/rknpu/rknpu_gem.c | 4 ++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/rknpu/include/rknpu_drv.h b/drivers/rknpu/include/rknpu_drv.h index dbcb1b69a744..ce4a06fa9721 100644 --- a/drivers/rknpu/include/rknpu_drv.h +++ b/drivers/rknpu/include/rknpu_drv.h @@ -179,5 +179,6 @@ struct rknpu_session { int rknpu_power_get(struct rknpu_device *rknpu_dev); int rknpu_power_put(struct rknpu_device *rknpu_dev); +int rknpu_power_put_delay(struct rknpu_device *rknpu_dev); #endif /* __LINUX_RKNPU_DRV_H_ */ diff --git a/drivers/rknpu/rknpu_drv.c b/drivers/rknpu/rknpu_drv.c index b706491795f3..9e7bbfe46fa1 100644 --- a/drivers/rknpu/rknpu_drv.c +++ b/drivers/rknpu/rknpu_drv.c @@ -263,13 +263,20 @@ static int rknpu_power_off(struct rknpu_device *rknpu_dev); static void rknpu_power_off_delay_work(struct work_struct *power_off_work) { + int ret = 0; struct rknpu_device *rknpu_dev = container_of(to_delayed_work(power_off_work), struct rknpu_device, power_off_work); mutex_lock(&rknpu_dev->power_lock); - if (atomic_dec_if_positive(&rknpu_dev->power_refcount) == 0) - rknpu_power_off(rknpu_dev); + if (atomic_dec_if_positive(&rknpu_dev->power_refcount) == 0) { + ret = rknpu_power_off(rknpu_dev); + if (ret) + atomic_inc(&rknpu_dev->power_refcount); + } mutex_unlock(&rknpu_dev->power_lock); + + if (ret) + rknpu_power_put_delay(rknpu_dev); } int rknpu_power_get(struct rknpu_device *rknpu_dev) @@ -289,14 +296,20 @@ int rknpu_power_put(struct rknpu_device *rknpu_dev) int ret = 0; mutex_lock(&rknpu_dev->power_lock); - if (atomic_dec_if_positive(&rknpu_dev->power_refcount) == 0) + if (atomic_dec_if_positive(&rknpu_dev->power_refcount) == 0) { ret = rknpu_power_off(rknpu_dev); + if (ret) + atomic_inc(&rknpu_dev->power_refcount); + } mutex_unlock(&rknpu_dev->power_lock); + if (ret) + rknpu_power_put_delay(rknpu_dev); + return ret; } -static int rknpu_power_put_delay(struct rknpu_device *rknpu_dev) +int rknpu_power_put_delay(struct rknpu_device *rknpu_dev) { if (rknpu_dev->power_put_delay == 0) return rknpu_power_put(rknpu_dev); diff --git a/drivers/rknpu/rknpu_gem.c b/drivers/rknpu/rknpu_gem.c index 4cabe13a54c0..81fbb29334af 100644 --- a/drivers/rknpu/rknpu_gem.c +++ b/drivers/rknpu/rknpu_gem.c @@ -1019,7 +1019,11 @@ static int rknpu_gem_mmap_buffer(struct rknpu_gem_object *rknpu_obj, void rknpu_gem_free_object(struct drm_gem_object *obj) { + struct rknpu_device *rknpu_dev = obj->dev->dev_private; + + rknpu_power_get(rknpu_dev); rknpu_gem_object_destroy(to_rknpu_obj(obj)); + rknpu_power_put_delay(rknpu_dev); } int rknpu_gem_dumb_create(struct drm_file *file_priv, struct drm_device *drm,