/* Copyright (c) 2016-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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include "cam_req_mgr_interface.h"
#include "cam_req_mgr_util.h"
#include "cam_req_mgr_core.h"
#include "cam_req_mgr_workq.h"
#include "cam_req_mgr_debug.h"
#include "cam_trace.h"
#include "cam_debug_util.h"
#include "cam_req_mgr_dev.h"

static struct cam_req_mgr_core_device *g_crm_core_dev;

void cam_req_mgr_handle_core_shutdown(void)
{
	struct cam_req_mgr_core_session *session;
	struct cam_req_mgr_core_session *tsession;
	struct cam_req_mgr_session_info ses_info;

	if (!list_empty(&g_crm_core_dev->session_head)) {
		list_for_each_entry_safe(session, tsession,
			&g_crm_core_dev->session_head, entry) {
			ses_info.session_hdl =
				session->session_hdl;
			cam_req_mgr_destroy_session(&ses_info);
		}
	}
}

static int __cam_req_mgr_setup_payload(struct cam_req_mgr_core_workq *workq)
{
	int32_t                  i = 0;
	int                      rc = 0;
	struct crm_task_payload *task_data = NULL;

	task_data = kcalloc(
		workq->task.num_task, sizeof(*task_data),
		GFP_KERNEL);
	if (!task_data) {
		rc = -ENOMEM;
	} else {
		for (i = 0; i < workq->task.num_task; i++)
			workq->task.pool[i].payload = &task_data[i];
	}

	return rc;
}

/**
 * __cam_req_mgr_reset_req_tbl()
 *
 * @brief : Initialize req table data
 * @in_q  : request queue pointer
 *
 * @return: 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_print_req_tbl(struct cam_req_mgr_req_data *req)
{
	int                           rc = 0;
	int32_t                       i = 0;
	struct cam_req_mgr_req_queue *in_q = req->in_q;
	struct cam_req_mgr_req_tbl   *req_tbl = req->l_tbl;

	if (!in_q || !req_tbl) {
		CAM_WARN(CAM_CRM, "NULL pointer %pK %pK", in_q, req_tbl);
		return -EINVAL;
	}
	CAM_DBG(CAM_CRM, "in_q %pK %pK %d", in_q, req_tbl, req_tbl->num_slots);
	mutex_lock(&req->lock);
	for (i = 0; i < in_q->num_slots; i++) {
		CAM_DBG(CAM_CRM, "IN_Q %d: idx %d, red_id %lld", i,
			in_q->slot[i].idx, CRM_GET_REQ_ID(in_q, i));
	}

	while (req_tbl != NULL) {
		for (i = 0; i < req_tbl->num_slots; i++) {
			CAM_DBG(CAM_CRM, "idx= %d, map= %x, state= %d",
				req_tbl->slot[i].idx,
				req_tbl->slot[i].req_ready_map,
				req_tbl->slot[i].state);
		}
		CAM_DBG(CAM_CRM,
			"TBL:id= %d, pd=%d cnt=%d mask=%x skip=%d num_slt= %d",
			req_tbl->id, req_tbl->pd, req_tbl->dev_count,
			req_tbl->dev_mask, req_tbl->skip_traverse,
			req_tbl->num_slots);
		req_tbl = req_tbl->next;
	}
	mutex_unlock(&req->lock);

	return rc;
}

/**
 * __cam_req_mgr_find_pd_tbl()
 *
 * @brief    : Find pipeline delay based table pointer which matches delay
 * @tbl      : Pointer to list of request table
 * @delay    : Pipeline delay value to be searched for comparison
 *
 * @return   : pointer to request table for matching pipeline delay table.
 *
 */
static struct cam_req_mgr_req_tbl *__cam_req_mgr_find_pd_tbl(
	struct cam_req_mgr_req_tbl *tbl, int32_t delay)
{
	if (!tbl)
		return NULL;

	do {
		if (delay != tbl->pd)
			tbl = tbl->next;
		else
			return tbl;
	} while (tbl != NULL);

	return NULL;
}

/**
 * __cam_req_mgr_inc_idx()
 *
 * @brief    : Increment val passed by step size and rollover after max_val
 * @val      : value to be incremented
 * @step     : amount/step by which val is incremented
 * @max_val  : max val after which idx will roll over
 *
 */
static void __cam_req_mgr_inc_idx(int32_t *val, int32_t step, int32_t max_val)
{
	*val = (*val + step) % max_val;
}

/**
 * __cam_req_mgr_dec_idx()
 *
 * @brief    : Decrement val passed by step size and rollover after max_val
 * @val      : value to be decremented
 * @step     : amount/step by which val is decremented
 * @max_val  : after zero value will roll over to max val
 *
 */
static void __cam_req_mgr_dec_idx(int32_t *val, int32_t step, int32_t max_val)
{
	*val = *val - step;
	if (*val < 0)
		*val = max_val + (*val);
}

/**
 * __cam_req_mgr_traverse()
 *
 * @brief    : Traverse through pd tables, it will internally cover all linked
 *             pd tables. Each pd table visited will check if idx passed to its
 *             in ready state. If ready means all devices linked to the pd table
 *             have this request id packet ready. Then it calls subsequent pd
 *             tbl with new idx. New idx value takes into account the delta
 *             between current pd table and next one.
 * @traverse_data: contains all the info to traverse through pd tables
 *
 * @return: 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_traverse(struct cam_req_mgr_traverse *traverse_data)
{
	int                          rc = 0;
	int32_t                      next_idx = traverse_data->idx;
	int32_t                      curr_idx = traverse_data->idx;
	struct cam_req_mgr_req_tbl  *tbl;
	struct cam_req_mgr_apply    *apply_data;

	if (!traverse_data->tbl || !traverse_data->apply_data) {
		CAM_ERR(CAM_CRM, "NULL pointer %pK %pK",
			traverse_data->tbl, traverse_data->apply_data);
		traverse_data->result = 0;
		return -EINVAL;
	}

	tbl = traverse_data->tbl;
	apply_data = traverse_data->apply_data;
	CAM_DBG(CAM_CRM,
		"Enter pd %d idx %d state %d skip %d status %d skip_idx %d",
		tbl->pd, curr_idx, tbl->slot[curr_idx].state,
		tbl->skip_traverse, traverse_data->in_q->slot[curr_idx].status,
		traverse_data->in_q->slot[curr_idx].skip_idx);

	if ((tbl->inject_delay > 0) &&
		(traverse_data->self_link == true)) {
		CAM_DBG(CAM_CRM, "Injecting Delay of one frame");
		apply_data[tbl->pd].req_id = -1;
		tbl->inject_delay--;
		/* This pd table is not ready to proceed with asked idx */
		SET_FAILURE_BIT(traverse_data->result, tbl->pd);
		return -EAGAIN;
	}

	/* Check if req is ready or in skip mode or pd tbl is in skip mode */
	if (tbl->slot[curr_idx].state == CRM_REQ_STATE_READY ||
		traverse_data->in_q->slot[curr_idx].skip_idx == 1 ||
		tbl->skip_traverse > 0) {
		if (tbl->next) {
			__cam_req_mgr_dec_idx(&next_idx, tbl->pd_delta,
				tbl->num_slots);
			traverse_data->idx = next_idx;
			traverse_data->tbl = tbl->next;
			rc = __cam_req_mgr_traverse(traverse_data);
		}
		if (rc >= 0) {
			SET_SUCCESS_BIT(traverse_data->result, tbl->pd);

			if (traverse_data->validate_only == false) {
				apply_data[tbl->pd].pd = tbl->pd;
				apply_data[tbl->pd].req_id =
					CRM_GET_REQ_ID(
					traverse_data->in_q, curr_idx);
				apply_data[tbl->pd].idx = curr_idx;

				CAM_DBG(CAM_CRM, "req_id: %lld with pd of %d",
				apply_data[tbl->pd].req_id,
				apply_data[tbl->pd].pd);
				/*
				 * If traverse is successful decrement
				 * traverse skip
				 */
				if (tbl->skip_traverse > 0) {
					apply_data[tbl->pd].req_id = -1;
					tbl->skip_traverse--;
				}
			}
		} else {
			/* linked pd table is not ready for this traverse yet */
			return rc;
		}
	} else {
		/* This pd table is not ready to proceed with asked idx */
		CAM_INFO(CAM_CRM,
			"Skip Frame: req: %lld not ready pd: %d open_req count: %d",
			CRM_GET_REQ_ID(traverse_data->in_q, curr_idx),
			tbl->pd,
			traverse_data->open_req_cnt);
		SET_FAILURE_BIT(traverse_data->result, tbl->pd);
		return -EAGAIN;
	}
	return 0;
}

/**
 * __cam_req_mgr_in_q_skip_idx()
 *
 * @brief    : Decrement val passed by step size and rollover after max_val
 * @in_q     : input queue pointer
 * @idx      : Sets skip_idx bit of the particular slot to true so when traverse
 *             happens for this idx, no req will be submitted for devices
 *             handling this idx.
 *
 */
static void __cam_req_mgr_in_q_skip_idx(struct cam_req_mgr_req_queue *in_q,
	int32_t idx)
{
	in_q->slot[idx].req_id = -1;
	in_q->slot[idx].skip_idx = 1;
	in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
	CAM_DBG(CAM_CRM, "SET IDX SKIP on slot= %d", idx);
}

/**
 * __cam_req_mgr_tbl_set_id()
 *
 * @brief    : Set unique id to table
 * @tbl      : pipeline based table which requires new id
 * @req      : pointer to request data wihch contains num_tables counter
 *
 */
static void __cam_req_mgr_tbl_set_id(struct cam_req_mgr_req_tbl *tbl,
	struct cam_req_mgr_req_data *req)
{
	if (!tbl)
		return;
	do {
		tbl->id = req->num_tbl++;
		CAM_DBG(CAM_CRM, "%d: pd %d skip_traverse %d delta %d",
			tbl->id, tbl->pd, tbl->skip_traverse,
			tbl->pd_delta);
		tbl = tbl->next;
	} while (tbl != NULL);
}

/**
 * __cam_req_mgr_tbl_set_all_skip_cnt()
 *
 * @brief    : Each pd table sets skip value based on delta between itself and
 *             max pd value. During initial streamon or bubble case this is
 *             used. That way each pd table skips required num of traverse and
 *             align themselve with req mgr connected devs.
 * @l_tbl    : iterates through list of pd tables and sets skip traverse
 *
 */
static void __cam_req_mgr_tbl_set_all_skip_cnt(
	struct cam_req_mgr_req_tbl **l_tbl)
{
	struct cam_req_mgr_req_tbl *tbl = *l_tbl;
	int32_t                     max_pd;

	if (!tbl)
		return;

	max_pd = tbl->pd;
	do {
		tbl->skip_traverse = max_pd - tbl->pd;
		CAM_DBG(CAM_CRM, "%d: pd %d skip_traverse %d delta %d",
			tbl->id, tbl->pd, tbl->skip_traverse,
			tbl->pd_delta);
		tbl = tbl->next;
	} while (tbl != NULL);
}

