Xenomai 3.3.2
Loading...
Searching...
No Matches
16550A_io.h
1/*
2 * Copyright (C) 2007 Jan Kiszka <jan.kiszka@web.de>.
3 *
4 * Xenomai is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * Xenomai is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Xenomai; if not, write to the Free Software Foundation,
16 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19/* Manages the I/O access method of the driver. */
20
21typedef enum { MODE_PIO, MODE_MMIO } io_mode_t;
22
23#if defined(CONFIG_XENO_DRIVERS_16550A_PIO) || \
24 defined(CONFIG_XENO_DRIVERS_16550A_ANY)
25static unsigned long io[MAX_DEVICES];
26module_param_array(io, ulong, NULL, 0400);
27MODULE_PARM_DESC(io, "I/O port addresses of the serial devices");
28#endif /* CONFIG_XENO_DRIVERS_16550A_PIO || CONFIG_XENO_DRIVERS_16550A_ANY */
29
30#if defined(CONFIG_XENO_DRIVERS_16550A_MMIO) || \
31 defined(CONFIG_XENO_DRIVERS_16550A_ANY)
32static unsigned long mem[MAX_DEVICES];
33static void *mapped_io[MAX_DEVICES];
34module_param_array(mem, ulong, NULL, 0400);
35MODULE_PARM_DESC(mem, "I/O memory addresses of the serial devices");
36#endif /* CONFIG_XENO_DRIVERS_16550A_MMIO || CONFIG_XENO_DRIVERS_16550A_ANY */
37
38#ifdef CONFIG_XENO_DRIVERS_16550A_PIO
39
40#define RT_16550_IO_INLINE inline
41
42extern void *mapped_io[]; /* dummy */
43
44static inline unsigned long rt_16550_addr_param(int dev_id)
45{
46 return io[dev_id];
47}
48
49static inline int rt_16550_addr_param_valid(int dev_id)
50{
51 return 1;
52}
53
54static inline unsigned long rt_16550_base_addr(int dev_id)
55{
56 return io[dev_id];
57}
58
59static inline io_mode_t rt_16550_io_mode(int dev_id)
60{
61 return MODE_PIO;
62}
63
64static inline io_mode_t
65rt_16550_io_mode_from_ctx(struct rt_16550_context *ctx)
66{
67 return MODE_PIO;
68}
69
70static inline void
71rt_16550_init_io_ctx(int dev_id, struct rt_16550_context *ctx)
72{
73 ctx->base_addr = io[dev_id];
74}
75
76#elif defined(CONFIG_XENO_DRIVERS_16550A_MMIO)
77
78#define RT_16550_IO_INLINE inline
79
80extern unsigned long io[]; /* dummy */
81
82static inline unsigned long rt_16550_addr_param(int dev_id)
83{
84 return mem[dev_id];
85}
86
87static inline int rt_16550_addr_param_valid(int dev_id)
88{
89 return 1;
90}
91
92static inline unsigned long rt_16550_base_addr(int dev_id)
93{
94 return (unsigned long)mapped_io[dev_id];
95}
96
97static inline io_mode_t rt_16550_io_mode(int dev_id)
98{
99 return MODE_MMIO;
100}
101
102static inline io_mode_t
103rt_16550_io_mode_from_ctx(struct rt_16550_context *ctx)
104{
105 return MODE_MMIO;
106}
107
108static inline void
109rt_16550_init_io_ctx(int dev_id, struct rt_16550_context *ctx)
110{
111 ctx->base_addr = (unsigned long)mapped_io[dev_id];
112}
113
114#elif defined(CONFIG_XENO_DRIVERS_16550A_ANY)
115
116#define RT_16550_IO_INLINE /* uninline */
117
118static inline unsigned long rt_16550_addr_param(int dev_id)
119{
120 return (io[dev_id]) ? io[dev_id] : mem[dev_id];
121}
122
123static inline int rt_16550_addr_param_valid(int dev_id)
124{
125 return !(io[dev_id] && mem[dev_id]);
126}
127
128static inline unsigned long rt_16550_base_addr(int dev_id)
129{
130 return (io[dev_id]) ? io[dev_id] : (unsigned long)mapped_io[dev_id];
131}
132
133static inline io_mode_t rt_16550_io_mode(int dev_id)
134{
135 return (io[dev_id]) ? MODE_PIO : MODE_MMIO;
136}
137
138static inline io_mode_t
139rt_16550_io_mode_from_ctx(struct rt_16550_context *ctx)
140{
141 return ctx->io_mode;
142}
143
144static inline void
145rt_16550_init_io_ctx(int dev_id, struct rt_16550_context *ctx)
146{
147 if (io[dev_id]) {
148 ctx->base_addr = io[dev_id];
149 ctx->io_mode = MODE_PIO;
150 } else {
151 ctx->base_addr = (unsigned long)mapped_io[dev_id];
152 ctx->io_mode = MODE_MMIO;
153 }
154}
155
156#else
157# error Unsupported I/O access method
158#endif
159
160static RT_16550_IO_INLINE u8
161rt_16550_reg_in(io_mode_t io_mode, unsigned long base, int off)
162{
163 switch (io_mode) {
164 case MODE_PIO:
165 return inb(base + off);
166 default: /* MODE_MMIO */
167 return readb((void *)base + off);
168 }
169}
170
171static RT_16550_IO_INLINE void
172rt_16550_reg_out(io_mode_t io_mode, unsigned long base, int off, u8 val)
173{
174 switch (io_mode) {
175 case MODE_PIO:
176 outb(val, base + off);
177 break;
178 case MODE_MMIO:
179 writeb(val, (void *)base + off);
180 break;
181 }
182}
183
184static int rt_16550_init_io(int dev_id, char* name)
185{
186 switch (rt_16550_io_mode(dev_id)) {
187 case MODE_PIO:
188 if (!request_region(rt_16550_addr_param(dev_id), 8, name))
189 return -EBUSY;
190 break;
191 case MODE_MMIO:
192 mapped_io[dev_id] = ioremap(rt_16550_addr_param(dev_id), 8);
193 if (!mapped_io[dev_id])
194 return -EBUSY;
195 break;
196 }
197 return 0;
198}
199
200static void rt_16550_release_io(int dev_id)
201{
202 switch (rt_16550_io_mode(dev_id)) {
203 case MODE_PIO:
204 release_region(io[dev_id], 8);
205 break;
206 case MODE_MMIO:
207 iounmap(mapped_io[dev_id]);
208 break;
209 }
210}