staging: tidspbridge: remove cmm_init() and cmm_exit()
[deliverable/linux.git] / drivers / staging / tidspbridge / pmgr / dev.c
CommitLineData
c4ca3d5a
ORL
1/*
2 * dev.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Implementation of Bridge Bridge driver device operations.
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 */
2094f12d 18#include <linux/types.h>
5fb45dac 19#include <linux/list.h>
c4ca3d5a
ORL
20
21/* ----------------------------------- Host OS */
22#include <dspbridge/host_os.h>
23
24/* ----------------------------------- DSP/BIOS Bridge */
c4ca3d5a
ORL
25#include <dspbridge/dbdefs.h>
26
c4ca3d5a
ORL
27/* ----------------------------------- Platform Manager */
28#include <dspbridge/cod.h>
29#include <dspbridge/drv.h>
30#include <dspbridge/proc.h>
677f2ded 31#include <dspbridge/dmm.h>
c4ca3d5a
ORL
32
33/* ----------------------------------- Resource Manager */
34#include <dspbridge/mgr.h>
35#include <dspbridge/node.h>
36
37/* ----------------------------------- Others */
38#include <dspbridge/dspapi.h> /* DSP API version info. */
39
40#include <dspbridge/chnl.h>
41#include <dspbridge/io.h>
42#include <dspbridge/msg.h>
43#include <dspbridge/cmm.h>
61a5b769 44#include <dspbridge/dspdeh.h>
c4ca3d5a
ORL
45
46/* ----------------------------------- This */
47#include <dspbridge/dev.h>
48
49/* ----------------------------------- Defines, Data Structures, Typedefs */
50
51#define MAKEVERSION(major, minor) (major * 10 + minor)
52#define BRD_API_VERSION MAKEVERSION(BRD_API_MAJOR_VERSION, \
53 BRD_API_MINOR_VERSION)
54
55/* The Bridge device object: */
56struct dev_object {
c4ca3d5a
ORL
57 struct list_head link; /* Link to next dev_object. */
58 u8 dev_type; /* Device Type */
59 struct cfg_devnode *dev_node_obj; /* Platform specific dev id */
60 /* Bridge Context Handle */
085467b8 61 struct bridge_dev_context *bridge_context;
c4ca3d5a
ORL
62 /* Function interface to Bridge driver. */
63 struct bridge_drv_interface bridge_interface;
64 struct brd_object *lock_owner; /* Client with exclusive access. */
65 struct cod_manager *cod_mgr; /* Code manager handle. */
085467b8
RS
66 struct chnl_mgr *chnl_mgr; /* Channel manager. */
67 struct deh_mgr *deh_mgr; /* DEH manager. */
68 struct msg_mgr *msg_mgr; /* Message manager. */
121e8f9b 69 struct io_mgr *iomgr; /* IO manager (CHNL, msg_ctrl) */
085467b8 70 struct cmm_object *cmm_mgr; /* SM memory manager. */
677f2ded 71 struct dmm_object *dmm_mgr; /* Dynamic memory manager. */
c4ca3d5a 72 u32 word_size; /* DSP word size: quick access. */
085467b8 73 struct drv_object *drv_obj; /* Driver Object */
ba44df6f
IN
74 /* List of Processors attached to this device */
75 struct list_head proc_list;
085467b8 76 struct node_mgr *node_mgr;
c4ca3d5a
ORL
77};
78
e8184e6c
IGC
79struct drv_ext {
80 struct list_head link;
81 char sz_string[MAXREGPATHLENGTH];
82};
83
c4ca3d5a
ORL
84/* ----------------------------------- Globals */
85static u32 refs; /* Module reference count */
86
87/* ----------------------------------- Function Prototypes */
88static int fxn_not_implemented(int arg, ...);
89static int init_cod_mgr(struct dev_object *dev_obj);
90static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
e6bf74f0 91 struct bridge_drv_interface *intf_fxns);
c4ca3d5a
ORL
92/*
93 * ======== dev_brd_write_fxn ========
94 * Purpose:
95 * Exported function to be used as the COD write function. This function
96 * is passed a handle to a DEV_hObject, then calls the
97 * device's bridge_brd_write() function.
98 */
5e2eae57 99u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf,
95870a88 100 u32 ul_num_bytes, u32 mem_space)
c4ca3d5a 101{
aa09b091 102 struct dev_object *dev_obj = (struct dev_object *)arb;
c4ca3d5a
ORL
103 u32 ul_written = 0;
104 int status;
105
c4ca3d5a
ORL
106 if (dev_obj) {
107 /* Require of BrdWrite() */
e17ba7f2 108 status = (*dev_obj->bridge_interface.brd_write) (
085467b8 109 dev_obj->bridge_context, host_buf,
5e2eae57 110 dsp_add, ul_num_bytes, mem_space);
c4ca3d5a
ORL
111 /* Special case of getting the address only */
112 if (ul_num_bytes == 0)
113 ul_num_bytes = 1;
157990f0 114 if (!status)
c4ca3d5a
ORL
115 ul_written = ul_num_bytes;
116
117 }
118 return ul_written;
119}
120
121/*
122 * ======== dev_create_device ========
123 * Purpose:
124 * Called by the operating system to load the PM Bridge Driver for a
125 * PM board (device).
126 */
e6bf74f0 127int dev_create_device(struct dev_object **device_obj,
9d7d0a52 128 const char *driver_file_name,
c4ca3d5a
ORL
129 struct cfg_devnode *dev_node_obj)
130{
131 struct cfg_hostres *host_res;
c4ca3d5a
ORL
132 struct bridge_drv_interface *drv_fxns = NULL;
133 struct dev_object *dev_obj = NULL;
134 struct chnl_mgrattrs mgr_attrs;
135 struct io_attrs io_mgr_attrs;
136 u32 num_windows;
137 struct drv_object *hdrv_obj = NULL;
73b87a91 138 struct drv_data *drv_datap = dev_get_drvdata(bridge);
c4ca3d5a 139 int status = 0;
c4ca3d5a
ORL
140
141 status = drv_request_bridge_res_dsp((void *)&host_res);
142
51d5e099 143 if (status) {
c4ca3d5a
ORL
144 dev_dbg(bridge, "%s: Failed to reserve bridge resources\n",
145 __func__);
146 goto leave;
147 }
148
149 /* Get the Bridge driver interface functions */
150 bridge_drv_entry(&drv_fxns, driver_file_name);
73b87a91
IGC
151
152 /* Retrieve the Object handle from the driver data */
153 if (drv_datap && drv_datap->drv_object) {
154 hdrv_obj = drv_datap->drv_object;
155 } else {
c4ca3d5a 156 status = -EPERM;
73b87a91 157 pr_err("%s: Failed to retrieve the object handle\n", __func__);
c4ca3d5a 158 }
73b87a91 159
c4ca3d5a
ORL
160 /* Create the device object, and pass a handle to the Bridge driver for
161 * storage. */
157990f0 162 if (!status) {
c4ca3d5a
ORL
163 dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL);
164 if (dev_obj) {
165 /* Fill out the rest of the Dev Object structure: */
166 dev_obj->dev_node_obj = dev_node_obj;
c4ca3d5a 167 dev_obj->cod_mgr = NULL;
085467b8
RS
168 dev_obj->chnl_mgr = NULL;
169 dev_obj->deh_mgr = NULL;
c4ca3d5a
ORL
170 dev_obj->lock_owner = NULL;
171 dev_obj->word_size = DSPWORDSIZE;
085467b8 172 dev_obj->drv_obj = hdrv_obj;
c4ca3d5a
ORL
173 dev_obj->dev_type = DSP_UNIT;
174 /* Store this Bridge's interface functions, based on its
175 * version. */
176 store_interface_fxns(drv_fxns,
177 &dev_obj->bridge_interface);
178
179 /* Call fxn_dev_create() to get the Bridge's device
180 * context handle. */
09f13304 181 status = (dev_obj->bridge_interface.dev_create)
085467b8 182 (&dev_obj->bridge_context, dev_obj,
c4ca3d5a 183 host_res);
c4ca3d5a
ORL
184 } else {
185 status = -ENOMEM;
186 }
187 }
188 /* Attempt to create the COD manager for this device: */
157990f0 189 if (!status)
c4ca3d5a
ORL
190 status = init_cod_mgr(dev_obj);
191
192 /* Attempt to create the channel manager for this device: */
157990f0 193 if (!status) {
c4ca3d5a
ORL
194 mgr_attrs.max_channels = CHNL_MAXCHANNELS;
195 io_mgr_attrs.birq = host_res->birq_registers;
196 io_mgr_attrs.irq_shared =
197 (host_res->birq_attrib & CFG_IRQSHARED);
198 io_mgr_attrs.word_size = DSPWORDSIZE;
199 mgr_attrs.word_size = DSPWORDSIZE;
200 num_windows = host_res->num_mem_windows;
201 if (num_windows) {
202 /* Assume last memory window is for CHNL */
5108de0a
RS
203 io_mgr_attrs.shm_base = host_res->mem_base[1] +
204 host_res->offset_for_monitor;
a534f17b 205 io_mgr_attrs.sm_length =
5108de0a
RS
206 host_res->mem_length[1] -
207 host_res->offset_for_monitor;
c4ca3d5a
ORL
208 } else {
209 io_mgr_attrs.shm_base = 0;
a534f17b 210 io_mgr_attrs.sm_length = 0;
c4ca3d5a
ORL
211 pr_err("%s: No memory reserved for shared structures\n",
212 __func__);
213 }
085467b8 214 status = chnl_create(&dev_obj->chnl_mgr, dev_obj, &mgr_attrs);
c4ca3d5a
ORL
215 if (status == -ENOSYS) {
216 /* It's OK for a device not to have a channel
217 * manager: */
218 status = 0;
219 }
220 /* Create CMM mgr even if Msg Mgr not impl. */
085467b8 221 status = cmm_create(&dev_obj->cmm_mgr,
c4ca3d5a
ORL
222 (struct dev_object *)dev_obj, NULL);
223 /* Only create IO manager if we have a channel manager */
085467b8 224 if (!status && dev_obj->chnl_mgr) {
121e8f9b 225 status = io_create(&dev_obj->iomgr, dev_obj,
c4ca3d5a
ORL
226 &io_mgr_attrs);
227 }
228 /* Only create DEH manager if we have an IO manager */
157990f0 229 if (!status) {
c4ca3d5a 230 /* Instantiate the DEH module */
085467b8 231 status = bridge_deh_create(&dev_obj->deh_mgr, dev_obj);
c4ca3d5a 232 }
677f2ded
FC
233 /* Create DMM mgr . */
234 status = dmm_create(&dev_obj->dmm_mgr,
235 (struct dev_object *)dev_obj, NULL);
c4ca3d5a
ORL
236 }
237 /* Add the new DEV_Object to the global list: */
5fb45dac 238 if (!status)
c4ca3d5a 239 status = drv_insert_dev_object(hdrv_obj, dev_obj);
5fb45dac 240
c4ca3d5a 241 /* Create the Processor List */
5fb45dac
IN
242 if (!status)
243 INIT_LIST_HEAD(&dev_obj->proc_list);
c4ca3d5a
ORL
244leave:
245 /* If all went well, return a handle to the dev object;
157990f0
ER
246 * else, cleanup and return NULL in the OUT parameter. */
247 if (!status) {
e436d07d 248 *device_obj = dev_obj;
c4ca3d5a
ORL
249 } else {
250 if (dev_obj) {
c4ca3d5a
ORL
251 if (dev_obj->cod_mgr)
252 cod_delete(dev_obj->cod_mgr);
677f2ded
FC
253 if (dev_obj->dmm_mgr)
254 dmm_destroy(dev_obj->dmm_mgr);
c4ca3d5a
ORL
255 kfree(dev_obj);
256 }
257
e436d07d 258 *device_obj = NULL;
c4ca3d5a
ORL
259 }
260
c4ca3d5a
ORL
261 return status;
262}
263
264/*
265 * ======== dev_create2 ========
266 * Purpose:
267 * After successful loading of the image from api_init_complete2
268 * (PROC Auto_Start) or proc_load this fxn is called. This creates
269 * the Node Manager and updates the DEV Object.
270 */
271int dev_create2(struct dev_object *hdev_obj)
272{
273 int status = 0;
274 struct dev_object *dev_obj = hdev_obj;
275
c4ca3d5a 276 /* There can be only one Node Manager per DEV object */
085467b8 277 status = node_create_mgr(&dev_obj->node_mgr, hdev_obj);
51d5e099 278 if (status)
085467b8 279 dev_obj->node_mgr = NULL;
c4ca3d5a 280
c4ca3d5a
ORL
281 return status;
282}
283
284/*
285 * ======== dev_destroy2 ========
286 * Purpose:
287 * Destroys the Node manager for this device.
288 */
289int dev_destroy2(struct dev_object *hdev_obj)
290{
291 int status = 0;
292 struct dev_object *dev_obj = hdev_obj;
293
085467b8
RS
294 if (dev_obj->node_mgr) {
295 if (node_delete_mgr(dev_obj->node_mgr))
c4ca3d5a
ORL
296 status = -EPERM;
297 else
085467b8 298 dev_obj->node_mgr = NULL;
c4ca3d5a
ORL
299
300 }
301
c4ca3d5a
ORL
302 return status;
303}
304
305/*
306 * ======== dev_destroy_device ========
307 * Purpose:
308 * Destroys the channel manager for this device, if any, calls
309 * bridge_dev_destroy(), and then attempts to unload the Bridge module.
310 */
311int dev_destroy_device(struct dev_object *hdev_obj)
312{
313 int status = 0;
314 struct dev_object *dev_obj = hdev_obj;
315
c4ca3d5a
ORL
316 if (hdev_obj) {
317 if (dev_obj->cod_mgr) {
318 cod_delete(dev_obj->cod_mgr);
319 dev_obj->cod_mgr = NULL;
320 }
321
085467b8
RS
322 if (dev_obj->node_mgr) {
323 node_delete_mgr(dev_obj->node_mgr);
324 dev_obj->node_mgr = NULL;
c4ca3d5a
ORL
325 }
326
327 /* Free the io, channel, and message managers for this board: */
121e8f9b
RS
328 if (dev_obj->iomgr) {
329 io_destroy(dev_obj->iomgr);
330 dev_obj->iomgr = NULL;
c4ca3d5a 331 }
085467b8
RS
332 if (dev_obj->chnl_mgr) {
333 chnl_destroy(dev_obj->chnl_mgr);
334 dev_obj->chnl_mgr = NULL;
c4ca3d5a 335 }
085467b8
RS
336 if (dev_obj->msg_mgr) {
337 msg_delete(dev_obj->msg_mgr);
338 dev_obj->msg_mgr = NULL;
c4ca3d5a
ORL
339 }
340
085467b8 341 if (dev_obj->deh_mgr) {
c4ca3d5a 342 /* Uninitialize DEH module. */
085467b8
RS
343 bridge_deh_destroy(dev_obj->deh_mgr);
344 dev_obj->deh_mgr = NULL;
c4ca3d5a 345 }
085467b8
RS
346 if (dev_obj->cmm_mgr) {
347 cmm_destroy(dev_obj->cmm_mgr, true);
348 dev_obj->cmm_mgr = NULL;
c4ca3d5a
ORL
349 }
350
677f2ded
FC
351 if (dev_obj->dmm_mgr) {
352 dmm_destroy(dev_obj->dmm_mgr);
353 dev_obj->dmm_mgr = NULL;
354 }
355
c4ca3d5a
ORL
356 /* Call the driver's bridge_dev_destroy() function: */
357 /* Require of DevDestroy */
085467b8 358 if (dev_obj->bridge_context) {
09f13304 359 status = (*dev_obj->bridge_interface.dev_destroy)
085467b8
RS
360 (dev_obj->bridge_context);
361 dev_obj->bridge_context = NULL;
c4ca3d5a
ORL
362 } else
363 status = -EPERM;
157990f0 364 if (!status) {
c4ca3d5a 365 /* Remove this DEV_Object from the global list: */
085467b8 366 drv_remove_dev_object(dev_obj->drv_obj, dev_obj);
c4ca3d5a
ORL
367 /* Free The library * LDR_FreeModule
368 * (dev_obj->module_obj); */
369 /* Free this dev object: */
370 kfree(dev_obj);
371 dev_obj = NULL;
372 }
373 } else {
374 status = -EFAULT;
375 }
376
377 return status;
378}
379
380/*
381 * ======== dev_get_chnl_mgr ========
382 * Purpose:
383 * Retrieve the handle to the channel manager handle created for this
384 * device.
385 */
386int dev_get_chnl_mgr(struct dev_object *hdev_obj,
e6bf74f0 387 struct chnl_mgr **mgr)
c4ca3d5a
ORL
388{
389 int status = 0;
390 struct dev_object *dev_obj = hdev_obj;
391
c4ca3d5a 392 if (hdev_obj) {
085467b8 393 *mgr = dev_obj->chnl_mgr;
c4ca3d5a 394 } else {
e436d07d 395 *mgr = NULL;
c4ca3d5a
ORL
396 status = -EFAULT;
397 }
398
c4ca3d5a
ORL
399 return status;
400}
401
402/*
403 * ======== dev_get_cmm_mgr ========
404 * Purpose:
405 * Retrieve the handle to the shared memory manager created for this
406 * device.
407 */
408int dev_get_cmm_mgr(struct dev_object *hdev_obj,
e6bf74f0 409 struct cmm_object **mgr)
c4ca3d5a
ORL
410{
411 int status = 0;
412 struct dev_object *dev_obj = hdev_obj;
413
c4ca3d5a 414 if (hdev_obj) {
085467b8 415 *mgr = dev_obj->cmm_mgr;
c4ca3d5a 416 } else {
e436d07d 417 *mgr = NULL;
c4ca3d5a
ORL
418 status = -EFAULT;
419 }
420
c4ca3d5a
ORL
421 return status;
422}
423
677f2ded
FC
424/*
425 * ======== dev_get_dmm_mgr ========
426 * Purpose:
427 * Retrieve the handle to the dynamic memory manager created for this
428 * device.
429 */
430int dev_get_dmm_mgr(struct dev_object *hdev_obj,
431 struct dmm_object **mgr)
432{
433 int status = 0;
434 struct dev_object *dev_obj = hdev_obj;
435
677f2ded
FC
436 if (hdev_obj) {
437 *mgr = dev_obj->dmm_mgr;
438 } else {
439 *mgr = NULL;
440 status = -EFAULT;
441 }
442
677f2ded
FC
443 return status;
444}
445
c4ca3d5a
ORL
446/*
447 * ======== dev_get_cod_mgr ========
448 * Purpose:
449 * Retrieve the COD manager create for this device.
450 */
451int dev_get_cod_mgr(struct dev_object *hdev_obj,
e6bf74f0 452 struct cod_manager **cod_mgr)
c4ca3d5a
ORL
453{
454 int status = 0;
455 struct dev_object *dev_obj = hdev_obj;
456
c4ca3d5a 457 if (hdev_obj) {
a5120278 458 *cod_mgr = dev_obj->cod_mgr;
c4ca3d5a 459 } else {
a5120278 460 *cod_mgr = NULL;
c4ca3d5a
ORL
461 status = -EFAULT;
462 }
463
c4ca3d5a
ORL
464 return status;
465}
466
467/*
468 * ========= dev_get_deh_mgr ========
469 */
470int dev_get_deh_mgr(struct dev_object *hdev_obj,
e6bf74f0 471 struct deh_mgr **deh_manager)
c4ca3d5a
ORL
472{
473 int status = 0;
474
c4ca3d5a 475 if (hdev_obj) {
085467b8 476 *deh_manager = hdev_obj->deh_mgr;
c4ca3d5a 477 } else {
a5120278 478 *deh_manager = NULL;
c4ca3d5a
ORL
479 status = -EFAULT;
480 }
481 return status;
482}
483
484/*
485 * ======== dev_get_dev_node ========
486 * Purpose:
487 * Retrieve the platform specific device ID for this device.
488 */
489int dev_get_dev_node(struct dev_object *hdev_obj,
e6bf74f0 490 struct cfg_devnode **dev_nde)
c4ca3d5a
ORL
491{
492 int status = 0;
493 struct dev_object *dev_obj = hdev_obj;
494
c4ca3d5a 495 if (hdev_obj) {
e436d07d 496 *dev_nde = dev_obj->dev_node_obj;
c4ca3d5a 497 } else {
e436d07d 498 *dev_nde = NULL;
c4ca3d5a
ORL
499 status = -EFAULT;
500 }
501
c4ca3d5a
ORL
502 return status;
503}
504
505/*
506 * ======== dev_get_first ========
507 * Purpose:
508 * Retrieve the first Device Object handle from an internal linked list
509 * DEV_OBJECTs maintained by DEV.
510 */
511struct dev_object *dev_get_first(void)
512{
513 struct dev_object *dev_obj = NULL;
514
515 dev_obj = (struct dev_object *)drv_get_first_dev_object();
516
517 return dev_obj;
518}
519
520/*
521 * ======== dev_get_intf_fxns ========
522 * Purpose:
523 * Retrieve the Bridge interface function structure for the loaded driver.
13b18c29 524 * if_fxns != NULL.
c4ca3d5a
ORL
525 */
526int dev_get_intf_fxns(struct dev_object *hdev_obj,
e6bf74f0 527 struct bridge_drv_interface **if_fxns)
c4ca3d5a
ORL
528{
529 int status = 0;
530 struct dev_object *dev_obj = hdev_obj;
531
c4ca3d5a 532 if (hdev_obj) {
13b18c29 533 *if_fxns = &dev_obj->bridge_interface;
c4ca3d5a 534 } else {
13b18c29 535 *if_fxns = NULL;
c4ca3d5a
ORL
536 status = -EFAULT;
537 }
538
c4ca3d5a
ORL
539 return status;
540}
541
542/*
543 * ========= dev_get_io_mgr ========
544 */
545int dev_get_io_mgr(struct dev_object *hdev_obj,
e6bf74f0 546 struct io_mgr **io_man)
c4ca3d5a
ORL
547{
548 int status = 0;
549
c4ca3d5a 550 if (hdev_obj) {
121e8f9b 551 *io_man = hdev_obj->iomgr;
c4ca3d5a 552 } else {
e436d07d 553 *io_man = NULL;
c4ca3d5a
ORL
554 status = -EFAULT;
555 }
556
557 return status;
558}
559
560/*
561 * ======== dev_get_next ========
562 * Purpose:
563 * Retrieve the next Device Object handle from an internal linked list
564 * of DEV_OBJECTs maintained by DEV, after having previously called
565 * dev_get_first() and zero or more dev_get_next
566 */
567struct dev_object *dev_get_next(struct dev_object *hdev_obj)
568{
569 struct dev_object *next_dev_object = NULL;
570
571 if (hdev_obj) {
572 next_dev_object = (struct dev_object *)
573 drv_get_next_dev_object((u32) hdev_obj);
574 }
575
576 return next_dev_object;
577}
578
579/*
580 * ========= dev_get_msg_mgr ========
581 */
e6bf74f0 582void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man)
c4ca3d5a 583{
085467b8 584 *msg_man = hdev_obj->msg_mgr;
c4ca3d5a
ORL
585}
586
587/*
588 * ======== dev_get_node_manager ========
589 * Purpose:
590 * Retrieve the Node Manager Handle
591 */
592int dev_get_node_manager(struct dev_object *hdev_obj,
e6bf74f0 593 struct node_mgr **node_man)
c4ca3d5a
ORL
594{
595 int status = 0;
596 struct dev_object *dev_obj = hdev_obj;
597
c4ca3d5a 598 if (hdev_obj) {
085467b8 599 *node_man = dev_obj->node_mgr;
c4ca3d5a 600 } else {
daa89e6c 601 *node_man = NULL;
c4ca3d5a
ORL
602 status = -EFAULT;
603 }
604
c4ca3d5a
ORL
605 return status;
606}
607
608/*
609 * ======== dev_get_symbol ========
610 */
611int dev_get_symbol(struct dev_object *hdev_obj,
e6bf74f0 612 const char *str_sym, u32 * pul_value)
c4ca3d5a
ORL
613{
614 int status = 0;
615 struct cod_manager *cod_mgr;
616
c4ca3d5a
ORL
617 if (hdev_obj) {
618 status = dev_get_cod_mgr(hdev_obj, &cod_mgr);
619 if (cod_mgr)
383b8345 620 status = cod_get_sym_value(cod_mgr, (char *)str_sym,
c4ca3d5a
ORL
621 pul_value);
622 else
623 status = -EFAULT;
624 }
625
626 return status;
627}
628
629/*
630 * ======== dev_get_bridge_context ========
631 * Purpose:
632 * Retrieve the Bridge Context handle, as returned by the
633 * bridge_dev_create fxn.
634 */
635int dev_get_bridge_context(struct dev_object *hdev_obj,
e6bf74f0 636 struct bridge_dev_context **phbridge_context)
c4ca3d5a
ORL
637{
638 int status = 0;
639 struct dev_object *dev_obj = hdev_obj;
640
c4ca3d5a 641 if (hdev_obj) {
085467b8 642 *phbridge_context = dev_obj->bridge_context;
c4ca3d5a
ORL
643 } else {
644 *phbridge_context = NULL;
645 status = -EFAULT;
646 }
647
c4ca3d5a
ORL
648 return status;
649}
650
651/*
652 * ======== dev_exit ========
653 * Purpose:
654 * Decrement reference count, and free resources when reference count is
655 * 0.
656 */
657void dev_exit(void)
658{
c4ca3d5a
ORL
659 refs--;
660
a71aa396 661 if (refs == 0)
677f2ded 662 dmm_exit();
c4ca3d5a
ORL
663}
664
665/*
666 * ======== dev_init ========
667 * Purpose:
668 * Initialize DEV's private state, keeping a reference count on each call.
669 */
670bool dev_init(void)
671{
a71aa396 672 bool ret = true;
677f2ded 673
a71aa396
VMJL
674 if (refs == 0)
675 dmm_init();
c4ca3d5a
ORL
676
677 if (ret)
678 refs++;
679
c4ca3d5a
ORL
680 return ret;
681}
682
683/*
684 * ======== dev_notify_clients ========
685 * Purpose:
686 * Notify all clients of this device of a change in device status.
687 */
ba44df6f 688int dev_notify_clients(struct dev_object *dev_obj, u32 ret)
c4ca3d5a 689{
5fb45dac 690 struct list_head *curr;
c4ca3d5a 691
5fb45dac
IN
692 /*
693 * FIXME: this code needs struct proc_object to have a list_head
25985edc 694 * at the beginning. If not, this can go horribly wrong.
5fb45dac
IN
695 */
696 list_for_each(curr, &dev_obj->proc_list)
ba44df6f 697 proc_notify_clients((void *)curr, ret);
c4ca3d5a 698
5fb45dac 699 return 0;
c4ca3d5a
ORL
700}
701
702/*
703 * ======== dev_remove_device ========
704 */
705int dev_remove_device(struct cfg_devnode *dev_node_obj)
706{
707 struct dev_object *hdev_obj; /* handle to device object */
708 int status = 0;
e8184e6c
IGC
709 struct drv_data *drv_datap = dev_get_drvdata(bridge);
710
711 if (!drv_datap)
712 status = -ENODATA;
713
714 if (!dev_node_obj)
715 status = -EFAULT;
c4ca3d5a 716
25985edc 717 /* Retrieve the device object handle originally stored with
c4ca3d5a 718 * the dev_node: */
157990f0 719 if (!status) {
e8184e6c
IGC
720 /* check the device string and then store dev object */
721 if (!strcmp((char *)((struct drv_ext *)dev_node_obj)->sz_string,
722 "TIOMAP1510")) {
723 hdev_obj = drv_datap->dev_object;
724 /* Destroy the device object. */
725 status = dev_destroy_device(hdev_obj);
726 } else {
727 status = -EPERM;
728 }
c4ca3d5a
ORL
729 }
730
e8184e6c
IGC
731 if (status)
732 pr_err("%s: Failed, status 0x%x\n", __func__, status);
733
c4ca3d5a
ORL
734 return status;
735}
736
737/*
738 * ======== dev_set_chnl_mgr ========
739 * Purpose:
740 * Set the channel manager for this device.
741 */
742int dev_set_chnl_mgr(struct dev_object *hdev_obj,
743 struct chnl_mgr *hmgr)
744{
745 int status = 0;
746 struct dev_object *dev_obj = hdev_obj;
747
c4ca3d5a 748 if (hdev_obj)
085467b8 749 dev_obj->chnl_mgr = hmgr;
c4ca3d5a
ORL
750 else
751 status = -EFAULT;
752
c4ca3d5a
ORL
753 return status;
754}
755
756/*
757 * ======== dev_set_msg_mgr ========
758 * Purpose:
759 * Set the message manager for this device.
760 */
761void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr)
762{
085467b8 763 hdev_obj->msg_mgr = hmgr;
c4ca3d5a
ORL
764}
765
766/*
767 * ======== dev_start_device ========
768 * Purpose:
769 * Initializes the new device with the BRIDGE environment.
770 */
771int dev_start_device(struct cfg_devnode *dev_node_obj)
772{
773 struct dev_object *hdev_obj = NULL; /* handle to 'Bridge Device */
774 /* Bridge driver filename */
2c36fac4 775 char *bridge_file_name = "UMA";
c4ca3d5a
ORL
776 int status;
777 struct mgr_object *hmgr_obj = NULL;
a47d4dee 778 struct drv_data *drv_datap = dev_get_drvdata(bridge);
c4ca3d5a 779
c4ca3d5a
ORL
780 /* Given all resources, create a device object. */
781 status = dev_create_device(&hdev_obj, bridge_file_name,
782 dev_node_obj);
157990f0 783 if (!status) {
c4ca3d5a 784 /* Store away the hdev_obj with the DEVNODE */
a47d4dee
IGC
785 if (!drv_datap || !dev_node_obj) {
786 status = -EFAULT;
787 pr_err("%s: Failed, status 0x%x\n", __func__, status);
788 } else if (!(strcmp((char *)dev_node_obj, "TIOMAP1510"))) {
789 drv_datap->dev_object = (void *) hdev_obj;
790 }
791 if (!status) {
792 /* Create the Manager Object */
793 status = mgr_create(&hmgr_obj, dev_node_obj);
794 if (status && !(strcmp((char *)dev_node_obj,
795 "TIOMAP1510"))) {
796 /* Ensure the device extension is NULL */
797 drv_datap->dev_object = NULL;
798 }
799 }
51d5e099 800 if (status) {
c4ca3d5a
ORL
801 /* Clean up */
802 dev_destroy_device(hdev_obj);
803 hdev_obj = NULL;
804 }
805 }
c4ca3d5a
ORL
806
807 return status;
808}
809
810/*
811 * ======== fxn_not_implemented ========
812 * Purpose:
813 * Takes the place of a Bridge Null Function.
814 * Parameters:
815 * Multiple, optional.
816 * Returns:
817 * -ENOSYS: Always.
818 */
819static int fxn_not_implemented(int arg, ...)
820{
821 return -ENOSYS;
822}
823
824/*
825 * ======== init_cod_mgr ========
826 * Purpose:
827 * Create a COD manager for this device.
828 * Parameters:
829 * dev_obj: Pointer to device object created with
830 * dev_create_device()
831 * Returns:
832 * 0: Success.
833 * -EFAULT: Invalid hdev_obj.
834 * Requires:
835 * Should only be called once by dev_create_device() for a given DevObject.
836 * Ensures:
837 */
838static int init_cod_mgr(struct dev_object *dev_obj)
839{
840 int status = 0;
841 char *sz_dummy_file = "dummy";
842
5db9e2bf 843 status = cod_create(&dev_obj->cod_mgr, sz_dummy_file);
c4ca3d5a
ORL
844
845 return status;
846}
847
848/*
849 * ======== dev_insert_proc_object ========
850 * Purpose:
851 * Insert a ProcObject into the list maintained by DEV.
852 * Parameters:
853 * p_proc_object: Ptr to ProcObject to insert.
854 * dev_obj: Ptr to Dev Object where the list is.
aa09b091 855 * already_attached: Ptr to return the bool
c4ca3d5a
ORL
856 * Returns:
857 * 0: If successful.
858 * Requires:
859 * List Exists
860 * hdev_obj is Valid handle
861 * DEV Initialized
aa09b091 862 * already_attached != NULL
c4ca3d5a
ORL
863 * proc_obj != 0
864 * Ensures:
865 * 0 and List is not Empty.
866 */
867int dev_insert_proc_object(struct dev_object *hdev_obj,
e6bf74f0 868 u32 proc_obj, bool *already_attached)
c4ca3d5a 869{
c4ca3d5a
ORL
870 struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
871
5fb45dac 872 if (!list_empty(&dev_obj->proc_list))
aa09b091 873 *already_attached = true;
c4ca3d5a
ORL
874
875 /* Add DevObject to tail. */
5fb45dac
IN
876 /*
877 * FIXME: this code needs struct proc_object to have a list_head
25985edc 878 * at the beginning. If not, this can go horribly wrong.
5fb45dac
IN
879 */
880 list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list);
c4ca3d5a 881
ba44df6f 882 return 0;
c4ca3d5a
ORL
883}
884
885/*
886 * ======== dev_remove_proc_object ========
887 * Purpose:
888 * Search for and remove a Proc object from the given list maintained
889 * by the DEV
890 * Parameters:
891 * p_proc_object: Ptr to ProcObject to insert.
892 * dev_obj Ptr to Dev Object where the list is.
893 * Returns:
894 * 0: If successful.
895 * Requires:
896 * List exists and is not empty
897 * proc_obj != 0
898 * hdev_obj is a valid Dev handle.
899 * Ensures:
900 * Details:
901 * List will be deleted when the DEV is destroyed.
902 */
903int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj)
904{
905 int status = -EPERM;
906 struct list_head *cur_elem;
907 struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
908
c4ca3d5a 909 /* Search list for dev_obj: */
5fb45dac 910 list_for_each(cur_elem, &dev_obj->proc_list) {
c4ca3d5a 911 if ((u32) cur_elem == proc_obj) {
5fb45dac 912 list_del(cur_elem);
c4ca3d5a
ORL
913 status = 0;
914 break;
915 }
916 }
917
918 return status;
919}
920
ba44df6f 921int dev_get_dev_type(struct dev_object *dev_obj, u8 *dev_type)
c4ca3d5a 922{
c4ca3d5a 923 *dev_type = dev_obj->dev_type;
ba44df6f 924 return 0;
c4ca3d5a
ORL
925}
926
927/*
928 * ======== store_interface_fxns ========
929 * Purpose:
930 * Copy the Bridge's interface functions into the device object,
931 * ensuring that fxn_not_implemented() is set for:
932 *
933 * 1. All Bridge function pointers which are NULL; and
934 * 2. All function slots in the struct dev_object structure which have no
935 * corresponding slots in the the Bridge's interface, because the Bridge
936 * is of an *older* version.
937 * Parameters:
938 * intf_fxns: Interface fxn Structure of the Bridge's Dev Object.
939 * drv_fxns: Interface Fxns offered by the Bridge during DEV_Create().
940 * Returns:
941 * Requires:
942 * Input pointers are valid.
943 * Bridge driver is *not* written for a newer DSP API.
944 * Ensures:
945 * All function pointers in the dev object's fxn interface are not NULL.
946 */
947static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
e6bf74f0 948 struct bridge_drv_interface *intf_fxns)
c4ca3d5a
ORL
949{
950 u32 bridge_version;
951
952 /* Local helper macro: */
953#define STORE_FXN(cast, pfn) \
954 (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
955 (cast)fxn_not_implemented))
956
c4ca3d5a
ORL
957 bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version,
958 drv_fxns->brd_api_minor_version);
959 intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version;
960 intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version;
961 /* Install functions up to DSP API version .80 (first alpha): */
962 if (bridge_version > 0) {
09f13304
RS
963 STORE_FXN(fxn_dev_create, dev_create);
964 STORE_FXN(fxn_dev_destroy, dev_destroy);
e17ba7f2 965 STORE_FXN(fxn_dev_ctrl, dev_cntrl);
3c882de5 966 STORE_FXN(fxn_brd_monitor, brd_monitor);
e17ba7f2
RS
967 STORE_FXN(fxn_brd_start, brd_start);
968 STORE_FXN(fxn_brd_stop, brd_stop);
969 STORE_FXN(fxn_brd_status, brd_status);
3c882de5 970 STORE_FXN(fxn_brd_read, brd_read);
e17ba7f2
RS
971 STORE_FXN(fxn_brd_write, brd_write);
972 STORE_FXN(fxn_brd_setstate, brd_set_state);
3c882de5
RS
973 STORE_FXN(fxn_brd_memcopy, brd_mem_copy);
974 STORE_FXN(fxn_brd_memwrite, brd_mem_write);
975 STORE_FXN(fxn_brd_memmap, brd_mem_map);
976 STORE_FXN(fxn_brd_memunmap, brd_mem_un_map);
e17ba7f2
RS
977 STORE_FXN(fxn_chnl_create, chnl_create);
978 STORE_FXN(fxn_chnl_destroy, chnl_destroy);
979 STORE_FXN(fxn_chnl_open, chnl_open);
980 STORE_FXN(fxn_chnl_close, chnl_close);
981 STORE_FXN(fxn_chnl_addioreq, chnl_add_io_req);
982 STORE_FXN(fxn_chnl_getioc, chnl_get_ioc);
983 STORE_FXN(fxn_chnl_cancelio, chnl_cancel_io);
984 STORE_FXN(fxn_chnl_flushio, chnl_flush_io);
985 STORE_FXN(fxn_chnl_getinfo, chnl_get_info);
986 STORE_FXN(fxn_chnl_getmgrinfo, chnl_get_mgr_info);
987 STORE_FXN(fxn_chnl_idle, chnl_idle);
988 STORE_FXN(fxn_chnl_registernotify, chnl_register_notify);
09f13304
RS
989 STORE_FXN(fxn_io_create, io_create);
990 STORE_FXN(fxn_io_destroy, io_destroy);
991 STORE_FXN(fxn_io_onloaded, io_on_loaded);
992 STORE_FXN(fxn_io_getprocload, io_get_proc_load);
993 STORE_FXN(fxn_msg_create, msg_create);
994 STORE_FXN(fxn_msg_createqueue, msg_create_queue);
995 STORE_FXN(fxn_msg_delete, msg_delete);
996 STORE_FXN(fxn_msg_deletequeue, msg_delete_queue);
997 STORE_FXN(fxn_msg_get, msg_get);
998 STORE_FXN(fxn_msg_put, msg_put);
999 STORE_FXN(fxn_msg_registernotify, msg_register_notify);
1000 STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id);
c4ca3d5a
ORL
1001 }
1002 /* Add code for any additional functions in newerBridge versions here */
c4ca3d5a
ORL
1003#undef STORE_FXN
1004}
This page took 0.202542 seconds and 5 git commands to generate.