/**
 * __cam_req_mgr_reset_req_slot()
 *
 * @brief    : reset specified idx/slot in input queue as well as all pd tables
 * @link     : link pointer
 * @idx      : slot index which will be reset
 *
 */
static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link,
	int32_t idx)
{
	struct cam_req_mgr_slot      *slot;
	struct cam_req_mgr_req_tbl   *tbl = link->req.l_tbl;
	struct cam_req_mgr_req_queue *in_q = link->req.in_q;

	slot = &in_q->slot[idx];
	CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status);

	/* Check if CSL has already pushed new request*/
	if (slot->status == CRM_SLOT_STATUS_REQ_ADDED)
		return;

	/* Reset input queue slot */
	slot->req_id = -1;
	slot->skip_idx = 0;
	slot->recover = 0;
	slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
	slot->status = CRM_SLOT_STATUS_NO_REQ;

	/* Reset all pd table slot */
	while (tbl != NULL) {
		CAM_DBG(CAM_CRM, "pd: %d: idx %d state %d",
			tbl->pd, idx, tbl->slot[idx].state);
		tbl->slot[idx].req_ready_map = 0;
		tbl->slot[idx].state = CRM_REQ_STATE_EMPTY;
		tbl = tbl->next;
	}
}

/**
 * __cam_req_mgr_check_next_req_slot()
 *
 * @brief    : While streaming if input queue does not contain any pending
 *             request, req mgr still needs to submit pending request ids to
 *             devices with lower pipeline delay value.
 * @in_q     : Pointer to input queue where req mgr wil peep into
 *
 */
static void __cam_req_mgr_check_next_req_slot(
	struct cam_req_mgr_req_queue *in_q)
{
	int32_t                  idx = in_q->rd_idx;
	struct cam_req_mgr_slot *slot;

	__cam_req_mgr_inc_idx(&idx, 1, in_q->num_slots);
	slot = &in_q->slot[idx];

	CAM_DBG(CAM_CRM, "idx: %d: slot->status %d", idx, slot->status);

	/* Check if there is new req from CSL, if not complete req */
	if (slot->status == CRM_SLOT_STATUS_NO_REQ) {
		__cam_req_mgr_in_q_skip_idx(in_q, idx);
		if (in_q->wr_idx != idx)
			CAM_WARN(CAM_CRM,
				"CHECK here wr %d, rd %d", in_q->wr_idx, idx);
		__cam_req_mgr_inc_idx(&in_q->wr_idx, 1, in_q->num_slots);
	}
}

/**
 * __cam_req_mgr_send_req()
 *
 * @brief    : send request id to be applied to each device connected on link
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 * @in_q     : pointer to input request queue
 *
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_req_queue *in_q, uint32_t trigger)
{
	int                                  rc = 0, pd, i, idx;
	struct cam_req_mgr_connected_device *dev = NULL;
	struct cam_req_mgr_apply_request     apply_req;
	struct cam_req_mgr_link_evt_data     evt_data;

	apply_req.link_hdl = link->link_hdl;
	apply_req.report_if_bubble = 0;

	for (i = 0; i < link->num_devs; i++) {
		dev = &link->l_dev[i];
		if (dev) {
			pd = dev->dev_info.p_delay;
			if (pd >= CAM_PIPELINE_DELAY_MAX) {
				CAM_WARN(CAM_CRM, "pd %d greater than max",
					pd);
				continue;
			}
			if (link->req.apply_data[pd].skip_idx ||
				link->req.apply_data[pd].req_id < 0) {
				CAM_DBG(CAM_CRM, "skip %d req_id %lld",
					link->req.apply_data[pd].skip_idx,
					link->req.apply_data[pd].req_id);
				continue;
			}
			if (!(dev->dev_info.trigger & trigger))
				continue;

			apply_req.dev_hdl = dev->dev_hdl;
			apply_req.request_id =
				link->req.apply_data[pd].req_id;
			idx = link->req.apply_data[pd].idx;
			apply_req.report_if_bubble =
				in_q->slot[idx].recover;

			trace_cam_req_mgr_apply_request(link, &apply_req, dev);

			apply_req.trigger_point = trigger;
			CAM_DBG(CAM_CRM, "SEND: link_hdl: %x pd %d req_id %lld",
				link->link_hdl, pd, apply_req.request_id);
			if (dev->ops && dev->ops->apply_req) {
				rc = dev->ops->apply_req(&apply_req);
				if (rc < 0)
					break;

				if (pd == link->max_delay)
					link->open_req_cnt--;
			}
		}
	}
	if (rc < 0) {
		CAM_ERR_RATE_LIMIT(CAM_CRM, "APPLY FAILED pd %d req_id %lld",
			dev->dev_info.p_delay, apply_req.request_id);
		/* Apply req failed notify already applied devs */
		for (; i >= 0; i--) {
			dev = &link->l_dev[i];
			evt_data.evt_type = CAM_REQ_MGR_LINK_EVT_ERR;
			evt_data.dev_hdl = dev->dev_hdl;
			evt_data.link_hdl =  link->link_hdl;
			evt_data.req_id = apply_req.request_id;
			evt_data.u.error = CRM_KMD_ERR_BUBBLE;
			if (dev->ops && dev->ops->process_evt)
				dev->ops->process_evt(&evt_data);
		}
	}
	return rc;
}

/**
 * __cam_req_mgr_check_link_is_ready()
 *
 * @brief    : traverse through all request tables and see if all devices are
 *             ready to apply request settings.
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 * @idx      : index within input request queue
 * @validate_only : Whether to validate only and/or update settings
 * @self_link : To indicate whether the validation is for the given link or
 *              other sync link
 *
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link,
	int32_t idx, bool validate_only, bool self_link)
{
	int                            rc;
	struct cam_req_mgr_traverse    traverse_data;
	struct cam_req_mgr_req_queue  *in_q;
	struct cam_req_mgr_apply      *apply_data;

	in_q = link->req.in_q;

	apply_data = link->req.apply_data;

	if (validate_only == false) {
		memset(apply_data, 0,
		    sizeof(struct cam_req_mgr_apply) * CAM_PIPELINE_DELAY_MAX);
	}

	traverse_data.apply_data = apply_data;
	traverse_data.idx = idx;
	traverse_data.tbl = link->req.l_tbl;
	traverse_data.in_q = in_q;
	traverse_data.result = 0;
	traverse_data.validate_only = validate_only;
	traverse_data.self_link = self_link;
	traverse_data.open_req_cnt = link->open_req_cnt;
	/*
	 *  Traverse through all pd tables, if result is success,
	 *  apply the settings
	 */

	rc = __cam_req_mgr_traverse(&traverse_data);
	CAM_DBG(CAM_CRM,
		"SOF: idx %d self_link %d validate %d result %x pd_mask %x rc %d",
		idx, traverse_data.self_link, traverse_data.validate_only,
		traverse_data.result, link->pd_mask, rc);

	if (!rc && traverse_data.result == link->pd_mask) {
		CAM_DBG(CAM_CRM,
			"APPLY: link_hdl= %x idx= %d, req_id= %lld :%lld :%lld",
			link->link_hdl, idx,
			apply_data[2].req_id,
			apply_data[1].req_id,
			apply_data[0].req_id);
	} else
		rc = -EAGAIN;

	return rc;
}

/**
 * __cam_req_mgr_find_slot_for_req()
 *
 * @brief    : Find idx from input queue at which req id is enqueued
 * @in_q     : input request queue pointer
 * @req_id   : request id which needs to be searched in input queue
 *
 * @return   : slot index where passed request id is stored, -1 for failure
 *
 */
static int32_t __cam_req_mgr_find_slot_for_req(
	struct cam_req_mgr_req_queue *in_q, int64_t req_id)
{
	int32_t                   idx, i;
	struct cam_req_mgr_slot  *slot;

	idx = in_q->rd_idx;
	for (i = 0; i < in_q->num_slots; i++) {
		slot = &in_q->slot[idx];
		if (slot->req_id == req_id) {
			CAM_DBG(CAM_CRM,
				"req: %lld found at idx: %d status: %d sync_mode: %d",
				req_id, idx, slot->status, slot->sync_mode);
			break;
		}
		__cam_req_mgr_dec_idx(&idx, 1, in_q->num_slots);
	}
	if (i >= in_q->num_slots)
		idx = -1;

	return idx;
}

/**
 * __cam_req_mgr_reset_sof_cnt()
 *
 * @brief    : the sof_count for both the links are reset
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 *
 */
static void __cam_req_mgr_reset_sof_cnt(
	struct cam_req_mgr_core_link *link)
{
	link->sof_counter = -1;
	link->sync_link->sof_counter = -1;
	link->frame_skip_flag = false;

	CAM_DBG(CAM_CRM,
		"link_hdl %x self_counter %lld other_counter %lld frame_skip_lag %d",
		link->link_hdl, link->sof_counter,
		link->sync_link->sof_counter, link->frame_skip_flag);
}

/**
 * __cam_req_mgr_sof_cnt_initialize()
 *
 * @brief    : when the sof count is intially -1 it increments count
 *             and computes the sync_self_ref for this link
 *             the count needs to be wrapped back starting from 0
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 *
 */
static void __cam_req_mgr_sof_cnt_initialize(
	struct cam_req_mgr_core_link *link)
{
	link->sof_counter++;
	link->sync_self_ref = link->sof_counter -
		link->sync_link->sof_counter;

	CAM_DBG(CAM_CRM,
		"link_hdl %x self_counter %lld other_counter %lld",
		link->link_hdl, link->sof_counter,
		link->sync_link->sof_counter);
}

/**
 * __cam_req_mgr_wrap_sof_cnt()
 *
 * @brief    : once the sof count reaches a predefined maximum
 *             the count needs to be wrapped back starting from 0
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 *
 */
static void __cam_req_mgr_wrap_sof_cnt(
	struct cam_req_mgr_core_link *link)
{
	link->sof_counter = (MAX_SYNC_COUNT -
		(link->sync_link->sof_counter));
	link->sync_link->sof_counter = 0;

	CAM_DBG(CAM_CRM,
		"link_hdl %x self_counter %lld sync_link_hdl %x other_counter %lld",
		link->link_hdl, link->sof_counter,
		link->sync_link->link_hdl, link->sync_link->sof_counter);
}

