/* * 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> /* ----------------------------------- 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 continue * 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 executable 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 */ *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; }