staging: ti dspbridge: Rename words with camel case.
[linux-2.6/x86.git] / drivers / staging / tidspbridge / rmgr / mgr.c
blob43be6693d7293430573f4153fa7d8780f3ab0aa0
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 /* ----------------------------------- DSP/BIOS Bridge */
22 #include <dspbridge/std.h>
23 #include <dspbridge/dbdefs.h>
25 /* ----------------------------------- Trace & Debug */
26 #include <dspbridge/dbc.h>
28 /* ----------------------------------- OS Adaptation Layer */
29 #include <dspbridge/cfg.h>
30 #include <dspbridge/sync.h>
32 /* ----------------------------------- Others */
33 #include <dspbridge/dbdcd.h>
34 #include <dspbridge/drv.h>
35 #include <dspbridge/dev.h>
37 /* ----------------------------------- This */
38 #include <dspbridge/mgr.h>
40 /* ----------------------------------- Defines, Data Structures, Typedefs */
41 #define ZLDLLNAME ""
43 struct mgr_object {
44 struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */
47 /* ----------------------------------- Globals */
48 static u32 refs;
51 * ========= mgr_create =========
52 * Purpose:
53 * MGR Object gets created only once during driver Loading.
55 int mgr_create(OUT struct mgr_object **phMgrObject,
56 struct cfg_devnode *dev_node_obj)
58 int status = 0;
59 struct mgr_object *pmgr_obj = NULL;
61 DBC_REQUIRE(phMgrObject != NULL);
62 DBC_REQUIRE(refs > 0);
64 pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
65 if (pmgr_obj) {
66 status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->hdcd_mgr);
67 if (DSP_SUCCEEDED(status)) {
68 /* If succeeded store the handle in the MGR Object */
69 status = cfg_set_object((u32) pmgr_obj, REG_MGR_OBJECT);
70 if (DSP_SUCCEEDED(status)) {
71 *phMgrObject = pmgr_obj;
72 } else {
73 dcd_destroy_manager(pmgr_obj->hdcd_mgr);
74 kfree(pmgr_obj);
76 } else {
77 /* failed to Create DCD Manager */
78 kfree(pmgr_obj);
80 } else {
81 status = -ENOMEM;
84 DBC_ENSURE(DSP_FAILED(status) || pmgr_obj);
85 return status;
89 * ========= mgr_destroy =========
90 * This function is invoked during bridge driver unloading.Frees MGR object.
92 int mgr_destroy(struct mgr_object *hmgr_obj)
94 int status = 0;
95 struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
97 DBC_REQUIRE(refs > 0);
98 DBC_REQUIRE(hmgr_obj);
100 /* Free resources */
101 if (hmgr_obj->hdcd_mgr)
102 dcd_destroy_manager(hmgr_obj->hdcd_mgr);
104 kfree(pmgr_obj);
105 /* Update the Registry with NULL for MGR Object */
106 (void)cfg_set_object(0, REG_MGR_OBJECT);
108 return status;
112 * ======== mgr_enum_node_info ========
113 * Enumerate and get configuration information about nodes configured
114 * in the node database.
116 int mgr_enum_node_info(u32 node_id, OUT struct dsp_ndbprops *pndb_props,
117 u32 undb_props_size, OUT u32 *pu_num_nodes)
119 int status = 0;
120 struct dsp_uuid node_uuid, temp_uuid;
121 u32 temp_index = 0;
122 u32 node_index = 0;
123 struct dcd_genericobj gen_obj;
124 struct mgr_object *pmgr_obj = NULL;
126 DBC_REQUIRE(pndb_props != NULL);
127 DBC_REQUIRE(pu_num_nodes != NULL);
128 DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops));
129 DBC_REQUIRE(refs > 0);
131 *pu_num_nodes = 0;
132 /* Get The Manager Object from the Registry */
133 status = cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT);
134 if (DSP_FAILED(status))
135 goto func_cont;
137 DBC_ASSERT(pmgr_obj);
138 /* Forever loop till we hit failed or no more items in the
139 * Enumeration. We will exit the loop other than 0; */
140 while (status == 0) {
141 status = dcd_enumerate_object(temp_index++, DSP_DCDNODETYPE,
142 &temp_uuid);
143 if (status == 0) {
144 node_index++;
145 if (node_id == (node_index - 1))
146 node_uuid = temp_uuid;
150 if (DSP_SUCCEEDED(status)) {
151 if (node_id > (node_index - 1)) {
152 status = -EINVAL;
153 } else {
154 status = dcd_get_object_def(pmgr_obj->hdcd_mgr,
155 (struct dsp_uuid *)
156 &node_uuid, DSP_DCDNODETYPE,
157 &gen_obj);
158 if (DSP_SUCCEEDED(status)) {
159 /* Get the Obj def */
160 *pndb_props =
161 gen_obj.obj_data.node_obj.ndb_props;
162 *pu_num_nodes = node_index;
167 func_cont:
168 DBC_ENSURE((DSP_SUCCEEDED(status) && *pu_num_nodes > 0) ||
169 (DSP_FAILED(status) && *pu_num_nodes == 0));
171 return status;
175 * ======== mgr_enum_processor_info ========
176 * Enumerate and get configuration information about available
177 * DSP processors.
179 int mgr_enum_processor_info(u32 processor_id,
180 OUT struct dsp_processorinfo *
181 processor_info, u32 processor_info_size,
182 OUT u8 *pu_num_procs)
184 int status = 0;
185 int status1 = 0;
186 int status2 = 0;
187 struct dsp_uuid temp_uuid;
188 u32 temp_index = 0;
189 u32 proc_index = 0;
190 struct dcd_genericobj gen_obj;
191 struct mgr_object *pmgr_obj = NULL;
192 struct mgr_processorextinfo *ext_info;
193 struct dev_object *hdev_obj;
194 struct drv_object *hdrv_obj;
195 u8 dev_type;
196 struct cfg_devnode *dev_node;
197 bool proc_detect = false;
199 DBC_REQUIRE(processor_info != NULL);
200 DBC_REQUIRE(pu_num_procs != NULL);
201 DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo));
202 DBC_REQUIRE(refs > 0);
204 *pu_num_procs = 0;
205 status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
206 if (DSP_SUCCEEDED(status)) {
207 status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
208 if (DSP_SUCCEEDED(status)) {
209 status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
210 status = dev_get_dev_node(hdev_obj, &dev_node);
211 if (dev_type != DSP_UNIT)
212 status = -EPERM;
214 if (DSP_SUCCEEDED(status))
215 processor_info->processor_type = DSPTYPE64;
218 if (DSP_FAILED(status))
219 goto func_end;
221 /* Get The Manager Object from the Registry */
222 if (DSP_FAILED(cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT))) {
223 dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
224 goto func_end;
226 DBC_ASSERT(pmgr_obj);
227 /* Forever loop till we hit no more items in the
228 * Enumeration. We will exit the loop other than 0; */
229 while (status1 == 0) {
230 status1 = dcd_enumerate_object(temp_index++,
231 DSP_DCDPROCESSORTYPE,
232 &temp_uuid);
233 if (status1 != 0)
234 break;
236 proc_index++;
237 /* Get the Object properties to find the Device/Processor
238 * Type */
239 if (proc_detect != false)
240 continue;
242 status2 = dcd_get_object_def(pmgr_obj->hdcd_mgr,
243 (struct dsp_uuid *)&temp_uuid,
244 DSP_DCDPROCESSORTYPE, &gen_obj);
245 if (DSP_SUCCEEDED(status2)) {
246 /* Get the Obj def */
247 if (processor_info_size <
248 sizeof(struct mgr_processorextinfo)) {
249 *processor_info = gen_obj.obj_data.proc_info;
250 } else {
251 /* extended info */
252 ext_info = (struct mgr_processorextinfo *)
253 processor_info;
254 *ext_info = gen_obj.obj_data.ext_proc_obj;
256 dev_dbg(bridge, "%s: Got proctype from DCD %x\n",
257 __func__, processor_info->processor_type);
258 /* See if we got the needed processor */
259 if (dev_type == DSP_UNIT) {
260 if (processor_info->processor_type ==
261 DSPPROCTYPE_C64)
262 proc_detect = true;
263 } else if (dev_type == IVA_UNIT) {
264 if (processor_info->processor_type ==
265 IVAPROCTYPE_ARM7)
266 proc_detect = true;
268 /* User applciatiuons aonly check for chip type, so
269 * this clumsy overwrite */
270 processor_info->processor_type = DSPTYPE64;
271 } else {
272 dev_dbg(bridge, "%s: Failed to get DCD processor info "
273 "%x\n", __func__, status2);
274 status = -EPERM;
277 *pu_num_procs = proc_index;
278 if (proc_detect == false) {
279 dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
280 "CFG registry\n", __func__);
281 processor_info->processor_type = DSPTYPE64;
283 func_end:
284 return status;
288 * ======== mgr_exit ========
289 * Decrement reference count, and free resources when reference count is
290 * 0.
292 void mgr_exit(void)
294 DBC_REQUIRE(refs > 0);
295 refs--;
296 if (refs == 0)
297 dcd_exit();
299 DBC_ENSURE(refs >= 0);
303 * ======== mgr_get_dcd_handle ========
304 * Retrieves the MGR handle. Accessor Function.
306 int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
307 OUT u32 *dcd_handle)
309 int status = -EPERM;
310 struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;
312 DBC_REQUIRE(refs > 0);
313 DBC_REQUIRE(dcd_handle != NULL);
315 *dcd_handle = (u32) NULL;
316 if (pmgr_obj) {
317 *dcd_handle = (u32) pmgr_obj->hdcd_mgr;
318 status = 0;
320 DBC_ENSURE((DSP_SUCCEEDED(status) && *dcd_handle != (u32) NULL) ||
321 (DSP_FAILED(status) && *dcd_handle == (u32) NULL));
323 return status;
327 * ======== mgr_init ========
328 * Initialize MGR's private state, keeping a reference count on each call.
330 bool mgr_init(void)
332 bool ret = true;
333 bool init_dcd = false;
335 DBC_REQUIRE(refs >= 0);
337 if (refs == 0) {
338 init_dcd = dcd_init(); /* DCD Module */
340 if (!init_dcd)
341 ret = false;
344 if (ret)
345 refs++;
347 DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
349 return ret;
353 * ======== mgr_wait_for_bridge_events ========
354 * Block on any Bridge event(s)
356 int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
357 u32 count, OUT u32 *pu_index,
358 u32 utimeout)
360 int status;
361 struct sync_object *sync_events[MAX_EVENTS];
362 u32 i;
364 DBC_REQUIRE(count < MAX_EVENTS);
366 for (i = 0; i < count; i++)
367 sync_events[i] = anotifications[i]->handle;
369 status = sync_wait_on_multiple_events(sync_events, count, utimeout,
370 pu_index);
372 return status;