/**
 * __cam_req_mgr_validate_sof_cnt()
 *
 * @brief     : validates sof count difference for a given link
 * @link      : pointer to link whose input queue and req tbl are
 *              traversed through
 * @sync_link : pointer to the sync link
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_validate_sof_cnt(
	struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_core_link *sync_link)
{
	int64_t sync_diff = 0;
	int rc = 0;

	if (link->sof_counter == MAX_SYNC_COUNT)
		__cam_req_mgr_wrap_sof_cnt(link);

	sync_diff = link->sof_counter - sync_link->sof_counter;

	CAM_DBG(CAM_CRM,
		"link[%x] self_counter=%lld other_counter=%lld diff=%lld sync_self_ref=%lld",
		link->link_hdl, link->sof_counter,
		sync_link->sof_counter, sync_diff, link->sync_self_ref);

	if (sync_diff > SYNC_LINK_SOF_CNT_MAX_LMT) {
		link->sync_link->frame_skip_flag = true;
		CAM_WARN(CAM_CRM,
			"Detected anomaly, skip link_hdl %x self_counter=%lld other_counter=%lld sync_self_ref=%lld",
			link->link_hdl, link->sof_counter,
			sync_link->sof_counter, link->sync_self_ref);
		rc = -EPERM;
	}

	return rc;
}


/**
 * __cam_req_mgr_process_sync_req()
 *
 * @brief    : processes requests during sync mode
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 * @slot     : pointer to the current slot being processed
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_process_sync_req(
	struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_slot *slot)
{
	struct cam_req_mgr_core_link *sync_link = NULL;
	int64_t req_id = 0;
	int sync_slot_idx = 0, rc = 0;

	if (!link->sync_link) {
		CAM_ERR(CAM_CRM, "Sync link null");
		return -EINVAL;
	}

	sync_link = link->sync_link;
	req_id = slot->req_id;

	CAM_DBG(CAM_CRM,
		"link_hdl %x req %lld sync_self_ref %lld sof_counter %lld frame_skip_flag %d sync_link_self_ref %lld",
		link->link_hdl, req_id, link->sync_self_ref, link->sof_counter,
		link->frame_skip_flag, link->sync_link->sync_self_ref);

	if (sync_link->sync_link_sof_skip) {
		CAM_DBG(CAM_CRM,
			"No req applied on corresponding SOF on sync link: %x",
			sync_link->link_hdl);
		sync_link->sync_link_sof_skip = false;
		/*It is to manage compensate inject delay for each pd*/
		__cam_req_mgr_check_link_is_ready(link, slot->idx, true, true);
		return -EINVAL;
	}

	if (link->sof_counter == -1) {
		__cam_req_mgr_sof_cnt_initialize(link);
	} else if ((link->frame_skip_flag) &&
		(sync_link->sync_self_ref != -1)) {
		CAM_DBG(CAM_CRM, "Link[%x] Req[%lld] Resetting values ",
			link->link_hdl, req_id);
		__cam_req_mgr_reset_sof_cnt(link);
		__cam_req_mgr_sof_cnt_initialize(link);
	} else {
		link->sof_counter++;
	}

	rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true, true);
	if (rc) {
		CAM_DBG(CAM_CRM,
			"Req: %lld [My link]not available link: %x, rc=%d",
			req_id, link->link_hdl, rc);
		link->sync_link_sof_skip = true;
		goto failure;
	}

	sync_slot_idx = __cam_req_mgr_find_slot_for_req(
		sync_link->req.in_q, req_id);

	if (sync_slot_idx != -1) {
		rc = __cam_req_mgr_check_link_is_ready(
			sync_link, sync_slot_idx, true, false);
		CAM_DBG(CAM_CRM, "sync_slot_idx=%d, status=%d, rc=%d",
			sync_slot_idx,
			sync_link->req.in_q->slot[sync_slot_idx].status,
			rc);
	} else {
		CAM_DBG(CAM_CRM, "sync_slot_idx=%d, rc=%d",
			sync_slot_idx, rc);
	}

	if ((sync_slot_idx != -1) &&
	((sync_link->req.in_q->slot[sync_slot_idx].status ==
	CRM_SLOT_STATUS_REQ_APPLIED) || (rc == 0))) {
		rc = __cam_req_mgr_validate_sof_cnt(link, sync_link);
		if (rc) {
			CAM_DBG(CAM_CRM,
				"Req: %lld validate failed: %x",
				req_id, sync_link->link_hdl);
			goto failure;
		}

		CAM_DBG(CAM_CRM,
			"Req: %lld ready to apply on link: %x [validation successful]",
			req_id, link->link_hdl);
		/*
		 *  At this point all validation is successfully done
		 *  and we can proceed to apply the given request.
		 *  Ideally the next call should return success.
		 */
		rc = __cam_req_mgr_check_link_is_ready(link,
			slot->idx, false, true);

		if (rc) {
			CAM_WARN(CAM_CRM, "Unexpected return value rc: %d", rc);
		}
	} else {
		CAM_DBG(CAM_CRM,
			"Req: %lld [Other link] not ready to apply on link: %x",
			req_id, sync_link->link_hdl);
		rc = -EPERM;
		link->sync_link_sof_skip = true;
		goto failure;
	}

	return rc;

failure:
	link->sof_counter--;
	return rc;
}

/**
 * __cam_req_mgr_process_req()
 *
 * @brief    : processes read index in request queue and traverse through table
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 *
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
	uint32_t trigger)
{
	int                                  rc = 0, idx;
	struct cam_req_mgr_slot             *slot = NULL;
	struct cam_req_mgr_req_queue        *in_q;
	struct cam_req_mgr_core_session     *session;

	in_q = link->req.in_q;
	session = (struct cam_req_mgr_core_session *)link->parent;
	mutex_lock(&session->lock);
	/*
	 * Check if new read index,
	 * - if in pending  state, traverse again to complete
	 *    transaction of this read index.
	 * - if in applied_state, somthign wrong.
	 * - if in no_req state, no new req
	 */
	CAM_DBG(CAM_CRM, "SOF Req[%lld] idx %d req_status %d link_hdl %x",
		in_q->slot[in_q->rd_idx].req_id, in_q->rd_idx,
		in_q->slot[in_q->rd_idx].status, link->link_hdl);

	slot = &in_q->slot[in_q->rd_idx];
	if (slot->status == CRM_SLOT_STATUS_NO_REQ) {
		CAM_DBG(CAM_CRM, "No Pending req");
		rc = 0;
		goto error;
	}

	if ((trigger != CAM_TRIGGER_POINT_SOF) &&
		(trigger != CAM_TRIGGER_POINT_EOF))
		goto error;

	if ((trigger == CAM_TRIGGER_POINT_EOF) &&
		(!(link->trigger_mask & CAM_TRIGGER_POINT_SOF))) {
		CAM_DBG(CAM_CRM, "Applying for last SOF fails");
		rc = -EINVAL;
		goto error;
	}

	if (trigger == CAM_TRIGGER_POINT_SOF) {
		if (link->trigger_mask) {
			CAM_ERR_RATE_LIMIT(CAM_CRM,
				"Applying for last EOF fails");
			rc = -EINVAL;
			goto error;
		}

		if (slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)
			rc = __cam_req_mgr_process_sync_req(link, slot);
		else
			rc = __cam_req_mgr_check_link_is_ready(link,
				slot->idx, false, true);

		if (rc < 0) {
			/*
			 * If traverse result is not success, then some devices
			 * are not ready with packet for the asked request id,
			 * hence try again in next sof
			 */
			slot->status = CRM_SLOT_STATUS_REQ_PENDING;
			spin_lock_bh(&link->link_state_spin_lock);
			if (link->state == CAM_CRM_LINK_STATE_ERR) {
				/*
				 * During error recovery all tables should be
				 * ready, don't expect to enter here.
				 * @TODO: gracefully handle if recovery fails.
				 */
				CAM_ERR_RATE_LIMIT(CAM_CRM,
					"FATAL recovery cant finish idx %d status %d",
					in_q->rd_idx,
					in_q->slot[in_q->rd_idx].status);
				rc = -EPERM;
			}
			spin_unlock_bh(&link->link_state_spin_lock);
			goto error;
		}
	}

	rc = __cam_req_mgr_send_req(link, link->req.in_q, trigger);
	if (rc < 0) {
		/* Apply req failed retry at next sof */
		slot->status = CRM_SLOT_STATUS_REQ_PENDING;
	} else {
		link->trigger_mask |= trigger;

		CAM_DBG(CAM_CRM, "Applied req[%lld] on link[%x] success",
			slot->req_id, link->link_hdl);
		spin_lock_bh(&link->link_state_spin_lock);
		if (link->state == CAM_CRM_LINK_STATE_ERR) {
			CAM_WARN(CAM_CRM, "Err recovery done idx %d",
				in_q->rd_idx);
			link->state = CAM_CRM_LINK_STATE_READY;
		}
		spin_unlock_bh(&link->link_state_spin_lock);

		if (link->sync_link_sof_skip)
			link->sync_link_sof_skip = false;

		if (link->trigger_mask == link->subscribe_event) {
			slot->status = CRM_SLOT_STATUS_REQ_APPLIED;
			link->trigger_mask = 0;
			CAM_DBG(CAM_CRM, "req %d is applied on link %x",
				slot->req_id,
				link->link_hdl);
			idx = in_q->rd_idx;
			__cam_req_mgr_dec_idx(
				&idx, link->max_delay + 1,
				in_q->num_slots);
			__cam_req_mgr_reset_req_slot(link, idx);
		}
	}

	mutex_unlock(&session->lock);
	return rc;
error:
	mutex_unlock(&session->lock);
	return rc;
}

/**
 * __cam_req_mgr_add_tbl_to_link()
 *
 * @brief    : Add table to list under link sorted by pd decremeting order
 * @l_tbl    : list of pipeline delay tables.
 * @new_tbl  : new tbl which will be appended to above list as per its pd value
 *
 */
static void __cam_req_mgr_add_tbl_to_link(struct cam_req_mgr_req_tbl **l_tbl,
	struct cam_req_mgr_req_tbl *new_tbl)
{
	struct cam_req_mgr_req_tbl *tbl;

	if (!(*l_tbl) || (*l_tbl)->pd < new_tbl->pd) {
		new_tbl->next = *l_tbl;
		if (*l_tbl) {
			new_tbl->pd_delta =
				new_tbl->pd - (*l_tbl)->pd;
		}
		*l_tbl = new_tbl;
	} else {
		tbl = *l_tbl;

		/* Reach existing  tbl which has less pd value */
		while (tbl->next != NULL &&
			new_tbl->pd < tbl->next->pd) {
			tbl = tbl->next;
		}
		if (tbl->next != NULL) {
			new_tbl->pd_delta =
				new_tbl->pd - tbl->next->pd;
		} else {
			/* This is last table in linked list*/
			new_tbl->pd_delta = 0;
		}
		new_tbl->next = tbl->next;
		tbl->next = new_tbl;
		tbl->pd_delta = tbl->pd - new_tbl->pd;
	}
	CAM_DBG(CAM_CRM, "added pd %d tbl to link delta %d", new_tbl->pd,
		new_tbl->pd_delta);
}

/**
 * __cam_req_mgr_create_pd_tbl()
 *
 * @brief    : Creates new request table for new delay value
 * @delay    : New pd table allocated will have this delay value
 *
 * @return   : pointer to newly allocated table, NULL for failure
 *
 */
static struct cam_req_mgr_req_tbl *__cam_req_mgr_create_pd_tbl(int32_t delay)
{
	struct cam_req_mgr_req_tbl *tbl =
		kzalloc(sizeof(struct cam_req_mgr_req_tbl), GFP_KERNEL);
	if (tbl != NULL) {
		tbl->num_slots = MAX_REQ_SLOTS;
		CAM_DBG(CAM_CRM, "pd= %d slots= %d", delay, tbl->num_slots);
	}

