staging:ti dspbridge: remove DSP_SUCCEEDED macro from rmgr
[linux-2.6.git] / drivers / staging / tidspbridge / rmgr / mgr.c
blob57ae8077a7f46fea9694df7542542e5e7e36916a
1 /*
2 * mgr.c
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Implementation of Manager interface to the device object at the
7 * driver level. This queries the NDB data base and retrieves the
8 * data about Node and Processor.
10 * Copyright (C) 2005-2006 Texas Instruments, Inc.
12 * This package is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
16 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 #include <linux/types.h>
23 /* ----------------------------------- DSP/BIOS Bridge */
24 #include <dspbridge/dbdefs.h>
26 /* ----------------------------------- Trace & Debug */
27 #include <dspbridge/dbc.h>
29 /* ----------------------------------- OS Adaptation Layer */
30 #include <dspbridge/cfg.h>
31 #include <dspbridge/sync.h>
33 /* ----------------------------------- Others */
34 #include <dspbridge/dbdcd.h>
35 #include <dspbridge/drv.h>
36 #include <dspbridge/dev.h>
38 /* ----------------------------------- This */
39 #include <dspbridge/mgr.h>
41 /* ----------------------------------- Defines, Data Structures, Typedefs */
42 #define ZLDLLNAME ""
44 struct mgr_object {
45 struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */
48 /* ----------------------------------- Globals */
49 static u32 refs;
52 * ========= mgr_create =========
53 * Purpose:
54 * MGR Object gets created only once during driver Loading.
56 int mgr_create(struct mgr_object **mgr_obj,
57 struct cfg_devnode *dev_node_obj)
59 int status = 0;
60 struct mgr_object *pmgr_obj = NULL;
62 DBC_REQUIRE(mgr_obj != NULL);
63 DBC_REQUIRE(refs > 0);
65 pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
66 if (pmgr_obj) {
67 status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->hdcd_mgr);
68 if (!status) {
69 /* If succeeded store the handle in the MGR Object */
70 status = cfg_set_object((u32) pmgr_obj, REG_MGR_OBJECT);
71 if (!status) {
72 *mgr_obj = pmgr_obj;
73 } else {
74 dcd_destroy_manager(pmgr_obj->hdcd_mgr);
75 kfree(pmgr_obj);
77 } else {
78 /* failed to Create DCD Manager */
79 kfree(pmgr_obj);
81 } else {
82 status = -ENOMEM;
85 DBC_ENSURE(DSP_FAILED(status) || pmgr_obj);
86 return status;
90 * ========= mgr_destroy =========
91 * This function is invoked during bridge driver unloading.Frees MGR object.
93 int mgr_destroy(struct mgr_object *hmgr_obj)
95 int status = 0;
96 struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
98 DBC_REQUIRE(refs > 0);
99 DBC_REQUIRE(hmgr_obj);
101 /* Free resources */
102 if (hmgr_obj->hdcd_mgr)
103 dcd_destroy_manager(hmgr_obj->hdcd_mgr);
105 kfree(pmgr_obj);
106 /* Update the Registry with NULL for MGR Object */
107 (void)cfg_set_object(0, REG_MGR_OBJECT);
109 return status;
113 * ======== mgr_enum_node_info ========
114 * Enumerate and get configuration information about nodes configured
115 * in the node database.
117 int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
118 u32 undb_props_size, u32 *pu_num_nodes)
120 int status = 0;
121 struct dsp_uuid node_uuid, temp_uuid;
122 u32 temp_index = 0;
123 u32 node_index = 0;
124 struct dcd_genericobj gen_obj;
125 struct mgr_object *pmgr_obj = NULL;
127 DBC_REQUIRE(pndb_props != NULL);
128 DBC_REQUIRE(pu_num_nodes != NULL);
129 DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops));
130 DBC_REQUIRE(refs > 0);
132 *pu_num_nodes = 0;
133 /* Get The Manager Object from the Registry */
134 status = cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT);
135 if (DSP_FAILED(status))
136 goto func_cont;
138 DBC_ASSERT(pmgr_obj);
139 /* Forever loop till we hit failed or no more items in the
140 * Enumeration. We will exit the loop other than 0; */
141 while (status == 0) {
142 status = dcd_enumerate_object(temp_index++, DSP_DCDNODETYPE,
143 &temp_uuid);
144 if (status == 0) {
145 node_index++;
146 if (node_id == (node_index - 1))
147 node_uuid = temp_uuid;
151 if (!status) {
152 if (node_id > (node_index - 1)) {
153 status = -EINVAL;
154 } else {
155 status = dcd_get_object_def(pmgr_obj->hdcd_mgr,
156 (struct dsp_uuid *)
157 &node_uuid, DSP_DCDNODETYPE,
158 &gen_obj);
159 if (!status) {
160 /* Get the Obj def */
161 *pndb_props =
162 gen_obj.obj_data.node_obj.ndb_props;
163 *pu_num_nodes = node_index;
168 func_cont:
169 DBC_ENSURE((!status && *pu_num_nodes > 0) ||
170 (DSP_FAILED(status) && *pu_num_nodes == 0));
172 return status;
176 * ======== mgr_enum_processor_info ========
177 * Enumerate and get configuration information about available
178 * DSP processors.
180 int mgr_enum_processor_info(u32 processor_id,
181 struct dsp_processorinfo *
182 processor_info, u32 processor_info_size,
183 u8 *pu_num_procs)
185 int status = 0;
186 int status1 = 0;
187 int status2 = 0;
188 struct dsp_uuid temp_uuid;
189 u32 temp_index = 0;
190 u32 proc_index = 0;
191 struct dcd_genericobj gen_obj;
192 struct mgr_object *pmgr_obj = NULL;
193 struct mgr_processorextinfo *ext_info;
194 struct dev_object *hdev_obj;
195 struct drv_object *hdrv_obj;
196 u8 dev_type;
197 struct cfg_devnode *dev_node;
198 bool proc_detect = false;
200 DBC_REQUIRE(processor_info != NULL);
201 DBC_REQUIRE(pu_num_procs != NULL);
202 DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo));
203 DBC_REQUIRE(refs > 0);
205 *pu_num_procs = 0;
206 status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
207 if (!status) {
208 status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
209 if (!status) {
210 status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
211 status = dev_get_dev_node(hdev_obj, &dev_node);
212 if (dev_type != DSP_UNIT)
213 status = -EPERM;
215 if (!status)
216 processor_info->processor_type = DSPTYPE64;
219 if (DSP_FAILED(status))
220 goto func_end;
222 /* Get The Manager Object from the Registry */
223 if (DSP_FAILED(cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT))) {
224 dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
225 goto func_end;
227 DBC_ASSERT(pmgr_obj);
228 /* Forever loop till we hit no more items in the
229 * Enumeration. We will exit the loop other than 0; */
230 while (status1 == 0) {
231 status1 = dcd_enumerate_object(temp_index++,
232 DSP_DCDPROCESSORTYPE,
233 &temp_uuid);
234 if (status1 != 0)
235 break;
237 proc_index++;
238 /* Get the Object properties to find the Device/Processor
239 * Type */
240 if (proc_detect != false)
241 continue;
243 status2 = dcd_get_object_def(pmgr_obj->hdcd_mgr,
244 (struct dsp_uuid *)&temp_uuid,
245 DSP_DCDPROCESSORTYPE, &gen_obj);
246 if (!status2) {
247 /* Get the Obj def */
248 if (processor_info_size <
249 sizeof(struct mgr_processorextinfo)) {
250 *processor_info = gen_obj.obj_data.proc_info;
251 } else {
252 /* extended info */
253 ext_info = (struct mgr_processorextinfo *)
254 processor_info;
255 *ext_info = gen_obj.obj_data.ext_proc_obj;
257 dev_dbg(bridge, "%s: Got proctype from DCD %x\n",
258 __func__, processor_info->processor_type);
259 /* See if we got the needed processor */
260 if (dev_type == DSP_UNIT) {
261 if (processor_info->processor_type ==
262 DSPPROCTYPE_C64)
263 proc_detect = true;
264 } else if (dev_type == IVA_UNIT) {
265 if (processor_info->processor_type ==
266 IVAPROCTYPE_ARM7)
267 proc_detect = true;
269 /* User applciatiuons aonly check for chip type, so
270 * this clumsy overwrite */
271 processor_info->processor_type = DSPTYPE64;
272 } else {
273 dev_dbg(bridge, "%s: Failed to get DCD processor info "
274 "%x\n", __func__, status2);
275 status = -EPERM;
278 *pu_num_procs = proc_index;
279 if (proc_detect == false) {
280 dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
281 "CFG registry\n", __func__);
282 processor_info->processor_type = DSPTYPE64;
284 func_end:
285 return status;
289 * ======== mgr_exit ========
290 * Decrement reference count, and free resources when reference count is
291 * 0.
293 void mgr_exit(void)
295 DBC_REQUIRE(refs > 0);
296 refs--;
297 if (refs == 0)
298 dcd_exit();
300 DBC_ENSURE(refs >= 0);
304 * ======== mgr_get_dcd_handle ========
305 * Retrieves the MGR handle. Accessor Function.
307 int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
308 u32 *dcd_handle)
310 int status = -EPERM;
311 struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;
313 DBC_REQUIRE(refs > 0);
314 DBC_REQUIRE(dcd_handle != NULL);
316 *dcd_handle = (u32) NULL;
317 if (pmgr_obj) {
318 *dcd_handle = (u32) pmgr_obj->hdcd_mgr;
319 status = 0;
321 DBC_ENSURE((!status && *dcd_handle != (u32) NULL) ||
322 (DSP_FAILED(status) && *dcd_handle == (u32) NULL));
324 return status;
328 * ======== mgr_init ========
329 * Initialize MGR's private state, keeping a reference count on each call.
331 bool mgr_init(void)
333 bool ret = true;
334 bool init_dcd = false;
336 DBC_REQUIRE(refs >= 0);
338 if (refs == 0) {
339 init_dcd = dcd_init(); /* DCD Module */
341 if (!init_dcd)
342 ret = false;
345 if (ret)
346 refs++;
348 DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
350 return ret;
354 * ======== mgr_wait_for_bridge_events ========
355 * Block on any Bridge event(s)
357 int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
358 u32 count, u32 *pu_index,
359 u32 utimeout)
361 int status;
362 struct sync_object *sync_events[MAX_EVENTS];
363 u32 i;
365 DBC_REQUIRE(count < MAX_EVENTS);
367 for (i = 0; i < count; i++)
368 sync_events[i] = anotifications[i]->handle;
370 status = sync_wait_on_multiple_events(sync_events, count, utimeout,
371 pu_index);
373 return status;