mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 01:31:30 +03:00
- This change will remove linux nuances from dce-client-ipc.c
file and make it a core DCE-KMD file agnostic to OS.
- To do that, dce-client-ipc module will repalce linux specific
nuances for work queue related functionality with
dce-os-work module.
- Further to support existing dce_client_ipc asyn callback function
we need to make worker queue more generic by allowing clients
to pass any data of their choice as data param to the
callback function.
- Also take this opportunity to make following functions static:
- dce_resume_work_fn()
- dce_bootstrap_work_fn()
JIRA TDS-16581
Change-Id: I741b8675dd67ef932ee462e16cad016cbe8b7e2c
Signed-off-by: anupamg <anupamg@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3257808
Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
Reviewed-by: Arun Swain <arswain@nvidia.com>
Reviewed-by: svcacv <svcacv@nvidia.com>
148 lines
2.9 KiB
C
148 lines
2.9 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
*/
|
|
|
|
#include <linux/workqueue.h>
|
|
#include <dce-os-work.h>
|
|
#include <dce-os-types.h>
|
|
#include <dce-os-utils.h>
|
|
#include <dce-os-log.h>
|
|
|
|
struct dce_os_wq_struct {
|
|
struct workqueue_struct *wq;
|
|
};
|
|
|
|
struct dce_os_work_struct {
|
|
void *data;
|
|
struct work_struct work;
|
|
void (*dce_os_work_fn)(void *data);
|
|
};
|
|
|
|
/**
|
|
* dce_os_work_handle_fn : handler function for scheduled dce-work
|
|
*
|
|
* @work : Pointer to the scheduled work
|
|
*
|
|
* Return : void
|
|
*/
|
|
static void dce_os_work_handle_fn(struct work_struct *work)
|
|
{
|
|
struct dce_os_work_struct *dce_os_work = container_of(work,
|
|
struct dce_os_work_struct,
|
|
work);
|
|
|
|
if (dce_os_work->dce_os_work_fn != NULL)
|
|
dce_os_work->dce_os_work_fn(dce_os_work->data);
|
|
}
|
|
|
|
int dce_os_wq_work_init(struct tegra_dce *d,
|
|
dce_os_work_handle_t *p_work_handle,
|
|
void (*work_fn)(void *data), void *data)
|
|
{
|
|
struct dce_os_work_struct *p_work = NULL;
|
|
int ret = 0;
|
|
|
|
p_work = dce_os_kzalloc(d, sizeof(*p_work), false);
|
|
if (p_work == NULL) {
|
|
ret = -ENOMEM;
|
|
dce_os_err(d, "Work alloc failed");
|
|
goto fail;
|
|
}
|
|
|
|
p_work->data = data;
|
|
p_work->dce_os_work_fn = work_fn;
|
|
|
|
INIT_WORK(&p_work->work, dce_os_work_handle_fn);
|
|
|
|
*p_work_handle = p_work;
|
|
|
|
fail:
|
|
return ret;
|
|
}
|
|
|
|
void dce_os_wq_work_deinit(struct tegra_dce *d,
|
|
dce_os_work_handle_t work_handle)
|
|
{
|
|
dce_os_kfree(d, work_handle);
|
|
}
|
|
|
|
int dce_os_wq_work_schedule(struct tegra_dce *d,
|
|
dce_os_wq_handle_t wq_handle,
|
|
dce_os_work_handle_t work_handle)
|
|
{
|
|
int ret = 0;
|
|
struct workqueue_struct *wq = NULL;
|
|
|
|
if (work_handle == NULL) {
|
|
dce_os_err(d, "Invalid input work handle.");
|
|
ret = -1;
|
|
goto fail;
|
|
}
|
|
|
|
// If the OS Work queue is NULL, then use default sys hipri wq.
|
|
if (wq_handle == NULL) {
|
|
wq = system_highpri_wq;
|
|
} else {
|
|
/**
|
|
* If the OS Work queue is not NULL, then client must've
|
|
* initialized the work queue.
|
|
*/
|
|
wq = wq_handle->wq;
|
|
if (wq == NULL) {
|
|
dce_os_err(d, "Invalid WQ");
|
|
ret = -1;
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
queue_work(wq, &work_handle->work);
|
|
|
|
fail:
|
|
return ret;
|
|
}
|
|
|
|
int dce_os_wq_create(struct tegra_dce *d,
|
|
dce_os_wq_handle_t *p_wq_handle, const char *wq_name)
|
|
{
|
|
int ret = 0;
|
|
struct dce_os_wq_struct *p_wq = NULL;
|
|
|
|
if ((p_wq_handle == NULL) || (wq_name == NULL)) {
|
|
ret = -EINVAL;
|
|
dce_os_err(d, "Invalid input args");
|
|
goto fail;
|
|
}
|
|
|
|
p_wq = dce_os_kzalloc(d, sizeof(*p_wq), false);
|
|
if (p_wq == NULL) {
|
|
ret = -ENOMEM;
|
|
dce_os_err(d, "WQ alloc failed");
|
|
goto fail;
|
|
}
|
|
|
|
p_wq->wq = create_singlethread_workqueue(wq_name);
|
|
|
|
*p_wq_handle = p_wq;
|
|
|
|
fail:
|
|
return ret;
|
|
}
|
|
|
|
void dce_os_wq_destroy(struct tegra_dce *d,
|
|
dce_os_wq_handle_t wq_handle)
|
|
{
|
|
if ((wq_handle == NULL) || (wq_handle->wq == NULL)) {
|
|
dce_os_err(d, "Invalid input args");
|
|
goto fail;
|
|
}
|
|
|
|
flush_workqueue(wq_handle->wq);
|
|
destroy_workqueue(wq_handle->wq);
|
|
|
|
dce_os_kfree(d, wq_handle);
|
|
|
|
fail:
|
|
return;
|
|
}
|