	return tbl;
}

/**
 * __cam_req_mgr_destroy_all_tbl()
 *
 * @brief   : This func will destroy all pipeline delay based req table structs
 * @l_tbl    : pointer to first table in list and it has max pd .
 *
 */
static void __cam_req_mgr_destroy_all_tbl(struct cam_req_mgr_req_tbl **l_tbl)
{
	struct cam_req_mgr_req_tbl  *tbl = *l_tbl, *temp;

	CAM_DBG(CAM_CRM, "*l_tbl %pK", tbl);
	while (tbl != NULL) {
		temp = tbl->next;
		kfree(tbl);
		tbl = temp;
	}
	*l_tbl = NULL;
}

/**
 * __cam_req_mgr_setup_in_q()
 *
 * @brief : Initialize req table data
 * @req   : request data pointer
 *
 * @return: 0 for success, negative for failure
 *
 */
static int  __cam_req_mgr_setup_in_q(struct cam_req_mgr_req_data *req)
{
	int                           i;
	struct cam_req_mgr_req_queue *in_q = req->in_q;

	if (!in_q) {
		CAM_ERR(CAM_CRM, "NULL in_q");
		return -EINVAL;
	}

	mutex_lock(&req->lock);
	in_q->num_slots = MAX_REQ_SLOTS;

	for (i = 0; i < in_q->num_slots; i++) {
		in_q->slot[i].idx = i;
		in_q->slot[i].req_id = -1;
		in_q->slot[i].skip_idx = 0;
		in_q->slot[i].status = CRM_SLOT_STATUS_NO_REQ;
	}

	in_q->wr_idx = 0;
	in_q->rd_idx = 0;
	mutex_unlock(&req->lock);

	return 0;
}

/**
 * __cam_req_mgr_reset_req_tbl()
 *
 * @brief : Initialize req table data
 * @req   : request queue pointer
 *
 * @return: 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_reset_in_q(struct cam_req_mgr_req_data *req)
{
	struct cam_req_mgr_req_queue *in_q = req->in_q;

	if (!in_q) {
		CAM_ERR(CAM_CRM, "NULL in_q");
		return -EINVAL;
	}

	mutex_lock(&req->lock);
	memset(in_q->slot, 0,
		sizeof(struct cam_req_mgr_slot) * in_q->num_slots);
	in_q->num_slots = 0;

	in_q->wr_idx = 0;
	in_q->rd_idx = 0;
	mutex_unlock(&req->lock);

	return 0;
}

/**
 * __cam_req_mgr_sof_freeze()
 *
 * @brief : Apoptosis - Handles case when connected devices are not responding
 * @data  : timer pointer
 *
 */
static void __cam_req_mgr_sof_freeze(unsigned long data)
{
	struct cam_req_mgr_timer     *timer = (struct cam_req_mgr_timer *)data;
	struct cam_req_mgr_core_link    *link = NULL;
	struct cam_req_mgr_core_session *session = NULL;
	struct cam_req_mgr_message       msg;

	if (!timer) {
		CAM_ERR(CAM_CRM, "NULL timer");
		return;
	}
	link = (struct cam_req_mgr_core_link *)timer->parent;
	session = (struct cam_req_mgr_core_session *)link->parent;

	CAM_ERR(CAM_CRM, "SOF freeze for session %d link 0x%x",
		session->session_hdl, link->link_hdl);

	memset(&msg, 0, sizeof(msg));

	msg.session_hdl = session->session_hdl;
	msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_DEVICE;
	msg.u.err_msg.request_id = 0;
	msg.u.err_msg.link_hdl   = link->link_hdl;


	if (cam_req_mgr_notify_message(&msg,
		V4L_EVENT_CAM_REQ_MGR_ERROR, V4L_EVENT_CAM_REQ_MGR_EVENT))
		CAM_ERR(CAM_CRM,
			"Error notifying SOF freeze for session %d link 0x%x",
			session->session_hdl, link->link_hdl);
}

/**
 * __cam_req_mgr_create_subdevs()
 *
 * @brief   : Create new crm  subdev to link with realtime devices
 * @l_dev   : list of subdevs internal to crm
 * @num_dev : num of subdevs to be created for link
 *
 * @return  : pointer to allocated list of devices
 */
static int __cam_req_mgr_create_subdevs(
	struct cam_req_mgr_connected_device **l_dev, int32_t num_dev)
{
	int rc = 0;
	*l_dev = (struct cam_req_mgr_connected_device *)
		kzalloc(sizeof(struct cam_req_mgr_connected_device) * num_dev,
		GFP_KERNEL);
	if (!*l_dev)
		rc = -ENOMEM;

	return rc;
}

/**
 * __cam_req_mgr_destroy_subdev()
 *
 * @brief    : Cleans up the subdevs allocated by crm for link
 * @l_device : pointer to list of subdevs crm created
 *
 */
static void __cam_req_mgr_destroy_subdev(
	struct cam_req_mgr_connected_device *l_device)
{
	kfree(l_device);
	l_device = NULL;
}

/**
 * __cam_req_mgr_destroy_link_info()
 *
 * @brief    : Cleans up the mem allocated while linking
 * @link     : pointer to link, mem associated with this link is freed
 *
 * @return   : returns if unlink for any device was success or failure
 */
static int __cam_req_mgr_destroy_link_info(struct cam_req_mgr_core_link *link)
{
	int32_t                                 i = 0;
	struct cam_req_mgr_connected_device    *dev;
	struct cam_req_mgr_core_dev_link_setup  link_data;
	int                                     rc = 0;

	link_data.link_enable = 0;
	link_data.link_hdl = link->link_hdl;
	link_data.crm_cb = NULL;
	link_data.subscribe_event = 0;

	/* Using device ops unlink devices */
	for (i = 0; i < link->num_devs; i++) {
		dev = &link->l_dev[i];
		if (dev != NULL) {
			link_data.dev_hdl = dev->dev_hdl;
			if (dev->ops && dev->ops->link_setup) {
				rc = dev->ops->link_setup(&link_data);
				if (rc)
					CAM_ERR(CAM_CRM,
						"Unlink failed dev_hdl %d",
						dev->dev_hdl);
			}
			dev->dev_hdl = 0;
			dev->parent = NULL;
			dev->ops = NULL;
		}
	}
	__cam_req_mgr_destroy_all_tbl(&link->req.l_tbl);
	__cam_req_mgr_reset_in_q(&link->req);
	link->req.num_tbl = 0;
	mutex_destroy(&link->req.lock);

	link->pd_mask = 0;
	link->num_devs = 0;
	link->max_delay = 0;

	return rc;
}

/**
 * __cam_req_mgr_reserve_link()
 *
 * @brief: Reserves one link data struct within session
 * @session: session identifier
 *
 * @return: pointer to link reserved
 *
 */
static struct cam_req_mgr_core_link *__cam_req_mgr_reserve_link(
	struct cam_req_mgr_core_session *session)
{
	struct cam_req_mgr_core_link *link;
	struct cam_req_mgr_req_queue *in_q;
	int i;

	if (!session || !g_crm_core_dev) {
		CAM_ERR(CAM_CRM, "NULL session/core_dev ptr");
		return NULL;
	}

	if (session->num_links >= MAX_LINKS_PER_SESSION) {
		CAM_ERR(CAM_CRM, "Reached max links %d per session limit %d",
			session->num_links, MAX_LINKS_PER_SESSION);
		return NULL;
	}

	link = (struct cam_req_mgr_core_link *)
		kzalloc(sizeof(struct cam_req_mgr_core_link), GFP_KERNEL);
	if (!link) {
		CAM_ERR(CAM_CRM, "failed to create link, no mem");
		return NULL;
	}
	in_q = (struct cam_req_mgr_req_queue *)
		kzalloc(sizeof(struct cam_req_mgr_req_queue), GFP_KERNEL);
	if (!in_q) {
		CAM_ERR(CAM_CRM, "failed to create input queue, no mem");
		kfree(link);
		return NULL;
	}
	mutex_init(&link->lock);
	spin_lock_init(&link->link_state_spin_lock);

	mutex_lock(&link->lock);
	link->state = CAM_CRM_LINK_STATE_AVAILABLE;
	link->num_devs = 0;
	link->max_delay = 0;
	memset(in_q->slot, 0,
		sizeof(struct cam_req_mgr_slot) * MAX_REQ_SLOTS);
	link->req.in_q = in_q;
	in_q->num_slots = 0;
	link->state = CAM_CRM_LINK_STATE_IDLE;
	link->parent = (void *)session;
	link->sync_link = NULL;
	mutex_unlock(&link->lock);

	mutex_lock(&session->lock);
	/*  Loop through and find a free index */
	for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
		if (!session->links[i]) {
			CAM_DBG(CAM_CRM,
				"Free link index %d found, num_links=%d",
				i, session->num_links);
			session->links[i] = link;
			break;
		}
	}

	if (i == MAX_LINKS_PER_SESSION) {
		CAM_ERR(CAM_CRM, "Free link index not found");
		goto error;
	}

	session->num_links++;
	CAM_DBG(CAM_CRM, "Active session links (%d)",
		session->num_links);
	mutex_unlock(&session->lock);

	return link;
error:
	mutex_unlock(&session->lock);
	kfree(link);
	kfree(in_q);
	return NULL;
}

/*
 * __cam_req_mgr_free_link()
 *
 * @brief: Frees the link and its request queue
 *
 * @link: link identifier
 *
 */
static void __cam_req_mgr_free_link(struct cam_req_mgr_core_link *link)
{
	kfree(link->req.in_q);
	link->req.in_q = NULL;
	kfree(link);
}

/**
 * __cam_req_mgr_unreserve_link()
 *
 * @brief  : Removes the link data struct from the session and frees it
 * @session: session identifier
 * @link   : link identifier
 *
 */
static void __cam_req_mgr_unreserve_link(
	struct cam_req_mgr_core_session *session,
	struct cam_req_mgr_core_link *link)
{
	int i;

	if (!session || !link) {
		CAM_ERR(CAM_CRM, "NULL session/link ptr %pK %pK",
			session, link);
		return;
	}

	mutex_lock(&session->lock);
	if (!session->num_links) {
		CAM_WARN(CAM_CRM, "No active link or invalid state: hdl %x",
			link->link_hdl);
		mutex_unlock(&session->lock);
		return;
	}

	for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
		if (session->links[i] == link)
			session->links[i] = NULL;
	}

	if ((session->sync_mode != CAM_REQ_MGR_SYNC_MODE_NO_SYNC) &&
		(link->sync_link)) {
		/*
		 * make sure to unlink sync setup under the assumption
		 * of only having 2 links in a given session
		 */
		session->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
		for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
			if (session->links[i])
				session->links[i]->sync_link = NULL;
		}
	}

	session->num_links--;
	CAM_DBG(CAM_CRM, "Active session links (%d)", session->num_links);
	mutex_unlock(&session->lock);
	__cam_req_mgr_free_link(link);
}

/* Workqueue context processing section */

