Commit | Line | Data |
---|---|---|
7d55524d ORL |
1 | /* |
2 | * dspdrv.c | |
3 | * | |
4 | * DSP-BIOS Bridge driver support functions for TI OMAP processors. | |
5 | * | |
6 | * Interface to allocate and free bridge resources. | |
7 | * | |
8 | * Copyright (C) 2005-2006 Texas Instruments, Inc. | |
9 | * | |
10 | * This package is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License version 2 as | |
12 | * published by the Free Software Foundation. | |
13 | * | |
14 | * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
15 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
17 | */ | |
18 | ||
19 | /* ----------------------------------- Host OS */ | |
2094f12d | 20 | #include <linux/types.h> |
7d55524d ORL |
21 | #include <dspbridge/host_os.h> |
22 | ||
23 | /* ----------------------------------- DSP/BIOS Bridge */ | |
7d55524d ORL |
24 | #include <dspbridge/dbdefs.h> |
25 | ||
7d55524d ORL |
26 | /* ----------------------------------- Platform Manager */ |
27 | #include <dspbridge/drv.h> | |
28 | #include <dspbridge/dev.h> | |
29 | #include <dspbridge/dspapi.h> | |
30 | ||
31 | /* ----------------------------------- Resource Manager */ | |
32 | #include <dspbridge/mgr.h> | |
33 | ||
34 | /* ----------------------------------- This */ | |
35 | #include <dspbridge/dspdrv.h> | |
36 | ||
37 | /* | |
38 | * ======== dsp_init ======== | |
db6f016f | 39 | * Allocates bridge resources. Loads a base image onto DSP, if specified. |
7d55524d | 40 | */ |
e6bf74f0 | 41 | u32 dsp_init(u32 *init_status) |
7d55524d ORL |
42 | { |
43 | char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510"; | |
44 | int status = -EPERM; | |
45 | struct drv_object *drv_obj = NULL; | |
46 | u32 device_node; | |
47 | u32 device_node_string; | |
48 | ||
49 | if (!api_init()) | |
50 | goto func_cont; | |
51 | ||
52 | status = drv_create(&drv_obj); | |
b66e0986 | 53 | if (status) { |
7d55524d ORL |
54 | api_exit(); |
55 | goto func_cont; | |
56 | } | |
57 | ||
58 | /* End drv_create */ | |
59 | /* Request Resources */ | |
60 | status = drv_request_resources((u32) &dev_node, &device_node_string); | |
a741ea6e | 61 | if (!status) { |
7d55524d ORL |
62 | /* Attempt to Start the Device */ |
63 | status = dev_start_device((struct cfg_devnode *) | |
64 | device_node_string); | |
b66e0986 | 65 | if (status) |
7d55524d ORL |
66 | (void)drv_release_resources |
67 | ((u32) device_node_string, drv_obj); | |
68 | } else { | |
69 | dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__); | |
70 | status = -EPERM; | |
71 | } | |
72 | ||
73 | /* Unwind whatever was loaded */ | |
b66e0986 | 74 | if (status) { |
0142919c | 75 | /* irrespective of the status of dev_remove_device we continue |
7d55524d ORL |
76 | * unloading. Get the Driver Object iterate through and remove. |
77 | * Reset the status to E_FAIL to avoid going through | |
78 | * api_init_complete2. */ | |
79 | for (device_node = drv_get_first_dev_extension(); | |
80 | device_node != 0; | |
81 | device_node = drv_get_next_dev_extension(device_node)) { | |
82 | (void)dev_remove_device((struct cfg_devnode *) | |
83 | device_node); | |
84 | (void)drv_release_resources((u32) device_node, drv_obj); | |
85 | } | |
86 | /* Remove the Driver Object */ | |
87 | (void)drv_destroy(drv_obj); | |
88 | drv_obj = NULL; | |
89 | api_exit(); | |
90 | dev_dbg(bridge, "%s: Logical device failed init\n", __func__); | |
91 | } /* Unwinding the loaded drivers */ | |
92 | func_cont: | |
93 | /* Attempt to Start the Board */ | |
a741ea6e | 94 | if (!status) { |
0142919c | 95 | /* BRD_AutoStart could fail if the dsp executable is not the |
7d55524d ORL |
96 | * correct one. We should not propagate that error |
97 | * into the device loader. */ | |
98 | (void)api_init_complete2(); | |
99 | } else { | |
100 | dev_dbg(bridge, "%s: Failed\n", __func__); | |
101 | } /* End api_init_complete2 */ | |
7d55524d ORL |
102 | *init_status = status; |
103 | /* Return the Driver Object */ | |
104 | return (u32) drv_obj; | |
105 | } | |
106 | ||
107 | /* | |
108 | * ======== dsp_deinit ======== | |
db6f016f | 109 | * Frees the resources allocated for bridge. |
7d55524d | 110 | */ |
c8c1ad8c | 111 | bool dsp_deinit(u32 device_context) |
7d55524d ORL |
112 | { |
113 | bool ret = true; | |
114 | u32 device_node; | |
115 | struct mgr_object *mgr_obj = NULL; | |
73b87a91 | 116 | struct drv_data *drv_datap = dev_get_drvdata(bridge); |
7d55524d ORL |
117 | |
118 | while ((device_node = drv_get_first_dev_extension()) != 0) { | |
119 | (void)dev_remove_device((struct cfg_devnode *)device_node); | |
120 | ||
121 | (void)drv_release_resources((u32) device_node, | |
c8c1ad8c | 122 | (struct drv_object *)device_context); |
7d55524d ORL |
123 | } |
124 | ||
c8c1ad8c | 125 | (void)drv_destroy((struct drv_object *)device_context); |
7d55524d | 126 | |
73b87a91 | 127 | /* Get the Manager Object from driver data |
7d55524d | 128 | * MGR Destroy will unload the DCD dll */ |
73b87a91 IGC |
129 | if (drv_datap && drv_datap->mgr_object) { |
130 | mgr_obj = drv_datap->mgr_object; | |
7d55524d | 131 | (void)mgr_destroy(mgr_obj); |
73b87a91 IGC |
132 | } else { |
133 | pr_err("%s: Failed to retrieve the object handle\n", __func__); | |
134 | } | |
7d55524d ORL |
135 | |
136 | api_exit(); | |
137 | ||
138 | return ret; | |
139 | } |