/*
 * dspdrv.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Interface to allocate and free bridge resources.
 *
 * 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.
 */

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

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

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

/*  ----------------------------------- Platform Manager */
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>
#include <dspbridge/dspapi.h>

/*  ----------------------------------- Resource Manager */
#include <dspbridge/mgr.h>

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

/*
 *  ======== dsp_init ========
 *  	Allocates bridge resources. Loads a base image onto DSP, if specified.
 */
u32 dsp_init(u32 *init_status)
{
	char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510";
	int status = -EPERM;
	struct drv_object *drv_obj = NULL;
	u32 device_node;
	u32 device_node_string;

	if (!api_init())
		goto func_cont;

	status = drv_create(&drv_obj);
	if (status) {
		api_exit();
		goto func_cont;
	}

	/* End drv_create */
	/* Request Resources */
	status = drv_request_resources((u32) &dev_node, &device_node_string);
	if (!status) {
		/* Attempt to Start the Device */
		status = dev_start_device((struct cfg_devnode *)
					  device_node_string);
		if (status)
			(void)drv_release_resources
			    ((u32) device_node_string, drv_obj);
	} else {
		dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__);
		status = -EPERM;
	}

	/* Unwind whatever was loaded */
	if (status) {
		/* irrespective of the status of dev_remove_device we conitinue
		 * unloading. Get the Driver Object iterate through and remove.
		 * Reset the status to E_FAIL to avoid going through
		 * api_init_complete2. */
		for (device_node = drv_get_first_dev_extension();
		     device_node != 0;
		     device_node = drv_get_next_dev_extension(device_node)) {
			(void)dev_remove_device((struct cfg_devnode *)
						device_node);
			(void)drv_release_resources((u32) device_node, drv_obj);
		}
		/* Remove the Driver Object */
		(void)drv_destroy(drv_obj);
		drv_obj = NULL;
		api_exit();
		dev_dbg(bridge, "%s: Logical device failed init\n", __func__);
	}			/* Unwinding the loaded drivers */
func_cont:
	/* Attempt to Start the Board */
	if (!status) {
		/* BRD_AutoStart could fail if the dsp execuetable is not the
		 * correct one. We should not propagate that error
		 * into the device loader. */
		(void)api_init_complete2();
	} else {
		dev_dbg(bridge, "%s: Failed\n", __func__);
	}			/* End api_init_complete2 */
	DBC_ENSURE((!status && drv_obj != NULL) ||
		   (status && drv_obj == NULL));
	*init_status = status;
	/* Return the Driver Object */
	return (u32) drv_obj;
}

/*
 *  ======== dsp_deinit ========
 *  	Frees the resources allocated for bridge.
 */
bool dsp_deinit(u32 device_context)
{
	bool ret = true;
	u32 device_node;
	struct mgr_object *mgr_obj = NULL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	while ((device_node = drv_get_first_dev_extension()) != 0) {
		(void)dev_remove_device((struct cfg_devnode *)device_node);

		(void)drv_release_resources((u32) device_node,
					(struct drv_object *)device_context);
	}

	(void)drv_destroy((struct drv_object *)device_context);

	/* Get the Manager Object from driver data
	 * MGR Destroy will unload the DCD dll */
	if (drv_datap && drv_datap->mgr_object) {
		mgr_obj = drv_datap->mgr_object;
		(void)mgr_destroy(mgr_obj);
	} else {
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	}

	api_exit();

	return ret;
}