/**
 * cam_req_mgr_process_send_req()
 *
 * @brief: This runs in workque thread context. Call core funcs to send
 *         apply request id to drivers.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
int cam_req_mgr_process_send_req(void *priv, void *data)
{
	int                                 rc = 0;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_send_request     *send_req = NULL;
	struct cam_req_mgr_req_queue        *in_q = NULL;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}
	link = (struct cam_req_mgr_core_link *)priv;
	send_req = (struct cam_req_mgr_send_request *)data;
	in_q = send_req->in_q;

	rc = __cam_req_mgr_send_req(link, in_q, CAM_TRIGGER_POINT_SOF);
end:
	return rc;
}

/**
 * cam_req_mgr_process_flush_req()
 *
 * @brief: This runs in workque thread context. Call core funcs to check
 *         which requests need to be removed/cancelled.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
int cam_req_mgr_process_flush_req(void *priv, void *data)
{
	int                                  rc = 0, i = 0, idx = -1;
	struct cam_req_mgr_flush_info       *flush_info = NULL;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_req_queue        *in_q = NULL;
	struct cam_req_mgr_slot             *slot = NULL;
	struct cam_req_mgr_connected_device *device = NULL;
	struct cam_req_mgr_flush_request     flush_req;
	struct crm_task_payload             *task_data = NULL;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}
	link = (struct cam_req_mgr_core_link *)priv;
	task_data = (struct crm_task_payload *)data;
	flush_info  = (struct cam_req_mgr_flush_info *)&task_data->u;
	CAM_DBG(CAM_CRM, "link_hdl %x req_id %lld type %d",
		flush_info->link_hdl,
		flush_info->req_id,
		flush_info->flush_type);

	in_q = link->req.in_q;

	trace_cam_flush_req(link, flush_info);

	mutex_lock(&link->req.lock);
	if (flush_info->flush_type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
		for (i = 0; i < in_q->num_slots; i++) {
			slot = &in_q->slot[i];
			slot->req_id = -1;
			slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
			slot->skip_idx = 1;
			slot->status = CRM_SLOT_STATUS_NO_REQ;
		}
		in_q->wr_idx = 0;
		in_q->rd_idx = 0;
	} else if (flush_info->flush_type ==
		CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
		idx = __cam_req_mgr_find_slot_for_req(in_q, flush_info->req_id);
		if (idx < 0) {
			CAM_ERR(CAM_CRM, "req_id %lld not found in input queue",
			flush_info->req_id);
		} else {
			CAM_DBG(CAM_CRM, "req_id %lld found at idx %d",
				flush_info->req_id, idx);
			slot = &in_q->slot[idx];
			if (slot->status == CRM_SLOT_STATUS_REQ_PENDING ||
				slot->status == CRM_SLOT_STATUS_REQ_APPLIED) {
				CAM_WARN(CAM_CRM,
					"req_id %lld can not be cancelled",
					flush_info->req_id);
				mutex_unlock(&link->req.lock);
				return -EINVAL;
			}
			__cam_req_mgr_in_q_skip_idx(in_q, idx);
		}
	}

	for (i = 0; i < link->num_devs; i++) {
		device = &link->l_dev[i];
		flush_req.link_hdl = flush_info->link_hdl;
		flush_req.dev_hdl = device->dev_hdl;
		flush_req.req_id = flush_info->req_id;
		flush_req.type = flush_info->flush_type;
		/* @TODO: error return handling from drivers */
		if (device->ops && device->ops->flush_req)
			rc = device->ops->flush_req(&flush_req);
	}
	complete(&link->workq_comp);
	mutex_unlock(&link->req.lock);

end:
	return rc;
}

/**
 * cam_req_mgr_process_sched_req()
 *
 * @brief: This runs in workque thread context. Call core funcs to check
 *         which peding requests can be processed.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
int cam_req_mgr_process_sched_req(void *priv, void *data)
{
	int                               rc = 0;
	struct cam_req_mgr_sched_request *sched_req = NULL;
	struct cam_req_mgr_core_link     *link = NULL;
	struct cam_req_mgr_req_queue     *in_q = NULL;
	struct cam_req_mgr_slot          *slot = NULL;
	struct crm_task_payload          *task_data = NULL;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}
	link = (struct cam_req_mgr_core_link *)priv;
	task_data = (struct crm_task_payload *)data;
	sched_req  = (struct cam_req_mgr_sched_request *)&task_data->u;
	in_q = link->req.in_q;

	CAM_DBG(CAM_CRM, "link_hdl %x req_id %lld at slot %d sync_mode %d",
		sched_req->link_hdl, sched_req->req_id,
		in_q->wr_idx, sched_req->sync_mode);

	mutex_lock(&link->req.lock);
	slot = &in_q->slot[in_q->wr_idx];

	if (slot->status != CRM_SLOT_STATUS_NO_REQ &&
		slot->status != CRM_SLOT_STATUS_REQ_APPLIED)
		CAM_WARN(CAM_CRM, "in_q overwrite %d", slot->status);

	slot->status = CRM_SLOT_STATUS_REQ_ADDED;
	slot->req_id = sched_req->req_id;
	slot->sync_mode = sched_req->sync_mode;
	slot->skip_idx = 0;
	slot->recover = sched_req->bubble_enable;
	link->open_req_cnt++;
	__cam_req_mgr_inc_idx(&in_q->wr_idx, 1, in_q->num_slots);
	mutex_unlock(&link->req.lock);

end:
	return rc;
}

/**
 * cam_req_mgr_process_add_req()
 *
 * @brief: This runs in workque thread context. Call core funcs to check
 *         which peding requests can be processed.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
int cam_req_mgr_process_add_req(void *priv, void *data)
{
	int                                  rc = 0, i = 0, idx;
	struct cam_req_mgr_add_request      *add_req = NULL;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_connected_device *device = NULL;
	struct cam_req_mgr_req_tbl          *tbl = NULL;
	struct cam_req_mgr_tbl_slot         *slot = NULL;
	struct crm_task_payload             *task_data = NULL;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)priv;
	task_data = (struct crm_task_payload *)data;
	add_req = (struct cam_req_mgr_add_request *)&task_data->u;

	for (i = 0; i < link->num_devs; i++) {
		device = &link->l_dev[i];
		if (device->dev_hdl == add_req->dev_hdl) {
			tbl = device->pd_tbl;
			break;
		}
	}
	if (!tbl) {
		CAM_ERR_RATE_LIMIT(CAM_CRM, "dev_hdl not found %x, %x %x",
			add_req->dev_hdl,
			link->l_dev[0].dev_hdl,
			link->l_dev[1].dev_hdl);
		rc = -EINVAL;
		goto end;
	}
	/*
	 * Go through request table and add
	 * request id to proper table
	 * 1. find req slot in in_q matching req_id.sent by dev
	 * 2. goto table of this device based on p_delay
	 * 3. mark req_ready_map with this dev_bit.
	 */

	mutex_lock(&link->req.lock);
	idx = __cam_req_mgr_find_slot_for_req(link->req.in_q, add_req->req_id);
	if (idx < 0) {
		CAM_ERR(CAM_CRM, "req %lld not found in in_q", add_req->req_id);
		rc = -EBADSLT;
		mutex_unlock(&link->req.lock);
		goto end;
	}

	if (add_req->skip_before_applying > tbl->inject_delay)
		tbl->inject_delay = add_req->skip_before_applying;

	slot = &tbl->slot[idx];
	if (slot->state != CRM_REQ_STATE_PENDING &&
		slot->state != CRM_REQ_STATE_EMPTY) {
		CAM_WARN(CAM_CRM, "Unexpected state %d for slot %d map %x",
			slot->state, idx, slot->req_ready_map);
	}

	slot->state = CRM_REQ_STATE_PENDING;
	slot->req_ready_map |= (1 << device->dev_bit);

	CAM_DBG(CAM_CRM, "idx %d dev_hdl %x req_id %lld pd %d ready_map %x",
		idx, add_req->dev_hdl, add_req->req_id, tbl->pd,
		slot->req_ready_map);

	trace_cam_req_mgr_add_req(link, idx, add_req, tbl, device);

	if (slot->req_ready_map == tbl->dev_mask) {
		CAM_DBG(CAM_CRM, "idx %d req_id %lld pd %d SLOT READY",
			idx, add_req->req_id, tbl->pd);
		slot->state = CRM_REQ_STATE_READY;
	}
	mutex_unlock(&link->req.lock);

end:
	return rc;
}

/**
 * cam_req_mgr_process_error()
 *
 * @brief: This runs in workque thread context. bubble /err recovery.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
int cam_req_mgr_process_error(void *priv, void *data)
{
	int                                  rc = 0, idx = -1, i;
	struct cam_req_mgr_error_notify     *err_info = NULL;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_req_queue        *in_q = NULL;
	struct cam_req_mgr_slot             *slot = NULL;
	struct cam_req_mgr_connected_device *device = NULL;
	struct cam_req_mgr_link_evt_data     evt_data;
	struct crm_task_payload             *task_data = NULL;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}
	link = (struct cam_req_mgr_core_link *)priv;
	task_data = (struct crm_task_payload *)data;
	err_info  = (struct cam_req_mgr_error_notify *)&task_data->u;
	CAM_DBG(CAM_CRM, "link_hdl %x req_id %lld error %d",
		err_info->link_hdl,
		err_info->req_id,
		err_info->error);

	in_q = link->req.in_q;

	mutex_lock(&link->req.lock);
	if (err_info->error == CRM_KMD_ERR_BUBBLE) {
		idx = __cam_req_mgr_find_slot_for_req(in_q, err_info->req_id);
		if (idx < 0) {
			CAM_ERR_RATE_LIMIT(CAM_CRM,
				"req_id %lld not found in input queue",
				err_info->req_id);
		} else {
			CAM_DBG(CAM_CRM, "req_id %lld found at idx %d",
				err_info->req_id, idx);
			slot = &in_q->slot[idx];
			if (!slot->recover) {
				CAM_WARN(CAM_CRM,
					"err recovery disabled req_id %lld",
					err_info->req_id);
				mutex_unlock(&link->req.lock);
				return 0;
			} else if (slot->status != CRM_SLOT_STATUS_REQ_PENDING
			&& slot->status != CRM_SLOT_STATUS_REQ_APPLIED) {
				CAM_WARN(CAM_CRM,
					"req_id %lld can not be recovered %d",
					err_info->req_id, slot->status);
				mutex_unlock(&link->req.lock);
				return -EINVAL;
			}
			/* Notify all devices in the link about error */
			for (i = 0; i < link->num_devs; i++) {
				device = &link->l_dev[i];
				if (device != NULL) {
					evt_data.dev_hdl = device->dev_hdl;
					evt_data.evt_type =
						CAM_REQ_MGR_LINK_EVT_ERR;
					evt_data.link_hdl =  link->link_hdl;
					evt_data.req_id = err_info->req_id;
					evt_data.u.error = err_info->error;
					if (device->ops &&
						device->ops->process_evt)
						rc = device->ops->process_evt(
							&evt_data);
				}
			}
			/* Bring processing pointer to bubbled req id */
			__cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl);
			in_q->rd_idx = idx;
			in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
			spin_lock_bh(&link->link_state_spin_lock);
			link->state = CAM_CRM_LINK_STATE_ERR;
			spin_unlock_bh(&link->link_state_spin_lock);
		}
	}
	mutex_unlock(&link->req.lock);

