Xenomai  3.0.5
16550A_pci.h
1 /*
2  * Copyright (C) 2006-2007 Jan Kiszka <jan.kiszka@web.de>.
3  * Copyright (C) 2011 Stefan Kisdaroczi <kisda@hispeed.ch>.
4  *
5  * Xenomai is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Xenomai is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Xenomai; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19 
20 #if defined(CONFIG_XENO_DRIVERS_16550A_PCI)
21 
22 #include <linux/pci.h>
23 
24 struct rt_16550_pci_board {
25  char *name;
26  resource_size_t resource_base_addr;
27  unsigned int nports;
28  unsigned int port_ofs;
29  unsigned long irqtype;
30  unsigned int baud_base;
31  int tx_fifo;
32 };
33 
34 #if defined(CONFIG_XENO_DRIVERS_16550A_PCI_MOXA)
35 
36 #define PCI_DEVICE_ID_CP112UL 0x1120
37 #define PCI_DEVICE_ID_CP114UL 0x1143
38 #define PCI_DEVICE_ID_CP138U 0x1380
39 
40 static const struct rt_16550_pci_board rt_16550_moxa_c104 = {
41  .name = "Moxa C104H/PCI",
42  .resource_base_addr = 2,
43  .nports = 4,
44  .port_ofs = 8,
45  .baud_base = 921600,
46  .tx_fifo = 16,
47  .irqtype = RTDM_IRQTYPE_SHARED,
48 };
49 
50 static const struct rt_16550_pci_board rt_16550_moxa_c168 = {
51  .name = "Moxa C168H/PCI",
52  .resource_base_addr = 2,
53  .nports = 8,
54  .port_ofs = 8,
55  .baud_base = 921600,
56  .tx_fifo = 16,
57  .irqtype = RTDM_IRQTYPE_SHARED,
58 };
59 
60 static const struct rt_16550_pci_board rt_16550_moxa_cp114 = {
61  .name = "Moxa CP-114",
62  .resource_base_addr = 2,
63  .nports = 4,
64  .port_ofs = 8,
65  .baud_base = 921600,
66  .tx_fifo = 16,
67  .irqtype = RTDM_IRQTYPE_SHARED,
68 };
69 
70 static const struct rt_16550_pci_board rt_16550_moxa_cp132 = {
71  .name = "Moxa CP-132",
72  .resource_base_addr = 2,
73  .nports = 2,
74  .port_ofs = 8,
75  .baud_base = 921600,
76  .tx_fifo = 16,
77  .irqtype = RTDM_IRQTYPE_SHARED,
78 };
79 
80 static const struct rt_16550_pci_board rt_16550_moxa_cp102u = {
81  .name = "Moxa CP-102U",
82  .resource_base_addr = 2,
83  .nports = 2,
84  .port_ofs = 8,
85  .baud_base = 921600,
86  .tx_fifo = 16,
87  .irqtype = RTDM_IRQTYPE_SHARED,
88 };
89 
90 static const struct rt_16550_pci_board rt_16550_moxa_cp102ul = {
91  .name = "Moxa CP-102UL",
92  .resource_base_addr = 2,
93  .nports = 2,
94  .port_ofs = 8,
95  .baud_base = 921600,
96  .tx_fifo = 16,
97  .irqtype = RTDM_IRQTYPE_SHARED,
98 };
99 
100 static const struct rt_16550_pci_board rt_16550_moxa_cp104u = {
101  .name = "Moxa CP-104U",
102  .resource_base_addr = 2,
103  .nports = 4,
104  .port_ofs = 8,
105  .baud_base = 921600,
106  .tx_fifo = 16,
107  .irqtype = RTDM_IRQTYPE_SHARED,
108 };
109 
110 static const struct rt_16550_pci_board rt_16550_moxa_cp112ul = {
111  .name = "Moxa CP-112UL",
112  .resource_base_addr = 2,
113  .nports = 2,
114  .port_ofs = 8,
115  .baud_base = 921600,
116  .tx_fifo = 16,
117  .irqtype = RTDM_IRQTYPE_SHARED,
118 };
119 
120 static const struct rt_16550_pci_board rt_16550_moxa_cp114ul = {
121  .name = "Moxa CP-114UL",
122  .resource_base_addr = 2,
123  .nports = 4,
124  .port_ofs = 8,
125  .baud_base = 921600,
126  .tx_fifo = 16,
127  .irqtype = RTDM_IRQTYPE_SHARED,
128 };
129 
130 static const struct rt_16550_pci_board rt_16550_moxa_cp118u = {
131  .name = "Moxa CP-118U",
132  .resource_base_addr = 2,
133  .nports = 8,
134  .port_ofs = 8,
135  .baud_base = 921600,
136  .tx_fifo = 16,
137  .irqtype = RTDM_IRQTYPE_SHARED,
138 };
139 
140 static const struct rt_16550_pci_board rt_16550_moxa_cp132u = {
141  .name = "Moxa CP-132U",
142  .resource_base_addr = 2,
143  .nports = 2,
144  .port_ofs = 8,
145  .baud_base = 921600,
146  .tx_fifo = 16,
147  .irqtype = RTDM_IRQTYPE_SHARED,
148 };
149 
150 static const struct rt_16550_pci_board rt_16550_moxa_cp134u = {
151  .name = "Moxa CP-134U",
152  .resource_base_addr = 2,
153  .nports = 4,
154  .port_ofs = 8,
155  .baud_base = 921600,
156  .tx_fifo = 16,
157  .irqtype = RTDM_IRQTYPE_SHARED,
158 };
159 
160 static const struct rt_16550_pci_board rt_16550_moxa_cp138u = {
161  .name = "Moxa CP-138U",
162  .resource_base_addr = 2,
163  .nports = 8,
164  .port_ofs = 8,
165  .baud_base = 921600,
166  .tx_fifo = 16,
167  .irqtype = RTDM_IRQTYPE_SHARED,
168 };
169 
170 static const struct rt_16550_pci_board rt_16550_moxa_cp168u = {
171  .name = "Moxa CP-168U",
172  .resource_base_addr = 2,
173  .nports = 8,
174  .port_ofs = 8,
175  .baud_base = 921600,
176  .tx_fifo = 16,
177  .irqtype = RTDM_IRQTYPE_SHARED,
178 };
179 #endif
180 
181 const struct pci_device_id rt_16550_pci_table[] = {
182 #if defined(CONFIG_XENO_DRIVERS_16550A_PCI_MOXA)
183  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104),
184  .driver_data = (unsigned long)&rt_16550_moxa_c104},
185  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168),
186  .driver_data = (unsigned long)&rt_16550_moxa_c168},
187  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114),
188  .driver_data = (unsigned long)&rt_16550_moxa_cp114},
189  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132),
190  .driver_data = (unsigned long)&rt_16550_moxa_cp132},
191  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U),
192  .driver_data = (unsigned long)&rt_16550_moxa_cp102u},
193  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),
194  .driver_data = (unsigned long)&rt_16550_moxa_cp102ul},
195  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U),
196  .driver_data = (unsigned long)&rt_16550_moxa_cp104u},
197  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL),
198  .driver_data = (unsigned long)&rt_16550_moxa_cp112ul},
199  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL),
200  .driver_data = (unsigned long)&rt_16550_moxa_cp114ul},
201  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U),
202  .driver_data = (unsigned long)&rt_16550_moxa_cp118u},
203  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U),
204  .driver_data = (unsigned long)&rt_16550_moxa_cp132u},
205  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U),
206  .driver_data = (unsigned long)&rt_16550_moxa_cp134u},
207  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U),
208  .driver_data = (unsigned long)&rt_16550_moxa_cp138u},
209  {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U),
210  .driver_data = (unsigned long)&rt_16550_moxa_cp168u},
211 #endif
212  { }
213 };
214 
215 static int rt_16550_pci_probe(struct pci_dev *pdev,
216  const struct pci_device_id *ent)
217 {
218  struct rt_16550_pci_board *board;
219  int err;
220  int i;
221  int port = 0;
222  int base_addr;
223  int max_devices = 0;
224 
225  if (!ent->driver_data)
226  return -ENODEV;
227 
228  board = (struct rt_16550_pci_board *)ent->driver_data;
229 
230  for (i = 0; i < MAX_DEVICES; i++)
231  if (!rt_16550_addr_param(i))
232  max_devices++;
233 
234  if (board->nports > max_devices)
235  return -ENODEV;
236 
237  if ((err = pci_enable_device(pdev)))
238  return err;
239 
240  base_addr = pci_resource_start(pdev, board->resource_base_addr);
241 
242  for (i = 0; i < MAX_DEVICES; i++) {
243  if ((port < board->nports) && (!rt_16550_addr_param(i))) {
244  io[i] = base_addr + port * board->port_ofs;
245  irq[i] = pdev->irq;
246  irqtype[i] = board->irqtype;
247  baud_base[i] = board->baud_base;
248  tx_fifo[i] = board->tx_fifo;
249  port++;
250  }
251  }
252 
253  return 0;
254 }
255 
256 static void rt_16550_pci_remove(struct pci_dev *pdev) {
257  pci_disable_device( pdev );
258 };
259 
260 static struct pci_driver rt_16550_pci_driver = {
261  .name = RT_16550_DRIVER_NAME,
262  .id_table = rt_16550_pci_table,
263  .probe = rt_16550_pci_probe,
264  .remove = rt_16550_pci_remove
265 };
266 
267 static int pci_registered;
268 
269 static inline void rt_16550_pci_init(void)
270 {
271  if (pci_register_driver(&rt_16550_pci_driver) == 0)
272  pci_registered = 1;
273 }
274 
275 static inline void rt_16550_pci_cleanup(void)
276 {
277  if (pci_registered)
278  pci_unregister_driver(&rt_16550_pci_driver);
279 }
280 
281 #else /* Linux < 2.6.0 || !CONFIG_PCI || !(..._16550A_PCI */
282 
283 #define rt_16550_pci_init() do { } while (0)
284 #define rt_16550_pci_cleanup() do { } while (0)
285 
286 #endif /* Linux < 2.6.0 || !CONFIG_PCI || !(..._16550A_PCI */
#define RTDM_IRQTYPE_SHARED
Enable IRQ-sharing with other real-time drivers.
Definition: driver.h:811