dspdrv.c revision 73b87a916697999bfafd4c43956ba98a2905ecfe
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 */
20#include <linux/types.h>
21#include <dspbridge/host_os.h>
22
23/*  ----------------------------------- DSP/BIOS Bridge */
24#include <dspbridge/dbdefs.h>
25
26/*  ----------------------------------- Trace & Debug */
27#include <dspbridge/dbc.h>
28
29/*  ----------------------------------- OS Adaptation Layer */
30#include <dspbridge/cfg.h>
31
32/*  ----------------------------------- Platform Manager */
33#include <dspbridge/drv.h>
34#include <dspbridge/dev.h>
35#include <dspbridge/dspapi.h>
36
37/*  ----------------------------------- Resource Manager */
38#include <dspbridge/mgr.h>
39
40/*  ----------------------------------- This */
41#include <dspbridge/dspdrv.h>
42
43/*
44 *  ======== dsp_init ========
45 *  	Allocates bridge resources. Loads a base image onto DSP, if specified.
46 */
47u32 dsp_init(u32 *init_status)
48{
49	char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510";
50	int status = -EPERM;
51	struct drv_object *drv_obj = NULL;
52	u32 device_node;
53	u32 device_node_string;
54
55	if (!api_init())
56		goto func_cont;
57
58	status = drv_create(&drv_obj);
59	if (status) {
60		api_exit();
61		goto func_cont;
62	}
63
64	/* End drv_create */
65	/* Request Resources */
66	status = drv_request_resources((u32) &dev_node, &device_node_string);
67	if (!status) {
68		/* Attempt to Start the Device */
69		status = dev_start_device((struct cfg_devnode *)
70					  device_node_string);
71		if (status)
72			(void)drv_release_resources
73			    ((u32) device_node_string, drv_obj);
74	} else {
75		dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__);
76		status = -EPERM;
77	}
78
79	/* Unwind whatever was loaded */
80	if (status) {
81		/* irrespective of the status of dev_remove_device we conitinue
82		 * unloading. Get the Driver Object iterate through and remove.
83		 * Reset the status to E_FAIL to avoid going through
84		 * api_init_complete2. */
85		for (device_node = drv_get_first_dev_extension();
86		     device_node != 0;
87		     device_node = drv_get_next_dev_extension(device_node)) {
88			(void)dev_remove_device((struct cfg_devnode *)
89						device_node);
90			(void)drv_release_resources((u32) device_node, drv_obj);
91		}
92		/* Remove the Driver Object */
93		(void)drv_destroy(drv_obj);
94		drv_obj = NULL;
95		api_exit();
96		dev_dbg(bridge, "%s: Logical device failed init\n", __func__);
97	}			/* Unwinding the loaded drivers */
98func_cont:
99	/* Attempt to Start the Board */
100	if (!status) {
101		/* BRD_AutoStart could fail if the dsp execuetable is not the
102		 * correct one. We should not propagate that error
103		 * into the device loader. */
104		(void)api_init_complete2();
105	} else {
106		dev_dbg(bridge, "%s: Failed\n", __func__);
107	}			/* End api_init_complete2 */
108	DBC_ENSURE((!status && drv_obj != NULL) ||
109		   (status && drv_obj == NULL));
110	*init_status = status;
111	/* Return the Driver Object */
112	return (u32) drv_obj;
113}
114
115/*
116 *  ======== dsp_deinit ========
117 *  	Frees the resources allocated for bridge.
118 */
119bool dsp_deinit(u32 device_context)
120{
121	bool ret = true;
122	u32 device_node;
123	struct mgr_object *mgr_obj = NULL;
124	struct drv_data *drv_datap = dev_get_drvdata(bridge);
125
126	while ((device_node = drv_get_first_dev_extension()) != 0) {
127		(void)dev_remove_device((struct cfg_devnode *)device_node);
128
129		(void)drv_release_resources((u32) device_node,
130					(struct drv_object *)device_context);
131	}
132
133	(void)drv_destroy((struct drv_object *)device_context);
134
135	/* Get the Manager Object from driver data
136	 * MGR Destroy will unload the DCD dll */
137	if (drv_datap && drv_datap->mgr_object) {
138		mgr_obj = drv_datap->mgr_object;
139		(void)mgr_destroy(mgr_obj);
140	} else {
141		pr_err("%s: Failed to retrieve the object handle\n", __func__);
142	}
143
144	api_exit();
145
146	return ret;
147}
148