end:
	return rc;
}

/**
 * cam_req_mgr_process_trigger()
 *
 * @brief: This runs in workque thread context. Call core funcs to check
 *         which peding requests can be processed.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
static int cam_req_mgr_process_trigger(void *priv, void *data)
{
	int                                  rc = 0;
	struct cam_req_mgr_trigger_notify   *trigger_data = NULL;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_req_queue        *in_q = NULL;
	struct crm_task_payload             *task_data = NULL;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}
	link = (struct cam_req_mgr_core_link *)priv;
	task_data = (struct crm_task_payload *)data;
	trigger_data = (struct cam_req_mgr_trigger_notify *)&task_data->u;

	CAM_DBG(CAM_CRM, "link_hdl %x frame_id %lld, trigger %x\n",
		trigger_data->link_hdl,
		trigger_data->frame_id,
		trigger_data->trigger);

	in_q = link->req.in_q;

	mutex_lock(&link->req.lock);
	/*
	 * Check if current read index is in applied state, if yes make it free
	 *    and increment read index to next slot.
	 */
	CAM_DBG(CAM_CRM, "link_hdl %x curent idx %d req_status %d",
		link->link_hdl, in_q->rd_idx, in_q->slot[in_q->rd_idx].status);

	spin_lock_bh(&link->link_state_spin_lock);
	if (link->state == CAM_CRM_LINK_STATE_ERR)
		CAM_WARN(CAM_CRM, "Error recovery idx %d status %d",
			in_q->rd_idx,
			in_q->slot[in_q->rd_idx].status);

	spin_unlock_bh(&link->link_state_spin_lock);

	if (in_q->slot[in_q->rd_idx].status == CRM_SLOT_STATUS_REQ_APPLIED) {
		/*
		 * Do NOT reset req q slot data here, it can not be done
		 * here because we need to preserve the data to handle bubble.
		 *
		 * Check if any new req is pending in slot, if not finish the
		 * lower pipeline delay device with available req ids.
		 */
		 CAM_DBG(CAM_CRM, "link[%x] Req[%lld] invalidating slot",
			link->link_hdl, in_q->slot[in_q->rd_idx].req_id);
		__cam_req_mgr_check_next_req_slot(in_q);
		__cam_req_mgr_inc_idx(&in_q->rd_idx, 1, in_q->num_slots);
	}
	rc = __cam_req_mgr_process_req(link, trigger_data->trigger);
	mutex_unlock(&link->req.lock);

end:
	return rc;
}


/* Linked devices' Callback section */

/**
 * cam_req_mgr_cb_add_req()
 *
 * @brief    : Drivers call this function to notify new packet is available.
 * @add_req  : Information about new request available at a device.
 *
 * @return   : 0 on success, negative in case of failure
 *
 */
static int cam_req_mgr_cb_add_req(struct cam_req_mgr_add_request *add_req)
{
	int                             rc = 0, idx;
	struct crm_workq_task          *task = NULL;
	struct cam_req_mgr_core_link   *link = NULL;
	struct cam_req_mgr_add_request *dev_req;
	struct crm_task_payload        *task_data;

	if (!add_req) {
		CAM_ERR(CAM_CRM, "sof_data is NULL");
		return -EINVAL;
	}

	CAM_DBG(CAM_CRM, "E: dev %x dev req %lld",
		add_req->dev_hdl, add_req->req_id);
	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(add_req->link_hdl);

	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", add_req->link_hdl);
		return -EINVAL;
	}

	mutex_lock(&link->lock);
	spin_lock_bh(&link->link_state_spin_lock);
	if (link->state != CAM_CRM_LINK_STATE_READY) {
		CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
		rc = -EPERM;
		spin_unlock_bh(&link->link_state_spin_lock);
		goto end;
	}
	spin_unlock_bh(&link->link_state_spin_lock);

	/* Validate if req id is present in input queue */
	idx = __cam_req_mgr_find_slot_for_req(link->req.in_q, add_req->req_id);
	if (idx < 0) {
		CAM_ERR(CAM_CRM, "req %lld not found in in_q", add_req->req_id);
		rc = -ENOENT;
		goto end;
	}

	task = cam_req_mgr_workq_get_task(link->workq);
	if (!task) {
		CAM_ERR_RATE_LIMIT(CAM_CRM, "no empty task dev %x req %lld",
			add_req->dev_hdl, add_req->req_id);
		rc = -EBUSY;
		goto end;
	}

	task_data = (struct crm_task_payload *)task->payload;
	task_data->type = CRM_WORKQ_TASK_DEV_ADD_REQ;
	dev_req = (struct cam_req_mgr_add_request *)&task_data->u;
	dev_req->req_id = add_req->req_id;
	dev_req->link_hdl = add_req->link_hdl;
	dev_req->dev_hdl = add_req->dev_hdl;
	dev_req->skip_before_applying = add_req->skip_before_applying;
	task->process_cb = &cam_req_mgr_process_add_req;
	rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0);
	CAM_DBG(CAM_CRM, "X: dev %x dev req %lld",
		add_req->dev_hdl, add_req->req_id);

end:
	mutex_unlock(&link->lock);
	return rc;
}

/**
 * cam_req_mgr_cb_notify_err()
 *
 * @brief    : Error received from device, sends bubble recovery
 * @err_info : contains information about error occurred like bubble/overflow
 *
 * @return   : 0 on success, negative in case of failure
 *
 */
static int cam_req_mgr_cb_notify_err(
	struct cam_req_mgr_error_notify *err_info)
{
	int                              rc = 0;
	struct crm_workq_task           *task = NULL;
	struct cam_req_mgr_core_link    *link = NULL;
	struct cam_req_mgr_error_notify *notify_err;
	struct crm_task_payload         *task_data;

	if (!err_info) {
		CAM_ERR(CAM_CRM, "err_info is NULL");
		rc = -EINVAL;
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(err_info->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", err_info->link_hdl);
		rc = -EINVAL;
		goto end;
	}

	spin_lock_bh(&link->link_state_spin_lock);
	if (link->state != CAM_CRM_LINK_STATE_READY) {
		CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
		spin_unlock_bh(&link->link_state_spin_lock);
		rc = -EPERM;
		goto end;
	}
	crm_timer_reset(link->watchdog);
	spin_unlock_bh(&link->link_state_spin_lock);

	task = cam_req_mgr_workq_get_task(link->workq);
	if (!task) {
		CAM_ERR(CAM_CRM, "no empty task req_id %lld", err_info->req_id);
		rc = -EBUSY;
		goto end;
	}

	task_data = (struct crm_task_payload *)task->payload;
	task_data->type = CRM_WORKQ_TASK_NOTIFY_ERR;
	notify_err = (struct cam_req_mgr_error_notify *)&task_data->u;
	notify_err->req_id = err_info->req_id;
	notify_err->link_hdl = err_info->link_hdl;
	notify_err->dev_hdl = err_info->dev_hdl;
	notify_err->error = err_info->error;
	task->process_cb = &cam_req_mgr_process_error;
	rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0);

end:
	return rc;
}

/**
 * cam_req_mgr_cb_notify_trigger()
 *
 * @brief   : SOF received from device, sends trigger through workqueue
 * @sof_data: contains information about frame_id, link etc.
 *
 * @return  : 0 on success
 *
 */
static int cam_req_mgr_cb_notify_trigger(
	struct cam_req_mgr_trigger_notify *trigger_data)
{
	int                              rc = 0;
	struct crm_workq_task           *task = NULL;
	struct cam_req_mgr_core_link    *link = NULL;
	struct cam_req_mgr_trigger_notify   *notify_trigger;
	struct crm_task_payload         *task_data;

	if (!trigger_data) {
		CAM_ERR(CAM_CRM, "sof_data is NULL");
		rc = -EINVAL;
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(trigger_data->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", trigger_data->link_hdl);
		rc = -EINVAL;
		goto end;
	}

	spin_lock_bh(&link->link_state_spin_lock);
	if (link->state != CAM_CRM_LINK_STATE_READY) {
		CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
		spin_unlock_bh(&link->link_state_spin_lock);
		rc = -EPERM;
		goto end;
	}
	crm_timer_reset(link->watchdog);
	spin_unlock_bh(&link->link_state_spin_lock);

	task = cam_req_mgr_workq_get_task(link->workq);
	if (!task) {
		CAM_ERR(CAM_CRM, "no empty task frame %lld",
			trigger_data->frame_id);
		rc = -EBUSY;
		goto end;
	}
	task_data = (struct crm_task_payload *)task->payload;
	task_data->type = CRM_WORKQ_TASK_NOTIFY_SOF;
	notify_trigger = (struct cam_req_mgr_trigger_notify *)&task_data->u;
	notify_trigger->frame_id = trigger_data->frame_id;
	notify_trigger->link_hdl = trigger_data->link_hdl;
	notify_trigger->dev_hdl = trigger_data->dev_hdl;
	notify_trigger->trigger = trigger_data->trigger;
	task->process_cb = &cam_req_mgr_process_trigger;
	rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0);

end:
	return rc;
}

static struct cam_req_mgr_crm_cb cam_req_mgr_ops = {
	.notify_trigger = cam_req_mgr_cb_notify_trigger,
	.notify_err     = cam_req_mgr_cb_notify_err,
	.add_req        = cam_req_mgr_cb_add_req,
};

/**
 * __cam_req_mgr_setup_link_info()
 *
 * @brief     : Sets up input queue, create pd based tables, communicate with
 *              devs connected on this link and setup communication.
 * @link      : pointer to link to setup
 * @link_info : link_info coming from CSL to prepare link
 *
 * @return    : 0 on success, negative in case of failure
 *
 */
