video: rockchip: rga3: Add drv_shutdown callback

Need to reset hardware when driver exits.

Update driver version to 1.3.6

Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
Change-Id: I4c6cb394a1339cf689d2d0d011d5df3fb24f0425
This commit is contained in:
Yu Qiaowei
2022-05-06 15:33:40 +08:00
committed by Tao Huang
parent b430f82a6f
commit 263734a862
4 changed files with 90 additions and 1 deletions

View File

@@ -88,7 +88,7 @@
#define DRIVER_MAJOR_VERISON 1
#define DRIVER_MINOR_VERSION 3
#define DRIVER_REVISION_VERSION 5
#define DRIVER_REVISION_VERSION 6
#define DRIVER_PATCH_VERSION
#define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \
@@ -450,6 +450,9 @@ struct rga_drvdata_t {
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
struct rga_debugger *debugger;
#endif
bool shutdown;
struct rw_semaphore rwsem;
};
struct rga_irqs_data_t {

View File

@@ -38,6 +38,7 @@ struct rga_request *rga_request_lookup(struct rga_pending_request_manager *reque
uint32_t id);
int rga_request_commit(struct rga_request *user_request);
void rga_request_scheduler_shutdown(struct rga_scheduler_t *scheduler);
void rga_request_scheduler_abort(struct rga_scheduler_t *scheduler);
void rga_request_session_destroy_abort(struct rga_session *session);
int rga_request_put(struct rga_request *request);

View File

@@ -927,6 +927,15 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
if (DEBUGGER_EN(NONUSE))
return 0;
down_read(&rga_drvdata->rwsem);
if (rga_drvdata->shutdown) {
rga_log("driver has been shutdown\n");
up_read(&rga_drvdata->rwsem);
return -EBUSY;
}
switch (cmd) {
case RGA_BLIT_SYNC:
case RGA_BLIT_ASYNC:
@@ -1053,6 +1062,8 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
break;
}
up_read(&rga_drvdata->rwsem);
return ret;
}
@@ -1442,17 +1453,38 @@ pm_disable:
static int rga_drv_remove(struct platform_device *pdev)
{
struct rga_scheduler_t *scheduler = NULL;
down_write(&rga_drvdata->rwsem);
rga_drvdata->shutdown = true;
scheduler = (struct rga_scheduler_t *)platform_get_drvdata(pdev);
if (scheduler)
rga_request_scheduler_shutdown(scheduler);
#ifndef RGA_DISABLE_PM
device_init_wakeup(&pdev->dev, false);
pm_runtime_disable(&pdev->dev);
#endif /* #ifndef RGA_DISABLE_PM */
up_write(&rga_drvdata->rwsem);
return 0;
}
static void rga_drv_shutdown(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
rga_drv_remove(pdev);
dev_info(dev, "shutdown success\n");
}
static struct platform_driver rga3_driver = {
.probe = rga_drv_probe,
.remove = rga_drv_remove,
.shutdown = rga_drv_shutdown,
.driver = {
.name = "rga3",
.of_match_table = of_match_ptr(rga3_dt_ids),
@@ -1462,6 +1494,7 @@ static struct platform_driver rga3_driver = {
static struct platform_driver rga2_driver = {
.probe = rga_drv_probe,
.remove = rga_drv_remove,
.shutdown = rga_drv_shutdown,
.driver = {
.name = "rga2",
.of_match_table = of_match_ptr(rga2_dt_ids),
@@ -1479,6 +1512,8 @@ static int __init rga_init(void)
}
mutex_init(&rga_drvdata->lock);
init_rwsem(&rga_drvdata->rwsem);
rga_drvdata->shutdown = false;
ret = platform_driver_register(&rga3_driver);
if (ret != 0) {

View File

@@ -633,6 +633,56 @@ struct rga_request *rga_request_lookup(struct rga_pending_request_manager *manag
return request;
}
void rga_request_scheduler_shutdown(struct rga_scheduler_t *scheduler)
{
struct rga_job *job, *job_q;
unsigned long flags;
rga_power_enable(scheduler);
spin_lock_irqsave(&scheduler->irq_lock, flags);
job = scheduler->running_job;
if (job) {
if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state) ||
test_bit(RGA_JOB_STATE_FINISH, &job->state)) {
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
goto finish;
}
scheduler->running_job = NULL;
scheduler->status = RGA_SCHEDULER_ABORT;
scheduler->ops->soft_reset(scheduler);
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
rga_mm_unmap_job_info(job);
job->ret = -EBUSY;
rga_request_release_signal(scheduler, job);
/*
* Since the running job was abort, turn off the power here that
* should have been turned off after job done (corresponds to
* power_enable in rga_job_run()).
*/
rga_power_disable(scheduler);
} else {
/* Clean up the jobs in the todo list that need to be free. */
list_for_each_entry_safe(job, job_q, &scheduler->todo_list, head) {
rga_mm_unmap_job_info(job);
job->ret = -EBUSY;
rga_request_release_signal(scheduler, job);
}
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
}
finish:
rga_power_disable(scheduler);
}
void rga_request_scheduler_abort(struct rga_scheduler_t *scheduler)
{
struct rga_job *job;