1 From d1f74c03f166bf92278642867607111e21d68130 Mon Sep 17 00:00:00 2001
2 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
3 Date: Fri, 15 Aug 2008 01:55:54 +0300
4 Subject: [PATCH 08/10] TI DSP BRIDGE: Services
6 Initial port from omapzoom
7 http://omapzoom.org/gf/project/omapbridge
10 http://omapzoom.org/gf/project/omapbridge/docman/?subdir=3
12 Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
14 drivers/dsp/bridge/services/cfg.c | 484 +++++++++++++++++++++++++
15 drivers/dsp/bridge/services/clk.c | 376 ++++++++++++++++++++
16 drivers/dsp/bridge/services/csl.c | 274 ++++++++++++++
17 drivers/dsp/bridge/services/dbg.c | 119 +++++++
18 drivers/dsp/bridge/services/dpc.c | 275 ++++++++++++++
19 drivers/dsp/bridge/services/isr.c | 261 ++++++++++++++
20 drivers/dsp/bridge/services/kfile.c | 336 ++++++++++++++++++
21 drivers/dsp/bridge/services/list.c | 285 +++++++++++++++
22 drivers/dsp/bridge/services/mem.c | 594 +++++++++++++++++++++++++++++++
23 drivers/dsp/bridge/services/ntfy.c | 329 +++++++++++++++++
24 drivers/dsp/bridge/services/prcs.c | 119 +++++++
25 drivers/dsp/bridge/services/reg.c | 196 ++++++++++
26 drivers/dsp/bridge/services/regsup.c | 367 +++++++++++++++++++
27 drivers/dsp/bridge/services/regsup.h | 58 +++
28 drivers/dsp/bridge/services/services.c | 205 +++++++++++
29 drivers/dsp/bridge/services/sync.c | 610 ++++++++++++++++++++++++++++++++
30 16 files changed, 4888 insertions(+), 0 deletions(-)
31 create mode 100644 drivers/dsp/bridge/services/cfg.c
32 create mode 100644 drivers/dsp/bridge/services/clk.c
33 create mode 100644 drivers/dsp/bridge/services/csl.c
34 create mode 100644 drivers/dsp/bridge/services/dbg.c
35 create mode 100644 drivers/dsp/bridge/services/dpc.c
36 create mode 100644 drivers/dsp/bridge/services/isr.c
37 create mode 100644 drivers/dsp/bridge/services/kfile.c
38 create mode 100644 drivers/dsp/bridge/services/list.c
39 create mode 100644 drivers/dsp/bridge/services/mem.c
40 create mode 100644 drivers/dsp/bridge/services/ntfy.c
41 create mode 100644 drivers/dsp/bridge/services/prcs.c
42 create mode 100644 drivers/dsp/bridge/services/reg.c
43 create mode 100644 drivers/dsp/bridge/services/regsup.c
44 create mode 100644 drivers/dsp/bridge/services/regsup.h
45 create mode 100644 drivers/dsp/bridge/services/services.c
46 create mode 100644 drivers/dsp/bridge/services/sync.c
48 diff --git a/drivers/dsp/bridge/services/cfg.c b/drivers/dsp/bridge/services/cfg.c
50 index 0000000..1614d80
52 +++ b/drivers/dsp/bridge/services/cfg.c
55 + * linux/drivers/dsp/bridge/services/cfg.c
57 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
59 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
61 + * This package is free software; you can redistribute it and/or modify
62 + * it under the terms of the GNU General Public License version 2 as
63 + * published by the Free Software Foundation.
65 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
66 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
67 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
72 + * ======== cfgce.c ========
74 + * Implementation of platform specific config services.
76 + * Private Functions:
80 + * CFG_GetDSPResources
82 + * CFG_GetHostResources
89 + *! Revision History:
91 + *! 26-Arp-2004 hp Support for handling more than one Device.
92 + *! 26-Feb-2003 kc Removed unused CFG fxns.
93 + *! 10-Nov-2000 rr: CFG_GetBoardName local var initialized.
94 + *! 30-Oct-2000 kc: Changed local var. names to use Hungarian notation.
95 + *! 10-Aug-2000 rr: Cosmetic changes.
96 + *! 26-Jul-2000 rr: Added CFG_GetDCDName. CFG_Get/SetObject(based on a flag)
97 + *! replaces CFG_GetMgrObject & CFG_SetMgrObject.
98 + *! 17-Jul-2000 rr: Added CFG_GetMgrObject & CFG_SetMgrObject.
99 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
101 + *! 31-Jan-2000 rr: Comments and bugfixes: modified after code review
102 + *! 07-Jan-2000 rr: CFG_GetBoardName Ensure class checks CSL_Strlen of the
103 + *! read value from the registry against the passed in BufSize;
104 + *! CFG_GetZLFile,CFG_GetWMDFileName and
105 + *! CFG_GetExecFile also modified same way.
106 + *! 06-Jan-2000 rr: CFG_GetSearchPath & CFG_GetWinBRIDGEDir removed.
107 + *! 09-Dec-1999 rr: CFG_SetDevObject stores the DevNodeString pointer.
108 + *! 03-Dec-1999 rr: CFG_GetDevObject reads stored DevObject from Registry.
109 + *! CFG_GetDevNode reads the Devnodestring from the registry.
110 + *! CFG_SetDevObject stores the registry path as
111 + *! DevNodestring in the registry.
112 + *! 02-Dec-1999 rr: CFG_debugMask is declared static now. stdwin.h included
113 + *! 22-Nov-1999 kc: Added windows.h to remove warnings.
114 + *! 25-Oct-1999 rr: CFG_GetHostResources reads the HostResource structure
115 + *! from the registry which was set by the DRV Request
117 + *! 15-Oct-1999 rr: Changes in CFG_SetPrivateDword & HostResources reflecting
118 + *! changes for drv.h resource structure and wsxreg.h new
119 + *! entry(DevObject) Hard coded entries removed for those items
120 + *! 08-Oct-1999 rr: CFG_SetPrivateDword modified. it sets devobject into the
121 + *! registry. CFG_Get HostResources modified for opening up
122 + *! two mem winodws.
123 + *! 24-Sep-1999 rr: CFG_GetHostResources uses hardcoded Registry calls,uses NT
124 + *! type of Resource Structure.
125 + *! 19-Jul-1999 a0216266: Stubbed from cfgnt.c.
128 +/* ----------------------------------- DSP/BIOS Bridge */
131 +#include <errbase.h>
133 +/* ----------------------------------- Trace & Debug */
137 +/* ----------------------------------- OS Adaptation Layer */
141 +/* ----------------------------------- Others */
144 +/* ----------------------------------- This */
149 + struct LST_ELEM link;
150 + char szString[MAXREGPATHLENGTH];
153 +/* ----------------------------------- Globals */
155 +static struct GT_Mask CFG_debugMask = { NULL, NULL }; /* CFG debug Mask */
159 + * ======== CFG_Exit ========
161 + * Discontinue usage of the CFG module.
165 + GT_0trace(CFG_debugMask, GT_5CLASS, "Entered CFG_Exit\n");
169 + * ======== CFG_GetAutoStart ========
171 + * Retreive the autostart mask, if any, for this board.
173 +DSP_STATUS CFG_GetAutoStart(struct CFG_DEVNODE *hDevNode,
174 + OUT u32 *pdwAutoStart)
176 + DSP_STATUS status = DSP_SOK;
178 + GT_2trace(CFG_debugMask, GT_ENTER,
179 + "Entered CFG_GetAutoStart: \n\thDevNode:"
180 + "0x%x\n\tpdwAutoStart: 0x%x\n", hDevNode, pdwAutoStart);
181 + dwBufSize = sizeof(*pdwAutoStart);
183 + status = CFG_E_INVALIDHDEVNODE;
185 + status = CFG_E_INVALIDPOINTER;
186 + if (DSP_SUCCEEDED(status)) {
187 + status = REG_GetValue(NULL, (char *)hDevNode, AUTOSTART,
188 + (u8 *)pdwAutoStart, &dwBufSize);
189 + if (DSP_FAILED(status))
190 + status = CFG_E_RESOURCENOTAVAIL;
193 + if (DSP_SUCCEEDED(status)) {
194 + GT_0trace(CFG_debugMask, GT_1CLASS,
195 + "CFG_GetAutoStart SUCCESS \n");
197 + GT_0trace(CFG_debugMask, GT_6CLASS,
198 + "CFG_GetAutoStart Failed \n");
201 + DBC_Ensure((status == DSP_SOK &&
202 + (*pdwAutoStart == 0 || *pdwAutoStart == 1))
203 + || status != DSP_SOK);
208 + * ======== CFG_GetDevObject ========
210 + * Retrieve the Device Object handle for a given devnode.
212 +DSP_STATUS CFG_GetDevObject(struct CFG_DEVNODE *hDevNode, OUT u32 *pdwValue)
214 + DSP_STATUS status = DSP_SOK;
216 + GT_2trace(CFG_debugMask, GT_ENTER, "Entered CFG_GetDevObject, args: "
217 + "\n\thDevNode: 0x%x\n\tpdwValue: 0x%x\n", hDevNode,
220 + status = CFG_E_INVALIDHDEVNODE;
223 + status = CFG_E_INVALIDHDEVNODE;
225 + dwBufSize = sizeof(pdwValue);
226 + if (DSP_SUCCEEDED(status)) {
228 + /* check the device string and then call the REG_SetValue*/
229 + if (!(CSL_Strcmp((char *)((struct DRV_EXT *)hDevNode)->szString,
231 + GT_0trace(CFG_debugMask, GT_1CLASS,
232 + "Fetching DSP Device from "
234 + status = REG_GetValue(NULL, (char *)hDevNode,
236 + (u8 *)pdwValue, &dwBufSize);
238 + GT_0trace(CFG_debugMask, GT_6CLASS,
239 + "Failed to Identify the Device to Fetch \n");
243 + if (DSP_SUCCEEDED(status)) {
244 + GT_1trace(CFG_debugMask, GT_1CLASS,
245 + "CFG_GetDevObject SUCCESS DevObject"
246 + ": 0x%x\n ", *pdwValue);
248 + GT_0trace(CFG_debugMask, GT_6CLASS,
249 + "CFG_GetDevObject Failed \n");
256 + * ======== CFG_GetDSPResources ========
258 + * Get the DSP resources available to a given device.
260 +DSP_STATUS CFG_GetDSPResources(struct CFG_DEVNODE *hDevNode,
261 + OUT struct CFG_DSPRES *pDSPResTable)
263 + DSP_STATUS status = DSP_SOK; /* return value */
265 + GT_2trace(CFG_debugMask, GT_ENTER,
266 + "Entered CFG_GetDSPResources, args: "
267 + "\n\thDevNode: 0x%x\n\tpDSPResTable: 0x%x\n",
268 + hDevNode, pDSPResTable);
270 + status = CFG_E_INVALIDHDEVNODE;
271 + } else if (!pDSPResTable) {
272 + status = CFG_E_INVALIDPOINTER;
274 + status = REG_GetValue(NULL, CONFIG, DSPRESOURCES,
275 + (u8 *)pDSPResTable,
278 + if (DSP_SUCCEEDED(status)) {
279 + GT_0trace(CFG_debugMask, GT_1CLASS,
280 + "CFG_GetDSPResources SUCCESS\n");
282 + status = CFG_E_RESOURCENOTAVAIL;
283 + GT_0trace(CFG_debugMask, GT_6CLASS,
284 + "CFG_GetDSPResources Failed \n");
287 + /* assert that resource values are reasonable */
288 + DBC_Assert(pDSPResTable->uChipType < 256);
289 + DBC_Assert(pDSPResTable->uWordSize > 0);
290 + DBC_Assert(pDSPResTable->uWordSize < 32);
291 + DBC_Assert(pDSPResTable->cChips > 0);
292 + DBC_Assert(pDSPResTable->cChips < 256);
298 + * ======== CFG_GetExecFile ========
300 + * Retreive the default executable, if any, for this board.
302 +DSP_STATUS CFG_GetExecFile(struct CFG_DEVNODE *hDevNode, u32 ulBufSize,
303 + OUT char *pstrExecFile)
305 + DSP_STATUS status = DSP_SOK;
306 + u32 cExecSize = ulBufSize;
307 + GT_3trace(CFG_debugMask, GT_ENTER,
308 + "Entered CFG_GetExecFile:\n\tthDevNode: "
309 + "0x%x\n\tulBufSize: 0x%x\n\tpstrExecFile: 0x%x\n", hDevNode,
310 + ulBufSize, pstrExecFile);
312 + status = CFG_E_INVALIDHDEVNODE;
315 + status = CFG_E_INVALIDPOINTER;
317 + if (DSP_SUCCEEDED(status)) {
318 + status = REG_GetValue(NULL, (char *)hDevNode, DEFEXEC,
319 + (u8 *)pstrExecFile, &cExecSize);
320 + if (DSP_FAILED(status))
321 + status = CFG_E_RESOURCENOTAVAIL;
322 + else if (cExecSize > ulBufSize)
323 + status = DSP_ESIZE;
327 + if (DSP_SUCCEEDED(status)) {
328 + GT_1trace(CFG_debugMask, GT_1CLASS,
329 + "CFG_GetExecFile SUCCESS Exec File"
330 + "name : %s\n ", pstrExecFile);
332 + GT_0trace(CFG_debugMask, GT_6CLASS,
333 + "CFG_GetExecFile Failed \n");
336 + DBC_Ensure(((status == DSP_SOK) &&
337 + (CSL_Strlen(pstrExecFile) <= ulBufSize))
338 + || (status != DSP_SOK));
343 + * ======== CFG_GetHostResources ========
345 + * Get the Host allocated resources assigned to a given device.
347 +DSP_STATUS CFG_GetHostResources(struct CFG_DEVNODE *hDevNode,
348 + OUT struct CFG_HOSTRES *pHostResTable)
350 + DSP_STATUS status = DSP_SOK;
352 + GT_2trace(CFG_debugMask, GT_ENTER,
353 + "Entered CFG_GetHostResources, args:\n\t"
354 + "pHostResTable: 0x%x\n\thDevNode: 0x%x\n",
355 + pHostResTable, hDevNode);
357 + status = CFG_E_INVALIDHDEVNODE;
359 + if (!pHostResTable)
360 + status = CFG_E_INVALIDPOINTER;
362 + if (DSP_SUCCEEDED(status)) {
363 + dwBufSize = sizeof(struct CFG_HOSTRES);
364 + if (DSP_FAILED(REG_GetValue(NULL, (char *)hDevNode,
366 + (u8 *)pHostResTable, &dwBufSize))) {
367 + status = CFG_E_RESOURCENOTAVAIL;
371 + if (DSP_SUCCEEDED(status)) {
372 + GT_0trace(CFG_debugMask, GT_1CLASS,
373 + "CFG_GetHostResources SUCCESS \n");
375 + GT_0trace(CFG_debugMask, GT_6CLASS,
376 + "CFG_GetHostResources Failed \n");
383 + * ======== CFG_GetObject ========
385 + * Retrieve the Object handle from the Registry
387 +DSP_STATUS CFG_GetObject(OUT u32 *pdwValue, u32 dwType)
389 + DSP_STATUS status = DSP_EINVALIDARG;
391 + DBC_Require(pdwValue != NULL);
392 + GT_1trace(CFG_debugMask, GT_ENTER,
393 + "Entered CFG_GetObject, args:pdwValue: "
394 + "0x%x\n", *pdwValue);
395 + dwBufSize = sizeof(pdwValue);
397 + case (REG_DRV_OBJECT):
398 + status = REG_GetValue(NULL, CONFIG, DRVOBJECT,
402 + case (REG_MGR_OBJECT):
403 + status = REG_GetValue(NULL, CONFIG, MGROBJECT,
410 + if (DSP_SUCCEEDED(status)) {
411 + GT_1trace(CFG_debugMask, GT_1CLASS,
412 + "CFG_GetObject SUCCESS DrvObject: "
413 + "0x%x\n ", *pdwValue);
415 + status = CFG_E_RESOURCENOTAVAIL;
417 + GT_0trace(CFG_debugMask, GT_6CLASS, "CFG_GetObject Failed \n");
419 + DBC_Ensure((DSP_SUCCEEDED(status) && *pdwValue != 0) ||
420 + (DSP_FAILED(status) && *pdwValue == 0));
425 + * ======== CFG_Init ========
427 + * Initialize the CFG module's private state.
431 + struct CFG_DSPRES dspResources;
432 + GT_create(&CFG_debugMask, "CF"); /* CF for ConFig */
433 + GT_0trace(CFG_debugMask, GT_5CLASS, "Entered CFG_Init\n");
434 + GT_0trace(CFG_debugMask, GT_5CLASS, "Intializing DSP Registry Info \n");
436 + dspResources.uChipType = DSPTYPE_64;
437 + dspResources.cChips = 1;
438 + dspResources.uWordSize = DSPWORDSIZE;
439 + dspResources.cMemTypes = 0;
440 + dspResources.aMemDesc[0].uMemType = 0;
441 + dspResources.aMemDesc[0].ulMin = 0;
442 + dspResources.aMemDesc[0].ulMax = 0;
443 + if (DSP_SUCCEEDED(REG_SetValue(NULL, CONFIG, DSPRESOURCES, REG_BINARY,
444 + (u8 *)&dspResources, sizeof(struct CFG_DSPRES)))) {
445 + GT_0trace(CFG_debugMask, GT_5CLASS,
446 + "Initialized DSP resources in "
449 + GT_0trace(CFG_debugMask, GT_5CLASS,
450 + "Failed to Initialize DSP resources"
451 + " in Registry \n");
456 + * ======== CFG_SetDevObject ========
458 + * Store the Device Object handle and devNode pointer for a given devnode.
460 +DSP_STATUS CFG_SetDevObject(struct CFG_DEVNODE *hDevNode, u32 dwValue)
462 + DSP_STATUS status = DSP_SOK;
464 + GT_2trace(CFG_debugMask, GT_ENTER,
465 + "Entered CFG_SetDevObject, args: \n\t"
466 + "hDevNode: 0x%x\n\tdwValue: 0x%x\n", hDevNode, dwValue);
468 + status = CFG_E_INVALIDHDEVNODE;
470 + dwBuffSize = sizeof(dwValue);
471 + if (DSP_SUCCEEDED(status)) {
472 + /* Store the WCD device object in the Registry */
474 + if (!(CSL_Strcmp((char *)hDevNode, "TIOMAP1510"))) {
475 + GT_0trace(CFG_debugMask, GT_1CLASS,
476 + "Registering the DSP Device \n");
477 + status = REG_SetValue(NULL, (char *)hDevNode,
478 + "DEVICE_DSP", REG_DWORD,\
479 + (u8 *)&dwValue, dwBuffSize);
480 + if (DSP_SUCCEEDED(status)) {
481 + dwBuffSize = sizeof(hDevNode);
482 + status = REG_SetValue(NULL,
483 + (char *)hDevNode, "DEVNODESTRING_DSP",
484 + REG_DWORD, (u8 *)&hDevNode,
488 + GT_0trace(CFG_debugMask, GT_6CLASS,
489 + "Failed to Register Device \n");
493 + if (DSP_SUCCEEDED(status)) {
494 + GT_0trace(CFG_debugMask, GT_1CLASS,
495 + "CFG_SetDevObject SUCCESS \n");
497 + GT_0trace(CFG_debugMask, GT_6CLASS,
498 + "CFG_SetDevObject Failed \n");
505 + * ======== CFG_SetObject ========
507 + * Store the Driver Object handle
509 +DSP_STATUS CFG_SetObject(u32 dwValue, u32 dwType)
511 + DSP_STATUS status = DSP_EINVALIDARG;
513 + GT_1trace(CFG_debugMask, GT_ENTER,
514 + "Entered CFG_SetObject, args: dwValue: "
515 + "0x%x\n", dwValue);
516 + dwBuffSize = sizeof(dwValue);
518 + case (REG_DRV_OBJECT):
519 + status = REG_SetValue(NULL, CONFIG, DRVOBJECT, REG_DWORD,
520 + (u8 *)&dwValue, dwBuffSize);
522 + case (REG_MGR_OBJECT):
523 + status = REG_SetValue(NULL, CONFIG, MGROBJECT, REG_DWORD,
524 + (u8 *) &dwValue, dwBuffSize);
530 + if (DSP_SUCCEEDED(status))
531 + GT_0trace(CFG_debugMask, GT_1CLASS, "CFG_SetObject SUCCESS \n");
533 + GT_0trace(CFG_debugMask, GT_6CLASS, "CFG_SetObject Failed \n");
538 diff --git a/drivers/dsp/bridge/services/clk.c b/drivers/dsp/bridge/services/clk.c
540 index 0000000..dfe3e4f
542 +++ b/drivers/dsp/bridge/services/clk.c
545 + * linux/drivers/dsp/bridge/services/clk.c
547 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
549 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
551 + * This package is free software; you can redistribute it and/or modify
552 + * it under the terms of the GNU General Public License version 2 as
553 + * published by the Free Software Foundation.
555 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
556 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
557 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
561 + * ======== clk.c ========
563 + * Clock and Timer services.
565 + * Public Functions:
572 + *! Revision History:
573 + *! ================
574 + *! 08-May-2007 rg: moved all clock functions from sync module.
575 + * And added CLK_Set_32KHz, CLK_Set_SysClk.
578 +/* ----------------------------------- Host OS */
579 +#include <host_os.h>
581 +/* ----------------------------------- DSP/BIOS Bridge */
584 +#include <errbase.h>
586 +/* ----------------------------------- Trace & Debug */
590 +/* ----------------------------------- OS Adaptation Layer */
594 +/* ----------------------------------- This */
599 +/* ----------------------------------- Defines, Data Structures, Typedefs */
601 +typedef volatile unsigned long REG_UWORD32;
603 +#define SSI_Base 0x48058000
605 +#define SSI_BASE IO_ADDRESS(SSI_Base)
608 +struct SERVICES_Clk_t {
609 + struct clk *clk_handle;
610 + const char *clk_name;
613 +/* The row order of the below array needs to match with the clock enumerations
614 + * 'SERVICES_ClkId' provided in the header file.. any changes in the
615 + * enumerations needs to be fixed in the array as well */
616 +static struct SERVICES_Clk_t SERVICES_Clks[] = {
618 + {NULL, "mailboxes_ick"},
619 + {NULL, "gpt5_fck"},
620 + {NULL, "gpt5_ick"},
621 + {NULL, "gpt6_fck"},
622 + {NULL, "gpt6_ick"},
623 + {NULL, "gpt7_fck"},
624 + {NULL, "gpt7_ick"},
625 + {NULL, "gpt8_fck"},
626 + {NULL, "gpt8_ick"},
629 + {NULL, "mcbsp1_fck"},
630 + {NULL, "mcbsp1_ick"},
631 + {NULL, "mcbsp2_fck"},
632 + {NULL, "mcbsp2_ick"},
633 + {NULL, "mcbsp3_fck"},
634 + {NULL, "mcbsp3_ick"},
635 + {NULL, "mcbsp4_fck"},
636 + {NULL, "mcbsp4_ick"},
637 + {NULL, "mcbsp5_fck"},
638 + {NULL, "mcbsp5_ick"},
639 + {NULL, "ssi_ssr_sst_fck"},
641 + {NULL, "omap_32k_fck"},
647 +#ifndef CONFIG_DISABLE_BRIDGE_PM
648 +extern struct platform_device dspbridge_device;
653 +/* Generic TIMER object: */
654 +struct TIMER_OBJECT {
655 + struct timer_list timer;
658 +/* ----------------------------------- Globals */
660 +static struct GT_Mask CLK_debugMask = { NULL, NULL }; /* GT trace variable */
663 +struct GPT6_configuration {
671 +/* Shadow settings to save the GPT6 timer settings */
672 +struct GPT6_configuration gpt6_config;
675 + * ======== CLK_Exit ========
677 + * Cleanup CLK module.
683 + GT_0trace(CLK_debugMask, GT_5CLASS, "CLK_Exit\n");
684 + /* Relinquish the clock handles */
685 + while (i < SERVICESCLK_NOT_DEFINED) {
686 + if (SERVICES_Clks[i].clk_handle)
687 + clk_put(SERVICES_Clks[i].clk_handle);
689 + SERVICES_Clks[i].clk_handle = NULL;
696 + * ======== CLK_Init ========
698 + * Initialize CLK module.
702 + struct clk *clk_handle;
704 + GT_create(&CLK_debugMask, "CK"); /* CK for CLK */
705 + GT_0trace(CLK_debugMask, GT_5CLASS, "CLK_Init\n");
707 + /* Get the clock handles from base port and store locally */
708 + while (i < SERVICESCLK_NOT_DEFINED) {
709 + /* get the handle from BP */
710 +#ifndef CONFIG_DISABLE_BRIDGE_PM
711 + clk_handle = clk_get(&dspbridge_device.dev,
712 + SERVICES_Clks[i].clk_name);
714 + clk_handle = clk_get(NULL, SERVICES_Clks[i].clk_name);
718 + GT_1trace(CLK_debugMask, GT_7CLASS,
719 + "CLK_Init: failed to get Clk "
720 + "handle %s \n", SERVICES_Clks[i].clk_name);
721 + /* should we fail here?? */
723 + GT_1trace(CLK_debugMask, GT_7CLASS,
724 + "CLK_Init: PASS and Clk handle"
725 + "%s \n", SERVICES_Clks[i].clk_name);
727 + SERVICES_Clks[i].clk_handle = clk_handle;
735 + * ======== CLK_Enable ========
740 +DSP_STATUS CLK_Enable(IN enum SERVICES_ClkId clk_id)
742 + DSP_STATUS status = DSP_SOK;
745 + DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED);
746 + GT_1trace(CLK_debugMask, GT_6CLASS,
747 + "CLK_Enable: CLK Id = 0x%x \n", clk_id);
749 + pClk = SERVICES_Clks[clk_id].clk_handle;
751 + if (clk_enable(pClk) == 0x0) {
754 + GT_1trace(CLK_debugMask, GT_7CLASS,
755 + "CLK_Enable: failed to Enable "
756 + "CLK %s \n", SERVICES_Clks[clk_id].clk_name);
757 + status = DSP_EFAIL;
760 + GT_1trace(CLK_debugMask, GT_7CLASS,
761 + "CLK_Enable: failed to get "
762 + "CLK %s \n", SERVICES_Clks[clk_id].clk_name);
763 + status = DSP_EFAIL;
765 + /* The SSI module need to configured not to have the Forced idle for
766 + * master interface. If it is set to forced idle, the SSI module is
767 + * transitioning to standby thereby causing the client in the DSP hang
768 + * waiting for the SSI module to be active after enabling the clocks
770 + if (clk_id == SERVICESCLK_ssi_fck)
771 + SSI_Clk_Prepare(true);
776 + * ======== CLK_Set_32KHz ========
778 + * To Set parent of a clock to 32KHz.
781 +DSP_STATUS CLK_Set_32KHz(IN enum SERVICES_ClkId clk_id)
783 + DSP_STATUS status = DSP_SOK;
785 + struct clk *pClkParent;
786 + enum SERVICES_ClkId sys_32k_id = SERVICESCLK_sys_32k_ck;
787 + pClkParent = SERVICES_Clks[sys_32k_id].clk_handle;
789 + DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED);
790 + GT_1trace(CLK_debugMask, GT_6CLASS, "CLK_Set_32KHz: CLK Id = 0x%x is "
791 + "setting to 32KHz \n", clk_id);
792 + pClk = SERVICES_Clks[clk_id].clk_handle;
794 + if (!(clk_set_parent(pClk, pClkParent) == 0x0)) {
795 + GT_1trace(CLK_debugMask, GT_7CLASS,
796 + "CLK_Set_32KHz: Failed to "
797 + "set to 32KHz %s \n",
798 + SERVICES_Clks[clk_id].clk_name);
799 + status = DSP_EFAIL;
806 + * ======== CLK_Disable ========
808 + * Disable the clock.
811 +DSP_STATUS CLK_Disable(IN enum SERVICES_ClkId clk_id)
813 + DSP_STATUS status = DSP_SOK;
817 + DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED);
818 + GT_1trace(CLK_debugMask, GT_6CLASS,
819 + "CLK_Disable: CLK Id = 0x%x \n", clk_id);
821 + pClk = SERVICES_Clks[clk_id].clk_handle;
823 + clkUseCnt = CLK_Get_UseCnt(clk_id);
824 + if (clkUseCnt == -1) {
825 + GT_1trace(CLK_debugMask, GT_7CLASS,
826 + "CLK_Disable: failed to get "
827 + "CLK Use count for Clk %s \n",
828 + SERVICES_Clks[clk_id].clk_name);
829 + } else if (clkUseCnt == 0) {
830 + GT_1trace(CLK_debugMask, GT_7CLASS,
831 + "CLK_Disable: Clk %s is already"
832 + "disabled\n", SERVICES_Clks[clk_id].clk_name);
835 + if (clk_id == SERVICESCLK_ssi_ick)
836 + SSI_Clk_Prepare(false);
841 + GT_1trace(CLK_debugMask, GT_7CLASS,
842 + "CLK_Disable: failed to get "
843 + "CLK %s \n", SERVICES_Clks[clk_id].clk_name);
844 + status = DSP_EFAIL;
850 + * ======== CLK_GetRate ========
856 +DSP_STATUS CLK_GetRate(IN enum SERVICES_ClkId clk_id, u32 *speedKhz)
858 + DSP_STATUS status = DSP_SOK;
862 + DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED);
865 + GT_1trace(CLK_debugMask, GT_7CLASS,
866 + "CLK_GetRate: CLK Id = 0x%x \n", clk_id);
867 + pClk = SERVICES_Clks[clk_id].clk_handle;
869 + clkSpeedHz = clk_get_rate(pClk);
870 + *speedKhz = clkSpeedHz / 1000;
871 + GT_2trace(CLK_debugMask, GT_6CLASS,
872 + "CLK_GetRate: clkSpeedHz = %d , "
873 + "speedinKhz=%d \n", clkSpeedHz, *speedKhz);
875 + GT_1trace(CLK_debugMask, GT_7CLASS,
876 + "CLK_GetRate: failed to get CLK %s\n",
877 + SERVICES_Clks[clk_id].clk_name);
878 + status = DSP_EFAIL;
883 +s32 CLK_Get_UseCnt(IN enum SERVICES_ClkId clk_id)
885 + DSP_STATUS status = DSP_SOK;
888 + DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED);
890 + pClk = SERVICES_Clks[clk_id].clk_handle;
893 + useCount = clk_get_usecount(pClk);
895 + GT_1trace(CLK_debugMask, GT_7CLASS,
896 + "CLK_GetRate: failed to get "
897 + "CLK %s \n", SERVICES_Clks[clk_id].clk_name);
898 + status = DSP_EFAIL;
903 +void SSI_Clk_Prepare(bool FLAG)
906 + ssi_sysconfig = __raw_readl((SSI_BASE) + 0x10);
910 + /* Set Autoidle, SIDLEMode to smart idle, and MIDLEmode to
912 + ssi_sysconfig = 0x1011;
914 + /* Set Autoidle, SIDLEMode to forced idle, and MIDLEmode to
916 + ssi_sysconfig = 0x1;
918 + __raw_writel((u32)ssi_sysconfig, SSI_BASE + 0x10);
920 diff --git a/drivers/dsp/bridge/services/csl.c b/drivers/dsp/bridge/services/csl.c
922 index 0000000..a8b2ec8
924 +++ b/drivers/dsp/bridge/services/csl.c
927 + * linux/drivers/dsp/bridge/services/csl.c
929 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
931 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
933 + * This package is free software; you can redistribute it and/or modify
934 + * it under the terms of the GNU General Public License version 2 as
935 + * published by the Free Software Foundation.
937 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
938 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
939 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
944 + * ======== cslce.c ========
946 + * Provides platform independent C Standard library functions.
948 + * Public Functions:
961 + *! Revision History:
962 + *! ================
963 + *! 07-Aug-2002 jeh: Added CSL_Strtokr().
964 + *! 21-Sep-2001 jeh: Added CSL_Strncmp(). Alphabetized functions.
965 + *! 22-Nov-2000 map: Added CSL_Atoi and CSL_Strtok
966 + *! 19-Nov-2000 kc: Added CSL_ByteSwap.
967 + *! 09-Nov-2000 kc: Added CSL_Strncat.
968 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
970 + *! 15-Dec-1999 ag: Removed incorrect assertion CSL_NumToAscii()
971 + *! 29-Oct-1999 kc: Added CSL_Wstrlen for UNICODE strings.
972 + *! 30-Sep-1999 ag: Removed DBC assertion (!CSL_DebugMask.flags) in
974 + *! 20-Sep-1999 ag: Added CSL_WcharToAnsi().
975 + *! Removed call to GT_set().
976 + *! 19-Jan-1998 cr: Code review cleanup.
977 + *! 29-Dec-1997 cr: Made platform independant, using MS CRT code, and
978 + *! combined csl32.c csl95.c and cslnt.c into csl.c. Also
979 + *! changed CSL_lowercase to CSL_Uppercase.
980 + *! 21-Aug-1997 gp: Fix to CSL_strcpyn to initialize Source string, the NT way.
981 + *! 25-Jun-1997 cr: Created from csl95, added CSL_strcmp.
984 +/* ----------------------------------- Host OS */
985 +#include <host_os.h>
987 +/* ----------------------------------- DSP/BIOS Bridge */
991 +/* ----------------------------------- Trace & Debug */
995 +/* ----------------------------------- This */
998 +/* Is character c in the string pstrDelim? */
999 +#define IsDelimiter(c, pstrDelim) ((c != '\0') && \
1000 + (strchr(pstrDelim, c) != NULL))
1002 +/* ----------------------------------- Globals */
1004 +static struct GT_Mask CSL_DebugMask = { NULL, NULL }; /* GT trace var. */
1008 + * ======= CSL_Atoi =======
1010 + * Convert a string to an integer
1012 +s32 CSL_Atoi(IN CONST char *ptstrSrc)
1014 + char *end_position;
1016 + DBC_Require(ptstrSrc);
1018 + return simple_strtol(ptstrSrc, &end_position, 10);
1022 + * ======== CSL_Exit ========
1024 + * Discontinue usage of the CSL module.
1026 +void CSL_Exit(void)
1028 + GT_0trace(CSL_DebugMask, GT_5CLASS, "CSL_Exit\n");
1032 + * ======== CSL_Init ========
1034 + * Initialize the CSL module's private state.
1036 +bool CSL_Init(void)
1038 + GT_create(&CSL_DebugMask, "CS");
1040 + GT_0trace(CSL_DebugMask, GT_5CLASS, "CSL_Init\n");
1046 + * ======== CSL_NumToAscii ========
1048 + * Convert a 1 or 2 digit number to a 2 digit string.
1050 +void CSL_NumToAscii(OUT char *pstrNumber, u32 dwNum)
1054 + DBC_Require(dwNum < 100);
1056 + if (dwNum < 100) {
1057 + tens = (char) dwNum / 10;
1058 + dwNum = dwNum % 10;
1061 + pstrNumber[0] = tens + '0';
1062 + pstrNumber[1] = (char) dwNum + '0';
1063 + pstrNumber[2] = '\0';
1065 + pstrNumber[0] = (char) dwNum + '0';
1066 + pstrNumber[1] = '\0';
1069 + pstrNumber[0] = '\0';
1074 + * ======== CSL_Strcmp ========
1076 + * Compare 2 ASCII strings. Works the same was as stdio's strcmp.
1078 +s32 CSL_Strcmp(IN CONST char *pstrStr1, IN CONST char *pstrStr2)
1080 + return strcmp(pstrStr1, pstrStr2);
1084 + * ======== CSL_Strstr ========
1086 + * Find substring in a stringn.
1088 + * haystack: Ptr to string1.
1089 + * needle: Ptr to substring to catch.
1091 + * Ptr to first char matching the substring in the main string.
1093 + * CSL initialized.
1094 + * haystack is valid.
1095 + * needle is valid.
1099 +char *CSL_Strstr(IN CONST char *haystack, IN CONST char *needle)
1101 + return strstr(haystack, needle);
1105 + * ======== CSL_Strcpyn ========
1107 + * Safe strcpy function.
1109 +char *CSL_Strcpyn(OUT char *pstrDest, IN CONST char *pstrSrc, u32 cMax)
1111 + return strncpy(pstrDest, pstrSrc, cMax);
1115 + * ======== CSL_Strlen ========
1117 + * Determine the length of a null terminated ASCII string.
1119 +u32 CSL_Strlen(IN CONST char *pstrSrc)
1121 + CONST char *pStr = pstrSrc;
1124 + DBC_Require(pstrSrc);
1129 + retVal = (u32) (pStr - pstrSrc - 1);
1134 + * ======== CSL_Strncat ========
1136 + * Concatenate two strings together
1138 +char *CSL_Strncat(IN char *pszDest, IN char *pszSrc, IN u32 dwSize)
1141 + DBC_Require(pszDest && pszSrc);
1143 + return strncat(pszDest, pszSrc, dwSize);
1147 + * ======== CSL_Strncmp ========
1149 + * Compare at most n characters of two ASCII strings. Works the same
1150 + * way as stdio's strncmp.
1152 +s32 CSL_Strncmp(IN CONST char *pstrStr1, IN CONST char *pstrStr2, u32 n)
1154 + return strncmp(pstrStr1, pstrStr2, n);
1158 + * ======= CSL_Strtokr =======
1160 + * Re-entrant version of strtok.
1162 +char *CSL_Strtokr(IN char *pstrSrc, IN CONST char *szSeparators,
1163 + OUT char **ppstrLast)
1168 + DBC_Require(szSeparators != NULL);
1169 + DBC_Require(ppstrLast != NULL);
1170 + DBC_Require(pstrSrc != NULL || *ppstrLast != NULL);
1173 + * Set string location to beginning (pstrSrc != NULL) or to the
1174 + * beginning of the next token.
1176 + pstrTemp = (pstrSrc != NULL) ? pstrSrc : *ppstrLast;
1177 + if (*pstrTemp == '\0') {
1180 + pstrToken = pstrTemp;
1181 + while (*pstrTemp != '\0' && !IsDelimiter(*pstrTemp,
1185 + if (*pstrTemp != '\0') {
1186 + while (IsDelimiter(*pstrTemp, szSeparators)) {
1187 + /* TODO: Shouldn't we do this for
1188 + * only 1 char?? */
1194 + /* Location in string for next call */
1195 + *ppstrLast = pstrTemp;
1200 diff --git a/drivers/dsp/bridge/services/dbg.c b/drivers/dsp/bridge/services/dbg.c
1201 new file mode 100644
1202 index 0000000..b93f1de
1204 +++ b/drivers/dsp/bridge/services/dbg.c
1207 + * linux/drivers/dsp/bridge/services/dbg.c
1209 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1211 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1213 + * This package is free software; you can redistribute it and/or modify
1214 + * it under the terms of the GNU General Public License version 2 as
1215 + * published by the Free Software Foundation.
1217 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1218 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1219 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1224 + * ======== dbgce.c ========
1226 + * Provide debugging services for DSP/BIOS Bridge Mini Drivers.
1228 + * Public Functions:
1236 + * This implementation does not create GT masks on a per WMD basis.
1237 + * There is currently no facility for a WMD to alter the GT mask.
1239 + *! Revision History:
1240 + *! ================
1241 + *! 15-Feb-2000 rr: DBG_Trace prints based on the DebugZones.
1242 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
1244 + *! 29-Oct-1999 kc: Cleaned up for code review.
1245 + *! 10-Oct-1997 cr: Added DBG_Printf service.
1246 + *! 28-May-1997 cr: Added reference counting.
1247 + *! 23-May-1997 cr: Updated DBG_Trace to new gt interface.
1248 + *! 29-May-1996 gp: Removed WCD_ prefix.
1249 + *! 20-May-1996 gp: Remove DEBUG conditional compilation.
1250 + *! 15-May-1996 gp: Created.
1253 +/* ----------------------------------- DSP/BIOS Bridge */
1255 +#include <dbdefs.h>
1256 +#include <errbase.h>
1258 +/* ----------------------------------- Trace & Debug */
1262 +/* ----------------------------------- This */
1265 +/* ----------------------------------- Globals */
1267 +static struct GT_Mask DBG_debugMask = { NULL, NULL }; /* GT trace var. */
1270 +#if ((defined DEBUG) || (defined DDSP_DEBUG_PRODUCT)) && GT_TRACE
1273 + * ======== DBG_Init ========
1275 + * Ensures trace capability is set up for link drivers.
1277 +bool DBG_Init(void)
1279 + GT_create(&DBG_debugMask, "WD"); /* for WmD (link driver) debug */
1281 + GT_0trace(DBG_debugMask, GT_5CLASS, "DBG_Init\n");
1287 + * ======== DBG_Trace ========
1289 + * Output a trace message to the debugger, if the given trace level
1292 +DSP_STATUS DBG_Trace(u8 bLevel, char *pstrFormat, ...)
1294 + s32 arg1, arg2, arg3, arg4, arg5, arg6;
1297 + va_start(va, pstrFormat);
1299 + arg1 = va_arg(va, s32);
1300 + arg2 = va_arg(va, s32);
1301 + arg3 = va_arg(va, s32);
1302 + arg4 = va_arg(va, s32);
1303 + arg5 = va_arg(va, s32);
1304 + arg6 = va_arg(va, s32);
1308 + if (bLevel & *(DBG_debugMask).flags)
1309 + (*GT->PRINTFXN)(pstrFormat, arg1, arg2, arg3, arg4, arg5, arg6);
1315 + * ======== DBG_Exit ========
1317 + * Discontinue usage of the DBG module.
1319 +void DBG_Exit(void)
1321 + GT_0trace(DBG_debugMask, GT_5CLASS, "DBG_Exit\n");
1324 +#endif /* ((defined DEBUG) || (defined DDSP_DEBUG_PRODUCT)) && GT_TRACE */
1325 diff --git a/drivers/dsp/bridge/services/dpc.c b/drivers/dsp/bridge/services/dpc.c
1326 new file mode 100644
1327 index 0000000..a053ee7
1329 +++ b/drivers/dsp/bridge/services/dpc.c
1332 + * linux/drivers/dsp/bridge/services/dpc.c
1334 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1336 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1338 + * This package is free software; you can redistribute it and/or modify
1339 + * it under the terms of the GNU General Public License version 2 as
1340 + * published by the Free Software Foundation.
1342 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1343 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1344 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1349 + * ======== dpcce.c ========
1351 + * Deferred Procedure Call(DPC) Services.
1354 + * Public Functions:
1361 + *! Revision History:
1362 + *! ================
1363 + *! 28-Mar-2001 ag: Added #ifdef CHNL_NOIPCINTR to set DPC thread priority
1364 + *! to THREAD_PRIORITY_IDLE for polling IPC.
1365 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
1367 + *! 31-Jan-2000 rr: Changes after code review.Terminate thread,handle
1368 + *! modified.DPC_Destroy frees the DPC_Object only on
1369 + *! Successful termination of the thread and the handle.
1370 + *! 06-Jan-1999 ag: Format cleanup for code review.
1371 + *! Removed DPC_[Lower|Raise]IRQL[From|To]DispatchLevel.
1372 + *! 10-Dec-1999 ag: Added SetProcPermissions in DPC_DeferredProcedure().
1373 + *! (Needed to access client(s) CHNL buffers).
1374 + *! 19-Sep-1999 a0216266: Stubbed from dpcnt.c.
1377 +/* ----------------------------------- Host OS */
1378 +#include <host_os.h>
1380 +/* ----------------------------------- DSP/BIOS Bridge */
1382 +#include <dbdefs.h>
1383 +#include <errbase.h>
1385 +/* ----------------------------------- Trace & Debug */
1389 +/* ----------------------------------- OS Adaptation Layer */
1392 +/* ----------------------------------- This */
1395 +/* ----------------------------------- Defines, Data Structures, Typedefs */
1396 +#define SIGNATURE 0x5f435044 /* "DPC_" (in reverse). */
1398 +/* The DPC object, passed to our priority event callback routine: */
1399 +struct DPC_OBJECT {
1400 + u32 dwSignature; /* Used for object validation. */
1401 + void *pRefData; /* Argument for client's DPC. */
1402 + DPC_PROC pfnDPC; /* Client's DPC. */
1403 + u32 numRequested; /* Number of requested DPC's. */
1404 + u32 numScheduled; /* Number of executed DPC's. */
1405 + struct tasklet_struct dpc_tasklet;
1408 + u32 cEntryCount; /* Number of times DPC reentered. */
1409 + u32 numRequestedMax; /* Keep track of max pending DPC's. */
1412 + spinlock_t dpc_lock;
1415 +/* ----------------------------------- Globals */
1417 +static struct GT_Mask DPC_DebugMask = { NULL, NULL }; /* DPC Debug Mask */
1420 +/* ----------------------------------- Function Prototypes */
1421 +static void DPC_DeferredProcedure(IN unsigned long pDeferredContext);
1424 + * ======== DPC_Create ========
1426 + * Create a DPC object, allowing a client's own DPC procedure to be
1427 + * scheduled for a call with client reference data.
1429 +DSP_STATUS DPC_Create(OUT struct DPC_OBJECT **phDPC, DPC_PROC pfnDPC,
1432 + DSP_STATUS status = DSP_SOK;
1433 + struct DPC_OBJECT *pDPCObject = NULL;
1435 + if ((phDPC != NULL) && (pfnDPC != NULL)) {
1437 + * Allocate a DPC object to store information allowing our DPC
1438 + * callback to dispatch to the client's DPC.
1440 + MEM_AllocObject(pDPCObject, struct DPC_OBJECT, SIGNATURE);
1441 + if (pDPCObject != NULL) {
1442 + tasklet_init(&pDPCObject->dpc_tasklet,
1443 + DPC_DeferredProcedure,
1444 + (u32) pDPCObject);
1445 + /* Fill out our DPC Object: */
1446 + pDPCObject->pRefData = pRefData;
1447 + pDPCObject->pfnDPC = pfnDPC;
1448 + pDPCObject->numRequested = 0;
1449 + pDPCObject->numScheduled = 0;
1451 + pDPCObject->numRequestedMax = 0;
1452 + pDPCObject->cEntryCount = 0;
1454 + pDPCObject->dpc_lock =
1455 + __SPIN_LOCK_UNLOCKED(pDPCObject.dpc_lock);
1456 + *phDPC = pDPCObject;
1458 + GT_0trace(DPC_DebugMask, GT_6CLASS,
1459 + "DPC_Create: DSP_EMEMORY\n");
1460 + status = DSP_EMEMORY;
1463 + GT_0trace(DPC_DebugMask, GT_6CLASS,
1464 + "DPC_Create: DSP_EPOINTER\n");
1465 + status = DSP_EPOINTER;
1467 + DBC_Ensure((DSP_FAILED(status) && (!phDPC || (phDPC && *phDPC == NULL)))
1468 + || DSP_SUCCEEDED(status));
1473 + * ======== DPC_Destroy ========
1475 + * Cancel the last scheduled DPC, and deallocate a DPC object previously
1476 + * allocated with DPC_Create(). Frees the Object only if the thread
1477 + * and the event terminated successfuly.
1479 +DSP_STATUS DPC_Destroy(struct DPC_OBJECT *hDPC)
1481 + DSP_STATUS status = DSP_SOK;
1482 + struct DPC_OBJECT *pDPCObject = (struct DPC_OBJECT *)hDPC;
1484 + if (MEM_IsValidHandle(hDPC, SIGNATURE)) {
1486 + /* Free our DPC object: */
1487 + if (DSP_SUCCEEDED(status)) {
1488 + tasklet_kill(&pDPCObject->dpc_tasklet);
1489 + MEM_FreeObject(pDPCObject);
1490 + pDPCObject = NULL;
1491 + GT_0trace(DPC_DebugMask, GT_2CLASS,
1492 + "DPC_Destroy: SUCCESS\n");
1495 + GT_0trace(DPC_DebugMask, GT_6CLASS,
1496 + "DPC_Destroy: DSP_EHANDLE\n");
1497 + status = DSP_EHANDLE;
1499 + DBC_Ensure((DSP_SUCCEEDED(status) && pDPCObject == NULL)
1500 + || DSP_FAILED(status));
1505 + * ======== DPC_Exit ========
1507 + * Discontinue usage of the DPC module.
1509 +void DPC_Exit(void)
1511 + GT_0trace(DPC_DebugMask, GT_5CLASS, "Entered DPC_Exit\n");
1515 + * ======== DPC_Init ========
1517 + * Initialize the DPC module's private state.
1519 +bool DPC_Init(void)
1521 + GT_create(&DPC_DebugMask, "DP");
1523 + GT_0trace(DPC_DebugMask, GT_5CLASS, "Entered DPC_Init\n");
1529 + * ======== DPC_Schedule ========
1531 + * Schedule a deferred procedure call to be executed at a later time.
1532 + * Latency and order of DPC execution is platform specific.
1534 +DSP_STATUS DPC_Schedule(struct DPC_OBJECT *hDPC)
1536 + DSP_STATUS status = DSP_SOK;
1537 + struct DPC_OBJECT *pDPCObject = (struct DPC_OBJECT *)hDPC;
1538 + unsigned long flags;
1540 + GT_1trace(DPC_DebugMask, GT_ENTER, "DPC_Schedule hDPC %x\n", hDPC);
1541 + if (MEM_IsValidHandle(hDPC, SIGNATURE)) {
1542 + /* Increment count of DPC's pending. Needs to be protected
1543 + * from ISRs since this function is called from process
1544 + * context also. */
1545 + spin_lock_irqsave(&hDPC->dpc_lock, flags);
1546 + pDPCObject->numRequested++;
1547 + spin_unlock_irqrestore(&hDPC->dpc_lock, flags);
1548 + tasklet_schedule(&(hDPC->dpc_tasklet));
1550 + if (pDPCObject->numRequested > pDPCObject->numScheduled +
1551 + pDPCObject->numRequestedMax) {
1552 + pDPCObject->numRequestedMax = pDPCObject->numRequested -
1553 + pDPCObject->numScheduled;
1556 + /* If an interrupt occurs between incrementing numRequested and the
1557 + * assertion below, then DPC will get executed while returning from
1558 + * ISR, which will complete all requests and make numRequested equal
1559 + * to numScheduled, firing this assertion. This happens only when
1560 + * DPC is being scheduled in process context */
1562 + GT_0trace(DPC_DebugMask, GT_6CLASS,
1563 + "DPC_Schedule: DSP_EHANDLE\n");
1564 + status = DSP_EHANDLE;
1566 + GT_1trace(DPC_DebugMask, GT_ENTER, "DPC_Schedule status %x\n", status);
1571 + * ======== DeferredProcedure ========
1573 + * Main DPC routine. This is called by host OS DPC callback
1574 + * mechanism with interrupts enabled.
1576 +static void DPC_DeferredProcedure(IN unsigned long pDeferredContext)
1578 + struct DPC_OBJECT *pDPCObject = (struct DPC_OBJECT *)pDeferredContext;
1579 + /* read numRequested in local variable */
1583 + DBC_Require(pDPCObject != NULL);
1584 + requested = pDPCObject->numRequested;
1585 + serviced = pDPCObject->numScheduled;
1587 + GT_1trace(DPC_DebugMask, GT_ENTER, "> DPC_DeferredProcedure "
1588 + "pDeferredContext=%x\n", pDeferredContext);
1589 + /* Rollover taken care of using != instead of < */
1590 + if (serviced != requested) {
1591 + if (pDPCObject->pfnDPC != NULL) {
1592 + /* Process pending DPC's: */
1594 + /* Call client's DPC: */
1595 + (*(pDPCObject->pfnDPC))(pDPCObject->pRefData);
1597 + } while (serviced != requested);
1599 + pDPCObject->numScheduled = requested;
1601 + GT_2trace(DPC_DebugMask, GT_ENTER,
1602 + "< DPC_DeferredProcedure requested %d"
1603 + " serviced %d\n", requested, serviced);
1606 diff --git a/drivers/dsp/bridge/services/isr.c b/drivers/dsp/bridge/services/isr.c
1607 new file mode 100644
1608 index 0000000..781a19c
1610 +++ b/drivers/dsp/bridge/services/isr.c
1613 + * linux/drivers/dsp/bridge/services/isr.c
1615 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1617 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1619 + * This package is free software; you can redistribute it and/or modify
1620 + * it under the terms of the GNU General Public License version 2 as
1621 + * published by the Free Software Foundation.
1623 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1624 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1625 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1630 + * ======== isrce.c ========
1632 + * Interrupt services.
1634 + * Public Functions:
1641 + *! Revision History:
1642 + *! ================
1643 + *! 06-Feb-2003 kc: Renamed DSP_MAILBOX1 to ISR_MAILBOX1.
1644 + *! 14-Mar-2002 rr: Added HELEN1_V1 flag while installing the interrupt.
1645 + *! 05-Nov-2001 kc: Updated ISR_Install to support multiple HW interrupts.
1646 + *! 27-Jul-2001 rr: Interrupt Id is based on x86 or ARM define.
1647 + *! 24-Apr-2001 ag: Replaced nkintr.h with hw.h.
1648 + *! 10-Oct-2000 rr: CeSetThreadPriority used instead of SetThreadPriority.
1649 + *! 11-Aug-2000 ag: Removed #include <stdwin.h>
1650 + *! 10-Aug-2000 rr: InterruptInitialize happens before the IST creation.
1651 + *! 15-Feb-2000 rr: InterruptInitialize return value checked.
1652 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
1654 + *! 31-Jan-2000 rr: Changes after code review.Terminate thread,handle
1655 + *! modified.ISR_UnInstall frees the ISR_Object only on
1656 + *! Successful termination of the thread and the handle.
1657 + *! 19-Jan-2000 rr: Code Cleaned up after code review.
1658 + *! 06-Jan-2000 rr: Bus type included in the IRQ object. It is checked
1659 + *! during the install and uninstall.
1660 + *! 29-Dec-1999 rr: WaitForSingleObject removed during ISR_UnInstall
1661 + *! 22-Nov-1999 rr: Event gets created before CardRequestIRQ
1662 + *! 05-Nov-1999 rr: ISR_Install does not intialize the interrupt for PCMCIA
1663 + *! For other bus type this will happen. IST function return
1664 + *! value not checked as anyway we have to say InterruptDone
1665 + *! 29-Oct-1999 rr: Hardware IST is created here.
1666 + *! 25-Oct-1999 rr: New Isr design.
1667 + *! 13-Sep-1999 a0216266: Stubbed from isrnt.c.
1670 +/* ----------------------------------- Host OS */
1671 +#include <host_os.h>
1673 +/* ----------------------------------- DSP/BIOS Bridge */
1675 +#include <dbdefs.h>
1676 +#include <errbase.h>
1678 +/* ----------------------------------- Trace & Debug */
1682 +/* ----------------------------------- OS Adaptation Layer */
1686 +/* ----------------------------------- This */
1689 +/* ----------------------------------- Defines, Data Structures, Typedefs */
1690 +#define SIGNATURE 0x5f525349 /* "ISR_" (in reverse). */
1692 +/* The IRQ object, passed to our hardware and virtual interrupt routines: */
1694 + u32 dwSignature; /* Used for object validation. */
1695 + void *pRefData; /* Argument for client's ISR. */
1696 + ISR_PROC pfnISR; /* Client's ISR. */
1698 + u32 dwIntrID; /* hardware intertupt identifier */
1701 +/* ----------------------------------- Globals & Defines */
1703 +static struct GT_Mask ISR_DebugMask = { NULL, NULL }; /* ISR Debug Mask */
1706 +/* ----------------------------------- Function Prototypes */
1707 +static irqreturn_t HardwareIST(int irq, void *hIRQ);
1710 + * ======== ISR_Exit ========
1712 + * Discontinue usage of the ISR module.
1714 +void ISR_Exit(void)
1716 + GT_0trace(ISR_DebugMask, GT_ENTER, "Entered ISR_Exit\n");
1720 + * ======== ISR_Init ========
1722 + * Initialize the ISR module's private state.
1724 +bool ISR_Init(void)
1726 + GT_create(&ISR_DebugMask, "IS");
1728 + GT_0trace(ISR_DebugMask, GT_5CLASS, "Entered ISR_Init\n");
1734 + * ======== ISR_Install ========
1736 + * Register an ISR for a given IRQ with the system's interrupt manager.
1738 +DSP_STATUS ISR_Install(OUT struct ISR_IRQ **phIRQ,
1739 + IN CONST struct CFG_HOSTRES *pHostConfig,
1740 + ISR_PROC pfnISR, u32 dwIntrType, void *pRefData)
1742 + DSP_STATUS status = DSP_SOK;
1743 + struct ISR_IRQ *pIRQObject = NULL;
1745 + DBC_Require(pHostConfig);
1746 + DBC_Require(pRefData != NULL);
1748 + GT_5trace(ISR_DebugMask, GT_ENTER,
1749 + "Entered ISR_Install, args:" "\n\thIRQ:"
1750 + "0x%x\n\tpHostConfig: 0x%x\n\tpfnISR: 0x%x\n" "\tpRefData:"
1751 + "0x%x\n \tdwIntrType 0x%x\n", phIRQ, pHostConfig, pfnISR,
1752 + pRefData, dwIntrType);
1754 + if (phIRQ != NULL) {
1757 + * Allocate an IRQ object to store information allowing our
1758 + * interrupt handler to dispatch to the client's interrupt
1761 + MEM_AllocObject(pIRQObject, struct ISR_IRQ, SIGNATURE);
1762 + if (pIRQObject != NULL) {
1763 + /* Fill out the Object: */
1764 + pIRQObject->pRefData = pRefData;
1765 + pIRQObject->pfnISR = pfnISR;
1767 + /* Install different HW interrupts based on interrupt
1769 + switch (dwIntrType) {
1770 + case ISR_MAILBOX1:
1771 + pIRQObject->dwIntrID = INT_MAIL_MPU_IRQ;
1773 + GT_0trace(ISR_DebugMask, GT_1CLASS,
1774 + "Setting intr id for "
1775 + "ISR_MAILBOX1\n");
1778 + case ISR_MAILBOX2:
1779 + pIRQObject->dwIntrID = MAIL_U3_MPU_IRQ;
1780 + GT_0trace(ISR_DebugMask, GT_1CLASS,
1781 + "Setting intr id for "
1782 + "ISR_MAILBOX2\n");
1786 + case DSP_MMUFAULT:
1787 + pIRQObject->dwIntrID = INT_DSP_MMU_IRQ;
1788 + GT_0trace(ISR_DebugMask, GT_1CLASS,
1789 + "Setting intr id for "
1790 + "DSP_MMUFAULT\n");
1794 + pIRQObject->dwIntrID = (u32) 0x00;
1795 + GT_0trace(ISR_DebugMask, GT_1CLASS,
1796 + "Setting intr id to NULL\n");
1800 + if (pIRQObject->dwIntrID != 0) {
1801 + status = request_irq(pIRQObject->dwIntrID,
1803 + "DspBridge", pIRQObject);
1805 + status = DSP_EINVALIDARG;
1808 + if (DSP_SUCCEEDED(status)) {
1809 + *phIRQ = pIRQObject;
1810 + GT_1trace(ISR_DebugMask, GT_1CLASS,
1811 + "ISR:IRQ Object 0x%x \n",
1814 + MEM_FreeObject(pIRQObject);
1817 + DBC_Ensure(DSP_SUCCEEDED(status) || (!phIRQ || *phIRQ == NULL));
1822 + * ======== ISR_Uninstall ========
1824 + * Deregister the ISR previously installed by ISR_Install().
1825 + * if it fails we do not delete the IRQ object.
1827 +DSP_STATUS ISR_Uninstall(struct ISR_IRQ *hIRQ)
1829 + DSP_STATUS status = DSP_SOK;
1830 + struct ISR_IRQ *pIRQObject = (struct ISR_IRQ *)hIRQ;
1832 + DBC_Require(hIRQ > 0);
1834 + GT_1trace(ISR_DebugMask, GT_ENTER,
1835 + "Entered ISR_Uninstall, hIRQ: 0x%x\n", hIRQ);
1837 + if (MEM_IsValidHandle(hIRQ, SIGNATURE)) {
1838 + /* Linux function to uninstall ISR */
1839 + free_irq(pIRQObject->dwIntrID, pIRQObject);
1840 + pIRQObject->dwIntrID = (u32) -1;
1842 + status = DSP_EHANDLE;
1845 + /* Free our IRQ object: */
1846 + if (DSP_SUCCEEDED(status)) {
1847 + MEM_FreeObject(pIRQObject);
1848 + pIRQObject = NULL;
1851 + DBC_Ensure((DSP_SUCCEEDED(status) && pIRQObject == NULL) ||
1852 + DSP_FAILED(status));
1858 + * ======== HardwareIST ========
1860 + * Linux calls this IRQ handler on interrupt.
1862 +static irqreturn_t HardwareIST(int irq, void *hIRQ)
1864 + struct ISR_IRQ *pIRQObject = (struct ISR_IRQ *)hIRQ;
1866 + DBC_Require(irq == pIRQObject->dwIntrID);
1868 + /* Call the function registered in ISR_Install */
1869 + (*(pIRQObject->pfnISR)) (pIRQObject->pRefData);
1871 + return IRQ_HANDLED;
1873 diff --git a/drivers/dsp/bridge/services/kfile.c b/drivers/dsp/bridge/services/kfile.c
1874 new file mode 100644
1875 index 0000000..d5c02e3
1877 +++ b/drivers/dsp/bridge/services/kfile.c
1880 + * linux/drivers/dsp/bridge/services/kfile.c
1882 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1884 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1886 + * This package is free software; you can redistribute it and/or modify
1887 + * it under the terms of the GNU General Public License version 2 as
1888 + * published by the Free Software Foundation.
1890 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1891 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1892 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1897 + * ======== kfilece.c ========
1899 + * This module provides file i/o services.
1901 + * Public Functions:
1910 + *! Revision History
1911 + *! ================
1912 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
1914 + *! 22-Nov-1999 kc: Added changes from code review.
1915 + *! 12-Nov-1999 kc: Enabled CSL for UNICODE/ANSI string conversions.
1916 + *! 30-Sep-1999 ag: Changed KFILE_Read() GT level from _ENTER to _4CLASS.
1917 + *! Removed GT_set().
1918 + *! 25-Aug-1999 ag: Changed MEM_Calloc allocation type to MEM_PAGED.
1919 + *! 13-Jul-1999 a0216266(ww - TID): Stubbed from kfilent.c.
1922 +/* ----------------------------------- Host OS */
1923 +#include <host_os.h>
1925 +/* ----------------------------------- DSP/BIOS Bridge */
1927 +#include <dbdefs.h>
1928 +#include <errbase.h>
1930 +/* ----------------------------------- Trace & Debug */
1934 +/* ----------------------------------- OS Adaptation Layer */
1939 +/* ----------------------------------- This */
1942 +/* ----------------------------------- Defines, Data Structures, Typedefs */
1943 +#define SIGNATURE 0x4c49464b /* hex code of KFIL (reversed) */
1944 +#define MAXFILENAMELENGTH 256
1945 +#define GENERAL_FAILURE 0xffffffff /* SetFilePointer error */
1947 +/* The KFILE_FileObj abstracts the true file handle from a KFILE handle. */
1948 +struct KFILE_FileObj {
1950 + __kernel_pid_t owner_pid; /* PID of process that opened this file */
1955 + long hInternal; /* internal handle of file */
1956 + struct file *fileDesc;
1960 +/* ----------------------------------- Globals */
1962 +static struct GT_Mask KFILE_debugMask = { NULL, NULL }; /* Debug mask */
1966 + * ======== KFILE_Close ========
1968 + * This function closes a file's stream.
1970 +s32 KFILE_Close(struct KFILE_FileObj *hFile)
1972 + s32 cRetVal = 0; /* 0 indicates success */
1974 + __kernel_pid_t curr_pid;
1976 + GT_1trace(KFILE_debugMask, GT_ENTER, "KFILE_Close: hFile 0x%x\n",
1979 + /* Check for valid handle */
1980 + if (MEM_IsValidHandle(hFile, SIGNATURE)) {
1981 + /* Close file only if opened by the same process (id). Otherwise
1982 + * Linux closes all open file handles when process exits.*/
1983 + PRCS_GetCurrentHandle((void **)&curr_pid);
1985 + fRetVal = filp_close(hFile->fileDesc, NULL) ;
1987 + cRetVal = E_KFILE_ERROR;
1988 + GT_1trace(KFILE_debugMask, GT_6CLASS,
1989 + "KFILE_Close: sys_close "
1990 + "returned %d\n", fRetVal);
1992 + MEM_FreeObject(hFile);
1994 + cRetVal = E_KFILE_INVALIDHANDLE;
1995 + GT_0trace(KFILE_debugMask, GT_6CLASS, "KFILE_Close: "
1996 + "invalid file handle\n");
2002 + * ======== KFILE_Exit ========
2004 + * Decrement reference count, and free resources when reference count
2007 +void KFILE_Exit(void)
2009 + GT_0trace(KFILE_debugMask, GT_5CLASS, "KFILE_Exit\n");
2013 + * ======== KFILE_Init ========
2015 +bool KFILE_Init(void)
2017 + GT_create(&KFILE_debugMask, "KF"); /* "KF" for KFile */
2019 + GT_0trace(KFILE_debugMask, GT_5CLASS, "KFILE_Init\n");
2025 + * ======== KFILE_Open ========
2027 + * Open a file for reading ONLY
2029 +struct KFILE_FileObj *KFILE_Open(CONST char *pszFileName, CONST char *pszMode)
2031 + struct KFILE_FileObj *hFile; /* file handle */
2032 + DSP_STATUS status;
2035 + struct file*fileDesc = NULL;
2036 + DBC_Require(pszMode != NULL);
2037 + DBC_Require(pszFileName != NULL);
2039 + GT_2trace(KFILE_debugMask, GT_ENTER,
2040 + "KFILE_Open: pszFileName %s, pszMode "
2041 + "%s\n", pszFileName, pszMode);
2043 + /* create a KFILE object */
2044 + MEM_AllocObject(hFile, struct KFILE_FileObj, SIGNATURE);
2049 + /* Third argument is mode (permissions). Ignored unless creating file */
2050 + fileDesc = filp_open(pszFileName, O_RDONLY, 0);
2051 + if ((IS_ERR(fileDesc)) || (fileDesc == NULL) ||
2052 + (fileDesc->f_op == NULL) || (fileDesc->f_op->read == NULL)
2053 + || (fileDesc->f_op->llseek == NULL)) {
2054 + status = DSP_EFILE;
2056 + hFile->fileDesc = fileDesc;
2057 + hFile->fileName = (char *)pszFileName;
2058 + hFile->isOpen = true;
2059 + hFile->curPos = 0;
2060 + hFile->size = fileDesc->f_op->llseek(fileDesc, 0,
2062 + fileDesc->f_op->llseek(fileDesc, 0, SEEK_SET);
2063 + PRCS_GetCurrentHandle((void **) &hFile->owner_pid);
2067 + if (DSP_FAILED(status)) {
2068 + /* free memory, and clear handle */
2069 + MEM_FreeObject(hFile);
2073 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2074 + "KFILE_Open: MEM_AllocObject failed\n");
2075 + status = DSP_EMEMORY;
2081 + * ======== KFILE_Read ========
2083 + * Reads a specified number of bytes into a buffer.
2086 +KFILE_Read(void *pBuffer, s32 cSize, s32 cCount, struct KFILE_FileObj *hFile)
2088 + u32 dwBytesRead = 0;
2092 + DBC_Require(pBuffer != NULL);
2094 + GT_4trace(KFILE_debugMask, GT_4CLASS,
2095 + "KFILE_Read: buffer 0x%x, cSize 0x%x,"
2096 + "cCount 0x%x, hFile 0x%x\n", pBuffer, cSize, cCount, hFile);
2098 + /* check for valid file handle */
2099 + if (MEM_IsValidHandle(hFile, SIGNATURE)) {
2100 + if ((cSize > 0) && (cCount > 0) && pBuffer) {
2101 + /* read from file */
2104 + dwBytesRead = hFile->fileDesc->f_op->read(hFile->
2105 + fileDesc, pBuffer, cSize *cCount,
2106 + &(hFile->fileDesc->f_pos));
2108 + if (dwBytesRead) {
2109 + cRetVal = dwBytesRead / cSize;
2110 + hFile->curPos += dwBytesRead;
2111 + DBC_Assert((dwBytesRead / cSize) <= \
2114 + cRetVal = E_KFILE_ERROR;
2115 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2116 + "KFILE_Read: sys_read() failed\n");
2119 + cRetVal = DSP_EINVALIDARG;
2120 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2121 + "KFILE_Read: Invalid argument(s)\n");
2124 + cRetVal = E_KFILE_INVALIDHANDLE;
2125 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2126 + "KFILE_Read: invalid file handle\n");
2133 + * ======== KFILE_Seek ========
2135 + * Sets the file position indicator. NOTE: we don't support seeking
2136 + * beyond the boundaries of a file.
2138 +s32 KFILE_Seek(struct KFILE_FileObj *hFile, s32 lOffset, s32 cOrigin)
2140 + s32 cRetVal = 0; /* 0 for success */
2143 + struct file *fileDesc = NULL;
2145 + GT_3trace(KFILE_debugMask, GT_ENTER, "KFILE_Seek: hFile 0x%x, "
2146 + "lOffset 0x%x, cOrigin 0x%x\n",
2147 + hFile, lOffset, cOrigin);
2149 + /* check for valid file handle */
2150 + if (MEM_IsValidHandle(hFile, SIGNATURE)) {
2151 + /* based on the origin flag, move the internal pointer */
2153 + fileDesc = hFile->fileDesc;
2154 + switch (cOrigin) {
2155 + case KFILE_SEEK_SET:
2156 + dwCurPos = hFile->fileDesc->f_op->llseek(hFile->
2157 + fileDesc, lOffset, SEEK_SET);
2158 + cRetVal = ((dwCurPos >= 0) ? 0 : E_KFILE_ERROR);
2161 + case KFILE_SEEK_CUR:
2162 + dwCurPos = hFile->fileDesc->f_op->llseek(hFile->
2163 + fileDesc, lOffset, SEEK_CUR);
2164 + cRetVal = ((dwCurPos >= 0) ? 0 : E_KFILE_ERROR);
2166 + case KFILE_SEEK_END:
2167 + dwCurPos = hFile->fileDesc->f_op->llseek(hFile->
2168 + fileDesc, lOffset, SEEK_END);
2169 + cRetVal = ((dwCurPos >= 0) ? 0 : E_KFILE_ERROR);
2172 + cRetVal = E_KFILE_BADORIGINFLAG;
2173 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2174 + "KFILE_Seek:bad origin flag\n");
2178 + cRetVal = E_KFILE_INVALIDHANDLE;
2179 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2180 + "KFILE_Seek:invalid file handle\n");
2186 + * ======== KFILE_Tell ========
2188 + * Reports the current value of the position indicator. We did not
2189 + * consider 64 bit long file size, which implies a 4GB file limit
2190 + * (2 to 32 power).
2192 +s32 KFILE_Tell(struct KFILE_FileObj *hFile)
2195 + s32 lRetVal = E_KFILE_ERROR;
2197 + GT_1trace(KFILE_debugMask, GT_ENTER, "KFILE_Tell: hFile 0x%x\n", hFile);
2199 + if (MEM_IsValidHandle(hFile, SIGNATURE)) {
2201 + /* Get current position. */
2202 + dwCurPos = hFile->fileDesc->f_op->llseek(hFile->fileDesc, 0,
2204 + if (dwCurPos >= 0)
2205 + lRetVal = dwCurPos;
2208 + lRetVal = E_KFILE_INVALIDHANDLE;
2209 + GT_0trace(KFILE_debugMask, GT_6CLASS,
2210 + "KFILE_Seek:invalid file handle\n");
2215 diff --git a/drivers/dsp/bridge/services/list.c b/drivers/dsp/bridge/services/list.c
2216 new file mode 100644
2217 index 0000000..3d4c752
2219 +++ b/drivers/dsp/bridge/services/list.c
2222 + * linux/drivers/dsp/bridge/services/list.c
2224 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2226 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2228 + * This package is free software; you can redistribute it and/or modify
2229 + * it under the terms of the GNU General Public License version 2 as
2230 + * published by the Free Software Foundation.
2232 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2233 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2234 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2239 + * ======== listce.c ========
2241 + * Provides standard circular list handling functions.
2243 + * Public Functions:
2251 + * LST_InsertBefore
2256 + *! Revision History
2257 + *! ================
2258 + *! 06-Mar-2002 jeh Don't set element self to NULL in LST_RemoveElem().
2259 + *! 10-Aug-2000 ag: Added LST_InsertBefore().
2260 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
2262 + *! 22-Nov-1999 kc: Added changes from code review.
2263 + *! 10-Aug-1999 kc: Based on wsx-c18.
2264 + *! 16-Jun-1997 gp: Removed unnecessary enabling/disabling of interrupts around
2265 + *! list manipulation code.
2266 + *! 22-Oct-1996 gp: Added LST_RemoveElem, and LST_First/LST_Next iterators.
2267 + *! 10-Aug-1996 gp: Acquired from SMM for WinSPOX v. 1.1; renamed identifiers.
2270 +/* ----------------------------------- DSP/BIOS Bridge */
2272 +#include <dbdefs.h>
2274 +/* ----------------------------------- Trace & Debug */
2278 +/* ----------------------------------- OS Adaptation Layer */
2281 +/* ----------------------------------- This */
2284 +/* ----------------------------------- Globals */
2286 +static struct GT_Mask LST_debugMask = { NULL, NULL }; /* GT trace var. */
2290 + * ======== LST_Create ========
2292 + * Allocates and initializes a circular list.
2294 +struct LST_LIST *LST_Create(void)
2296 + struct LST_LIST *pList;
2298 + GT_0trace(LST_debugMask, GT_ENTER, "LST_Create: entered\n");
2300 + pList = (struct LST_LIST *) MEM_Calloc(sizeof(struct LST_LIST),
2302 + if (pList != NULL) {
2303 + pList->head.next = &pList->head;
2304 + pList->head.prev = &pList->head;
2305 + pList->head.self = NULL;
2312 + * ======== LST_Delete ========
2314 + * Removes a list by freeing its control structure's memory space.
2316 +void LST_Delete(struct LST_LIST *pList)
2318 + DBC_Require(pList != NULL);
2320 + GT_1trace(LST_debugMask, GT_ENTER, "LST_Delete: pList 0x%x\n", pList);
2326 + * ======== LST_Exit ========
2328 + * Discontinue usage of the LST module.
2330 +void LST_Exit(void)
2332 + GT_0trace(LST_debugMask, GT_5CLASS, "LST_Exit\n");
2336 + * ======== LST_First ========
2338 + * Returns a pointer to the first element of the list, or NULL if the
2341 +struct LST_ELEM *LST_First(struct LST_LIST *pList)
2343 + struct LST_ELEM *pElem = NULL;
2345 + DBC_Require(pList != NULL);
2347 + GT_1trace(LST_debugMask, GT_ENTER, "LST_First: pList 0x%x\n", pList);
2349 + if (!LST_IsEmpty(pList))
2350 + pElem = pList->head.next;
2356 + * ======== LST_GetHead ========
2358 + * "Pops" the head off the list and returns a pointer to it.
2360 +struct LST_ELEM *LST_GetHead(struct LST_LIST *pList)
2362 + struct LST_ELEM *pElem;
2364 + DBC_Require(pList != NULL);
2366 + GT_1trace(LST_debugMask, GT_ENTER, "LST_GetHead: pList 0x%x\n", pList);
2368 + if (LST_IsEmpty(pList))
2371 + /* pElem is always valid because the list cannot be empty
2372 + * at this point */
2373 + pElem = pList->head.next;
2374 + pList->head.next = pElem->next;
2375 + pElem->next->prev = &pList->head;
2377 + return pElem->self;
2381 + * ======== LST_Init ========
2383 + * Initialize LST module private state.
2385 +bool LST_Init(void)
2387 + GT_create(&LST_debugMask, "LS"); /* LS for LSt module */
2389 + GT_0trace(LST_debugMask, GT_5CLASS, "LST_Init\n");
2395 + * ======== LST_InitElem ========
2397 + * Initializes a list element to default (cleared) values
2399 +void LST_InitElem(struct LST_ELEM *pElem)
2401 + DBC_Require(pElem != NULL);
2403 + GT_1trace(LST_debugMask, GT_ENTER, "LST_InitElem: pElem 0x%x\n", pElem);
2406 + pElem->next = NULL;
2407 + pElem->prev = NULL;
2408 + pElem->self = pElem;
2413 + * ======== LST_InsertBefore ========
2415 + * Insert the element before the existing element.
2417 +void LST_InsertBefore(struct LST_LIST *pList, struct LST_ELEM *pElem,
2418 + struct LST_ELEM *pElemExisting)
2420 + DBC_Require(pList != NULL);
2421 + DBC_Require(pElem != NULL);
2422 + DBC_Require(pElemExisting != NULL);
2424 + GT_3trace(LST_debugMask, GT_ENTER, "LST_InsertBefore: pList 0x%x, "
2425 + "pElem 0x%x pElemExisting 0x%x\n", pList, pElem,
2428 + pElemExisting->prev->next = pElem;
2429 + pElem->prev = pElemExisting->prev;
2430 + pElem->next = pElemExisting;
2431 + pElemExisting->prev = pElem;
2435 + * ======== LST_Next ========
2437 + * Returns a pointer to the next element of the list, or NULL if the
2438 + * next element is the head of the list or the list is empty.
2440 +struct LST_ELEM *LST_Next(struct LST_LIST *pList, struct LST_ELEM *pCurElem)
2442 + struct LST_ELEM *pNextElem = NULL;
2444 + DBC_Require(pList != NULL);
2445 + DBC_Require(pCurElem != NULL);
2447 + GT_2trace(LST_debugMask, GT_ENTER,
2448 + "LST_Next: pList 0x%x, pCurElem 0x%x\n",
2451 + if (!LST_IsEmpty(pList)) {
2452 + if (pCurElem->next != &pList->head)
2453 + pNextElem = pCurElem->next;
2460 + * ======== LST_PutTail ========
2462 + * Adds the specified element to the tail of the list
2464 +void LST_PutTail(struct LST_LIST *pList, struct LST_ELEM *pElem)
2466 + DBC_Require(pList != NULL);
2467 + DBC_Require(pElem != NULL);
2469 + GT_2trace(LST_debugMask, GT_ENTER,
2470 + "LST_PutTail: pList 0x%x, pElem 0x%x\n",
2473 + pElem->prev = pList->head.prev;
2474 + pElem->next = &pList->head;
2475 + pList->head.prev = pElem;
2476 + pElem->prev->next = pElem;
2478 + DBC_Ensure(!LST_IsEmpty(pList));
2482 + * ======== LST_RemoveElem ========
2484 + * Removes (unlinks) the given element from the list, if the list is not
2485 + * empty. Does not free the list element.
2487 +void LST_RemoveElem(struct LST_LIST *pList, struct LST_ELEM *pCurElem)
2489 + DBC_Require(pList != NULL);
2490 + DBC_Require(pCurElem != NULL);
2492 + GT_2trace(LST_debugMask, GT_ENTER,
2493 + "LST_RemoveElem: pList 0x%x, pCurElem "
2494 + "0x%x\n", pList, pCurElem);
2496 + if (!LST_IsEmpty(pList)) {
2497 + pCurElem->prev->next = pCurElem->next;
2498 + pCurElem->next->prev = pCurElem->prev;
2500 + /* set elem fields to NULL to prevent illegal references */
2501 + pCurElem->next = NULL;
2502 + pCurElem->prev = NULL;
2506 diff --git a/drivers/dsp/bridge/services/mem.c b/drivers/dsp/bridge/services/mem.c
2507 new file mode 100644
2508 index 0000000..186684e
2510 +++ b/drivers/dsp/bridge/services/mem.c
2513 + * linux/drivers/dsp/bridge/services/mem.c
2515 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2517 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2519 + * This package is free software; you can redistribute it and/or modify
2520 + * it under the terms of the GNU General Public License version 2 as
2521 + * published by the Free Software Foundation.
2523 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2524 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2525 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2530 + * ======== mem.c ========
2532 + * Implementation of platform specific memory services.
2534 + * Public Functions:
2536 + * MEM_AllocPhysMem
2543 + * MEM_ExtPhysPoolInit
2545 + *! Revision History:
2546 + *! =================
2547 + *! 18-Jan-2004 hp: Added support for External physical memory pool
2548 + *! 19-Apr-2004 sb: Added Alloc/Free PhysMem, FlushCache, VirtualToPhysical
2549 + *! 01-Sep-2001 ag: Code cleanup.
2550 + *! 02-May-2001 ag: MEM_[UnMap]LinearAddress revamped to align Phys to Virt.
2551 + *! Set PAGE_PHYSICAL if phy addr <= 512MB. Opposite uSoft doc!
2552 + *! 29-Aug-2000 rr: MEM_LinearAddress does not check for 512MB for non-x86.
2553 + *! 28-Mar-2000 rr: MEM_LinearAddress changed.Handles address larger than 512MB
2554 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
2556 + *! 22-Nov-1999 kc: Added changes from code review.
2557 + *! 16-Aug-1999 kc: modified for WinCE.
2558 + *! 20-Mar-1999 ag: SP 4 fix in MEM_UMBCalloc().
2559 + *! Mdl offset now ORed not added to userBuf.
2560 + *! 23-Dec-1997 cr: Code review changes.
2561 + *! 08-Dec-1997 cr: Prepared for code review.
2562 + *! 24-Jun-1997 cr: Created.
2565 +/* ----------------------------------- Host OS */
2566 +#include <host_os.h>
2568 +/* ----------------------------------- DSP/BIOS Bridge */
2570 +#include <dbdefs.h>
2571 +#include <errbase.h>
2573 +/* ----------------------------------- Trace & Debug */
2577 +/* ----------------------------------- This */
2581 +/* ----------------------------------- Defines */
2582 +#define MEM_512MB 0x1fffffff
2583 +#define memInfoSign 0x464E494D /* "MINF" (in reverse). */
2586 +#define MEM_CHECK /* Use to detect source of memory leaks */
2589 +/* ----------------------------------- Globals */
2591 +static struct GT_Mask MEM_debugMask = { NULL, NULL }; /* GT trace variable */
2594 +static u32 cRefs; /* module reference count */
2596 +static bool extPhysMemPoolEnabled = false;
2598 +struct extPhysMemPool {
2602 + u32 nextPhysAllocPtr;
2605 +static struct extPhysMemPool extMemPool;
2607 +/* Information about each element allocated on heap */
2609 + struct LST_ELEM link; /* Must be first */
2612 + u32 dwSignature; /* Should be last */
2618 + * This structure holds a linked list to all memory elements allocated on
2619 + * heap by DSP/BIOS Bridge. This is used to report memory leaks and free
2620 + * such elements while removing the DSP/BIOS Bridge driver
2623 + struct LST_LIST lst;
2627 +static struct memMan mMan;
2630 + * These functions are similar to LST_PutTail and LST_RemoveElem and are
2631 + * duplicated here to make MEM independent of LST
2633 +static inline void MLST_PutTail(struct LST_LIST *pList, struct LST_ELEM *pElem)
2635 + pElem->prev = pList->head.prev;
2636 + pElem->next = &pList->head;
2637 + pList->head.prev = pElem;
2638 + pElem->prev->next = pElem;
2639 + pElem->self = pElem;
2642 +static inline void MLST_RemoveElem(struct LST_LIST *pList,
2643 + struct LST_ELEM *pCurElem)
2645 + pCurElem->prev->next = pCurElem->next;
2646 + pCurElem->next->prev = pCurElem->prev;
2647 + pCurElem->next = NULL;
2648 + pCurElem->prev = NULL;
2651 +void MEM_Check(void)
2653 + struct memInfo *pMem;
2654 + struct LST_ELEM *last = &mMan.lst.head;
2655 + struct LST_ELEM *curr = mMan.lst.head.next;
2657 + if (!LST_IsEmpty(&mMan.lst)) {
2658 + GT_0trace(MEM_debugMask, GT_7CLASS, "*** MEMORY LEAK ***\n");
2659 + GT_0trace(MEM_debugMask, GT_7CLASS,
2660 + "Addr Size Caller\n");
2661 + while (curr != last) {
2662 + pMem = (struct memInfo *)curr;
2663 + curr = curr->next;
2664 + if ((u32)pMem > PAGE_OFFSET &&
2665 + MEM_IsValidHandle(pMem, memInfoSign)) {
2666 + GT_3trace(MEM_debugMask, GT_7CLASS,
2667 + "%lx %d\t [<%p>]\n",
2668 + (u32) pMem + sizeof(struct memInfo),
2669 + pMem->size, pMem->caller);
2670 + MLST_RemoveElem(&mMan.lst,
2671 + (struct LST_ELEM *) pMem);
2674 + GT_1trace(MEM_debugMask, GT_7CLASS,
2675 + "Invalid allocation or "
2676 + "Buffer underflow at %x\n",
2677 + (u32)pMem + sizeof(struct memInfo));
2682 + DBC_Ensure(LST_IsEmpty(&mMan.lst));
2687 +void MEM_ExtPhysPoolInit(u32 poolPhysBase, u32 poolSize)
2691 + /* get the virtual address for the physical memory pool passed */
2692 + poolVirtBase = (u32)ioremap(poolPhysBase, poolSize);
2694 + if ((void **)poolVirtBase == NULL) {
2695 + GT_0trace(MEM_debugMask, GT_7CLASS,
2696 + "[PHYS_POOL]Mapping External "
2697 + "physical memory to virt failed \n");
2698 + extPhysMemPoolEnabled = false;
2700 + extMemPool.physMemBase = poolPhysBase;
2701 + extMemPool.physMemSize = poolSize;
2702 + extMemPool.virtMemBase = poolVirtBase;
2703 + extMemPool.nextPhysAllocPtr = poolPhysBase;
2704 + extPhysMemPoolEnabled = true;
2705 + GT_3trace(MEM_debugMask, GT_1CLASS,
2706 + "ExtMemory Pool details " "Pool"
2707 + "Physical mem base = %0x " "Pool Physical mem size "
2708 + "= %0x" "Pool Virtual mem base = %0x \n",
2709 + poolPhysBase, poolSize, poolVirtBase);
2713 +void MEM_ExtPhysPoolRelease(void)
2715 + GT_0trace(MEM_debugMask, GT_1CLASS,
2716 + "Releasing External memory pool \n");
2717 + if (extPhysMemPoolEnabled) {
2718 + iounmap((void *)(extMemPool.virtMemBase));
2719 + extPhysMemPoolEnabled = false;
2724 + * ======== MEM_ExtPhysMemAlloc ========
2726 + * Allocate physically contiguous, uncached memory from external memory pool
2729 +void *MEM_ExtPhysMemAlloc(u32 bytes, u32 align, OUT u32 *pPhysAddr)
2735 + GT_2trace(MEM_debugMask, GT_1CLASS,
2736 + "Ext Memory Allocation" "bytes=0x%x , "
2737 + "align=0x%x \n", bytes, align);
2739 + GT_0trace(MEM_debugMask, GT_7CLASS,
2740 + "ExtPhysical Memory Allocation "
2741 + "No alignment request in allocation call !! \n");
2744 + if (bytes > ((extMemPool.physMemBase + extMemPool.physMemSize)
2745 + - extMemPool.nextPhysAllocPtr)) {
2746 + GT_1trace(MEM_debugMask, GT_7CLASS,
2747 + "ExtPhysical Memory Allocation "
2748 + "unable to allocate memory for bytes = 0x%x \n",
2753 + offset = (extMemPool.nextPhysAllocPtr & (align - 1));
2755 + newAllocPtr = extMemPool.nextPhysAllocPtr;
2757 + newAllocPtr = (extMemPool.nextPhysAllocPtr) +
2759 + if ((newAllocPtr + bytes) <=
2760 + (extMemPool.physMemBase + extMemPool.physMemSize)) {
2761 + /* we can allocate */
2762 + *pPhysAddr = newAllocPtr;
2763 + extMemPool.nextPhysAllocPtr = newAllocPtr + bytes;
2764 + virtAddr = extMemPool.virtMemBase + (newAllocPtr -
2765 + extMemPool.physMemBase);
2766 + GT_2trace(MEM_debugMask, GT_1CLASS,
2767 + "Ext Memory Allocation succedded "
2768 + "phys address=0x%x , virtaddress=0x%x \n",
2769 + newAllocPtr, virtAddr);
2770 + return (void *)virtAddr;
2779 + * ======== MEM_Alloc ========
2781 + * Allocate memory from the paged or non-paged pools.
2783 +void *MEM_Alloc(u32 cBytes, enum MEM_POOLATTRS type)
2785 + struct memInfo *pMem = NULL;
2787 + GT_2trace(MEM_debugMask, GT_ENTER,
2788 + "MEM_Alloc: cBytes 0x%x\ttype 0x%x\n", cBytes, type);
2791 + case MEM_NONPAGED:
2792 + /* If non-paged memory required, see note at top of file. */
2795 + pMem = kmalloc(cBytes, GFP_ATOMIC);
2797 + pMem = kmalloc(cBytes + sizeof(struct memInfo),
2800 + pMem->size = cBytes;
2801 + pMem->caller = __builtin_return_address(0);
2802 + pMem->dwSignature = memInfoSign;
2804 + spin_lock(&mMan.lock);
2805 + MLST_PutTail(&mMan.lst,
2806 + (struct LST_ELEM *)pMem);
2807 + spin_unlock(&mMan.lock);
2809 + pMem = (void *)((u32)pMem +
2810 + sizeof(struct memInfo));
2814 + case MEM_LARGEVIRTMEM:
2816 + /* FIXME - Replace with 'vmalloc' after BP fix */
2817 + pMem = __vmalloc(cBytes, GFP_ATOMIC, PAGE_KERNEL);
2819 + /* FIXME - Replace with 'vmalloc' after BP fix */
2820 + pMem = __vmalloc((cBytes + sizeof(struct memInfo)),
2821 + GFP_ATOMIC, PAGE_KERNEL);
2823 + pMem->size = cBytes;
2824 + pMem->caller = __builtin_return_address(0);
2825 + pMem->dwSignature = memInfoSign;
2827 + spin_lock(&mMan.lock);
2828 + MLST_PutTail(&mMan.lst,
2829 + (struct LST_ELEM *) pMem);
2830 + spin_unlock(&mMan.lock);
2832 + pMem = (void *)((u32)pMem +
2833 + sizeof(struct memInfo));
2839 + GT_0trace(MEM_debugMask, GT_6CLASS,
2840 + "MEM_Alloc: unexpected "
2841 + "MEM_POOLATTRS value\n");
2850 + * ======== MEM_AllocPhysMem ========
2852 + * Allocate physically contiguous, uncached memory
2854 +void *MEM_AllocPhysMem(u32 cBytes, u32 ulAlign, OUT u32 *pPhysicalAddress)
2856 + void *pVaMem = NULL;
2859 + DBC_Require(cRefs > 0);
2861 + GT_2trace(MEM_debugMask, GT_ENTER,
2862 + "MEM_AllocPhysMem: cBytes 0x%x\tulAlign"
2863 + "0x%x\n", cBytes, ulAlign);
2866 + if (extPhysMemPoolEnabled) {
2867 + pVaMem = MEM_ExtPhysMemAlloc(cBytes, ulAlign,
2870 + pVaMem = dma_alloc_coherent(NULL, cBytes, &paMem,
2872 + if (pVaMem == NULL) {
2873 + *pPhysicalAddress = 0;
2874 + GT_1trace(MEM_debugMask, GT_6CLASS,
2875 + "MEM_AllocPhysMem failed: "
2876 + "0x%x\n", pVaMem);
2878 + *pPhysicalAddress = paMem;
2885 + * ======== MEM_Calloc ========
2887 + * Allocate zero-initialized memory from the paged or non-paged pools.
2889 +void *MEM_Calloc(u32 cBytes, enum MEM_POOLATTRS type)
2891 + struct memInfo *pMem = NULL;
2893 + GT_2trace(MEM_debugMask, GT_ENTER,
2894 + "MEM_Calloc: cBytes 0x%x\ttype 0x%x\n",
2899 + case MEM_NONPAGED:
2900 + /* If non-paged memory required, see note at top of file. */
2903 + pMem = kmalloc(cBytes, GFP_ATOMIC);
2905 + memset(pMem, 0, cBytes);
2908 + pMem = kmalloc(cBytes + sizeof(struct memInfo),
2911 + memset((void *)((u32)pMem +
2912 + sizeof(struct memInfo)), 0, cBytes);
2913 + pMem->size = cBytes;
2914 + pMem->caller = __builtin_return_address(0);
2915 + pMem->dwSignature = memInfoSign;
2916 + spin_lock(&mMan.lock);
2917 + MLST_PutTail(&mMan.lst,
2918 + (struct LST_ELEM *) pMem);
2919 + spin_unlock(&mMan.lock);
2920 + pMem = (void *)((u32)pMem +
2921 + sizeof(struct memInfo));
2925 + case MEM_LARGEVIRTMEM:
2927 + /* FIXME - Replace with 'vmalloc' after BP fix */
2928 + pMem = __vmalloc(cBytes, GFP_ATOMIC, PAGE_KERNEL);
2930 + memset(pMem, 0, cBytes);
2933 + /* FIXME - Replace with 'vmalloc' after BP fix */
2934 + pMem = __vmalloc(cBytes + sizeof(struct memInfo),
2935 + GFP_ATOMIC, PAGE_KERNEL);
2937 + memset((void *)((u32)pMem +
2938 + sizeof(struct memInfo)), 0, cBytes);
2939 + pMem->size = cBytes;
2940 + pMem->caller = __builtin_return_address(0);
2941 + pMem->dwSignature = memInfoSign;
2942 + spin_lock(&mMan.lock);
2943 + MLST_PutTail(&mMan.lst, (struct LST_ELEM *)
2945 + spin_unlock(&mMan.lock);
2946 + pMem = (void *)((u32)pMem +
2947 + sizeof(struct memInfo));
2952 + GT_1trace(MEM_debugMask, GT_6CLASS,
2953 + "MEM_Calloc: unexpected "
2954 + "MEM_POOLATTRS value 0x%x\n", type);
2963 + * ======== MEM_Exit ========
2965 + * Discontinue usage of the MEM module.
2967 +void MEM_Exit(void)
2969 + DBC_Require(cRefs > 0);
2971 + GT_1trace(MEM_debugMask, GT_5CLASS, "MEM_Exit: cRefs 0x%x\n", cRefs);
2979 + MEM_ExtPhysPoolRelease();
2980 + DBC_Ensure(cRefs >= 0);
2984 + * ======== MEM_FlushCache ========
2988 +void MEM_FlushCache(void *pMemBuf, u32 cBytes, s32 FlushType)
2990 + DBC_Require(cRefs > 0);
2992 + switch (FlushType) {
2993 + /* invalidate only */
2994 + case PROC_INVALIDATE_MEM:
2995 + dmac_inv_range(pMemBuf, pMemBuf + cBytes - 1);
2996 + outer_inv_range(__pa((u32)pMemBuf), __pa((u32)pMemBuf +
2999 + /* writeback only */
3000 + case PROC_WRITEBACK_MEM:
3001 + dmac_clean_range(pMemBuf, pMemBuf + cBytes - 1);
3002 + outer_clean_range(__pa((u32)pMemBuf), __pa((u32)pMemBuf +
3005 + /* writeback and invalidate */
3006 + case PROC_WRITEBACK_INVALIDATE_MEM:
3007 + dmac_flush_range(pMemBuf, pMemBuf + cBytes - 1);
3008 + outer_flush_range(__pa((u32)pMemBuf), __pa((u32)pMemBuf +
3012 + GT_1trace(MEM_debugMask, GT_6CLASS, "MEM_FlushCache: invalid "
3013 + "FlushMemType 0x%x\n", FlushType);
3021 + * ======== MEM_Free ========
3023 + * Free the given block of system memory.
3025 +void MEM_Free(IN void *pMemBuf)
3028 + struct memInfo *pMem = (void *)((u32)pMemBuf - sizeof(struct memInfo));
3031 + DBC_Require(pMemBuf != NULL);
3033 + GT_1trace(MEM_debugMask, GT_ENTER, "MEM_Free: pMemBufs 0x%x\n",
3041 + if (pMem->dwSignature == memInfoSign) {
3042 + spin_lock(&mMan.lock);
3043 + MLST_RemoveElem(&mMan.lst,
3044 + (struct LST_ELEM *) pMem);
3045 + spin_unlock(&mMan.lock);
3046 + pMem->dwSignature = 0;
3049 + GT_1trace(MEM_debugMask, GT_7CLASS,
3050 + "Invalid allocation or "
3051 + "Buffer underflow at %x\n",
3052 + (u32) pMem + sizeof(struct memInfo));
3060 + * ======== MEM_FreePhysMem ========
3062 + * Free the given block of physically contiguous memory.
3064 +void MEM_FreePhysMem(void *pVirtualAddress, u32 pPhysicalAddress,
3067 + DBC_Require(cRefs > 0);
3068 + DBC_Require(pVirtualAddress != NULL);
3070 + GT_1trace(MEM_debugMask, GT_ENTER, "MEM_FreePhysMem: pVirtualAddress "
3071 + "0x%x\n", pVirtualAddress);
3073 + if (!extPhysMemPoolEnabled)
3074 + dma_free_coherent(NULL, cBytes, pVirtualAddress,
3075 + pPhysicalAddress);
3079 + * ======== MEM_Init ========
3081 + * Initialize MEM module private state.
3083 +bool MEM_Init(void)
3085 + DBC_Require(cRefs >= 0);
3088 + GT_create(&MEM_debugMask, "MM"); /* MM for MeM module */
3091 + mMan.lst.head.next = &mMan.lst.head;
3092 + mMan.lst.head.prev = &mMan.lst.head;
3093 + mMan.lst.head.self = NULL;
3100 + GT_1trace(MEM_debugMask, GT_5CLASS, "MEM_Init: cRefs 0x%x\n", cRefs);
3102 + DBC_Ensure(cRefs > 0);
3106 diff --git a/drivers/dsp/bridge/services/ntfy.c b/drivers/dsp/bridge/services/ntfy.c
3107 new file mode 100644
3108 index 0000000..72bb1e4
3110 +++ b/drivers/dsp/bridge/services/ntfy.c
3113 + * linux/drivers/dsp/bridge/services/ntfy.c
3115 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3117 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3119 + * This package is free software; you can redistribute it and/or modify
3120 + * it under the terms of the GNU General Public License version 2 as
3121 + * published by the Free Software Foundation.
3123 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3124 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3125 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3130 + * ======== ntfyce.c ========
3132 + * Manage lists of notification events.
3134 + * Public Functions:
3142 + *! Revision History:
3143 + *! =================
3144 + *! 06-Feb-2003 kc Removed DSP_POSTMESSAGE related code.
3145 + *! 05-Nov-2001 kc Updated DSP_HNOTIFICATION structure.
3146 + *! 10-May-2001 jeh Removed SERVICES module init/exit from NTFY_Init/Exit.
3147 + *! NTFY_Register() returns DSP_ENOTIMPL for all but
3148 + *! DSP_SIGNALEVENT.
3149 + *! 12-Oct-2000 jeh Use MEM_IsValidHandle().
3150 + *! 07-Sep-2000 jeh Created.
3153 +/* ----------------------------------- Host OS */
3154 +#include <host_os.h>
3156 +/* ----------------------------------- DSP/BIOS Bridge */
3158 +#include <dbdefs.h>
3159 +#include <errbase.h>
3161 +/* ----------------------------------- Trace & Debug */
3165 +/* ----------------------------------- OS Adaptation Layer */
3171 +/* ----------------------------------- This */
3174 +/* ----------------------------------- Defines, Data Structures, Typedefs */
3175 +#define NTFY_SIGNATURE 0x5946544e /* "YFTN" */
3178 + * ======== NTFY_OBJECT ========
3180 +struct NTFY_OBJECT {
3181 + u32 dwSignature; /* For object validation */
3182 + struct LST_LIST *notifyList; /* List of NOTIFICATION objects */
3183 + struct SYNC_CSOBJECT *hSync; /* For critical sections */
3187 + * ======== NOTIFICATION ========
3188 + * This object will be created when a client registers for events.
3190 +struct NOTIFICATION {
3191 + struct LST_ELEM listElem;
3192 + u32 uEventMask; /* Events to be notified about */
3193 + u32 uNotifyType; /* Type of notification to be sent */
3196 + * We keep a copy of the event name to check if the event has
3197 + * already been registered. (SYNC also keeps a copy of the name).
3199 + char *pstrName; /* Name of event */
3200 + HANDLE hEvent; /* Handle for notification */
3201 + struct SYNC_OBJECT *hSync;
3204 +/* ----------------------------------- Globals */
3206 +static struct GT_Mask NTFY_debugMask = { NULL, NULL }; /* GT trace variable */
3209 +/* ----------------------------------- Function Prototypes */
3210 +static void DeleteNotify(struct NOTIFICATION *pNotify);
3213 + * ======== NTFY_Create ========
3215 + * Create an empty list of notifications.
3217 +DSP_STATUS NTFY_Create(struct NTFY_OBJECT **phNtfy)
3219 + struct NTFY_OBJECT *pNtfy;
3220 + DSP_STATUS status = DSP_SOK;
3222 + DBC_Require(phNtfy != NULL);
3225 + MEM_AllocObject(pNtfy, struct NTFY_OBJECT, NTFY_SIGNATURE);
3229 + status = SYNC_InitializeDPCCS(&pNtfy->hSync);
3230 + if (DSP_SUCCEEDED(status)) {
3231 + pNtfy->notifyList = LST_Create();
3232 + if (pNtfy->notifyList == NULL) {
3233 + (void) SYNC_DeleteCS(pNtfy->hSync);
3234 + MEM_FreeObject(pNtfy);
3235 + status = DSP_EMEMORY;
3241 + status = DSP_EMEMORY;
3244 + DBC_Ensure((DSP_FAILED(status) && *phNtfy == NULL) ||
3245 + (DSP_SUCCEEDED(status) && MEM_IsValidHandle((*phNtfy),
3246 + NTFY_SIGNATURE)));
3252 + * ======== NTFY_Delete ========
3254 + * Free resources allocated in NTFY_Create.
3256 +void NTFY_Delete(struct NTFY_OBJECT *hNtfy)
3258 + struct NOTIFICATION *pNotify;
3260 + DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));
3262 + /* Remove any elements remaining in list */
3263 + if (hNtfy->notifyList) {
3264 + while ((pNotify = (struct NOTIFICATION *)LST_GetHead(hNtfy->
3266 + DeleteNotify(pNotify);
3268 + DBC_Assert(LST_IsEmpty(hNtfy->notifyList));
3269 + LST_Delete(hNtfy->notifyList);
3272 + (void)SYNC_DeleteCS(hNtfy->hSync);
3274 + MEM_FreeObject(hNtfy);
3278 + * ======== NTFY_Exit ========
3280 + * Discontinue usage of NTFY module.
3282 +void NTFY_Exit(void)
3284 + GT_0trace(NTFY_debugMask, GT_5CLASS, "Entered NTFY_Exit\n");
3288 + * ======== NTFY_Init ========
3290 + * Initialize the NTFY module.
3292 +bool NTFY_Init(void)
3294 + GT_create(&NTFY_debugMask, "NY"); /* "NY" for NtfY */
3296 + GT_0trace(NTFY_debugMask, GT_5CLASS, "NTFY_Init()\n");
3302 + * ======== NTFY_Notify ========
3304 + * Execute notify function (signal event) for every
3305 + * element in the notification list that is to be notified about the
3306 + * event specified in uEventMask.
3308 +void NTFY_Notify(struct NTFY_OBJECT *hNtfy, u32 uEventMask)
3310 + struct NOTIFICATION *pNotify;
3312 + DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));
3315 + * Go through notifyList and notify all clients registered for
3316 + * uEventMask events.
3319 + (void) SYNC_EnterCS(hNtfy->hSync);
3321 + pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList);
3322 + while (pNotify != NULL) {
3323 + if (pNotify->uEventMask & uEventMask) {
3325 + if (pNotify->uNotifyType == DSP_SIGNALEVENT)
3326 + (void)SYNC_SetEvent(pNotify->hSync);
3329 + pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList,
3330 + (struct LST_ELEM *)pNotify);
3333 + (void) SYNC_LeaveCS(hNtfy->hSync);
3337 + * ======== NTFY_Register ========
3339 + * Add a notification element to the list. If the notification is already
3340 + * registered, and uEventMask != 0, the notification will get posted for
3341 + * events specified in the new event mask. If the notification is already
3342 + * registered and uEventMask == 0, the notification will be unregistered.
3344 +DSP_STATUS NTFY_Register(struct NTFY_OBJECT *hNtfy,
3345 + struct DSP_NOTIFICATION *hNotification,
3346 + u32 uEventMask, u32 uNotifyType)
3348 + struct NOTIFICATION *pNotify;
3349 + struct SYNC_ATTRS syncAttrs;
3350 + DSP_STATUS status = DSP_SOK;
3352 + DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));
3354 + if (hNotification == NULL)
3355 + status = DSP_EHANDLE;
3357 + /* Return DSP_ENOTIMPL if uNotifyType is not supported */
3358 + if (DSP_SUCCEEDED(status)) {
3359 + if (!IsValidNotifyMask(uNotifyType))
3360 + status = DSP_ENOTIMPL;
3364 + if (DSP_FAILED(status))
3367 + (void)SYNC_EnterCS(hNtfy->hSync);
3369 + pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList);
3370 + while (pNotify != NULL) {
3371 + /* If there is more than one notification type, each
3372 + * type may require its own handler code. */
3374 + if (hNotification->handle == pNotify->hSync) {
3378 + pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList,
3379 + (struct LST_ELEM *)pNotify);
3381 + if (pNotify == NULL) {
3382 + /* Not registered */
3383 + if (uEventMask == 0) {
3384 + status = DSP_EVALUE;
3386 + /* Allocate NOTIFICATION object, add to list */
3387 + pNotify = MEM_Calloc(sizeof(struct NOTIFICATION),
3389 + if (pNotify == NULL)
3390 + status = DSP_EMEMORY;
3393 + if (DSP_SUCCEEDED(status)) {
3394 + LST_InitElem((struct LST_ELEM *) pNotify);
3395 + /* If there is more than one notification type, each
3396 + * type may require its own handler code. */
3397 + status = SYNC_OpenEvent(&pNotify->hSync, &syncAttrs);
3398 + hNotification->handle = pNotify->hSync;
3400 + if (DSP_SUCCEEDED(status)) {
3401 + pNotify->uEventMask = uEventMask;
3402 + pNotify->uNotifyType = uNotifyType;
3403 + LST_PutTail(hNtfy->notifyList,
3404 + (struct LST_ELEM *)pNotify);
3406 + DeleteNotify(pNotify);
3410 + /* Found in list */
3411 + if (uEventMask == 0) {
3412 + /* Remove from list and free */
3413 + LST_RemoveElem(hNtfy->notifyList,
3414 + (struct LST_ELEM *)pNotify);
3415 + DeleteNotify(pNotify);
3417 + /* Update notification mask (type shouldn't change) */
3418 + pNotify->uEventMask = uEventMask;
3421 + (void)SYNC_LeaveCS(hNtfy->hSync);
3426 + * ======== DeleteNotify ========
3428 + * Free the notification object.
3430 +static void DeleteNotify(struct NOTIFICATION *pNotify)
3432 + if (pNotify->hSync)
3433 + (void) SYNC_CloseEvent(pNotify->hSync);
3435 + if (pNotify->pstrName)
3436 + MEM_Free(pNotify->pstrName);
3438 + MEM_Free(pNotify);
3441 diff --git a/drivers/dsp/bridge/services/prcs.c b/drivers/dsp/bridge/services/prcs.c
3442 new file mode 100644
3443 index 0000000..cb45541
3445 +++ b/drivers/dsp/bridge/services/prcs.c
3448 + * linux/drivers/dsp/bridge/services/prcs.c
3450 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3452 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3454 + * This package is free software; you can redistribute it and/or modify
3455 + * it under the terms of the GNU General Public License version 2 as
3456 + * published by the Free Software Foundation.
3458 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3459 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3460 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3465 + * ======== procce.c ========
3467 + * Provide information about processes and threads.
3469 + * Public Functions:
3471 + * PRCS_GetCurrentHandle
3474 + *! Revision History:
3475 + *! ================
3476 + *! 18-Dec-2000 rr: PRCS_GetCurrentProcesshandle's DBC_Ensure class
3477 + *! removed. See the foot node.
3478 + *! 06-Jul-2000 rr: Prefix changed to PRCS to accomodate RM PROC.
3479 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
3481 + *! 22-Nov-1999 kc: Added changes from code review.
3482 + *! 22-Sep-1999 kc: Modified from procnt.c.
3483 + *! 26-Aug-1997 cr: Implemented.
3484 + *! 16-Aug-1997 cr: Stubbed from proc95.c
3487 +/* ----------------------------------- Host OS */
3488 +#include <host_os.h>
3490 +/* ----------------------------------- DSP/BIOS Bridge */
3492 +#include <dbdefs.h>
3493 +#include <errbase.h>
3495 +/* ----------------------------------- Trace & Debug */
3499 +/* ----------------------------------- This */
3502 +/* ----------------------------------- Globals & Defines */
3504 +static struct GT_Mask PRCS_debugMask = { NULL, NULL }; /* GT trace var. */
3508 + * ======== PRCS_Exit ========
3510 + * Discontinue usage of the PRCS module.
3512 +void PRCS_Exit(void)
3514 + GT_0trace(PRCS_debugMask, GT_5CLASS, "PRCS_Exit\n");
3518 + * ======== PRCS_GetCurrentHandle ========
3520 + * This functions returns the process handle of the
3523 +DSP_STATUS PRCS_GetCurrentHandle(OUT HANDLE *phProcess)
3525 + DSP_STATUS status;
3527 + DBC_Require(phProcess != NULL);
3529 + GT_1trace(PRCS_debugMask, GT_ENTER,
3530 + "PRCS_GetCurrentHandle: phProcess 0x%x\n",
3533 + if (!in_interrupt()) {
3534 + /* Return PID instead of process handle */
3535 + *phProcess = (HANDLE)current->pid;
3538 + *phProcess = NULL;
3539 + status = DSP_EFAIL;
3542 + *phProcess = NULL;
3543 + status = DSP_EPOINTER;
3544 + GT_0trace(PRCS_debugMask, GT_6CLASS,
3545 + "PRCS_GetCurrentHandle: invalid "
3552 + * ======== PRCS_Init ========
3554 + * Initialize the PRCS module's private state.
3556 +bool PRCS_Init(void)
3559 + GT_create(&PRCS_debugMask, "PS"); /* PS for ProcesS */
3561 + GT_0trace(PRCS_debugMask, GT_5CLASS, "PRCS_Init\n");
3566 diff --git a/drivers/dsp/bridge/services/reg.c b/drivers/dsp/bridge/services/reg.c
3567 new file mode 100644
3568 index 0000000..f540944
3570 +++ b/drivers/dsp/bridge/services/reg.c
3573 + * linux/drivers/dsp/bridge/services/reg.c
3575 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3577 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3579 + * This package is free software; you can redistribute it and/or modify
3580 + * it under the terms of the GNU General Public License version 2 as
3581 + * published by the Free Software Foundation.
3583 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3584 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3585 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3590 + * ======== regce.c ========
3592 + * Provide registry functions.
3594 + * Public Functions:
3602 + *! Revision History:
3603 + *! ================
3607 +/* ----------------------------------- Host OS */
3608 +#include <host_os.h>
3610 +/* ----------------------------------- DSP/BIOS Bridge */
3612 +#include <dbdefs.h>
3613 +#include <errbase.h>
3615 +/* ----------------------------------- Trace & Debug */
3619 +/* ----------------------------------- OS Adaptation Layer */
3623 +/* ----------------------------------- Others */
3626 +/* ----------------------------------- This */
3628 +#include <regsup.h>
3631 +struct GT_Mask REG_debugMask = { NULL, NULL }; /* GT trace var. */
3635 + * ======== REG_DeleteValue ========
3636 + * Deletes a registry entry value. NOTE: A registry entry value is not the
3637 + * same as * a registry key.
3639 +DSP_STATUS REG_DeleteValue(OPTIONAL IN HANDLE *phKey, IN CONST char *pstrSubkey,
3640 + IN CONST char *pstrValue)
3642 + DSP_STATUS status;
3643 + DBC_Require(pstrSubkey && pstrValue);
3644 + DBC_Require(phKey == NULL);
3645 + DBC_Require(CSL_Strlen(pstrSubkey) < REG_MAXREGPATHLENGTH);
3646 + DBC_Require(CSL_Strlen(pstrValue) < REG_MAXREGPATHLENGTH);
3648 + GT_0trace(REG_debugMask, GT_ENTER, "REG_DeleteValue: entered\n");
3650 + /* Note that we don't use phKey */
3651 + if (regsupDeleteValue(pstrSubkey, pstrValue) == DSP_SOK)
3654 + status = DSP_EFAIL;
3660 + * ======== REG_EnumValue ========
3661 + * Enumerates a registry key and retrieve values stored under the key.
3662 + * We will assume the input pdwValueSize is smaller than
3663 + * REG_MAXREGPATHLENGTH for implementation purposes.
3665 +DSP_STATUS REG_EnumValue(IN HANDLE *phKey, IN u32 dwIndex,
3666 + IN CONST char *pstrKey, IN OUT char *pstrValue,
3667 + IN OUT u32 *pdwValueSize, IN OUT char *pstrData,
3668 + IN OUT u32 *pdwDataSize)
3670 + DSP_STATUS status;
3672 + DBC_Require(pstrKey && pstrValue && pdwValueSize && pstrData &&
3674 + DBC_Require(*pdwValueSize <= REG_MAXREGPATHLENGTH);
3675 + DBC_Require(phKey == NULL);
3676 + DBC_Require(CSL_Strlen(pstrKey) < REG_MAXREGPATHLENGTH);
3678 + GT_0trace(REG_debugMask, GT_ENTER, "REG_EnumValue: entered\n");
3680 + status = regsupEnumValue(dwIndex, pstrKey, pstrValue, pdwValueSize,
3681 + pstrData, pdwDataSize);
3687 + * ======== REG_Exit ========
3688 + * Discontinue usage of the REG module.
3690 +void REG_Exit(void)
3692 + GT_0trace(REG_debugMask, GT_5CLASS, "REG_Exit\n");
3698 + * ======== REG_GetValue ========
3699 + * Retrieve a value from the registry.
3701 +DSP_STATUS REG_GetValue(OPTIONAL IN HANDLE *phKey, IN CONST char *pstrSubkey,
3702 + IN CONST char *pstrValue, OUT u8 *pbData,
3703 + IN OUT u32 *pdwDataSize)
3705 + DSP_STATUS status;
3707 + DBC_Require(pstrSubkey && pstrValue && pbData);
3708 + DBC_Require(phKey == NULL);
3709 + DBC_Require(CSL_Strlen(pstrSubkey) < REG_MAXREGPATHLENGTH);
3710 + DBC_Require(CSL_Strlen(pstrValue) < REG_MAXREGPATHLENGTH);
3712 + GT_0trace(REG_debugMask, GT_ENTER, "REG_GetValue: entered\n");
3714 + /* We need to use regsup calls... */
3715 + /* ...for now we don't need the key handle or */
3716 + /* the subkey, all we need is the value to lookup. */
3717 + if (regsupGetValue((char *)pstrValue, pbData, pdwDataSize) == DSP_SOK)
3720 + status = DSP_EFAIL;
3726 + * ======== REG_Init ========
3727 + * Initialize the REG module's private state.
3729 +bool REG_Init(void)
3733 + GT_create(®_debugMask, "RG"); /* RG for ReG */
3735 + fInit = regsupInit();
3737 + GT_0trace(REG_debugMask, GT_5CLASS, "REG_Init\n");
3743 + * ======== REG_SetValue ========
3744 + * Set a value in the registry.
3746 +DSP_STATUS REG_SetValue(OPTIONAL IN HANDLE *phKey, IN CONST char *pstrSubkey,
3747 + IN CONST char *pstrValue, IN CONST u32 dwType,
3748 + IN u8 *pbData, IN u32 dwDataSize)
3750 + DSP_STATUS status;
3752 + DBC_Require(pstrValue && pbData);
3753 + DBC_Require(phKey == NULL);
3754 + DBC_Require(dwDataSize > 0);
3755 + DBC_Require(CSL_Strlen(pstrValue) < REG_MAXREGPATHLENGTH);
3757 + /* We need to use regsup calls... */
3758 + /* ...for now we don't need the key handle or */
3759 + /* the subkey, all we need is the value to lookup. */
3760 + if (regsupSetValue((char *)pstrValue, pbData, dwDataSize) == DSP_SOK)
3763 + status = DSP_EFAIL;
3768 diff --git a/drivers/dsp/bridge/services/regsup.c b/drivers/dsp/bridge/services/regsup.c
3769 new file mode 100644
3770 index 0000000..f1d2c51
3772 +++ b/drivers/dsp/bridge/services/regsup.c
3775 + * linux/drivers/dsp/bridge/services/regsup.c
3777 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3779 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3781 + * This package is free software; you can redistribute it and/or modify
3782 + * it under the terms of the GNU General Public License version 2 as
3783 + * published by the Free Software Foundation.
3785 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3786 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3787 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3792 + * ======== regsup.c ========
3794 + * Provide registry support functions.
3796 + *! Revision History:
3797 + *! ================
3798 + *! 28-May-2002 map: Integrated PSI's dspimage update mechanism
3799 + *! 11-May-2002 gp: Turned PERF "on".
3800 + *! 21-May-2002 map: Fixed bug in SetValue - if resizing datasize, set
3804 +/* ----------------------------------- Host OS */
3805 +#include <host_os.h>
3807 +/* ----------------------------------- DSP/BIOS Bridge */
3809 +#include <dbdefs.h>
3810 +#include <errbase.h>
3813 +/* ----------------------------------- Trace & Debug */
3817 +/* ----------------------------------- OS Adaptation Layer */
3821 +/* ----------------------------------- This */
3822 +#include <regsup.h>
3824 +struct RegValueStruct {
3825 + char name[BRIDGE_MAX_NAME_SIZE]; /* Name of a given value entry */
3826 + u32 dataSize; /* Size of the data */
3827 + void *pData; /* Pointer to the actual data */
3830 +struct RegKeyStruct {
3831 + /*The current number of value entries this key has*/
3832 + u32 numValueEntries;
3833 + /* Array of value entries */
3834 + struct RegValueStruct values[BRIDGE_MAX_NUM_REG_ENTRIES];
3838 +/* Pointer to the registry support key */
3839 +static struct RegKeyStruct *pRegKey;
3842 +extern struct GT_Mask REG_debugMask; /* GT trace var. */
3844 + * ======== printS ========
3846 + * Displays printable characters in pBuf, if any.
3848 +static inline void printS(void *pBuf)
3851 + if (*(REG_debugMask).flags & (GT_2CLASS)) {
3852 + while (*(u8 *)((pBuf)+pos) >= ' ' &&
3853 + *(u8 *)((pBuf)+pos) <= '~') {
3854 + GT_1trace(REG_debugMask, GT_2CLASS, "%c",
3855 + *(u8 *)((pBuf) + pos++));
3858 + GT_0trace(REG_debugMask, GT_2CLASS, "\n");
3862 +#define printS(pBuf)
3866 + * ======== regsupInit ========
3868 + * Initialize the Registry Support module's private state.
3870 +bool regsupInit(void)
3872 + if (pRegKey != NULL)
3875 + /* Need to allocate and setup our registry. */
3876 + pRegKey = MEM_Calloc(sizeof(struct RegKeyStruct), MEM_NONPAGED);
3877 + if (pRegKey == NULL)
3884 + * ======== regsupExit ========
3886 + * Release all registry support allocations.
3888 +void regsupExit(void)
3892 + /* Make sure data has actually been allocated. */
3893 + if (pRegKey == NULL) {
3894 + /* Nothing initialized.return! */
3898 + GT_1trace(REG_debugMask, GT_2CLASS, "pRegKey->numValueEntries %d\n",
3899 + pRegKey->numValueEntries);
3901 + /* Now go through each entry and free all resources. */
3902 + for (i = 0; ((i < BRIDGE_MAX_NUM_REG_ENTRIES) &&
3903 + (i < pRegKey->numValueEntries)); i++) {
3904 + if (pRegKey->values[i].name[0] != '\0') {
3905 + /* We have a valid entry.free it up! */
3906 + if (pRegKey->values[i].pData != NULL) {
3907 + GT_3trace(REG_debugMask, GT_2CLASS,
3908 + "E %d\t %s DATA %x ", i,
3909 + pRegKey->values[i].name,
3910 + *(u32 *)pRegKey->values[i].pData);
3911 + printS((u8 *)(pRegKey->values[i].pData));
3912 + MEM_Free(pRegKey->values[i].pData);
3914 + pRegKey->values[i].pData = NULL;
3915 + pRegKey->values[i].dataSize = 0;
3916 + pRegKey->values[i].name[0] = '\0';
3920 + /* Now that all of the resources are freed up, free the main one! */
3921 + MEM_Free(pRegKey);
3923 + /* Don't forget to NULL out the global entry! */
3928 + * ======== regsupGetValue ========
3930 + * Get the value of the entry having the given name.
3932 +DSP_STATUS regsupGetValue(char *valName, void *pBuf, u32 *dataSize)
3934 + DSP_STATUS retVal = DSP_EFAIL;
3937 + /* Need to search through the entries looking for the right one. */
3938 + for (i = 0; i < pRegKey->numValueEntries; i++) {
3939 + /* See if the name matches. */
3940 + if (CSL_Strncmp(pRegKey->values[i].name, valName,
3941 + BRIDGE_MAX_NAME_SIZE) == 0) {
3943 + /* We have a match! Copy out the data. */
3944 + memcpy(pBuf, pRegKey->values[i].pData,
3945 + pRegKey->values[i].dataSize);
3947 + /* Get the size for the caller. */
3948 + *dataSize = pRegKey->values[i].dataSize;
3950 + /* Set our status to good and exit. */
3956 + if (DSP_SUCCEEDED(retVal)) {
3957 + GT_2trace(REG_debugMask, GT_2CLASS, "G %s DATA %x ", valName,
3959 + printS((u8 *)pBuf);
3961 + GT_1trace(REG_debugMask, GT_3CLASS, "G %s FAILED\n", valName);
3968 + * ======== regsupSetValue ========
3970 + * Sets the value of the entry having the given name.
3972 +DSP_STATUS regsupSetValue(char *valName, void *pBuf, u32 dataSize)
3974 + DSP_STATUS retVal = DSP_EFAIL;
3977 + GT_2trace(REG_debugMask, GT_2CLASS, "S %s DATA %x ", valName,
3979 + printS((u8 *)pBuf);
3981 + /* Need to search through the entries looking for the right one. */
3982 + for (i = 0; i < pRegKey->numValueEntries; i++) {
3983 + /* See if the name matches. */
3984 + if (CSL_Strncmp(pRegKey->values[i].name, valName,
3985 + BRIDGE_MAX_NAME_SIZE) == 0) {
3986 + /* Make sure the new data size is the same. */
3987 + if (dataSize != pRegKey->values[i].dataSize) {
3988 + /* The caller needs a different data size! */
3989 + MEM_Free(pRegKey->values[i].pData);
3990 + pRegKey->values[i].pData = MEM_Alloc(dataSize,
3992 + if (pRegKey->values[i].pData == NULL)
3997 + /* We have a match! Copy out the data. */
3998 + memcpy(pRegKey->values[i].pData, pBuf, dataSize);
4000 + /* Reset datasize - overwrite if new or same */
4001 + pRegKey->values[i].dataSize = dataSize;
4003 + /* Set our status to good and exit. */
4009 + /* See if we found a match or if this is a new entry */
4010 + if (i == pRegKey->numValueEntries) {
4011 + /* No match, need to make a new entry */
4012 + /* First check to see if we can make any more entries. */
4013 + if (pRegKey->numValueEntries < BRIDGE_MAX_NUM_REG_ENTRIES) {
4014 + CSL_Strcpyn(pRegKey->
4015 + values[pRegKey->numValueEntries].name, valName,
4016 + BRIDGE_MAX_NAME_SIZE);
4017 + pRegKey->values[pRegKey->numValueEntries].pData =
4018 + MEM_Alloc(dataSize, MEM_NONPAGED);
4019 + if (pRegKey->values[pRegKey->numValueEntries].pData !=
4022 + values[pRegKey->numValueEntries].pData,
4025 + values[pRegKey->numValueEntries].dataSize =
4027 + pRegKey->numValueEntries++;
4031 + GT_0trace(REG_debugMask, GT_7CLASS,
4032 + "MAX NUM REG ENTRIES REACHED\n");
4040 + * ======== regsupEnumValue ========
4042 + * Returns registry "values" and their "data" under a (sub)key.
4044 +DSP_STATUS regsupEnumValue(IN u32 dwIndex, IN CONST char *pstrKey,
4045 + IN OUT char *pstrValue, IN OUT u32 *pdwValueSize,
4046 + IN OUT char *pstrData, IN OUT u32 *pdwDataSize)
4048 + DSP_STATUS retVal = REG_E_INVALIDSUBKEY;
4050 + u32 dwKeyLen = CSL_Strlen(pstrKey);
4053 + /* Need to search through the entries looking for the right one. */
4054 + for (i = 0; i < pRegKey->numValueEntries; i++) {
4055 + /* See if the name matches. */
4056 + if ((CSL_Strncmp(pRegKey->values[i].name, pstrKey,
4057 + dwKeyLen) == 0) && count++ == dwIndex) {
4058 + /* We have a match! Copy out the data. */
4059 + memcpy(pstrData, pRegKey->values[i].pData,
4060 + pRegKey->values[i].dataSize);
4061 + /* Get the size for the caller. */
4062 + *pdwDataSize = pRegKey->values[i].dataSize;
4063 + *pdwValueSize = CSL_Strlen(&(pRegKey->
4064 + values[i].name[dwKeyLen]));
4065 + CSL_Strcpyn(pstrValue,
4066 + &(pRegKey->values[i].name[dwKeyLen]),
4067 + *pdwValueSize + 1);
4068 + GT_3trace(REG_debugMask, GT_2CLASS,
4069 + "E Key %s, Value %s, Data %x ",
4070 + pstrKey, pstrValue, *(u32 *)pstrData);
4071 + printS((u8 *)pstrData);
4072 + /* Set our status to good and exit. */
4078 + if (count && DSP_FAILED(retVal))
4079 + retVal = REG_E_NOMOREITEMS;
4085 + * ======== regsupDeleteValue ========
4087 +DSP_STATUS regsupDeleteValue(IN CONST char *pstrSubkey,
4088 + IN CONST char *pstrValue)
4090 + DSP_STATUS retVal = DSP_EFAIL;
4093 + for (i = 0; ((i < BRIDGE_MAX_NUM_REG_ENTRIES) &&
4094 + (i < pRegKey->numValueEntries)); i++) {
4095 + /* See if the name matches... */
4096 + if (CSL_Strncmp(pRegKey->values[i].name, pstrValue,
4097 + BRIDGE_MAX_NAME_SIZE) == 0) {
4098 + /* We have a match! Delete this key. To delete a
4099 + * key, we free all resources associated with this
4100 + * key and, if we're not already the last entry in
4101 + * the array, we copy that entry into this deleted
4104 + MEM_Free(pRegKey->values[i].pData);
4105 + if ((pRegKey->numValueEntries - 1) == i) {
4106 + /* we're deleting the last one */
4107 + pRegKey->values[i].name[0] = '\0';
4108 + pRegKey->values[i].dataSize = 0;
4109 + pRegKey->values[i].pData = NULL;
4111 + /* move the last one here */
4112 + CSL_Strcpyn(pRegKey->values[i].name,
4114 + values[pRegKey->numValueEntries - 1].name,
4115 + BRIDGE_MAX_NAME_SIZE);
4116 + pRegKey->values[i].dataSize =
4118 + values[pRegKey->numValueEntries-1].dataSize;
4119 + pRegKey->values[i].pData =
4121 + values[pRegKey->numValueEntries-1].pData;
4122 + /* don't have to do this, but for
4123 + * the paranoid... */
4125 + values[pRegKey->numValueEntries-1].name[0] =
4129 + /* another one bites the dust. */
4130 + pRegKey->numValueEntries--;
4132 + /* Set our status to good and exit... */
4141 diff --git a/drivers/dsp/bridge/services/regsup.h b/drivers/dsp/bridge/services/regsup.h
4142 new file mode 100644
4143 index 0000000..8893854
4145 +++ b/drivers/dsp/bridge/services/regsup.h
4148 + * linux/drivers/dsp/bridge/services/regsup.h
4150 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
4152 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
4154 + * This package is free software; you can redistribute it and/or modify
4155 + * it under the terms of the GNU General Public License version 2 as
4156 + * published by the Free Software Foundation.
4158 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
4159 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
4160 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
4165 + * ======== regsup.h ========
4167 + *! Revision History
4168 + *! ================
4174 +#define BRIDGE_MAX_NAME_SIZE MAXREGPATHLENGTH
4175 +#define BRIDGE_MAX_NUM_REG_ENTRIES 52
4177 +/* Init function. MUST be called BEFORE any calls are */
4178 +/* made into this psuedo-registry!!! Returns TRUE/FALSE for SUCCESS/ERROR */
4179 +extern bool regsupInit(void);
4181 +/* Release all registry support allocations. */
4182 +extern void regsupExit(void);
4185 + * ======== regsupDeleteValue ========
4187 +extern DSP_STATUS regsupDeleteValue(IN CONST char *pstrSubkey,
4188 + IN CONST char *pstrValue);
4189 +/* Get the value of the entry having the given name. Returns DSP_SOK */
4190 +/* if an entry was found and the value retrieved. Returns DSP_EFAIL
4192 +extern DSP_STATUS regsupGetValue(char *valName, void *pBuf, u32 *dataSize);
4194 +/* Sets the value of the entry having the given name. Returns DSP_SOK */
4195 +/* if an entry was found and the value set. Returns DSP_EFAIL otherwise. */
4196 +extern DSP_STATUS regsupSetValue(char *valName, void *pBuf, u32 dataSize);
4198 +/* Returns registry "values" and their "data" under a (sub)key. */
4199 +extern DSP_STATUS regsupEnumValue(IN u32 dwIndex, IN CONST char *pstrKey,
4200 + IN OUT char *pstrValue, IN OUT u32 *pdwValueSize,
4201 + IN OUT char *pstrData, IN OUT u32 *pdwDataSize);
4205 diff --git a/drivers/dsp/bridge/services/services.c b/drivers/dsp/bridge/services/services.c
4206 new file mode 100644
4207 index 0000000..5e92d3e
4209 +++ b/drivers/dsp/bridge/services/services.c
4212 + * linux/drivers/dsp/bridge/services/services.c
4214 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
4216 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
4218 + * This package is free software; you can redistribute it and/or modify
4219 + * it under the terms of the GNU General Public License version 2 as
4220 + * published by the Free Software Foundation.
4222 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
4223 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
4224 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
4229 + * ======== services.c ========
4231 + * Provide SERVICES loading.
4233 + * Public Functions:
4238 + *! Revision History
4239 + *! ================
4240 + *! 20-Nov-2000 rr: NTFY_Init/Exit added.
4241 + *! 06-Jul-2000 rr: PROC prefix changed to PRCS to accomodate RM.
4242 + *! 01-Feb-2000 kc: Created.
4245 +#include <host_os.h>
4247 +/* ----------------------------------- DSP/BIOS Bridge */
4249 +#include <dbdefs.h>
4251 +/* ----------------------------------- Trace & Debug */
4255 +/* ----------------------------------- OS Adaptation Layer */
4271 +/* ----------------------------------- This */
4272 +#include <services.h>
4274 +/* ----------------------------------- Globals */
4276 +static struct GT_Mask SERVICES_debugMask = { NULL, NULL }; /* GT trace var. */
4279 +static u32 cRefs; /* SERVICES module reference count */
4282 + * ======== SERVICES_Exit ========
4284 + * Discontinue usage of module; free resources when reference count
4287 +void SERVICES_Exit(void)
4289 + DBC_Require(cRefs > 0);
4291 + GT_1trace(SERVICES_debugMask, GT_5CLASS, "SERVICES_Exit: cRefs 0x%x\n",
4296 + /* Uninitialize all SERVICES modules here */
4315 + DBC_Ensure(cRefs >= 0);
4319 + * ======== SERVICES_Init ========
4321 + * Initializes SERVICES modules.
4323 +bool SERVICES_Init(void)
4325 + bool fInit = true;
4326 + bool fCFG, fCSL, fDBG, fDPC, fISR, fKFILE, fLST, fMEM;
4327 + bool fPRCS, fREG, fSYNC, fCLK, fUTIL, fNTFY;
4329 + DBC_Require(cRefs >= 0);
4334 + GT_create(&SERVICES_debugMask, "OS"); /* OS for OSal */
4336 + GT_0trace(SERVICES_debugMask, GT_ENTER,
4337 + "SERVICES_Init: entered\n");
4339 + /* Perform required initialization of SERVICES modules. */
4340 + fMEM = MEM_Init();
4341 + fREG = REG_Init();
4342 + fCFG = CFG_Init();
4343 + fCSL = CSL_Init();
4344 + fDBG = DBG_Init();
4345 + fDPC = DPC_Init();
4346 + fISR = ISR_Init();
4347 + fKFILE = KFILE_Init();
4348 + fLST = LST_Init();
4349 + fPRCS = PRCS_Init();
4350 + /* fREG = REG_Init(); */
4351 + fSYNC = SYNC_Init();
4352 + fCLK = CLK_Init();
4353 + fUTIL = UTIL_Init();
4354 + fNTFY = NTFY_Init();
4356 + fInit = fCFG && fCSL && fDBG && fDPC && fISR && fKFILE &&
4357 + fLST && fMEM && fPRCS && fREG && fSYNC && fCLK && fUTIL;
4408 + GT_1trace(SERVICES_debugMask, GT_5CLASS, "SERVICES_Init: cRefs 0x%x\n",
4411 + DBC_Ensure((fInit && (cRefs > 0)) || (!fInit && (cRefs >= 0)));
4416 diff --git a/drivers/dsp/bridge/services/sync.c b/drivers/dsp/bridge/services/sync.c
4417 new file mode 100644
4418 index 0000000..f472b2d
4420 +++ b/drivers/dsp/bridge/services/sync.c
4423 + * linux/drivers/dsp/bridge/services/sync.c
4425 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
4427 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
4429 + * This package is free software; you can redistribute it and/or modify
4430 + * it under the terms of the GNU General Public License version 2 as
4431 + * published by the Free Software Foundation.
4433 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
4434 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
4435 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
4439 + * ======== syncce.c ========
4441 + * Synchronization services.
4443 + * Public Functions:
4449 + * SYNC_InitializeCS
4454 + * SYNC_WaitOnEvent
4455 + * SYNC_WaitOnMultipleEvents
4457 + *! Revision History:
4458 + *! ================
4459 + *! 05-Nov-2001 kc: Minor cosmetic changes.
4460 + *! 05-Oct-2000 jeh Added SYNC_WaitOnMultipleEvents().
4461 + *! 10-Aug-2000 rr: SYNC_PostMessage added.
4462 + *! 10-Jul-2000 jeh Modified SYNC_OpenEvent() to handle NULL attrs.
4463 + *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit.
4465 + *! 01-Dec-1999 ag: Added optional named event creation in SYNC_OpenEvent().
4466 + *! 22-Nov-1999 kc: Added changes from code review.
4467 + *! 22-Sep-1999 kc: Modified from sync95.c.
4468 + *! 05-Aug-1996 gp: Created.
4471 +/* ----------------------------------- Host OS */
4472 +#include <host_os.h>
4474 +/* ----------------------------------- DSP/BIOS Bridge */
4476 +#include <dbdefs.h>
4477 +#include <errbase.h>
4479 +/* ----------------------------------- Trace & Debug */
4483 +/* ----------------------------------- OS Adaptation Layer */
4487 +/* ----------------------------------- This */
4490 +/* ----------------------------------- Defines, Data Structures, Typedefs */
4491 +#define SIGNATURE 0x434e5953 /* "SYNC" (in reverse) */
4492 +#define SIGNATURECS 0x53435953 /* "SYCS" (in reverse) */
4493 +#define SIGNATUREDPCCS 0x53445953 /* "SYDS" (in reverse) */
4505 +struct WAIT_OBJECT {
4506 + enum wait_state state;
4507 + struct SYNC_OBJECT *signalling_event;
4508 + struct semaphore sem;
4511 +/* Generic SYNC object: */
4512 +struct SYNC_OBJECT {
4513 + u32 dwSignature; /* Used for object validation. */
4514 + enum sync_state state;
4515 + spinlock_t sync_lock;
4516 + struct WAIT_OBJECT *pWaitObj;
4519 +struct SYNC_CSOBJECT {
4520 + u32 dwSignature; /* used for object validation */
4521 + struct semaphore sem;
4524 +struct SYNC_DPCCSOBJECT {
4525 + u32 dwSignature; /* used for object validation */
4526 + spinlock_t sync_dpccs_lock;
4530 +/* ----------------------------------- Globals */
4532 +static struct GT_Mask SYNC_debugMask = { NULL, NULL }; /* GT trace variable */
4535 +static int test_and_set(volatile void *ptr, int val)
4538 + asm volatile (" swp %0, %0, [%1]" : "+r" (ret) : "r"(ptr) : "memory");
4542 +static void timeout_callback(unsigned long hWaitObj);
4545 + * ======== SYNC_CloseEvent ========
4547 + * Close an existing SYNC event object.
4549 +DSP_STATUS SYNC_CloseEvent(struct SYNC_OBJECT *hEvent)
4551 + DSP_STATUS status = DSP_SOK;
4552 + struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent;
4554 + DBC_Require(pEvent != NULL && pEvent->pWaitObj == NULL);
4556 + GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_CloseEvent: hEvent 0x%x\n",
4559 + if (MEM_IsValidHandle(hEvent, SIGNATURE)) {
4560 + if (pEvent->pWaitObj) {
4561 + status = DSP_EFAIL;
4562 + GT_0trace(SYNC_debugMask, GT_6CLASS,
4563 + "SYNC_CloseEvent: Wait object not NULL\n");
4565 + MEM_FreeObject(pEvent);
4568 + status = DSP_EHANDLE;
4569 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4570 + "SYNC_CloseEvent: invalid "
4571 + "hEvent handle 0x%x\n", hEvent);
4578 + * ======== SYNC_Exit ========
4580 + * Cleanup SYNC module.
4582 +void SYNC_Exit(void)
4584 + GT_0trace(SYNC_debugMask, GT_5CLASS, "SYNC_Exit\n");
4588 + * ======== SYNC_Init ========
4590 + * Initialize SYNC module.
4592 +bool SYNC_Init(void)
4594 + GT_create(&SYNC_debugMask, "SY"); /* SY for SYnc */
4596 + GT_0trace(SYNC_debugMask, GT_5CLASS, "SYNC_Init\n");
4602 + * ======== SYNC_OpenEvent ========
4604 + * Open a new synchronization event object.
4606 +DSP_STATUS SYNC_OpenEvent(OUT struct SYNC_OBJECT **phEvent,
4607 + IN OPTIONAL struct SYNC_ATTRS *pAttrs)
4609 + struct SYNC_OBJECT *pEvent = NULL;
4610 + DSP_STATUS status = DSP_SOK;
4612 + DBC_Require(phEvent != NULL);
4614 + GT_2trace(SYNC_debugMask, GT_ENTER,
4615 + "SYNC_OpenEvent: phEvent 0x%x, pAttrs "
4616 + "0x%x\n", phEvent, pAttrs);
4618 + /* Allocate memory for sync object */
4619 + MEM_AllocObject(pEvent, struct SYNC_OBJECT, SIGNATURE);
4620 + if (pEvent != NULL) {
4621 + pEvent->state = so_reset;
4622 + pEvent->pWaitObj = NULL;
4623 + pEvent->sync_lock = __SPIN_LOCK_UNLOCKED(pEvent.sync_lock);
4625 + status = DSP_EMEMORY;
4626 + GT_0trace(SYNC_debugMask, GT_6CLASS,
4627 + "SYNC_OpenEvent: MEM_AllocObject failed\n");
4630 + *phEvent = pEvent;
4636 + * ======== SYNC_ResetEvent ========
4638 + * Reset an event to non-signalled.
4640 +DSP_STATUS SYNC_ResetEvent(struct SYNC_OBJECT *hEvent)
4642 + DSP_STATUS status = DSP_SOK;
4643 + struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent;
4645 + GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_ResetEvent: hEvent 0x%x\n",
4648 + if (MEM_IsValidHandle(hEvent, SIGNATURE)) {
4649 + pEvent->state = so_reset;
4652 + status = DSP_EHANDLE;
4653 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4654 + "SYNC_ResetEvent: invalid hEvent "
4655 + "handle 0x%x\n", hEvent);
4662 + * ======== SYNC_SetEvent ========
4664 + * Set an event to signaled and unblock one waiting thread.
4666 + * This function is called from ISR, DPC and user context. Hence interrupts
4667 + * are disabled to ensure atomicity.
4670 +DSP_STATUS SYNC_SetEvent(struct SYNC_OBJECT *hEvent)
4672 + DSP_STATUS status = DSP_SOK;
4673 + struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent;
4674 + unsigned long flags;
4676 + GT_1trace(SYNC_debugMask, GT_6CLASS, "SYNC_SetEvent: hEvent 0x%x\n",
4679 + if (MEM_IsValidHandle(hEvent, SIGNATURE)) {
4680 + spin_lock_irqsave(&hEvent->sync_lock, flags);
4681 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4682 + "SYNC_SetEvent: pEvent->pWaitObj "
4683 + "= 0x%x \n", pEvent->pWaitObj);
4684 + if (pEvent->pWaitObj)
4685 + GT_1trace(SYNC_debugMask, GT_6CLASS, "SYNC_SetEvent: "
4686 + "pEvent->pWaitObj->state = 0x%x \n",
4687 + pEvent->pWaitObj->state);
4688 + if (pEvent->pWaitObj != NULL &&
4689 + test_and_set(&pEvent->pWaitObj->state,
4690 + wo_signalled) == wo_waiting) {
4692 + pEvent->state = so_reset;
4693 + pEvent->pWaitObj->signalling_event = pEvent;
4694 + up(&pEvent->pWaitObj->sem);
4695 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4696 + "SYNC_SetEvent: Unlock "
4697 + "Semaphore for hEvent 0x%x\n", hEvent);
4699 + pEvent->state = so_signalled;
4701 + spin_unlock_irqrestore(&hEvent->sync_lock, flags);
4703 + status = DSP_EHANDLE;
4704 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4705 + "SYNC_SetEvent: invalid hEvent "
4706 + "handle 0x%x\n", hEvent);
4712 + * ======== SYNC_WaitOnEvent ========
4714 + * Wait for an event to be signalled, up to the specified timeout.
4715 + * Note: dwTimeOut must be 0xffffffff to signal infinite wait.
4717 +DSP_STATUS SYNC_WaitOnEvent(struct SYNC_OBJECT *hEvent, u32 dwTimeout)
4719 + DSP_STATUS status = DSP_SOK;
4720 + struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent;
4723 + GT_2trace(SYNC_debugMask, GT_6CLASS, "SYNC_WaitOnEvent: hEvent 0x%x\n, "
4724 + "dwTimeOut 0x%x", hEvent, dwTimeout);
4725 + if (MEM_IsValidHandle(hEvent, SIGNATURE)) {
4726 + status = SYNC_WaitOnMultipleEvents(&pEvent, 1, dwTimeout,
4729 + status = DSP_EHANDLE;
4730 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4731 + "SYNC_WaitOnEvent: invalid hEvent"
4732 + "handle 0x%x\n", hEvent);
4738 + * ======== SYNC_WaitOnMultipleEvents ========
4740 + * Wait for any of an array of events to be signalled, up to the
4741 + * specified timeout.
4743 +DSP_STATUS SYNC_WaitOnMultipleEvents(struct SYNC_OBJECT **hSyncEvents,
4744 + u32 uCount, u32 dwTimeout,
4748 + DSP_STATUS status = DSP_SOK;
4750 + struct WAIT_OBJECT *Wp;
4752 + DBC_Require(uCount > 0);
4753 + DBC_Require(hSyncEvents != NULL);
4754 + DBC_Require(puIndex != NULL);
4756 + for (i = 0; i < uCount; i++)
4757 + DBC_Require(MEM_IsValidHandle(hSyncEvents[i], SIGNATURE));
4759 + GT_4trace(SYNC_debugMask, GT_6CLASS,
4760 + "SYNC_WaitOnMultipleEvents: hSyncEvents:"
4761 + "0x%x\tuCount: 0x%x" "\tdwTimeout: 0x%x\tpuIndex: 0x%x\n",
4762 + hSyncEvents, uCount, dwTimeout, puIndex);
4764 + Wp = MEM_Calloc(sizeof(struct WAIT_OBJECT), MEM_NONPAGED);
4766 + return DSP_EMEMORY;
4768 + Wp->state = wo_waiting;
4769 + Wp->signalling_event = NULL;
4770 + init_MUTEX_LOCKED(&(Wp->sem));
4772 + for (curr = 0; curr < uCount; curr++) {
4773 + hSyncEvents[curr]->pWaitObj = Wp;
4774 + if (hSyncEvents[curr]->state == so_signalled) {
4775 + GT_0trace(SYNC_debugMask, GT_6CLASS,
4776 + "Detected signaled Event !!!\n");
4777 + if (test_and_set(&(Wp->state), wo_signalled) ==
4779 + GT_0trace(SYNC_debugMask, GT_6CLASS,
4780 + "Setting Signal Event!!!\n");
4781 + hSyncEvents[curr]->state = so_reset;
4782 + Wp->signalling_event = hSyncEvents[curr];
4784 + curr++; /* Will try optimizing later */
4789 + curr--; /* Will try optimizing later */
4790 + if (Wp->state != wo_signalled && dwTimeout > 0) {
4791 + struct timer_list timeout;
4792 + if (dwTimeout != SYNC_INFINITE) {
4793 + init_timer(&timeout);
4794 + timeout.function = timeout_callback;
4795 + timeout.data = (unsigned long)Wp;
4796 + timeout.expires = jiffies + dwTimeout * HZ / 1000;
4797 + add_timer(&timeout);
4799 + if (down_interruptible(&(Wp->sem))) {
4800 + GT_0trace(SYNC_debugMask, GT_7CLASS, "SYNC: "
4801 + "WaitOnMultipleEvents Interrupted by signal\n");
4802 + status = DSP_EFAIL;
4804 + if (dwTimeout != SYNC_INFINITE) {
4805 + if (in_interrupt()) {
4806 + if (!del_timer(&timeout)) {
4807 + GT_0trace(SYNC_debugMask, GT_7CLASS,
4808 + "SYNC: Timer expired\n");
4811 + if (!del_timer_sync(&timeout)) {
4812 + GT_0trace(SYNC_debugMask, GT_7CLASS,
4813 + "SYNC: Timer expired\n");
4818 + for (i = 0; i <= curr; i++) {
4819 + if (MEM_IsValidHandle(hSyncEvents[i], SIGNATURE)) {
4820 + /* Memory corruption here if hSyncEvents[i] is
4821 + * freed before following statememt. */
4822 + hSyncEvents[i]->pWaitObj = NULL;
4824 + if (hSyncEvents[i] == Wp->signalling_event)
4828 + if (Wp->signalling_event == NULL && DSP_SUCCEEDED(status)) {
4829 + GT_0trace(SYNC_debugMask, GT_7CLASS,
4830 + "SYNC:Signaling Event NULL!!!(:-\n");
4831 + status = DSP_ETIMEOUT;
4838 +static void timeout_callback(unsigned long hWaitObj)
4840 + struct WAIT_OBJECT *pWaitObj = (struct WAIT_OBJECT *)hWaitObj;
4841 + if (test_and_set(&pWaitObj->state, wo_signalled) == wo_waiting)
4842 + up(&pWaitObj->sem);
4847 + * ======== SYNC_DeleteCS ========
4849 +DSP_STATUS SYNC_DeleteCS(struct SYNC_CSOBJECT *hCSObj)
4851 + DSP_STATUS status = DSP_SOK;
4852 + struct SYNC_CSOBJECT *pCSObj = (struct SYNC_CSOBJECT *)hCSObj;
4854 + GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_DeleteCS\n");
4856 + if (MEM_IsValidHandle(hCSObj, SIGNATURECS)) {
4857 + if (down_trylock(&pCSObj->sem) != 0) {
4858 + GT_1trace(SYNC_debugMask, GT_7CLASS,
4859 + "CS in use (locked) while "
4860 + "deleting! pCSObj=0x%X", pCSObj);
4863 + MEM_FreeObject(hCSObj);
4864 + } else if (MEM_IsValidHandle(hCSObj, SIGNATUREDPCCS)) {
4865 + struct SYNC_DPCCSOBJECT *pDPCCSObj =
4866 + (struct SYNC_DPCCSOBJECT *)hCSObj;
4867 + if (pDPCCSObj->count != 1) {
4868 + GT_1trace(SYNC_debugMask, GT_7CLASS,
4869 + "DPC CS in use (locked) while "
4870 + "deleting! pCSObj=0x%X", pCSObj);
4873 + MEM_FreeObject(pDPCCSObj);
4875 + status = DSP_EHANDLE;
4876 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4877 + "SYNC_DeleteCS: invalid hCSObj "
4878 + "handle 0x%x\n", hCSObj);
4885 + * ======== SYNC_EnterCS ========
4887 +DSP_STATUS SYNC_EnterCS(struct SYNC_CSOBJECT *hCSObj)
4889 + DSP_STATUS status = DSP_SOK;
4890 + struct SYNC_CSOBJECT *pCSObj = (struct SYNC_CSOBJECT *)hCSObj;
4892 + GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_EnterCS: hCSObj %p\n",
4894 + if (MEM_IsValidHandle(hCSObj, SIGNATURECS)) {
4895 + if (in_interrupt()) {
4896 + status = DSP_EFAIL;
4897 + GT_0trace(SYNC_debugMask, GT_7CLASS,
4898 + "SYNC_EnterCS called from "
4899 + "ISR/DPC or with ISR/DPC disabled!");
4901 + } else if (down_interruptible(&pCSObj->sem)) {
4902 + GT_1trace(SYNC_debugMask, GT_7CLASS,
4903 + "CS interrupted by signal! "
4904 + "pCSObj=0x%X", pCSObj);
4905 + status = DSP_EFAIL;
4907 + } else if (MEM_IsValidHandle(hCSObj, SIGNATUREDPCCS)) {
4908 + struct SYNC_DPCCSOBJECT *pDPCCSObj =
4909 + (struct SYNC_DPCCSOBJECT *)hCSObj;
4910 + GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_EnterCS DPC\n");
4911 + spin_lock_bh(&pDPCCSObj->sync_dpccs_lock);
4912 + pDPCCSObj->count--;
4913 + if (pDPCCSObj->count != 0) {
4914 + /* FATAL ERROR : Failed to acquire DPC CS */
4915 + GT_2trace(SYNC_debugMask, GT_7CLASS,
4916 + "SYNC_EnterCS DPCCS %x locked,"
4917 + "count %d", pDPCCSObj, pDPCCSObj->count);
4918 + spin_unlock_bh(&pDPCCSObj->sync_dpccs_lock);
4922 + status = DSP_EHANDLE;
4923 + GT_1trace(SYNC_debugMask, GT_6CLASS,
4924 + "SYNC_EnterCS: invalid hCSObj "
4925 + "handle 0x%x\n", hCSObj);
4932 + * ======== SYNC_InitializeCS ========
4934 +DSP_STATUS SYNC_InitializeCS(OUT struct SYNC_CSOBJECT **phCSObj)
4936 + DSP_STATUS status = DSP_SOK;
4937 + struct SYNC_CSOBJECT *pCSObj = NULL;
4939 + GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_InitializeCS\n");
4941 + /* Allocate memory for sync CS object */
4942 + MEM_AllocObject(pCSObj, struct SYNC_CSOBJECT, SIGNATURECS);
4943 + if (pCSObj != NULL) {
4944 + init_MUTEX(&pCSObj->sem);
4946 + status = DSP_EMEMORY;
4947 + GT_0trace(SYNC_debugMask, GT_6CLASS,
4948 + "SYNC_InitializeCS: MEM_AllocObject"
4951 + /* return CS object */
4952 + *phCSObj = pCSObj;
4953 + DBC_Assert(DSP_FAILED(status) || (pCSObj));
4957 +DSP_STATUS SYNC_InitializeDPCCS(OUT struct SYNC_CSOBJECT **phCSObj)
4959 + DSP_STATUS status = DSP_SOK;
4960 + struct SYNC_DPCCSOBJECT *pCSObj = NULL;
4962 + DBC_Require(phCSObj);
4964 + GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_InitializeDPCCS\n");
4967 + /* Allocate memory for sync CS object */
4968 + MEM_AllocObject(pCSObj, struct SYNC_DPCCSOBJECT,
4970 + if (pCSObj != NULL) {
4971 + pCSObj->count = 1;
4972 + pCSObj->sync_dpccs_lock =
4973 + __SPIN_LOCK_UNLOCKED(pCSObj.sync_dpccs_lock);
4975 + status = DSP_EMEMORY;
4976 + GT_0trace(SYNC_debugMask, GT_6CLASS,
4977 + "SYNC_InitializeDPCCS: "
4978 + "MEM_AllocObject failed\n");
4981 + /* return CS object */
4982 + *phCSObj = (struct SYNC_CSOBJECT *)pCSObj;
4984 + status = DSP_EPOINTER;
4987 + GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_InitializeDPCCS "
4988 + "pCSObj %p\n", pCSObj);
4989 + DBC_Assert(DSP_FAILED(status) || (pCSObj));
4995 + * ======== SYNC_LeaveCS ========
4997 +DSP_STATUS SYNC_LeaveCS(struct SYNC_CSOBJECT *hCSObj)
4999 + DSP_STATUS status = DSP_SOK;
5000 + struct SYNC_CSOBJECT *pCSObj = (struct SYNC_CSOBJECT *)hCSObj;
5002 + GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_LeaveCS: hCSObj %p\n",
5005 + if (MEM_IsValidHandle(hCSObj, SIGNATURECS)) {
5007 + } else if (MEM_IsValidHandle(hCSObj, SIGNATUREDPCCS)) {
5008 + struct SYNC_DPCCSOBJECT *pDPCCSObj =
5009 + (struct SYNC_DPCCSOBJECT *)hCSObj;
5010 + pDPCCSObj->count++;
5011 + if (pDPCCSObj->count != 1) {
5012 + /* FATAL ERROR : Invalid DPC CS count */
5013 + GT_2trace(SYNC_debugMask, GT_7CLASS,
5014 + "SYNC_LeaveCS DPCCS %x, "
5015 + "Invalid count %d", pDPCCSObj,
5016 + pDPCCSObj->count);
5017 + spin_unlock_bh(&pDPCCSObj->sync_dpccs_lock);
5019 + spin_lock_bh(&pDPCCSObj->sync_dpccs_lock);
5021 + spin_unlock_bh(&pDPCCSObj->sync_dpccs_lock);
5022 + GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_LeaveCS DPC\n");
5024 + status = DSP_EHANDLE;
5025 + GT_1trace(SYNC_debugMask, GT_6CLASS,
5026 + "SYNC_LeaveCS: invalid hCSObj "
5027 + "handle 0x%x\n", hCSObj);