static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_link_info *link_info)
{
	int                                     rc = 0, i = 0;
	struct cam_req_mgr_core_dev_link_setup  link_data;
	struct cam_req_mgr_connected_device    *dev;
	struct cam_req_mgr_req_tbl             *pd_tbl;
	enum cam_pipeline_delay                 max_delay;
	uint32_t                                subscribe_event = 0;

	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES)
		return -EPERM;

	mutex_init(&link->req.lock);
	CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
	link->req.num_tbl = 0;

	rc = __cam_req_mgr_setup_in_q(&link->req);
	if (rc < 0)
		return rc;

	max_delay = CAM_PIPELINE_DELAY_0;
	for (i = 0; i < link_info->num_devices; i++) {
		dev = &link->l_dev[i];
		/* Using dev hdl, get ops ptr to communicate with device */
		dev->ops = (struct cam_req_mgr_kmd_ops *)
			cam_get_device_ops(link_info->dev_hdls[i]);
		if (!dev->ops ||
			!dev->ops->get_dev_info ||
			!dev->ops->link_setup) {
			CAM_ERR(CAM_CRM, "FATAL: device ops NULL");
			rc = -ENXIO;
			goto error;
		}
		dev->dev_hdl = link_info->dev_hdls[i];
		dev->parent = (void *)link;
		dev->dev_info.dev_hdl = dev->dev_hdl;
		rc = dev->ops->get_dev_info(&dev->dev_info);

		trace_cam_req_mgr_connect_device(link, &dev->dev_info);

		CAM_DBG(CAM_CRM,
			"%x: connected: %s, id %d, delay %d, trigger %x",
			link_info->session_hdl, dev->dev_info.name,
			dev->dev_info.dev_id, dev->dev_info.p_delay,
			dev->dev_info.trigger);
		if (rc < 0 ||
			dev->dev_info.p_delay >=
			CAM_PIPELINE_DELAY_MAX ||
			dev->dev_info.p_delay <
			CAM_PIPELINE_DELAY_0) {
			CAM_ERR(CAM_CRM, "get device info failed");
			goto error;
		} else {
			CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
				link_info->session_hdl,
				dev->dev_info.name,
				dev->dev_info.p_delay);
			if (dev->dev_info.p_delay > max_delay)
				max_delay = dev->dev_info.p_delay;

			subscribe_event |= (uint32_t)dev->dev_info.trigger;
		}
	}

	link->subscribe_event = subscribe_event;
	link_data.link_enable = 1;
	link_data.link_hdl = link->link_hdl;
	link_data.crm_cb = &cam_req_mgr_ops;
	link_data.max_delay = max_delay;
	link_data.subscribe_event = subscribe_event;

	for (i = 0; i < link_info->num_devices; i++) {
		dev = &link->l_dev[i];

		link_data.dev_hdl = dev->dev_hdl;
		/*
		 * For unique pipeline delay table create request
		 * tracking table
		 */
		if (link->pd_mask & (1 << dev->dev_info.p_delay)) {
			pd_tbl = __cam_req_mgr_find_pd_tbl(link->req.l_tbl,
				dev->dev_info.p_delay);
			if (!pd_tbl) {
				CAM_ERR(CAM_CRM, "pd %d tbl not found",
					dev->dev_info.p_delay);
				rc = -ENXIO;
				goto error;
			}
		} else {
			pd_tbl = __cam_req_mgr_create_pd_tbl(
				dev->dev_info.p_delay);
			if (pd_tbl == NULL) {
				CAM_ERR(CAM_CRM, "create new pd tbl failed");
				rc = -ENXIO;
				goto error;
			}
			pd_tbl->pd = dev->dev_info.p_delay;
			link->pd_mask |= (1 << pd_tbl->pd);
			/*
			 * Add table to list and also sort list
			 * from max pd to lowest
			 */
			__cam_req_mgr_add_tbl_to_link(&link->req.l_tbl, pd_tbl);
		}
		dev->dev_bit = pd_tbl->dev_count++;
		dev->pd_tbl = pd_tbl;
		pd_tbl->dev_mask |= (1 << dev->dev_bit);

		/* Communicate with dev to establish the link */
		dev->ops->link_setup(&link_data);

		if (link->max_delay < dev->dev_info.p_delay)
			link->max_delay = dev->dev_info.p_delay;
	}
	link->num_devs = link_info->num_devices;

	/* Assign id for pd tables */
	__cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req);

	/* At start, expect max pd devices, all are in skip state */
	__cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl);

	return 0;

error:
	__cam_req_mgr_destroy_link_info(link);
	return rc;
}

/* IOCTLs handling section */
int cam_req_mgr_create_session(
	struct cam_req_mgr_session_info *ses_info)
{
	int                              rc = 0;
	int32_t                          session_hdl;
	struct cam_req_mgr_core_session *cam_session = NULL;

	if (!ses_info) {
		CAM_DBG(CAM_CRM, "NULL session info pointer");
		return -EINVAL;
	}
	mutex_lock(&g_crm_core_dev->crm_lock);
	cam_session = (struct cam_req_mgr_core_session *)
		kzalloc(sizeof(*cam_session), GFP_KERNEL);
	if (!cam_session) {
		rc = -ENOMEM;
		goto end;
	}

	session_hdl = cam_create_session_hdl((void *)cam_session);
	if (session_hdl < 0) {
		CAM_ERR(CAM_CRM, "unable to create session_hdl = %x",
			session_hdl);
		rc = session_hdl;
		kfree(cam_session);
		goto end;
	}
	ses_info->session_hdl = session_hdl;

	mutex_init(&cam_session->lock);
	CAM_DBG(CAM_CRM, "LOCK_DBG session lock %pK", &cam_session->lock);

	mutex_lock(&cam_session->lock);
	cam_session->session_hdl = session_hdl;
	cam_session->num_links = 0;
	cam_session->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
	list_add(&cam_session->entry, &g_crm_core_dev->session_head);
	mutex_unlock(&cam_session->lock);
end:
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

/**
 * __cam_req_mgr_unlink()
 *
 * @brief : Unlink devices on a link structure from the session
 * @link  : Pointer to the link structure
 *
 * @return: 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link)
{
	int rc;

	mutex_lock(&link->lock);
	spin_lock_bh(&link->link_state_spin_lock);
	link->state = CAM_CRM_LINK_STATE_IDLE;

	/* Destroy timer of link */
	crm_timer_exit(&link->watchdog);
	spin_unlock_bh(&link->link_state_spin_lock);
	__cam_req_mgr_print_req_tbl(&link->req);

	/* Destroy workq payload data */
	kfree(link->workq->task.pool[0].payload);
	link->workq->task.pool[0].payload = NULL;

	/* Destroy workq of link */
	cam_req_mgr_workq_destroy(&link->workq);

	/* Cleanup request tables and unlink devices */
	rc = __cam_req_mgr_destroy_link_info(link);
	if (rc)
		CAM_ERR(CAM_CORE,
			"Unlink for all devices was not successful");

	/* Free memory holding data of linked devs */
	__cam_req_mgr_destroy_subdev(link->l_dev);

	/* Destroy the link handle */
	rc = cam_destroy_device_hdl(link->link_hdl);
	if (rc < 0) {
		CAM_ERR(CAM_CRM, "error while destroying dev handle %d %x",
			rc, link->link_hdl);
	}

	mutex_unlock(&link->lock);
	return rc;
}

int cam_req_mgr_destroy_session(
		struct cam_req_mgr_session_info *ses_info)
{
	int rc;
	int i;
	struct cam_req_mgr_core_session *cam_session = NULL;
	struct cam_req_mgr_core_link *link;

	if (!ses_info) {
		CAM_DBG(CAM_CRM, "NULL session info pointer");
		return -EINVAL;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(ses_info->session_hdl);
	if (!cam_session) {
		CAM_ERR(CAM_CRM, "failed to get session priv");
		rc = -ENOENT;
		goto end;

	}
	mutex_lock(&cam_session->lock);
	if (cam_session->num_links) {
		CAM_DBG(CAM_CRM, "destroy session %x num_active_links %d",
			ses_info->session_hdl,
			cam_session->num_links);

		for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
			link = cam_session->links[i];

			if (!link)
				continue;

			/* Ignore return value since session is going away */
			__cam_req_mgr_unlink(link);
			__cam_req_mgr_free_link(link);
		}
	}
	list_del(&cam_session->entry);
	mutex_unlock(&cam_session->lock);
	mutex_destroy(&cam_session->lock);
	kfree(cam_session);

	rc = cam_destroy_session_hdl(ses_info->session_hdl);
	if (rc < 0)
		CAM_ERR(CAM_CRM, "unable to destroy session_hdl = %x rc %d",
			ses_info->session_hdl, rc);

end:
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
{
	int                                     rc = 0;
	char                                    buf[128];
	struct cam_create_dev_hdl               root_dev;
	struct cam_req_mgr_core_session        *cam_session;
	struct cam_req_mgr_core_link           *link;

	if (!link_info) {
		CAM_DBG(CAM_CRM, "NULL pointer");
		return -EINVAL;
	}
	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) {
		CAM_ERR(CAM_CRM, "Invalid num devices %d",
			link_info->num_devices);
		return -EINVAL;
	}

	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(link_info->session_hdl);
	if (!cam_session) {
		CAM_DBG(CAM_CRM, "NULL pointer");
		return -EINVAL;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);

	/* Allocate link struct and map it with session's request queue */
	link = __cam_req_mgr_reserve_link(cam_session);
	if (!link) {
		CAM_ERR(CAM_CRM, "failed to reserve new link");
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}
	CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);

	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
	root_dev.session_hdl = link_info->session_hdl;
	root_dev.priv = (void *)link;

	mutex_lock(&link->lock);
	/* Create unique dev handle for link */
	link->link_hdl = cam_create_device_hdl(&root_dev);
	if (link->link_hdl < 0) {
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new device handle");
		rc = link->link_hdl;
		goto link_hdl_fail;
	}
	link_info->link_hdl = link->link_hdl;

	/* Allocate memory to hold data of all linked devs */
	rc = __cam_req_mgr_create_subdevs(&link->l_dev,
		link_info->num_devices);
	if (rc < 0) {
		CAM_ERR(CAM_CRM,
			"Insufficient memory to create new crm subdevs");
		goto create_subdev_failed;
	}

	/* Using device ops query connected devs, prepare request tables */
	rc = __cam_req_mgr_setup_link_info(link, link_info);
	if (rc < 0)
		goto setup_failed;

	spin_lock_bh(&link->link_state_spin_lock);
	link->state = CAM_CRM_LINK_STATE_READY;
	spin_unlock_bh(&link->link_state_spin_lock);

	/* Create worker for current link */
	snprintf(buf, sizeof(buf), "%x-%x",
		link_info->session_hdl, link->link_hdl);
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
		&link->workq, CRM_WORKQ_USAGE_NON_IRQ);
	if (rc < 0) {
		CAM_ERR(CAM_CRM, "FATAL: unable to create worker");
		__cam_req_mgr_destroy_link_info(link);
		goto setup_failed;
	}

	/* Assign payload to workqueue tasks */
	rc = __cam_req_mgr_setup_payload(link->workq);
	if (rc < 0) {
		__cam_req_mgr_destroy_link_info(link);
		cam_req_mgr_workq_destroy(&link->workq);
		goto setup_failed;
	}

	mutex_unlock(&link->lock);
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
setup_failed:
	__cam_req_mgr_destroy_subdev(link->l_dev);
create_subdev_failed:
	cam_destroy_device_hdl(link->link_hdl);
	link_info->link_hdl = 0;
