blob: 60254c2db84c5b9a982d0d641847a820b88f0ed4 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_REQ_MGR_WORKQ_H_
#define _CAM_REQ_MGR_WORKQ_H_
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/sched.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <uapi/linux/sched/types.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include "cam_req_mgr_core.h"
/* Flag to create a high priority workq */
#define CAM_WORKQ_FLAG_HIGH_PRIORITY (1 << 0)
/*
* This flag ensures only one task from a given
* workq will execute at any given point on any
* given CPU.
*/
#define CAM_WORKQ_FLAG_SERIAL (1 << 1)
/* Task priorities, lower the number higher the priority*/
enum crm_task_priority {
CRM_TASK_PRIORITY_0,
CRM_TASK_PRIORITY_1,
CRM_TASK_PRIORITY_MAX,
};
/* workqueue will be used from irq context or not */
enum crm_workq_context {
CRM_WORKQ_USAGE_NON_IRQ,
CRM_WORKQ_USAGE_IRQ,
CRM_WORKQ_USAGE_INVALID,
};
/** struct crm_workq_task
* @priority : caller can assign priority to task based on type.
* @payload : depending of user of task this payload type will change
* @process_cb : registered callback called by workq when task enqueued is
* ready for processing in workq thread context
* @parent : workq's parent is link which is enqqueing taks to this workq
* @entry : list head of this list entry is worker's empty_head
* @cancel : if caller has got free task from pool but wants to abort
* or put back without using it
* @priv : when task is enqueuer caller can attach priv along which
* it will get in process callback
* @ret : return value in future to use for blocking calls
*/
struct crm_workq_task {
int32_t priority;
void *payload;
int32_t (*process_cb)(void *priv, void *data);
void *parent;
struct list_head entry;
uint8_t cancel;
void *priv;
int32_t ret;
};
/** struct cam_req_mgr_core_workq
* @work : work token used by kthread
* @job_worker : kthread internal struct
* @job_worker_thread : kthread task_struct
* task -
* @lock_bh : lock for task structs
* @in_irq : set true if workque can be used in irq context
* @free_cnt : num of free/available tasks
* @empty_head : list head of available taska which can be used
* or acquired in order to enqueue a task to workq
* @pool : pool of tasks used for handling events in workq context
* @num_task : size of tasks pool
* -
*/
struct cam_req_mgr_core_workq {
struct kthread_work work;
struct kthread_worker job_worker;
struct task_struct *job_worker_thread;
spinlock_t lock_bh;
uint32_t in_irq;
/* tasks */
struct {
struct mutex lock;
atomic_t pending_cnt;
atomic_t free_cnt;
struct list_head process_head[CRM_TASK_PRIORITY_MAX];
struct list_head empty_head;
struct crm_workq_task *pool;
uint32_t num_task;
} task;
};
/**
* cam_req_mgr_workq_create()
* @brief : create a workqueue
* @name : Name of the workque to be allocated, it is combination
* of session handle and link handle
* @num_task : Num_tasks to be allocated for workq
* @workq : Double pointer worker
* @in_irq : Set to one if workq might be used in irq context
* @flags : Bitwise OR of Flags for workq behavior.
* e.g. CAM_REQ_MGR_WORKQ_HIGH_PRIORITY | CAM_REQ_MGR_WORKQ_SERIAL
* This function will allocate and create workqueue and pass
* the workq pointer to caller.
*/
int cam_req_mgr_workq_create(char *name, int32_t num_tasks,
struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq,
int flags);
/**
* cam_req_mgr_workq_destroy()
* @brief: destroy workqueue
* @workq: pointer to worker data struct
* this function will destroy workqueue and clean up resources
* associated with worker such as tasks.
*/
void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **workq);
/**
* cam_req_mgr_workq_enqueue_task()
* @brief: Enqueue task in worker queue
* @task : task to be processed by worker
* @priv : clients private data
* @prio : task priority
* process callback func
*/
int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
void *priv, int32_t prio);
/**
* cam_req_mgr_workq_get_task()
* @brief: Returns empty task pointer for use
* @workq: workque used for processing
*/
struct crm_workq_task *cam_req_mgr_workq_get_task(
struct cam_req_mgr_core_workq *workq);
#endif