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