summaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/pmgr/chnl.c
blob: 90317b58f8eb1fb87a686dddf8fbf6703dccd5d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * chnl.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * DSP API channel interface: multiplexes data streams through the single
 * physical link managed by a Bridge Bridge driver.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/types.h>
/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/cfg.h>
#include <dspbridge/sync.h>

/*  ----------------------------------- Platform Manager */
#include <dspbridge/proc.h>
#include <dspbridge/dev.h>

/*  ----------------------------------- Others */
#include <dspbridge/chnlpriv.h>
#include <chnlobj.h>

/*  ----------------------------------- This */
#include <dspbridge/chnl.h>

/*  ----------------------------------- Globals */
static u32 refs;

/*
 *  ======== chnl_create ========
 *  Purpose:
 *      Create a channel manager object, responsible for opening new channels
 *      and closing old ones for a given 'Bridge board.
 */
int chnl_create(struct chnl_mgr **channel_mgr,
		       struct dev_object *hdev_obj,
		       const struct chnl_mgrattrs *mgr_attrts)
{
	int status;
	struct chnl_mgr *hchnl_mgr;
	struct chnl_mgr_ *chnl_mgr_obj = NULL;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(channel_mgr != NULL);
	DBC_REQUIRE(mgr_attrts != NULL);

	*channel_mgr = NULL;

	/* Validate args: */
	if ((0 < mgr_attrts->max_channels) &&
	    (mgr_attrts->max_channels <= CHNL_MAXCHANNELS))
		status = 0;
	else if (mgr_attrts->max_channels == 0)
		status = -EINVAL;
	else
		status = -ECHRNG;

	if (mgr_attrts->word_size == 0)
		status = -EINVAL;

	if (!status) {
		status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
		if (!status && hchnl_mgr != NULL)
			status = -EEXIST;

	}

	if (!status) {
		struct bridge_drv_interface *intf_fxns;
		dev_get_intf_fxns(hdev_obj, &intf_fxns);
		/* Let Bridge channel module finish the create: */
		status = (*intf_fxns->pfn_chnl_create) (&hchnl_mgr, hdev_obj,
							mgr_attrts);
		if (!status) {
			/* Fill in DSP API channel module's fields of the
			 * chnl_mgr structure */
			chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
			chnl_mgr_obj->intf_fxns = intf_fxns;
			/* Finally, return the new channel manager handle: */
			*channel_mgr = hchnl_mgr;
		}
	}

	DBC_ENSURE(status || chnl_mgr_obj);

	return status;
}

/*
 *  ======== chnl_destroy ========
 *  Purpose:
 *      Close all open channels, and destroy the channel manager.
 */
int chnl_destroy(struct chnl_mgr *hchnl_mgr)
{
	struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
	struct bridge_drv_interface *intf_fxns;
	int status;

	DBC_REQUIRE(refs > 0);

	if (chnl_mgr_obj) {
		intf_fxns = chnl_mgr_obj->intf_fxns;
		/* Let Bridge channel module destroy the chnl_mgr: */
		status = (*intf_fxns->pfn_chnl_destroy) (hchnl_mgr);
	} else {
		status = -EFAULT;
	}

	return status;
}

/*
 *  ======== chnl_exit ========
 *  Purpose:
 *      Discontinue usage of the CHNL module.
 */
void chnl_exit(void)
{
	DBC_REQUIRE(refs > 0);

	refs--;

	DBC_ENSURE(refs >= 0);
}

/*
 *  ======== chnl_init ========
 *  Purpose:
 *      Initialize the CHNL module's private state.
 */
bool chnl_init(void)
{
	bool ret = true;

	DBC_REQUIRE(refs >= 0);

	if (ret)
		refs++;

	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));

	return ret;
}
OpenPOWER on IntegriCloud