/*
 * mgr.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Implementation of Manager interface to the device object at the
 * driver level. This queries the NDB data base and retrieves the
 * data about Node and Processor.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/types.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/sync.h>

/*  ----------------------------------- Others */
#include <dspbridge/dbdcd.h>
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>

/*  ----------------------------------- This */
#include <dspbridge/mgr.h>

/*  ----------------------------------- Defines, Data Structures, Typedefs */
#define ZLDLLNAME               ""

struct mgr_object {
	struct dcd_manager *dcd_mgr;	/* Proc/Node data manager */
};

/*  ----------------------------------- Globals */
static u32 refs;

/*
 *  ========= mgr_create =========
 *  Purpose:
 *      MGR Object gets created only once during driver Loading.
 */
int mgr_create(struct mgr_object **mgr_obj,
		      struct cfg_devnode *dev_node_obj)
{
	int status = 0;
	struct mgr_object *pmgr_obj = NULL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	DBC_REQUIRE(mgr_obj != NULL);
	DBC_REQUIRE(refs > 0);

	pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
	if (pmgr_obj) {
		status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->dcd_mgr);
		if (!status) {
			/* If succeeded store the handle in the MGR Object */
			if (drv_datap) {
				drv_datap->mgr_object = (void *)pmgr_obj;
			} else {
				status = -EPERM;
				pr_err("%s: Failed to store MGR object\n",
								__func__);
			}

			if (!status) {
				*mgr_obj = pmgr_obj;
			} else {
				dcd_destroy_manager(pmgr_obj->dcd_mgr);
				kfree(pmgr_obj);
			}
		} else {
			/* failed to Create DCD Manager */
			kfree(pmgr_obj);
		}
	} else {
		status = -ENOMEM;
	}

	DBC_ENSURE(status || pmgr_obj);
	return status;
}

/*
 *  ========= mgr_destroy =========
 *     This function is invoked during bridge driver unloading.Frees MGR object.
 */
int mgr_destroy(struct mgr_object *hmgr_obj)
{
	int status = 0;
	struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(hmgr_obj);

	/* Free resources */
	if (hmgr_obj->dcd_mgr)
		dcd_destroy_manager(hmgr_obj->dcd_mgr);

	kfree(pmgr_obj);
	/* Update the driver data with NULL for MGR Object */
	if (drv_datap) {
		drv_datap->mgr_object = NULL;
	} else {
		status = -EPERM;
		pr_err("%s: Failed to store MGR object\n", __func__);
	}

	return status;
}

/*
 *  ======== mgr_enum_node_info ========
 *      Enumerate and get configuration information about nodes configured
 *      in the node database.
 */
int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
			      u32 undb_props_size, u32 *pu_num_nodes)
{
	int status = 0;
	struct dsp_uuid node_uuid;
	u32 node_index = 0;
	struct dcd_genericobj gen_obj;
	struct mgr_object *pmgr_obj = NULL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	DBC_REQUIRE(pndb_props != NULL);
	DBC_REQUIRE(pu_num_nodes != NULL);
	DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops));
	DBC_REQUIRE(refs > 0);

	*pu_num_nodes = 0;
	/* Get the Manager Object from the driver data */
	if (!drv_datap || !drv_datap->mgr_object) {
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
		return -ENODATA;
	}
	pmgr_obj = drv_datap->mgr_object;

	DBC_ASSERT(pmgr_obj);
	/* Forever loop till we hit failed or no more items in the
	 * Enumeration. We will exit the loop other than 0; */
	while (!status) {
		status = dcd_enumerate_object(node_index++, DSP_DCDNODETYPE,
				&node_uuid);
		if (status)
			break;
		*pu_num_nodes = node_index;
		if (node_id == (node_index - 1)) {
			status = dcd_get_object_def(pmgr_obj->dcd_mgr,
					&node_uuid, DSP_DCDNODETYPE, &gen_obj);
			if (status)
				break;
			/* Get the Obj def */
			*pndb_props = gen_obj.obj_data.node_obj.ndb_props;
		}
	}

	/* the last status is not 0, but neither an error */
	if (status > 0)
		status = 0;

	return status;
}

/*
 *  ======== mgr_enum_processor_info ========
 *      Enumerate and get configuration information about available
 *      DSP processors.
 */