link_hdl_fail:
	mutex_unlock(&link->lock);
	__cam_req_mgr_unreserve_link(cam_session, link);
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
{
	int                              rc = 0;
	struct cam_req_mgr_core_session *cam_session;
	struct cam_req_mgr_core_link    *link;

	if (!unlink_info) {
		CAM_ERR(CAM_CRM, "NULL pointer");
		return -EINVAL;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	CAM_DBG(CAM_CRM, "link_hdl %x", unlink_info->link_hdl);

	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(unlink_info->session_hdl);
	if (!cam_session) {
		CAM_ERR(CAM_CRM, "NULL pointer");
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}

	/* link hdl's priv data is core_link struct */
	link = cam_get_device_priv(unlink_info->link_hdl);
	if (!link) {
		CAM_ERR(CAM_CRM, "NULL pointer");
		rc = -EINVAL;
		goto done;
	}

	rc = __cam_req_mgr_unlink(link);

	/* Free curent link and put back into session's free pool of links */
	if (!rc)
		__cam_req_mgr_unreserve_link(cam_session, link);

done:
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_schedule_request(
			struct cam_req_mgr_sched_request *sched_req)
{
	int                               rc = 0;
	struct cam_req_mgr_core_link     *link = NULL;
	struct cam_req_mgr_core_session  *session = NULL;
	struct cam_req_mgr_sched_request *sched;
	struct crm_task_payload           task_data;

	if (!sched_req) {
		CAM_ERR(CAM_CRM, "csl_req is NULL");
		return -EINVAL;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(sched_req->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", sched_req->link_hdl);
		rc = -EINVAL;
		goto end;
	}

	session = (struct cam_req_mgr_core_session *)link->parent;
	if (!session) {
		CAM_WARN(CAM_CRM, "session ptr NULL %x", sched_req->link_hdl);
		rc = -EINVAL;
		goto end;
	}

	CAM_DBG(CAM_CRM, "link %x req %lld, sync_mode %d",
		sched_req->link_hdl, sched_req->req_id, sched_req->sync_mode);

	task_data.type = CRM_WORKQ_TASK_SCHED_REQ;
	sched = (struct cam_req_mgr_sched_request *)&task_data.u;
	sched->req_id = sched_req->req_id;
	sched->sync_mode = sched_req->sync_mode;
	sched->link_hdl = sched_req->link_hdl;
	if (session->force_err_recovery == AUTO_RECOVERY) {
		sched->bubble_enable = sched_req->bubble_enable;
	} else {
		sched->bubble_enable =
		(session->force_err_recovery == FORCE_ENABLE_RECOVERY) ? 1 : 0;
	}

	rc = cam_req_mgr_process_sched_req(link, &task_data);

	CAM_DBG(CAM_CRM, "DONE dev %x req %lld sync_mode %d",
		sched_req->link_hdl, sched_req->req_id, sched_req->sync_mode);
end:
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_sync_config(
	struct cam_req_mgr_sync_mode *sync_info)
{
	int                              rc = 0;
	struct cam_req_mgr_core_session *cam_session;
	struct cam_req_mgr_core_link    *link1 = NULL;
	struct cam_req_mgr_core_link    *link2 = NULL;

	if (!sync_info) {
		CAM_ERR(CAM_CRM, "NULL pointer");
		return -EINVAL;
	}

	if ((sync_info->num_links < 0) ||
		(sync_info->num_links > MAX_LINKS_PER_SESSION)) {
		CAM_ERR(CAM_CRM, "Invalid num links %d", sync_info->num_links);
		return -EINVAL;
	}

	if ((!sync_info->link_hdls[0]) || (!sync_info->link_hdls[1])) {
		CAM_WARN(CAM_CRM, "Invalid link handles 0x%x 0x%x",
			sync_info->link_hdls[0], sync_info->link_hdls[1]);
		return -EINVAL;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	/* session hdl's priv data is cam session struct */
	cam_session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(sync_info->session_hdl);
	if (!cam_session) {
		CAM_ERR(CAM_CRM, "NULL pointer");
		mutex_unlock(&g_crm_core_dev->crm_lock);
		return -EINVAL;
	}

	mutex_lock(&cam_session->lock);

	CAM_DBG(CAM_CRM, "link handles %x %x",
		sync_info->link_hdls[0], sync_info->link_hdls[1]);

	/* only two links existing per session in dual cam use case*/
	link1 = cam_get_device_priv(sync_info->link_hdls[0]);
	if (!link1) {
		CAM_ERR(CAM_CRM, "link1 NULL pointer");
		rc = -EINVAL;
		goto done;
	}

	link2 = cam_get_device_priv(sync_info->link_hdls[1]);
	if (!link2) {
		CAM_ERR(CAM_CRM, "link2 NULL pointer");
		rc = -EINVAL;
		goto done;
	}

	link1->sof_counter = -1;
	link1->sync_self_ref = -1;
	link1->frame_skip_flag = false;
	link1->sync_link_sof_skip = false;
	link1->sync_link = link2;

	link2->sof_counter = -1;
	link2->sync_self_ref = -1;
	link2->frame_skip_flag = false;
	link2->sync_link_sof_skip = false;
	link2->sync_link = link1;

	cam_session->sync_mode = sync_info->sync_mode;

done:
	mutex_unlock(&cam_session->lock);
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_flush_requests(
	struct cam_req_mgr_flush_info *flush_info)
{
	int                               rc = 0;
	struct crm_workq_task            *task = NULL;
	struct cam_req_mgr_core_link     *link = NULL;
	struct cam_req_mgr_flush_info    *flush;
	struct crm_task_payload          *task_data;
	struct cam_req_mgr_core_session  *session = NULL;

	if (!flush_info) {
		CAM_ERR(CAM_CRM, "flush req is NULL");
		rc = -EFAULT;
		goto end;
	}
	if (flush_info->flush_type >= CAM_REQ_MGR_FLUSH_TYPE_MAX) {
		CAM_ERR(CAM_CRM, "incorrect flush type %x",
			flush_info->flush_type);
		rc = -EINVAL;
		goto end;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	/* session hdl's priv data is cam session struct */
	session = (struct cam_req_mgr_core_session *)
		cam_get_device_priv(flush_info->session_hdl);
	if (!session) {
		CAM_ERR(CAM_CRM, "Invalid session %x", flush_info->session_hdl);
		rc = -EINVAL;
		goto end;
	}
	if (session->num_links <= 0) {
		CAM_WARN(CAM_CRM, "No active links in session %x",
		flush_info->session_hdl);
		goto end;
	}

	link = (struct cam_req_mgr_core_link *)
		cam_get_device_priv(flush_info->link_hdl);
	if (!link) {
		CAM_DBG(CAM_CRM, "link ptr NULL %x", flush_info->link_hdl);
		rc = -EINVAL;
		goto end;
	}

	task = cam_req_mgr_workq_get_task(link->workq);
	if (!task) {
		rc = -ENOMEM;
		goto end;
	}

	task_data = (struct crm_task_payload *)task->payload;
	task_data->type = CRM_WORKQ_TASK_FLUSH_REQ;
	flush = (struct cam_req_mgr_flush_info *)&task_data->u;
	flush->req_id = flush_info->req_id;
	flush->link_hdl = flush_info->link_hdl;
	flush->flush_type = flush_info->flush_type;
	task->process_cb = &cam_req_mgr_process_flush_req;
	init_completion(&link->workq_comp);
	rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0);

	/* Blocking call */
	rc = wait_for_completion_timeout(
		&link->workq_comp,
		msecs_to_jiffies(CAM_REQ_MGR_SCHED_REQ_TIMEOUT));
end:
	mutex_unlock(&g_crm_core_dev->crm_lock);
	return rc;
}

int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control)
{
	int                               rc = 0;
	int                               i, j;
	struct cam_req_mgr_core_link     *link = NULL;

	struct cam_req_mgr_connected_device *dev = NULL;
	struct cam_req_mgr_link_evt_data     evt_data;

	if (!control) {
		CAM_ERR(CAM_CRM, "Control command is NULL");
		rc = -EINVAL;
		goto end;
	}

	mutex_lock(&g_crm_core_dev->crm_lock);
	for (i = 0; i < control->num_links; i++) {
		link = (struct cam_req_mgr_core_link *)
			cam_get_device_priv(control->link_hdls[i]);
		if (!link) {
			CAM_ERR(CAM_CRM, "Link(%d) is NULL on session 0x%x",
				i, control->session_hdl);
			rc = -EINVAL;
			break;
		}

		mutex_lock(&link->lock);
		if (control->ops == CAM_REQ_MGR_LINK_ACTIVATE) {
			/* Start SOF watchdog timer */
			rc = crm_timer_init(&link->watchdog,
				CAM_REQ_MGR_WATCHDOG_TIMEOUT, link,
				&__cam_req_mgr_sof_freeze);
			if (rc < 0) {
				CAM_ERR(CAM_CRM,
					"SOF timer start fails: link=0x%x",
					link->link_hdl);
				rc = -EFAULT;
			}
			/* notify nodes */
			for (j = 0; j < link->num_devs; j++) {
				dev = &link->l_dev[j];
				evt_data.evt_type = CAM_REQ_MGR_LINK_EVT_RESUME;
				evt_data.link_hdl =  link->link_hdl;
				evt_data.dev_hdl = dev->dev_hdl;
				evt_data.req_id = 0;
				if (dev->ops && dev->ops->process_evt)
					dev->ops->process_evt(&evt_data);
			}
		} else if (control->ops == CAM_REQ_MGR_LINK_DEACTIVATE) {
			/* Destroy SOF watchdog timer */
			spin_lock_bh(&link->link_state_spin_lock);
			crm_timer_exit(&link->watchdog);
			spin_unlock_bh(&link->link_state_spin_lock);
			/* notify nodes */
			for (j = 0; j < link->num_devs; j++) {
				dev = &link->l_dev[j];
				evt_data.evt_type = CAM_REQ_MGR_LINK_EVT_PAUSE;
				evt_data.link_hdl =  link->link_hdl;
				evt_data.dev_hdl = dev->dev_hdl;
				evt_data.req_id = 0;
				if (dev->ops && dev->ops->process_evt)
					dev->ops->process_evt(&evt_data);
			}
		} else {
			CAM_ERR(CAM_CRM, "Invalid link control command");
			rc = -EINVAL;
		}
		mutex_unlock(&link->lock);
	}
	mutex_unlock(&g_crm_core_dev->crm_lock);
end:
	return rc;
}


int cam_req_mgr_core_device_init(void)
{
	CAM_DBG(CAM_CRM, "Enter g_crm_core_dev %pK", g_crm_core_dev);

	if (g_crm_core_dev) {
		CAM_WARN(CAM_CRM, "core device is already initialized");
		return 0;
	}
	g_crm_core_dev = (struct cam_req_mgr_core_device *)
		kzalloc(sizeof(*g_crm_core_dev), GFP_KERNEL);
	if (!g_crm_core_dev)
		return -ENOMEM;

	CAM_DBG(CAM_CRM, "g_crm_core_dev %pK", g_crm_core_dev);
	INIT_LIST_HEAD(&g_crm_core_dev->session_head);
	mutex_init(&g_crm_core_dev->crm_lock);
	cam_req_mgr_debug_register(g_crm_core_dev);

	return 0;
}

int cam_req_mgr_core_device_deinit(void)
{
	if (!g_crm_core_dev) {
		CAM_ERR(CAM_CRM, "NULL pointer");
		return -EINVAL;
	}

	CAM_DBG(CAM_CRM, "g_crm_core_dev %pK", g_crm_core_dev);
	mutex_destroy(&g_crm_core_dev->crm_lock);
	kfree(g_crm_core_dev);
	g_crm_core_dev = NULL;

	return 0;
}
