Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 1 | /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. |
| 2 | * |
| 3 | * This program is free software; you can redistribute it and/or modify |
| 4 | * it under the terms of the GNU General Public License version 2 and |
| 5 | * only version 2 as published by the Free Software Foundation. |
| 6 | * |
| 7 | * This program is distributed in the hope that it will be useful, |
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | * GNU General Public License for more details. |
| 11 | */ |
| 12 | |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 13 | #ifndef _CAM_REQ_MGR_WORKQ_H_ |
| 14 | #define _CAM_REQ_MGR_WORKQ_H_ |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 15 | |
| 16 | #include<linux/kernel.h> |
| 17 | #include<linux/module.h> |
| 18 | #include<linux/init.h> |
| 19 | #include<linux/sched.h> |
| 20 | #include <linux/workqueue.h> |
| 21 | #include <linux/slab.h> |
| 22 | #include <linux/timer.h> |
| 23 | |
| 24 | #include "cam_req_mgr_core.h" |
| 25 | |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 26 | /* Task priorities, lower the number higher the priority*/ |
| 27 | enum crm_task_priority { |
Sagar Gore | 9f40471 | 2017-05-22 16:57:25 -0700 | [diff] [blame] | 28 | CRM_TASK_PRIORITY_0, |
| 29 | CRM_TASK_PRIORITY_1, |
| 30 | CRM_TASK_PRIORITY_MAX, |
| 31 | }; |
| 32 | |
| 33 | /* workqueue will be used from irq context or not */ |
| 34 | enum crm_workq_context { |
| 35 | CRM_WORKQ_USAGE_NON_IRQ, |
| 36 | CRM_WORKQ_USAGE_IRQ, |
| 37 | CRM_WORKQ_USAGE_INVALID, |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 38 | }; |
| 39 | |
| 40 | /** struct crm_workq_task |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 41 | * @priority : caller can assign priority to task based on type. |
| 42 | * @payload : depending of user of task this payload type will change |
| 43 | * @process_cb : registered callback called by workq when task enqueued is |
| 44 | * ready for processing in workq thread context |
| 45 | * @parent : workq's parent is link which is enqqueing taks to this workq |
| 46 | * @entry : list head of this list entry is worker's empty_head |
| 47 | * @cancel : if caller has got free task from pool but wants to abort |
| 48 | * or put back without using it |
| 49 | * @priv : when task is enqueuer caller can attach priv along which |
| 50 | * it will get in process callback |
| 51 | * @ret : return value in future to use for blocking calls |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 52 | */ |
| 53 | struct crm_workq_task { |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 54 | int32_t priority; |
| 55 | void *payload; |
| 56 | int32_t (*process_cb)(void *, void *); |
| 57 | void *parent; |
| 58 | struct list_head entry; |
| 59 | uint8_t cancel; |
| 60 | void *priv; |
| 61 | int32_t ret; |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 62 | }; |
| 63 | |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 64 | /** struct cam_req_mgr_core_workq |
| 65 | * @work : work token used by workqueue |
| 66 | * @job : workqueue internal job struct |
| 67 | * task - |
Sagar Gore | 9f40471 | 2017-05-22 16:57:25 -0700 | [diff] [blame] | 68 | * @lock_bh : lock for task structs |
| 69 | * @in_irq : set true if workque can be used in irq context |
| 70 | * @free_cnt : num of free/available tasks |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 71 | * @empty_head : list head of available taska which can be used |
| 72 | * or acquired in order to enqueue a task to workq |
| 73 | * @pool : pool of tasks used for handling events in workq context |
| 74 | * @num_task : size of tasks pool |
| 75 | * - |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 76 | */ |
| 77 | struct cam_req_mgr_core_workq { |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 78 | struct work_struct work; |
| 79 | struct workqueue_struct *job; |
| 80 | spinlock_t lock_bh; |
Sagar Gore | 9f40471 | 2017-05-22 16:57:25 -0700 | [diff] [blame] | 81 | uint32_t in_irq; |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 82 | |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 83 | /* tasks */ |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 84 | struct { |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 85 | struct mutex lock; |
| 86 | atomic_t pending_cnt; |
| 87 | atomic_t free_cnt; |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 88 | |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 89 | struct list_head process_head[CRM_TASK_PRIORITY_MAX]; |
| 90 | struct list_head empty_head; |
| 91 | struct crm_workq_task *pool; |
| 92 | uint32_t num_task; |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 93 | } task; |
| 94 | }; |
| 95 | |
| 96 | /** |
| 97 | * cam_req_mgr_workq_create() |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 98 | * @brief : create a workqueue |
| 99 | * @name : Name of the workque to be allocated, it is combination |
| 100 | * of session handle and link handle |
| 101 | * @num_task : Num_tasks to be allocated for workq |
| 102 | * @workq : Double pointer worker |
Sagar Gore | 9f40471 | 2017-05-22 16:57:25 -0700 | [diff] [blame] | 103 | * @in_irq : Set to one if workq might be used in irq context |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 104 | * This function will allocate and create workqueue and pass |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 105 | * the workq pointer to caller. |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 106 | */ |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 107 | int cam_req_mgr_workq_create(char *name, int32_t num_tasks, |
Sagar Gore | 9f40471 | 2017-05-22 16:57:25 -0700 | [diff] [blame] | 108 | struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq); |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 109 | |
| 110 | /** |
| 111 | * cam_req_mgr_workq_destroy() |
| 112 | * @brief: destroy workqueue |
| 113 | * @workq: pointer to worker data struct |
| 114 | * this function will destroy workqueue and clean up resources |
| 115 | * associated with worker such as tasks. |
| 116 | */ |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 117 | void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **workq); |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 118 | |
| 119 | /** |
| 120 | * cam_req_mgr_workq_enqueue_task() |
| 121 | * @brief: Enqueue task in worker queue |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 122 | * @task : task to be processed by worker |
| 123 | * @priv : clients private data |
| 124 | * @prio : task priority |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 125 | * process callback func |
| 126 | */ |
Sagar Gore | d79f95e | 2017-03-14 18:32:17 -0700 | [diff] [blame] | 127 | int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, |
| 128 | void *priv, int32_t prio); |
Sagar Gore | 8d91a62 | 2017-02-23 14:57:18 -0800 | [diff] [blame] | 129 | |
| 130 | /** |
| 131 | * cam_req_mgr_workq_get_task() |
| 132 | * @brief: Returns empty task pointer for use |
| 133 | * @workq: workque used for processing |
| 134 | */ |
| 135 | struct crm_workq_task *cam_req_mgr_workq_get_task( |
| 136 | struct cam_req_mgr_core_workq *workq); |
| 137 | |
| 138 | #endif |