1 /*
2  * io.c
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * IO manager interface: Manages IO between CHNL and msg_ctrl.
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 #include <linux/types.h>
19 
20 /*  ----------------------------------- Host OS */
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 /*  ----------------------------------- Platform Manager */
30 #include <dspbridge/dev.h>
31 
32 /*  ----------------------------------- This */
33 #include <ioobj.h>
34 #include <dspbridge/io.h>
35 
36 /*  ----------------------------------- Globals */
37 static u32 refs;
38 
39 /*
40  *  ======== io_create ========
41  *  Purpose:
42  *      Create an IO manager object, responsible for managing IO between
43  *      CHNL and msg_ctrl
44  */
io_create(struct io_mgr ** io_man,struct dev_object * hdev_obj,const struct io_attrs * mgr_attrts)45 int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj,
46 		     const struct io_attrs *mgr_attrts)
47 {
48 	struct bridge_drv_interface *intf_fxns;
49 	struct io_mgr *hio_mgr = NULL;
50 	struct io_mgr_ *pio_mgr = NULL;
51 	int status = 0;
52 
53 	DBC_REQUIRE(refs > 0);
54 	DBC_REQUIRE(io_man != NULL);
55 	DBC_REQUIRE(mgr_attrts != NULL);
56 
57 	*io_man = NULL;
58 
59 	/* A memory base of 0 implies no memory base: */
60 	if ((mgr_attrts->shm_base != 0) && (mgr_attrts->sm_length == 0))
61 		status = -EINVAL;
62 
63 	if (mgr_attrts->word_size == 0)
64 		status = -EINVAL;
65 
66 	if (!status) {
67 		dev_get_intf_fxns(hdev_obj, &intf_fxns);
68 
69 		/* Let Bridge channel module finish the create: */
70 		status = (*intf_fxns->io_create) (&hio_mgr, hdev_obj,
71 						      mgr_attrts);
72 
73 		if (!status) {
74 			pio_mgr = (struct io_mgr_ *)hio_mgr;
75 			pio_mgr->intf_fxns = intf_fxns;
76 			pio_mgr->dev_obj = hdev_obj;
77 
78 			/* Return the new channel manager handle: */
79 			*io_man = hio_mgr;
80 		}
81 	}
82 
83 	return status;
84 }
85 
86 /*
87  *  ======== io_destroy ========
88  *  Purpose:
89  *      Delete IO manager.
90  */
io_destroy(struct io_mgr * hio_mgr)91 int io_destroy(struct io_mgr *hio_mgr)
92 {
93 	struct bridge_drv_interface *intf_fxns;
94 	struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr;
95 	int status;
96 
97 	DBC_REQUIRE(refs > 0);
98 
99 	intf_fxns = pio_mgr->intf_fxns;
100 
101 	/* Let Bridge channel module destroy the io_mgr: */
102 	status = (*intf_fxns->io_destroy) (hio_mgr);
103 
104 	return status;
105 }
106 
107 /*
108  *  ======== io_exit ========
109  *  Purpose:
110  *      Discontinue usage of the IO module.
111  */
io_exit(void)112 void io_exit(void)
113 {
114 	DBC_REQUIRE(refs > 0);
115 
116 	refs--;
117 
118 	DBC_ENSURE(refs >= 0);
119 }
120 
121 /*
122  *  ======== io_init ========
123  *  Purpose:
124  *      Initialize the IO module's private state.
125  */
io_init(void)126 bool io_init(void)
127 {
128 	bool ret = true;
129 
130 	DBC_REQUIRE(refs >= 0);
131 
132 	if (ret)
133 		refs++;
134 
135 	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
136 
137 	return ret;
138 }
139