1 /*
2  * dspdrv.c
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * Interface to allocate and free bridge resources.
7  *
8  * Copyright (C) 2005-2006 Texas Instruments, Inc.
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18 
19 /*  ----------------------------------- Host OS */
20 #include <linux/types.h>
21 #include <dspbridge/host_os.h>
22 
23 /*  ----------------------------------- DSP/BIOS Bridge */
24 #include <dspbridge/dbdefs.h>
25 
26 /*  ----------------------------------- Trace & Debug */
27 #include <dspbridge/dbc.h>
28 
29 /*  ----------------------------------- Platform Manager */
30 #include <dspbridge/drv.h>
31 #include <dspbridge/dev.h>
32 #include <dspbridge/dspapi.h>
33 
34 /*  ----------------------------------- Resource Manager */
35 #include <dspbridge/mgr.h>
36 
37 /*  ----------------------------------- This */
38 #include <dspbridge/dspdrv.h>
39 
40 /*
41  *  ======== dsp_init ========
42  *  	Allocates bridge resources. Loads a base image onto DSP, if specified.
43  */
dsp_init(u32 * init_status)44 u32 dsp_init(u32 *init_status)
45 {
46 	char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510";
47 	int status = -EPERM;
48 	struct drv_object *drv_obj = NULL;
49 	u32 device_node;
50 	u32 device_node_string;
51 
52 	if (!api_init())
53 		goto func_cont;
54 
55 	status = drv_create(&drv_obj);
56 	if (status) {
57 		api_exit();
58 		goto func_cont;
59 	}
60 
61 	/* End drv_create */
62 	/* Request Resources */
63 	status = drv_request_resources((u32) &dev_node, &device_node_string);
64 	if (!status) {
65 		/* Attempt to Start the Device */
66 		status = dev_start_device((struct cfg_devnode *)
67 					  device_node_string);
68 		if (status)
69 			(void)drv_release_resources
70 			    ((u32) device_node_string, drv_obj);
71 	} else {
72 		dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__);
73 		status = -EPERM;
74 	}
75 
76 	/* Unwind whatever was loaded */
77 	if (status) {
78 		/* irrespective of the status of dev_remove_device we conitinue
79 		 * unloading. Get the Driver Object iterate through and remove.
80 		 * Reset the status to E_FAIL to avoid going through
81 		 * api_init_complete2. */
82 		for (device_node = drv_get_first_dev_extension();
83 		     device_node != 0;
84 		     device_node = drv_get_next_dev_extension(device_node)) {
85 			(void)dev_remove_device((struct cfg_devnode *)
86 						device_node);
87 			(void)drv_release_resources((u32) device_node, drv_obj);
88 		}
89 		/* Remove the Driver Object */
90 		(void)drv_destroy(drv_obj);
91 		drv_obj = NULL;
92 		api_exit();
93 		dev_dbg(bridge, "%s: Logical device failed init\n", __func__);
94 	}			/* Unwinding the loaded drivers */
95 func_cont:
96 	/* Attempt to Start the Board */
97 	if (!status) {
98 		/* BRD_AutoStart could fail if the dsp execuetable is not the
99 		 * correct one. We should not propagate that error
100 		 * into the device loader. */
101 		(void)api_init_complete2();
102 	} else {
103 		dev_dbg(bridge, "%s: Failed\n", __func__);
104 	}			/* End api_init_complete2 */
105 	DBC_ENSURE((!status && drv_obj != NULL) ||
106 		   (status && drv_obj == NULL));
107 	*init_status = status;
108 	/* Return the Driver Object */
109 	return (u32) drv_obj;
110 }
111 
112 /*
113  *  ======== dsp_deinit ========
114  *  	Frees the resources allocated for bridge.
115  */
dsp_deinit(u32 device_context)116 bool dsp_deinit(u32 device_context)
117 {
118 	bool ret = true;
119 	u32 device_node;
120 	struct mgr_object *mgr_obj = NULL;
121 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
122 
123 	while ((device_node = drv_get_first_dev_extension()) != 0) {
124 		(void)dev_remove_device((struct cfg_devnode *)device_node);
125 
126 		(void)drv_release_resources((u32) device_node,
127 					(struct drv_object *)device_context);
128 	}
129 
130 	(void)drv_destroy((struct drv_object *)device_context);
131 
132 	/* Get the Manager Object from driver data
133 	 * MGR Destroy will unload the DCD dll */
134 	if (drv_datap && drv_datap->mgr_object) {
135 		mgr_obj = drv_datap->mgr_object;
136 		(void)mgr_destroy(mgr_obj);
137 	} else {
138 		pr_err("%s: Failed to retrieve the object handle\n", __func__);
139 	}
140 
141 	api_exit();
142 
143 	return ret;
144 }
145