Loading drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +1 −1 Original line number Diff line number Diff line Loading @@ -3400,7 +3400,7 @@ int sde_rotator_resume(struct platform_device *dev) */ int sde_rotator_session_open(struct sde_rot_mgr *mgr, struct sde_rot_file_private **pprivate, int session_id, struct sde_rot_queue *queue) struct sde_rot_queue_v1 *queue) { int ret; struct sde_rot_file_private *private; Loading drivers/media/platform/msm/sde/rotator/sde_rotator_core.h +10 −4 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -242,6 +242,12 @@ struct sde_rot_queue { struct sde_rot_hw_resource *hw; }; struct sde_rot_queue_v1 { struct kthread_worker *rot_kw; struct task_struct *rot_thread; struct sde_rot_timeline *timeline; struct sde_rot_hw_resource *hw; }; /* * struct sde_rot_entry_container - rotation request * @list: list of active requests managed by rotator manager Loading Loading @@ -294,7 +300,7 @@ struct sde_rot_entry { struct kthread_work commit_work; struct kthread_work done_work; struct sde_rot_queue *commitq; struct sde_rot_queue *fenceq; struct sde_rot_queue_v1 *fenceq; struct sde_rot_queue *doneq; struct sde_rot_entry_container *request; Loading Loading @@ -351,7 +357,7 @@ struct sde_rot_file_private { struct list_head req_list; struct list_head perf_list; struct sde_rot_mgr *mgr; struct sde_rot_queue *fenceq; struct sde_rot_queue_v1 *fenceq; }; /* Loading Loading @@ -586,7 +592,7 @@ void sde_rotator_core_dump(struct sde_rot_mgr *mgr); */ int sde_rotator_session_open(struct sde_rot_mgr *mgr, struct sde_rot_file_private **pprivate, int session_id, struct sde_rot_queue *queue); struct sde_rot_queue_v1 *queue); /* * sde_rotator_session_close - close the given rotator per file session Loading drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +52 −21 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -925,6 +925,7 @@ struct sde_rotator_ctx *sde_rotator_ctx_open( ctx->rotate = 0; ctx->secure = 0; ctx->abort_pending = 0; ctx->kthread_id = -1; ctx->format_cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ctx->format_cap.fmt.pix.pixelformat = SDE_PIX_FMT_Y_CBCR_H2V2; ctx->format_cap.fmt.pix.width = 640; Loading Loading @@ -982,18 +983,22 @@ struct sde_rotator_ctx *sde_rotator_ctx_open( goto error_create_sysfs; } snprintf(name, sizeof(name), "rot_fenceq_%d_%d", rot_dev->dev->id, ctx->session_id); kthread_init_worker(&ctx->work_queue.rot_kw); ctx->work_queue.rot_thread = kthread_run(kthread_worker_fn, &ctx->work_queue.rot_kw, name); if (IS_ERR(ctx->work_queue.rot_thread)) { SDEDEV_ERR(ctx->rot_dev->dev, "fail allocate kthread\n"); ret = -EPERM; ctx->work_queue.rot_thread = NULL; goto error_alloc_workqueue; for (i = 0; i < MAX_ROT_OPEN_SESSION; i++) { if (rot_dev->kthread_free[i]) { rot_dev->kthread_free[i] = false; ctx->kthread_id = i; ctx->work_queue.rot_kw = &rot_dev->rot_kw[i]; ctx->work_queue.rot_thread = rot_dev->rot_thread[i]; break; } } if (ctx->kthread_id < 0) { SDEDEV_ERR(ctx->rot_dev->dev, "fail to acquire the kthread\n"); ret = -EINVAL; goto error_alloc_kthread; } SDEDEV_DBG(ctx->rot_dev->dev, "kthread name=%s\n", name); snprintf(name, sizeof(name), "%d_%d", rot_dev->dev->id, ctx->session_id); Loading Loading @@ -1052,9 +1057,9 @@ struct sde_rotator_ctx *sde_rotator_ctx_open( error_open_session: sde_rot_mgr_unlock(rot_dev->mgr); sde_rotator_destroy_timeline(ctx->work_queue.timeline); kthread_flush_worker(&ctx->work_queue.rot_kw); kthread_stop(ctx->work_queue.rot_thread); error_alloc_workqueue: rot_dev->kthread_free[ctx->kthread_id] = true; ctx->kthread_id = -1; error_alloc_kthread: sysfs_remove_group(&ctx->kobj, &sde_rotator_fs_attr_group); error_create_sysfs: kobject_put(&ctx->kobj); Loading Loading @@ -1129,8 +1134,10 @@ static int sde_rotator_ctx_release(struct sde_rotator_ctx *ctx, mutex_lock(&rot_dev->lock); SDEDEV_DBG(rot_dev->dev, "release context s:%d\n", session_id); sde_rotator_destroy_timeline(ctx->work_queue.timeline); kthread_flush_worker(&ctx->work_queue.rot_kw); kthread_stop(ctx->work_queue.rot_thread); if (ctx->kthread_id >= 0 && ctx->work_queue.rot_kw) { kthread_flush_worker(ctx->work_queue.rot_kw); rot_dev->kthread_free[ctx->kthread_id] = true; } sysfs_remove_group(&ctx->kobj, &sde_rotator_fs_attr_group); kobject_put(&ctx->kobj); if (ctx->file) { Loading Loading @@ -1817,7 +1824,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd, } else { SDEROT_ERR("invalid stats timestamp\n"); } req->retire_kw = &ctx->work_queue.rot_kw; req->retire_kw = ctx->work_queue.rot_kw; req->retire_work = &request->retire_work; trace_rot_entry_fence( Loading Loading @@ -3170,7 +3177,7 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx, goto error_init_request; } req->retire_kw = &ctx->work_queue.rot_kw; req->retire_kw = ctx->work_queue.rot_kw; req->retire_work = &request->retire_work; ret = sde_rotator_handle_request_common( Loading Loading @@ -3468,7 +3475,7 @@ static int sde_rotator_job_ready(void *priv) list_del_init(&request->list); list_add_tail(&request->list, &ctx->pending_list); spin_unlock(&ctx->list_lock); kthread_queue_work(&ctx->work_queue.rot_kw, kthread_queue_work(ctx->work_queue.rot_kw, &request->submit_work); } } else if (request && !atomic_read(&request->req->pending_count)) { Loading Loading @@ -3522,7 +3529,8 @@ static int sde_rotator_probe(struct platform_device *pdev) { struct sde_rotator_device *rot_dev; struct video_device *vdev; int ret; int ret, i; char name[32]; SDEDEV_DBG(&pdev->dev, "SDE v4l2 rotator probed\n"); Loading Loading @@ -3605,9 +3613,29 @@ static int sde_rotator_probe(struct platform_device *pdev) rot_dev->debugfs_root = sde_rotator_create_debugfs(rot_dev); for (i = 0; i < MAX_ROT_OPEN_SESSION; i++) { snprintf(name, sizeof(name), "rot_fenceq_%d_%d", rot_dev->dev->id, i); kthread_init_worker(&rot_dev->rot_kw[i]); rot_dev->rot_thread[i] = kthread_run(kthread_worker_fn, &rot_dev->rot_kw[i], name); if (IS_ERR(rot_dev->rot_thread[i])) { SDEDEV_ERR(rot_dev->dev, "fail allocate kthread i:%d\n", i); ret = -EPERM; goto error_kthread_create; } rot_dev->kthread_free[i] = true; } SDEDEV_INFO(&pdev->dev, "SDE v4l2 rotator probe success\n"); return 0; error_kthread_create: for (i--; i >= 0; i--) kthread_stop(rot_dev->rot_thread[i]); sde_rotator_destroy_debugfs(rot_dev->debugfs_root); video_unregister_device(rot_dev->vdev); error_video_register: video_device_release(vdev); error_alloc_video_device: Loading @@ -3630,6 +3658,7 @@ static int sde_rotator_probe(struct platform_device *pdev) static int sde_rotator_remove(struct platform_device *pdev) { struct sde_rotator_device *rot_dev; int i; rot_dev = platform_get_drvdata(pdev); if (rot_dev == NULL) { Loading @@ -3638,6 +3667,8 @@ static int sde_rotator_remove(struct platform_device *pdev) } sde_rotator_pm_qos_remove(rot_dev->mdata); for (i = MAX_ROT_OPEN_SESSION - 1; i >= 0; i--) kthread_stop(rot_dev->rot_thread[i]); sde_rotator_destroy_debugfs(rot_dev->debugfs_root); video_unregister_device(rot_dev->vdev); video_device_release(rot_dev->vdev); Loading drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h +14 −2 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -41,6 +41,8 @@ /* maximum number of outstanding requests per ctx session */ #define SDE_ROTATOR_REQUEST_MAX 2 #define MAX_ROT_OPEN_SESSION 16 struct sde_rotator_device; struct sde_rotator_ctx; Loading Loading @@ -137,6 +139,7 @@ struct sde_rotator_request { * @retired_list: list of retired/free request * @requests: static allocation of free requests * @rotcfg: current core rotation configuration * @kthread_id: thread_id used for fence management */ struct sde_rotator_ctx { struct kobject kobj; Loading @@ -161,7 +164,7 @@ struct sde_rotator_ctx { struct sde_rotator_vbinfo *vbinfo_cap; struct sde_rotator_vbinfo *vbinfo_out; wait_queue_head_t wait_queue; struct sde_rot_queue work_queue; struct sde_rot_queue_v1 work_queue; struct sde_rot_file_private *private; struct llcc_slice_desc *slice; u32 commit_sequence_id; Loading @@ -171,6 +174,8 @@ struct sde_rotator_ctx { struct list_head retired_list; struct sde_rotator_request requests[SDE_ROTATOR_REQUEST_MAX]; struct sde_rotation_config rotcfg; int kthread_id; }; /* Loading Loading @@ -209,6 +214,9 @@ struct sde_rotator_statistics { * @open_timeout: maximum wait time for ctx open in msec * @open_wq: wait queue for ctx open * @excl_ctx: Pointer to exclusive ctx * @rot_kw: rotator thread work * @rot_thread: rotator threads * @kthread_free: check if thread is available or not */ struct sde_rotator_device { struct mutex lock; Loading @@ -234,6 +242,10 @@ struct sde_rotator_device { u32 open_timeout; wait_queue_head_t open_wq; struct sde_rotator_ctx *excl_ctx; struct kthread_worker rot_kw[MAX_ROT_OPEN_SESSION]; struct task_struct *rot_thread[MAX_ROT_OPEN_SESSION]; bool kthread_free[MAX_ROT_OPEN_SESSION]; }; static inline Loading Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +1 −1 Original line number Diff line number Diff line Loading @@ -3400,7 +3400,7 @@ int sde_rotator_resume(struct platform_device *dev) */ int sde_rotator_session_open(struct sde_rot_mgr *mgr, struct sde_rot_file_private **pprivate, int session_id, struct sde_rot_queue *queue) struct sde_rot_queue_v1 *queue) { int ret; struct sde_rot_file_private *private; Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_core.h +10 −4 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -242,6 +242,12 @@ struct sde_rot_queue { struct sde_rot_hw_resource *hw; }; struct sde_rot_queue_v1 { struct kthread_worker *rot_kw; struct task_struct *rot_thread; struct sde_rot_timeline *timeline; struct sde_rot_hw_resource *hw; }; /* * struct sde_rot_entry_container - rotation request * @list: list of active requests managed by rotator manager Loading Loading @@ -294,7 +300,7 @@ struct sde_rot_entry { struct kthread_work commit_work; struct kthread_work done_work; struct sde_rot_queue *commitq; struct sde_rot_queue *fenceq; struct sde_rot_queue_v1 *fenceq; struct sde_rot_queue *doneq; struct sde_rot_entry_container *request; Loading Loading @@ -351,7 +357,7 @@ struct sde_rot_file_private { struct list_head req_list; struct list_head perf_list; struct sde_rot_mgr *mgr; struct sde_rot_queue *fenceq; struct sde_rot_queue_v1 *fenceq; }; /* Loading Loading @@ -586,7 +592,7 @@ void sde_rotator_core_dump(struct sde_rot_mgr *mgr); */ int sde_rotator_session_open(struct sde_rot_mgr *mgr, struct sde_rot_file_private **pprivate, int session_id, struct sde_rot_queue *queue); struct sde_rot_queue_v1 *queue); /* * sde_rotator_session_close - close the given rotator per file session Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +52 −21 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -925,6 +925,7 @@ struct sde_rotator_ctx *sde_rotator_ctx_open( ctx->rotate = 0; ctx->secure = 0; ctx->abort_pending = 0; ctx->kthread_id = -1; ctx->format_cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ctx->format_cap.fmt.pix.pixelformat = SDE_PIX_FMT_Y_CBCR_H2V2; ctx->format_cap.fmt.pix.width = 640; Loading Loading @@ -982,18 +983,22 @@ struct sde_rotator_ctx *sde_rotator_ctx_open( goto error_create_sysfs; } snprintf(name, sizeof(name), "rot_fenceq_%d_%d", rot_dev->dev->id, ctx->session_id); kthread_init_worker(&ctx->work_queue.rot_kw); ctx->work_queue.rot_thread = kthread_run(kthread_worker_fn, &ctx->work_queue.rot_kw, name); if (IS_ERR(ctx->work_queue.rot_thread)) { SDEDEV_ERR(ctx->rot_dev->dev, "fail allocate kthread\n"); ret = -EPERM; ctx->work_queue.rot_thread = NULL; goto error_alloc_workqueue; for (i = 0; i < MAX_ROT_OPEN_SESSION; i++) { if (rot_dev->kthread_free[i]) { rot_dev->kthread_free[i] = false; ctx->kthread_id = i; ctx->work_queue.rot_kw = &rot_dev->rot_kw[i]; ctx->work_queue.rot_thread = rot_dev->rot_thread[i]; break; } } if (ctx->kthread_id < 0) { SDEDEV_ERR(ctx->rot_dev->dev, "fail to acquire the kthread\n"); ret = -EINVAL; goto error_alloc_kthread; } SDEDEV_DBG(ctx->rot_dev->dev, "kthread name=%s\n", name); snprintf(name, sizeof(name), "%d_%d", rot_dev->dev->id, ctx->session_id); Loading Loading @@ -1052,9 +1057,9 @@ struct sde_rotator_ctx *sde_rotator_ctx_open( error_open_session: sde_rot_mgr_unlock(rot_dev->mgr); sde_rotator_destroy_timeline(ctx->work_queue.timeline); kthread_flush_worker(&ctx->work_queue.rot_kw); kthread_stop(ctx->work_queue.rot_thread); error_alloc_workqueue: rot_dev->kthread_free[ctx->kthread_id] = true; ctx->kthread_id = -1; error_alloc_kthread: sysfs_remove_group(&ctx->kobj, &sde_rotator_fs_attr_group); error_create_sysfs: kobject_put(&ctx->kobj); Loading Loading @@ -1129,8 +1134,10 @@ static int sde_rotator_ctx_release(struct sde_rotator_ctx *ctx, mutex_lock(&rot_dev->lock); SDEDEV_DBG(rot_dev->dev, "release context s:%d\n", session_id); sde_rotator_destroy_timeline(ctx->work_queue.timeline); kthread_flush_worker(&ctx->work_queue.rot_kw); kthread_stop(ctx->work_queue.rot_thread); if (ctx->kthread_id >= 0 && ctx->work_queue.rot_kw) { kthread_flush_worker(ctx->work_queue.rot_kw); rot_dev->kthread_free[ctx->kthread_id] = true; } sysfs_remove_group(&ctx->kobj, &sde_rotator_fs_attr_group); kobject_put(&ctx->kobj); if (ctx->file) { Loading Loading @@ -1817,7 +1824,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd, } else { SDEROT_ERR("invalid stats timestamp\n"); } req->retire_kw = &ctx->work_queue.rot_kw; req->retire_kw = ctx->work_queue.rot_kw; req->retire_work = &request->retire_work; trace_rot_entry_fence( Loading Loading @@ -3170,7 +3177,7 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx, goto error_init_request; } req->retire_kw = &ctx->work_queue.rot_kw; req->retire_kw = ctx->work_queue.rot_kw; req->retire_work = &request->retire_work; ret = sde_rotator_handle_request_common( Loading Loading @@ -3468,7 +3475,7 @@ static int sde_rotator_job_ready(void *priv) list_del_init(&request->list); list_add_tail(&request->list, &ctx->pending_list); spin_unlock(&ctx->list_lock); kthread_queue_work(&ctx->work_queue.rot_kw, kthread_queue_work(ctx->work_queue.rot_kw, &request->submit_work); } } else if (request && !atomic_read(&request->req->pending_count)) { Loading Loading @@ -3522,7 +3529,8 @@ static int sde_rotator_probe(struct platform_device *pdev) { struct sde_rotator_device *rot_dev; struct video_device *vdev; int ret; int ret, i; char name[32]; SDEDEV_DBG(&pdev->dev, "SDE v4l2 rotator probed\n"); Loading Loading @@ -3605,9 +3613,29 @@ static int sde_rotator_probe(struct platform_device *pdev) rot_dev->debugfs_root = sde_rotator_create_debugfs(rot_dev); for (i = 0; i < MAX_ROT_OPEN_SESSION; i++) { snprintf(name, sizeof(name), "rot_fenceq_%d_%d", rot_dev->dev->id, i); kthread_init_worker(&rot_dev->rot_kw[i]); rot_dev->rot_thread[i] = kthread_run(kthread_worker_fn, &rot_dev->rot_kw[i], name); if (IS_ERR(rot_dev->rot_thread[i])) { SDEDEV_ERR(rot_dev->dev, "fail allocate kthread i:%d\n", i); ret = -EPERM; goto error_kthread_create; } rot_dev->kthread_free[i] = true; } SDEDEV_INFO(&pdev->dev, "SDE v4l2 rotator probe success\n"); return 0; error_kthread_create: for (i--; i >= 0; i--) kthread_stop(rot_dev->rot_thread[i]); sde_rotator_destroy_debugfs(rot_dev->debugfs_root); video_unregister_device(rot_dev->vdev); error_video_register: video_device_release(vdev); error_alloc_video_device: Loading @@ -3630,6 +3658,7 @@ static int sde_rotator_probe(struct platform_device *pdev) static int sde_rotator_remove(struct platform_device *pdev) { struct sde_rotator_device *rot_dev; int i; rot_dev = platform_get_drvdata(pdev); if (rot_dev == NULL) { Loading @@ -3638,6 +3667,8 @@ static int sde_rotator_remove(struct platform_device *pdev) } sde_rotator_pm_qos_remove(rot_dev->mdata); for (i = MAX_ROT_OPEN_SESSION - 1; i >= 0; i--) kthread_stop(rot_dev->rot_thread[i]); sde_rotator_destroy_debugfs(rot_dev->debugfs_root); video_unregister_device(rot_dev->vdev); video_device_release(rot_dev->vdev); Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h +14 −2 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -41,6 +41,8 @@ /* maximum number of outstanding requests per ctx session */ #define SDE_ROTATOR_REQUEST_MAX 2 #define MAX_ROT_OPEN_SESSION 16 struct sde_rotator_device; struct sde_rotator_ctx; Loading Loading @@ -137,6 +139,7 @@ struct sde_rotator_request { * @retired_list: list of retired/free request * @requests: static allocation of free requests * @rotcfg: current core rotation configuration * @kthread_id: thread_id used for fence management */ struct sde_rotator_ctx { struct kobject kobj; Loading @@ -161,7 +164,7 @@ struct sde_rotator_ctx { struct sde_rotator_vbinfo *vbinfo_cap; struct sde_rotator_vbinfo *vbinfo_out; wait_queue_head_t wait_queue; struct sde_rot_queue work_queue; struct sde_rot_queue_v1 work_queue; struct sde_rot_file_private *private; struct llcc_slice_desc *slice; u32 commit_sequence_id; Loading @@ -171,6 +174,8 @@ struct sde_rotator_ctx { struct list_head retired_list; struct sde_rotator_request requests[SDE_ROTATOR_REQUEST_MAX]; struct sde_rotation_config rotcfg; int kthread_id; }; /* Loading Loading @@ -209,6 +214,9 @@ struct sde_rotator_statistics { * @open_timeout: maximum wait time for ctx open in msec * @open_wq: wait queue for ctx open * @excl_ctx: Pointer to exclusive ctx * @rot_kw: rotator thread work * @rot_thread: rotator threads * @kthread_free: check if thread is available or not */ struct sde_rotator_device { struct mutex lock; Loading @@ -234,6 +242,10 @@ struct sde_rotator_device { u32 open_timeout; wait_queue_head_t open_wq; struct sde_rotator_ctx *excl_ctx; struct kthread_worker rot_kw[MAX_ROT_OPEN_SESSION]; struct task_struct *rot_thread[MAX_ROT_OPEN_SESSION]; bool kthread_free[MAX_ROT_OPEN_SESSION]; }; static inline Loading