int mgr_enum_processor_info(u32 processor_id,
				   struct dsp_processorinfo *
				   processor_info, u32 processor_info_size,
				   u8 *pu_num_procs)
{
	int status = 0;
	int status1 = 0;
	int status2 = 0;
	struct dsp_uuid temp_uuid;
	u32 temp_index = 0;
	u32 proc_index = 0;
	struct dcd_genericobj gen_obj;
	struct mgr_object *pmgr_obj = NULL;
	struct mgr_processorextinfo *ext_info;
	struct dev_object *hdev_obj;
	struct drv_object *hdrv_obj;
	u8 dev_type;
	struct cfg_devnode *dev_node;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	bool proc_detect = false;

	DBC_REQUIRE(processor_info != NULL);
	DBC_REQUIRE(pu_num_procs != NULL);
	DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo));
	DBC_REQUIRE(refs > 0);

	*pu_num_procs = 0;

	/* Retrieve the Object handle from the driver data */
	if (!drv_datap || !drv_datap->drv_object) {
		status = -ENODATA;
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	} else {
		hdrv_obj = drv_datap->drv_object;
	}

	if (!status) {
		status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
		if (!status) {
			status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
			status = dev_get_dev_node(hdev_obj, &dev_node);
			if (dev_type != DSP_UNIT)
				status = -EPERM;

			if (!status)
				processor_info->processor_type = DSPTYPE64;
		}
	}
	if (status)
		goto func_end;

	/* Get The Manager Object from the driver data */
	if (drv_datap && drv_datap->mgr_object) {
		pmgr_obj = drv_datap->mgr_object;
	} else {
		dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
		goto func_end;
	}
	DBC_ASSERT(pmgr_obj);
	/* Forever loop till we hit no more items in the
	 * Enumeration. We will exit the loop other than 0; */
	while (status1 == 0) {
		status1 = dcd_enumerate_object(temp_index++,
					       DSP_DCDPROCESSORTYPE,
					       &temp_uuid);
		if (status1 != 0)
			break;

		proc_index++;
		/* Get the Object properties to find the Device/Processor
		 * Type */
		if (proc_detect != false)
			continue;

		status2 = dcd_get_object_def(pmgr_obj->dcd_mgr,
					     (struct dsp_uuid *)&temp_uuid,
					     DSP_DCDPROCESSORTYPE, &gen_obj);
		if (!status2) {
			/* Get the Obj def */
			if (processor_info_size <
			    sizeof(struct mgr_processorextinfo)) {
				*processor_info = gen_obj.obj_data.proc_info;
			} else {
				/* extended info */
				ext_info = (struct mgr_processorextinfo *)
				    processor_info;
				*ext_info = gen_obj.obj_data.ext_proc_obj;
			}
			dev_dbg(bridge, "%s: Got proctype  from DCD %x\n",
				__func__, processor_info->processor_type);
			/* See if we got the needed processor */
			if (dev_type == DSP_UNIT) {
				if (processor_info->processor_type ==
				    DSPPROCTYPE_C64)
					proc_detect = true;
			} else if (dev_type == IVA_UNIT) {
				if (processor_info->processor_type ==
				    IVAPROCTYPE_ARM7)
					proc_detect = true;
			}
			/* User applciatiuons aonly check for chip type, so
			 * this clumsy overwrite */
			processor_info->processor_type = DSPTYPE64;
		} else {
			dev_dbg(bridge, "%s: Failed to get DCD processor info "
				"%x\n", __func__, status2);
			status = -EPERM;
		}
	}
	*pu_num_procs = proc_index;
	if (proc_detect == false) {
		dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
			"CFG registry\n", __func__);
		processor_info->processor_type = DSPTYPE64;
	}
func_end:
	return status;
}

/*
 *  ======== mgr_exit ========
 *      Decrement reference count, and free resources when reference count is
 *      0.
 */
void mgr_exit(void)
{
	DBC_REQUIRE(refs > 0);
	refs--;
	if (refs == 0)
		dcd_exit();

	DBC_ENSURE(refs >= 0);
}

/*
 *  ======== mgr_get_dcd_handle ========
 *      Retrieves the MGR handle. Accessor Function.
 */
int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
			      u32 *dcd_handle)
{
	int status = -EPERM;
	struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(dcd_handle != NULL);

	*dcd_handle = (u32) NULL;
	if (pmgr_obj) {
		*dcd_handle = (u32) pmgr_obj->dcd_mgr;
		status = 0;
	}
	DBC_ENSURE((!status && *dcd_handle != (u32) NULL) ||
		   (status && *dcd_handle == (u32) NULL));

	return status;
}

/*
 *  ======== mgr_init ========
 *      Initialize MGR's private state, keeping a reference count on each call.
 */
bool mgr_init(void)
{
	bool ret = true;
	bool init_dcd = false;

	DBC_REQUIRE(refs >= 0);

	if (refs == 0) {
		init_dcd = dcd_init();	/*  DCD Module */

		if (!init_dcd)
			ret = false;
	}

	if (ret)
		refs++;

	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));

	return ret;
}

/*
 *  ======== mgr_wait_for_bridge_events ========
 *      Block on any Bridge event(s)
 */
int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
				      u32 count, u32 *pu_index,
				      u32 utimeout)
{
	int status;
	struct sync_object *sync_events[MAX_EVENTS];
	u32 i;

	DBC_REQUIRE(count < MAX_EVENTS);

	for (i = 0; i < count; i++)
		sync_events[i] = anotifications[i]->handle;

	status = sync_wait_on_multiple_events(sync_events, count, utimeout,
					      pu_index);

	return status;

}
