diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-29 13:34:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-29 13:34:59 -0400 |
commit | 975f957dc408925805dd8f5aa4217b7eeea2d005 (patch) | |
tree | 2198bb72323a016d93c7440c9240bac94a5c0016 /drivers | |
parent | 2321fbd2b87539edc1fbfc2e186528a1ef93835f (diff) | |
parent | 661299d9d0437a0ff72240f3d60016ac3a361a6e (diff) |
Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-serial.git
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/parport/parport_serial.c | 339 | ||||
-rw-r--r-- | drivers/serial/8250_pci.c | 474 |
2 files changed, 343 insertions, 470 deletions
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 00498e2f1205..d3dad0aac7cb 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -23,13 +23,8 @@ | |||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/parport.h> | 24 | #include <linux/parport.h> |
25 | #include <linux/parport_pc.h> | 25 | #include <linux/parport_pc.h> |
26 | #include <linux/serial.h> | ||
27 | #include <linux/serialP.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/8250_pci.h> | 26 | #include <linux/8250_pci.h> |
30 | 27 | ||
31 | #include <asm/serial.h> | ||
32 | |||
33 | enum parport_pc_pci_cards { | 28 | enum parport_pc_pci_cards { |
34 | titan_110l = 0, | 29 | titan_110l = 0, |
35 | titan_210l, | 30 | titan_210l, |
@@ -168,182 +163,147 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
168 | }; | 163 | }; |
169 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); | 164 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); |
170 | 165 | ||
171 | struct pci_board_no_ids { | 166 | /* |
172 | int flags; | 167 | * This table describes the serial "geometry" of these boards. Any |
173 | int num_ports; | 168 | * quirks for these can be found in drivers/serial/8250_pci.c |
174 | int base_baud; | 169 | * |
175 | int uart_offset; | 170 | * Cards not tested are marked n/t |
176 | int reg_shift; | 171 | * If you have one of these cards and it works for you, please tell me.. |
177 | int (*init_fn)(struct pci_dev *dev, struct pci_board_no_ids *board, | 172 | */ |
178 | int enable); | 173 | static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { |
179 | int first_uart_offset; | 174 | [titan_110l] = { |
180 | }; | 175 | .flags = FL_BASE1 | FL_BASE_BARS, |
181 | 176 | .num_ports = 1, | |
182 | static int __devinit siig10x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable) | 177 | .base_baud = 921600, |
183 | { | 178 | .uart_offset = 8, |
184 | return pci_siig10x_fn(dev, enable); | 179 | }, |
185 | } | 180 | [titan_210l] = { |
186 | 181 | .flags = FL_BASE1 | FL_BASE_BARS, | |
187 | static int __devinit siig20x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable) | 182 | .num_ports = 2, |
188 | { | 183 | .base_baud = 921600, |
189 | return pci_siig20x_fn(dev, enable); | 184 | .uart_offset = 8, |
190 | } | 185 | }, |
191 | 186 | [netmos_9xx5_combo] = { | |
192 | static int __devinit netmos_serial_init(struct pci_dev *dev, struct pci_board_no_ids *board, int enable) | 187 | .flags = FL_BASE0 | FL_BASE_BARS, |
193 | { | 188 | .num_ports = 1, |
194 | board->num_ports = dev->subsystem_device & 0xf; | 189 | .base_baud = 115200, |
195 | return 0; | 190 | .uart_offset = 8, |
196 | } | 191 | }, |
197 | 192 | [netmos_9855] = { | |
198 | static struct pci_board_no_ids pci_boards[] __devinitdata = { | 193 | .flags = FL_BASE2 | FL_BASE_BARS, |
199 | /* | 194 | .num_ports = 1, |
200 | * PCI Flags, Number of Ports, Base (Maximum) Baud Rate, | 195 | .base_baud = 115200, |
201 | * Offset to get to next UART's registers, | 196 | .uart_offset = 8, |
202 | * Register shift to use for memory-mapped I/O, | 197 | }, |
203 | * Initialization function, first UART offset | 198 | [avlab_1s1p] = { /* n/t */ |
204 | */ | 199 | .flags = FL_BASE0 | FL_BASE_BARS, |
205 | 200 | .num_ports = 1, | |
206 | // Cards not tested are marked n/t | 201 | .base_baud = 115200, |
207 | // If you have one of these cards and it works for you, please tell me.. | 202 | .uart_offset = 8, |
208 | 203 | }, | |
209 | /* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, | 204 | [avlab_1s1p_650] = { /* nt */ |
210 | /* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, | 205 | .flags = FL_BASE0 | FL_BASE_BARS, |
211 | /* netmos_9xx5_combo */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, | 206 | .num_ports = 1, |
212 | /* netmos_9855 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, | 207 | .base_baud = 115200, |
213 | /* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 208 | .uart_offset = 8, |
214 | /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 209 | }, |
215 | /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 210 | [avlab_1s1p_850] = { /* nt */ |
216 | /* avlab_1s2p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 211 | .flags = FL_BASE0 | FL_BASE_BARS, |
217 | /* avlab_1s2p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 212 | .num_ports = 1, |
218 | /* avlab_1s2p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, | 213 | .base_baud = 115200, |
219 | /* avlab_2s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, | 214 | .uart_offset = 8, |
220 | /* avlab_2s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, | 215 | }, |
221 | /* avlab_2s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, | 216 | [avlab_1s2p] = { /* n/t */ |
222 | /* siig_1s1p_10x */ { SPCI_FL_BASE2, 1, 460800, 0, 0, siig10x_init_fn }, | 217 | .flags = FL_BASE0 | FL_BASE_BARS, |
223 | /* siig_2s1p_10x */ { SPCI_FL_BASE2, 1, 921600, 0, 0, siig10x_init_fn }, | 218 | .num_ports = 1, |
224 | /* siig_2p1s_20x */ { SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn }, | 219 | .base_baud = 115200, |
225 | /* siig_1s1p_20x */ { SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn }, | 220 | .uart_offset = 8, |
226 | /* siig_2s1p_20x */ { SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn }, | 221 | }, |
222 | [avlab_1s2p_650] = { /* nt */ | ||
223 | .flags = FL_BASE0 | FL_BASE_BARS, | ||
224 | .num_ports = 1, | ||
225 | .base_baud = 115200, | ||
226 | .uart_offset = 8, | ||
227 | }, | ||
228 | [avlab_1s2p_850] = { /* nt */ | ||
229 | .flags = FL_BASE0 | FL_BASE_BARS, | ||
230 | .num_ports = 1, | ||
231 | .base_baud = 115200, | ||
232 | .uart_offset = 8, | ||
233 | }, | ||
234 | [avlab_2s1p] = { /* n/t */ | ||
235 | .flags = FL_BASE0 | FL_BASE_BARS, | ||
236 | .num_ports = 2, | ||
237 | .base_baud = 115200, | ||
238 | .uart_offset = 8, | ||
239 | }, | ||
240 | [avlab_2s1p_650] = { /* nt */ | ||
241 | .flags = FL_BASE0 | FL_BASE_BARS, | ||
242 | .num_ports = 2, | ||
243 | .base_baud = 115200, | ||
244 | .uart_offset = 8, | ||
245 | }, | ||
246 | [avlab_2s1p_850] = { /* nt */ | ||
247 | .flags = FL_BASE0 | FL_BASE_BARS, | ||
248 | .num_ports = 2, | ||
249 | .base_baud = 115200, | ||
250 | .uart_offset = 8, | ||
251 | }, | ||
252 | [siig_1s1p_10x] = { | ||
253 | .flags = FL_BASE2, | ||
254 | .num_ports = 1, | ||
255 | .base_baud = 460800, | ||
256 | .uart_offset = 8, | ||
257 | }, | ||
258 | [siig_2s1p_10x] = { | ||
259 | .flags = FL_BASE2, | ||
260 | .num_ports = 1, | ||
261 | .base_baud = 921600, | ||
262 | .uart_offset = 8, | ||
263 | }, | ||
264 | [siig_2p1s_20x] = { | ||
265 | .flags = FL_BASE0, | ||
266 | .num_ports = 1, | ||
267 | .base_baud = 921600, | ||
268 | .uart_offset = 8, | ||
269 | }, | ||
270 | [siig_1s1p_20x] = { | ||
271 | .flags = FL_BASE0, | ||
272 | .num_ports = 1, | ||
273 | .base_baud = 921600, | ||
274 | .uart_offset = 8, | ||
275 | }, | ||
276 | [siig_2s1p_20x] = { | ||
277 | .flags = FL_BASE0, | ||
278 | .num_ports = 1, | ||
279 | .base_baud = 921600, | ||
280 | .uart_offset = 8, | ||
281 | }, | ||
227 | }; | 282 | }; |
228 | 283 | ||
229 | struct parport_serial_private { | 284 | struct parport_serial_private { |
230 | int num_ser; | 285 | struct serial_private *serial; |
231 | int line[20]; | ||
232 | struct pci_board_no_ids ser; | ||
233 | int num_par; | 286 | int num_par; |
234 | struct parport *port[PARPORT_MAX]; | 287 | struct parport *port[PARPORT_MAX]; |
235 | struct parport_pc_pci par; | 288 | struct parport_pc_pci par; |
236 | }; | 289 | }; |
237 | 290 | ||
238 | static int __devinit get_pci_port (struct pci_dev *dev, | ||
239 | struct pci_board_no_ids *board, | ||
240 | struct serial_struct *req, | ||
241 | int idx) | ||
242 | { | ||
243 | unsigned long port; | ||
244 | int base_idx; | ||
245 | int max_port; | ||
246 | int offset; | ||
247 | |||
248 | base_idx = SPCI_FL_GET_BASE(board->flags); | ||
249 | if (board->flags & SPCI_FL_BASE_TABLE) | ||
250 | base_idx += idx; | ||
251 | |||
252 | if (board->flags & SPCI_FL_REGION_SZ_CAP) { | ||
253 | max_port = pci_resource_len(dev, base_idx) / 8; | ||
254 | if (idx >= max_port) | ||
255 | return 1; | ||
256 | } | ||
257 | |||
258 | offset = board->first_uart_offset; | ||
259 | |||
260 | /* Timedia/SUNIX uses a mixture of BARs and offsets */ | ||
261 | /* Ugh, this is ugly as all hell --- TYT */ | ||
262 | if(dev->vendor == PCI_VENDOR_ID_TIMEDIA ) /* 0x1409 */ | ||
263 | switch(idx) { | ||
264 | case 0: base_idx=0; | ||
265 | break; | ||
266 | case 1: base_idx=0; offset=8; | ||
267 | break; | ||
268 | case 2: base_idx=1; | ||
269 | break; | ||
270 | case 3: base_idx=1; offset=8; | ||
271 | break; | ||
272 | case 4: /* BAR 2*/ | ||
273 | case 5: /* BAR 3 */ | ||
274 | case 6: /* BAR 4*/ | ||
275 | case 7: base_idx=idx-2; /* BAR 5*/ | ||
276 | } | ||
277 | |||
278 | port = pci_resource_start(dev, base_idx) + offset; | ||
279 | |||
280 | if ((board->flags & SPCI_FL_BASE_TABLE) == 0) | ||
281 | port += idx * (board->uart_offset ? board->uart_offset : 8); | ||
282 | |||
283 | if (pci_resource_flags (dev, base_idx) & IORESOURCE_IO) { | ||
284 | int high_bits_offset = ((sizeof(long)-sizeof(int))*8); | ||
285 | req->port = port; | ||
286 | if (high_bits_offset) | ||
287 | req->port_high = port >> high_bits_offset; | ||
288 | else | ||
289 | req->port_high = 0; | ||
290 | return 0; | ||
291 | } | ||
292 | req->io_type = SERIAL_IO_MEM; | ||
293 | req->iomem_base = ioremap(port, board->uart_offset); | ||
294 | req->iomem_reg_shift = board->reg_shift; | ||
295 | req->port = 0; | ||
296 | return req->iomem_base ? 0 : 1; | ||
297 | } | ||
298 | |||
299 | /* Register the serial port(s) of a PCI card. */ | 291 | /* Register the serial port(s) of a PCI card. */ |
300 | static int __devinit serial_register (struct pci_dev *dev, | 292 | static int __devinit serial_register (struct pci_dev *dev, |
301 | const struct pci_device_id *id) | 293 | const struct pci_device_id *id) |
302 | { | 294 | { |
303 | struct pci_board_no_ids *board; | ||
304 | struct parport_serial_private *priv = pci_get_drvdata (dev); | 295 | struct parport_serial_private *priv = pci_get_drvdata (dev); |
305 | struct serial_struct serial_req; | 296 | struct pciserial_board *board; |
306 | int base_baud; | 297 | struct serial_private *serial; |
307 | int k; | ||
308 | int success = 0; | ||
309 | |||
310 | priv->ser = pci_boards[id->driver_data]; | ||
311 | board = &priv->ser; | ||
312 | if (board->init_fn && ((board->init_fn) (dev, board, 1) != 0)) | ||
313 | return 1; | ||
314 | |||
315 | base_baud = board->base_baud; | ||
316 | if (!base_baud) | ||
317 | base_baud = BASE_BAUD; | ||
318 | memset (&serial_req, 0, sizeof (serial_req)); | ||
319 | |||
320 | for (k = 0; k < board->num_ports; k++) { | ||
321 | int line; | ||
322 | 298 | ||
323 | if (priv->num_ser == ARRAY_SIZE (priv->line)) { | 299 | board = &pci_parport_serial_boards[id->driver_data]; |
324 | printk (KERN_WARNING | 300 | serial = pciserial_init_ports(dev, board); |
325 | "parport_serial: %s: only %u serial lines " | ||
326 | "supported (%d reported)\n", pci_name (dev), | ||
327 | ARRAY_SIZE (priv->line), board->num_ports); | ||
328 | break; | ||
329 | } | ||
330 | 301 | ||
331 | serial_req.irq = dev->irq; | 302 | if (IS_ERR(serial)) |
332 | if (get_pci_port (dev, board, &serial_req, k)) | 303 | return PTR_ERR(serial); |
333 | break; | ||
334 | serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE; | ||
335 | serial_req.baud_base = base_baud; | ||
336 | line = register_serial (&serial_req); | ||
337 | if (line < 0) { | ||
338 | printk (KERN_DEBUG | ||
339 | "parport_serial: register_serial failed\n"); | ||
340 | continue; | ||
341 | } | ||
342 | priv->line[priv->num_ser++] = line; | ||
343 | success = 1; | ||
344 | } | ||
345 | 304 | ||
346 | return success ? 0 : 1; | 305 | priv->serial = serial; |
306 | return 0; | ||
347 | } | 307 | } |
348 | 308 | ||
349 | /* Register the parallel port(s) of a PCI card. */ | 309 | /* Register the parallel port(s) of a PCI card. */ |
@@ -411,7 +371,7 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev, | |||
411 | priv = kmalloc (sizeof *priv, GFP_KERNEL); | 371 | priv = kmalloc (sizeof *priv, GFP_KERNEL); |
412 | if (!priv) | 372 | if (!priv) |
413 | return -ENOMEM; | 373 | return -ENOMEM; |
414 | priv->num_ser = priv->num_par = 0; | 374 | memset(priv, 0, sizeof(struct parport_serial_private)); |
415 | pci_set_drvdata (dev, priv); | 375 | pci_set_drvdata (dev, priv); |
416 | 376 | ||
417 | err = pci_enable_device (dev); | 377 | err = pci_enable_device (dev); |
@@ -444,15 +404,12 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev) | |||
444 | struct parport_serial_private *priv = pci_get_drvdata (dev); | 404 | struct parport_serial_private *priv = pci_get_drvdata (dev); |
445 | int i; | 405 | int i; |
446 | 406 | ||
407 | pci_set_drvdata(dev, NULL); | ||
408 | |||
447 | // Serial ports | 409 | // Serial ports |
448 | for (i = 0; i < priv->num_ser; i++) { | 410 | if (priv->serial) |
449 | unregister_serial (priv->line[i]); | 411 | pciserial_remove_ports(priv->serial); |
450 | 412 | ||
451 | if (priv->ser.init_fn) | ||
452 | (priv->ser.init_fn) (dev, &priv->ser, 0); | ||
453 | } | ||
454 | pci_set_drvdata (dev, NULL); | ||
455 | |||
456 | // Parallel ports | 413 | // Parallel ports |
457 | for (i = 0; i < priv->num_par; i++) | 414 | for (i = 0; i < priv->num_par; i++) |
458 | parport_pc_unregister_port (priv->port[i]); | 415 | parport_pc_unregister_port (priv->port[i]); |
@@ -461,11 +418,47 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev) | |||
461 | return; | 418 | return; |
462 | } | 419 | } |
463 | 420 | ||
421 | static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state) | ||
422 | { | ||
423 | struct parport_serial_private *priv = pci_get_drvdata(dev); | ||
424 | |||
425 | if (priv->serial) | ||
426 | pciserial_suspend_ports(priv->serial); | ||
427 | |||
428 | /* FIXME: What about parport? */ | ||
429 | |||
430 | pci_save_state(dev); | ||
431 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int parport_serial_pci_resume(struct pci_dev *dev) | ||
436 | { | ||
437 | struct parport_serial_private *priv = pci_get_drvdata(dev); | ||
438 | |||
439 | pci_set_power_state(dev, PCI_D0); | ||
440 | pci_restore_state(dev); | ||
441 | |||
442 | /* | ||
443 | * The device may have been disabled. Re-enable it. | ||
444 | */ | ||
445 | pci_enable_device(dev); | ||
446 | |||
447 | if (priv->serial) | ||
448 | pciserial_resume_ports(priv->serial); | ||
449 | |||
450 | /* FIXME: What about parport? */ | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
464 | static struct pci_driver parport_serial_pci_driver = { | 455 | static struct pci_driver parport_serial_pci_driver = { |
465 | .name = "parport_serial", | 456 | .name = "parport_serial", |
466 | .id_table = parport_serial_pci_tbl, | 457 | .id_table = parport_serial_pci_tbl, |
467 | .probe = parport_serial_pci_probe, | 458 | .probe = parport_serial_pci_probe, |
468 | .remove = __devexit_p(parport_serial_pci_remove), | 459 | .remove = __devexit_p(parport_serial_pci_remove), |
460 | .suspend = parport_serial_pci_suspend, | ||
461 | .resume = parport_serial_pci_resume, | ||
469 | }; | 462 | }; |
470 | 463 | ||
471 | 464 | ||
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 07f05e9d0955..0e21f583690e 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -34,36 +34,6 @@ | |||
34 | #undef SERIAL_DEBUG_PCI | 34 | #undef SERIAL_DEBUG_PCI |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * Definitions for PCI support. | ||
38 | */ | ||
39 | #define FL_BASE_MASK 0x0007 | ||
40 | #define FL_BASE0 0x0000 | ||
41 | #define FL_BASE1 0x0001 | ||
42 | #define FL_BASE2 0x0002 | ||
43 | #define FL_BASE3 0x0003 | ||
44 | #define FL_BASE4 0x0004 | ||
45 | #define FL_GET_BASE(x) (x & FL_BASE_MASK) | ||
46 | |||
47 | /* Use successive BARs (PCI base address registers), | ||
48 | else use offset into some specified BAR */ | ||
49 | #define FL_BASE_BARS 0x0008 | ||
50 | |||
51 | /* do not assign an irq */ | ||
52 | #define FL_NOIRQ 0x0080 | ||
53 | |||
54 | /* Use the Base address register size to cap number of ports */ | ||
55 | #define FL_REGION_SZ_CAP 0x0100 | ||
56 | |||
57 | struct pci_board { | ||
58 | unsigned int flags; | ||
59 | unsigned int num_ports; | ||
60 | unsigned int base_baud; | ||
61 | unsigned int uart_offset; | ||
62 | unsigned int reg_shift; | ||
63 | unsigned int first_offset; | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * init function returns: | 37 | * init function returns: |
68 | * > 0 - number of ports | 38 | * > 0 - number of ports |
69 | * = 0 - use board->num_ports | 39 | * = 0 - use board->num_ports |
@@ -75,14 +45,15 @@ struct pci_serial_quirk { | |||
75 | u32 subvendor; | 45 | u32 subvendor; |
76 | u32 subdevice; | 46 | u32 subdevice; |
77 | int (*init)(struct pci_dev *dev); | 47 | int (*init)(struct pci_dev *dev); |
78 | int (*setup)(struct pci_dev *dev, struct pci_board *board, | 48 | int (*setup)(struct serial_private *, struct pciserial_board *, |
79 | struct uart_port *port, int idx); | 49 | struct uart_port *, int); |
80 | void (*exit)(struct pci_dev *dev); | 50 | void (*exit)(struct pci_dev *dev); |
81 | }; | 51 | }; |
82 | 52 | ||
83 | #define PCI_NUM_BAR_RESOURCES 6 | 53 | #define PCI_NUM_BAR_RESOURCES 6 |
84 | 54 | ||
85 | struct serial_private { | 55 | struct serial_private { |
56 | struct pci_dev *dev; | ||
86 | unsigned int nr; | 57 | unsigned int nr; |
87 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; | 58 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; |
88 | struct pci_serial_quirk *quirk; | 59 | struct pci_serial_quirk *quirk; |
@@ -101,17 +72,18 @@ static void moan_device(const char *str, struct pci_dev *dev) | |||
101 | } | 72 | } |
102 | 73 | ||
103 | static int | 74 | static int |
104 | setup_port(struct pci_dev *dev, struct uart_port *port, | 75 | setup_port(struct serial_private *priv, struct uart_port *port, |
105 | int bar, int offset, int regshift) | 76 | int bar, int offset, int regshift) |
106 | { | 77 | { |
107 | struct serial_private *priv = pci_get_drvdata(dev); | 78 | struct pci_dev *dev = priv->dev; |
108 | unsigned long base, len; | 79 | unsigned long base, len; |
109 | 80 | ||
110 | if (bar >= PCI_NUM_BAR_RESOURCES) | 81 | if (bar >= PCI_NUM_BAR_RESOURCES) |
111 | return -EINVAL; | 82 | return -EINVAL; |
112 | 83 | ||
84 | base = pci_resource_start(dev, bar); | ||
85 | |||
113 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { | 86 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { |
114 | base = pci_resource_start(dev, bar); | ||
115 | len = pci_resource_len(dev, bar); | 87 | len = pci_resource_len(dev, bar); |
116 | 88 | ||
117 | if (!priv->remapped_bar[bar]) | 89 | if (!priv->remapped_bar[bar]) |
@@ -120,13 +92,16 @@ setup_port(struct pci_dev *dev, struct uart_port *port, | |||
120 | return -ENOMEM; | 92 | return -ENOMEM; |
121 | 93 | ||
122 | port->iotype = UPIO_MEM; | 94 | port->iotype = UPIO_MEM; |
95 | port->iobase = 0; | ||
123 | port->mapbase = base + offset; | 96 | port->mapbase = base + offset; |
124 | port->membase = priv->remapped_bar[bar] + offset; | 97 | port->membase = priv->remapped_bar[bar] + offset; |
125 | port->regshift = regshift; | 98 | port->regshift = regshift; |
126 | } else { | 99 | } else { |
127 | base = pci_resource_start(dev, bar) + offset; | ||
128 | port->iotype = UPIO_PORT; | 100 | port->iotype = UPIO_PORT; |
129 | port->iobase = base; | 101 | port->iobase = base + offset; |
102 | port->mapbase = 0; | ||
103 | port->membase = NULL; | ||
104 | port->regshift = 0; | ||
130 | } | 105 | } |
131 | return 0; | 106 | return 0; |
132 | } | 107 | } |
@@ -136,7 +111,7 @@ setup_port(struct pci_dev *dev, struct uart_port *port, | |||
136 | * Not that ugly ;) -- HW | 111 | * Not that ugly ;) -- HW |
137 | */ | 112 | */ |
138 | static int | 113 | static int |
139 | afavlab_setup(struct pci_dev *dev, struct pci_board *board, | 114 | afavlab_setup(struct serial_private *priv, struct pciserial_board *board, |
140 | struct uart_port *port, int idx) | 115 | struct uart_port *port, int idx) |
141 | { | 116 | { |
142 | unsigned int bar, offset = board->first_offset; | 117 | unsigned int bar, offset = board->first_offset; |
@@ -149,7 +124,7 @@ afavlab_setup(struct pci_dev *dev, struct pci_board *board, | |||
149 | offset += (idx - 4) * board->uart_offset; | 124 | offset += (idx - 4) * board->uart_offset; |
150 | } | 125 | } |
151 | 126 | ||
152 | return setup_port(dev, port, bar, offset, board->reg_shift); | 127 | return setup_port(priv, port, bar, offset, board->reg_shift); |
153 | } | 128 | } |
154 | 129 | ||
155 | /* | 130 | /* |
@@ -189,13 +164,13 @@ static int __devinit pci_hp_diva_init(struct pci_dev *dev) | |||
189 | * some serial ports are supposed to be hidden on certain models. | 164 | * some serial ports are supposed to be hidden on certain models. |
190 | */ | 165 | */ |
191 | static int | 166 | static int |
192 | pci_hp_diva_setup(struct pci_dev *dev, struct pci_board *board, | 167 | pci_hp_diva_setup(struct serial_private *priv, struct pciserial_board *board, |
193 | struct uart_port *port, int idx) | 168 | struct uart_port *port, int idx) |
194 | { | 169 | { |
195 | unsigned int offset = board->first_offset; | 170 | unsigned int offset = board->first_offset; |
196 | unsigned int bar = FL_GET_BASE(board->flags); | 171 | unsigned int bar = FL_GET_BASE(board->flags); |
197 | 172 | ||
198 | switch (dev->subsystem_device) { | 173 | switch (priv->dev->subsystem_device) { |
199 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: | 174 | case PCI_DEVICE_ID_HP_DIVA_MAESTRO: |
200 | if (idx == 3) | 175 | if (idx == 3) |
201 | idx++; | 176 | idx++; |
@@ -212,7 +187,7 @@ pci_hp_diva_setup(struct pci_dev *dev, struct pci_board *board, | |||
212 | 187 | ||
213 | offset += idx * board->uart_offset; | 188 | offset += idx * board->uart_offset; |
214 | 189 | ||
215 | return setup_port(dev, port, bar, offset, board->reg_shift); | 190 | return setup_port(priv, port, bar, offset, board->reg_shift); |
216 | } | 191 | } |
217 | 192 | ||
218 | /* | 193 | /* |
@@ -307,7 +282,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev) | |||
307 | 282 | ||
308 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ | 283 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ |
309 | static int | 284 | static int |
310 | sbs_setup(struct pci_dev *dev, struct pci_board *board, | 285 | sbs_setup(struct serial_private *priv, struct pciserial_board *board, |
311 | struct uart_port *port, int idx) | 286 | struct uart_port *port, int idx) |
312 | { | 287 | { |
313 | unsigned int bar, offset = board->first_offset; | 288 | unsigned int bar, offset = board->first_offset; |
@@ -323,7 +298,7 @@ sbs_setup(struct pci_dev *dev, struct pci_board *board, | |||
323 | } else /* we have only 8 ports on PMC-OCTALPRO */ | 298 | } else /* we have only 8 ports on PMC-OCTALPRO */ |
324 | return 1; | 299 | return 1; |
325 | 300 | ||
326 | return setup_port(dev, port, bar, offset, board->reg_shift); | 301 | return setup_port(priv, port, bar, offset, board->reg_shift); |
327 | } | 302 | } |
328 | 303 | ||
329 | /* | 304 | /* |
@@ -389,6 +364,9 @@ static void __devexit sbs_exit(struct pci_dev *dev) | |||
389 | * - 10x cards have control registers in IO and/or memory space; | 364 | * - 10x cards have control registers in IO and/or memory space; |
390 | * - 20x cards have control registers in standard PCI configuration space. | 365 | * - 20x cards have control registers in standard PCI configuration space. |
391 | * | 366 | * |
367 | * Note: all 10x cards have PCI device ids 0x10.. | ||
368 | * all 20x cards have PCI device ids 0x20.. | ||
369 | * | ||
392 | * There are also Quartet Serial cards which use Oxford Semiconductor | 370 | * There are also Quartet Serial cards which use Oxford Semiconductor |
393 | * 16954 quad UART PCI chip clocked by 18.432 MHz quartz. | 371 | * 16954 quad UART PCI chip clocked by 18.432 MHz quartz. |
394 | * | 372 | * |
@@ -445,24 +423,18 @@ static int pci_siig20x_init(struct pci_dev *dev) | |||
445 | return 0; | 423 | return 0; |
446 | } | 424 | } |
447 | 425 | ||
448 | int pci_siig10x_fn(struct pci_dev *dev, int enable) | 426 | static int pci_siig_init(struct pci_dev *dev) |
449 | { | 427 | { |
450 | int ret = 0; | 428 | unsigned int type = dev->device & 0xff00; |
451 | if (enable) | ||
452 | ret = pci_siig10x_init(dev); | ||
453 | return ret; | ||
454 | } | ||
455 | 429 | ||
456 | int pci_siig20x_fn(struct pci_dev *dev, int enable) | 430 | if (type == 0x1000) |
457 | { | 431 | return pci_siig10x_init(dev); |
458 | int ret = 0; | 432 | else if (type == 0x2000) |
459 | if (enable) | 433 | return pci_siig20x_init(dev); |
460 | ret = pci_siig20x_init(dev); | ||
461 | return ret; | ||
462 | } | ||
463 | 434 | ||
464 | EXPORT_SYMBOL(pci_siig10x_fn); | 435 | moan_device("Unknown SIIG card", dev); |
465 | EXPORT_SYMBOL(pci_siig20x_fn); | 436 | return -ENODEV; |
437 | } | ||
466 | 438 | ||
467 | /* | 439 | /* |
468 | * Timedia has an explosion of boards, and to avoid the PCI table from | 440 | * Timedia has an explosion of boards, and to avoid the PCI table from |
@@ -523,7 +495,7 @@ static int __devinit pci_timedia_init(struct pci_dev *dev) | |||
523 | * Ugh, this is ugly as all hell --- TYT | 495 | * Ugh, this is ugly as all hell --- TYT |
524 | */ | 496 | */ |
525 | static int | 497 | static int |
526 | pci_timedia_setup(struct pci_dev *dev, struct pci_board *board, | 498 | pci_timedia_setup(struct serial_private *priv, struct pciserial_board *board, |
527 | struct uart_port *port, int idx) | 499 | struct uart_port *port, int idx) |
528 | { | 500 | { |
529 | unsigned int bar = 0, offset = board->first_offset; | 501 | unsigned int bar = 0, offset = board->first_offset; |
@@ -549,14 +521,15 @@ pci_timedia_setup(struct pci_dev *dev, struct pci_board *board, | |||
549 | bar = idx - 2; | 521 | bar = idx - 2; |
550 | } | 522 | } |
551 | 523 | ||
552 | return setup_port(dev, port, bar, offset, board->reg_shift); | 524 | return setup_port(priv, port, bar, offset, board->reg_shift); |
553 | } | 525 | } |
554 | 526 | ||
555 | /* | 527 | /* |
556 | * Some Titan cards are also a little weird | 528 | * Some Titan cards are also a little weird |
557 | */ | 529 | */ |
558 | static int | 530 | static int |
559 | titan_400l_800l_setup(struct pci_dev *dev, struct pci_board *board, | 531 | titan_400l_800l_setup(struct serial_private *priv, |
532 | struct pciserial_board *board, | ||
560 | struct uart_port *port, int idx) | 533 | struct uart_port *port, int idx) |
561 | { | 534 | { |
562 | unsigned int bar, offset = board->first_offset; | 535 | unsigned int bar, offset = board->first_offset; |
@@ -573,7 +546,7 @@ titan_400l_800l_setup(struct pci_dev *dev, struct pci_board *board, | |||
573 | offset = (idx - 2) * board->uart_offset; | 546 | offset = (idx - 2) * board->uart_offset; |
574 | } | 547 | } |
575 | 548 | ||
576 | return setup_port(dev, port, bar, offset, board->reg_shift); | 549 | return setup_port(priv, port, bar, offset, board->reg_shift); |
577 | } | 550 | } |
578 | 551 | ||
579 | static int __devinit pci_xircom_init(struct pci_dev *dev) | 552 | static int __devinit pci_xircom_init(struct pci_dev *dev) |
@@ -593,7 +566,7 @@ static int __devinit pci_netmos_init(struct pci_dev *dev) | |||
593 | } | 566 | } |
594 | 567 | ||
595 | static int | 568 | static int |
596 | pci_default_setup(struct pci_dev *dev, struct pci_board *board, | 569 | pci_default_setup(struct serial_private *priv, struct pciserial_board *board, |
597 | struct uart_port *port, int idx) | 570 | struct uart_port *port, int idx) |
598 | { | 571 | { |
599 | unsigned int bar, offset = board->first_offset, maxnr; | 572 | unsigned int bar, offset = board->first_offset, maxnr; |
@@ -604,13 +577,13 @@ pci_default_setup(struct pci_dev *dev, struct pci_board *board, | |||
604 | else | 577 | else |
605 | offset += idx * board->uart_offset; | 578 | offset += idx * board->uart_offset; |
606 | 579 | ||
607 | maxnr = (pci_resource_len(dev, bar) - board->first_offset) / | 580 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) / |
608 | (8 << board->reg_shift); | 581 | (8 << board->reg_shift); |
609 | 582 | ||
610 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | 583 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) |
611 | return 1; | 584 | return 1; |
612 | 585 | ||
613 | return setup_port(dev, port, bar, offset, board->reg_shift); | 586 | return setup_port(priv, port, bar, offset, board->reg_shift); |
614 | } | 587 | } |
615 | 588 | ||
616 | /* This should be in linux/pci_ids.h */ | 589 | /* This should be in linux/pci_ids.h */ |
@@ -754,152 +727,15 @@ static struct pci_serial_quirk pci_serial_quirks[] = { | |||
754 | .setup = sbs_setup, | 727 | .setup = sbs_setup, |
755 | .exit = __devexit_p(sbs_exit), | 728 | .exit = __devexit_p(sbs_exit), |
756 | }, | 729 | }, |
757 | |||
758 | /* | 730 | /* |
759 | * SIIG cards. | 731 | * SIIG cards. |
760 | * It is not clear whether these could be collapsed. | ||
761 | */ | 732 | */ |
762 | { | 733 | { |
763 | .vendor = PCI_VENDOR_ID_SIIG, | 734 | .vendor = PCI_VENDOR_ID_SIIG, |
764 | .device = PCI_DEVICE_ID_SIIG_1S_10x_550, | 735 | .device = PCI_ANY_ID, |
765 | .subvendor = PCI_ANY_ID, | ||
766 | .subdevice = PCI_ANY_ID, | ||
767 | .init = pci_siig10x_init, | ||
768 | .setup = pci_default_setup, | ||
769 | }, | ||
770 | { | ||
771 | .vendor = PCI_VENDOR_ID_SIIG, | ||
772 | .device = PCI_DEVICE_ID_SIIG_1S_10x_650, | ||
773 | .subvendor = PCI_ANY_ID, | ||
774 | .subdevice = PCI_ANY_ID, | ||
775 | .init = pci_siig10x_init, | ||
776 | .setup = pci_default_setup, | ||
777 | }, | ||
778 | { | ||
779 | .vendor = PCI_VENDOR_ID_SIIG, | ||
780 | .device = PCI_DEVICE_ID_SIIG_1S_10x_850, | ||
781 | .subvendor = PCI_ANY_ID, | ||
782 | .subdevice = PCI_ANY_ID, | ||
783 | .init = pci_siig10x_init, | ||
784 | .setup = pci_default_setup, | ||
785 | }, | ||
786 | { | ||
787 | .vendor = PCI_VENDOR_ID_SIIG, | ||
788 | .device = PCI_DEVICE_ID_SIIG_2S_10x_550, | ||
789 | .subvendor = PCI_ANY_ID, | ||
790 | .subdevice = PCI_ANY_ID, | ||
791 | .init = pci_siig10x_init, | ||
792 | .setup = pci_default_setup, | ||
793 | }, | ||
794 | { | ||
795 | .vendor = PCI_VENDOR_ID_SIIG, | ||
796 | .device = PCI_DEVICE_ID_SIIG_2S_10x_650, | ||
797 | .subvendor = PCI_ANY_ID, | ||
798 | .subdevice = PCI_ANY_ID, | ||
799 | .init = pci_siig10x_init, | ||
800 | .setup = pci_default_setup, | ||
801 | }, | ||
802 | { | ||
803 | .vendor = PCI_VENDOR_ID_SIIG, | ||
804 | .device = PCI_DEVICE_ID_SIIG_2S_10x_850, | ||
805 | .subvendor = PCI_ANY_ID, | ||
806 | .subdevice = PCI_ANY_ID, | ||
807 | .init = pci_siig10x_init, | ||
808 | .setup = pci_default_setup, | ||
809 | }, | ||
810 | { | ||
811 | .vendor = PCI_VENDOR_ID_SIIG, | ||
812 | .device = PCI_DEVICE_ID_SIIG_4S_10x_550, | ||
813 | .subvendor = PCI_ANY_ID, | ||
814 | .subdevice = PCI_ANY_ID, | ||
815 | .init = pci_siig10x_init, | ||
816 | .setup = pci_default_setup, | ||
817 | }, | ||
818 | { | ||
819 | .vendor = PCI_VENDOR_ID_SIIG, | ||
820 | .device = PCI_DEVICE_ID_SIIG_4S_10x_650, | ||
821 | .subvendor = PCI_ANY_ID, | ||
822 | .subdevice = PCI_ANY_ID, | ||
823 | .init = pci_siig10x_init, | ||
824 | .setup = pci_default_setup, | ||
825 | }, | ||
826 | { | ||
827 | .vendor = PCI_VENDOR_ID_SIIG, | ||
828 | .device = PCI_DEVICE_ID_SIIG_4S_10x_850, | ||
829 | .subvendor = PCI_ANY_ID, | ||
830 | .subdevice = PCI_ANY_ID, | ||
831 | .init = pci_siig10x_init, | ||
832 | .setup = pci_default_setup, | ||
833 | }, | ||
834 | { | ||
835 | .vendor = PCI_VENDOR_ID_SIIG, | ||
836 | .device = PCI_DEVICE_ID_SIIG_1S_20x_550, | ||
837 | .subvendor = PCI_ANY_ID, | ||
838 | .subdevice = PCI_ANY_ID, | ||
839 | .init = pci_siig20x_init, | ||
840 | .setup = pci_default_setup, | ||
841 | }, | ||
842 | { | ||
843 | .vendor = PCI_VENDOR_ID_SIIG, | ||
844 | .device = PCI_DEVICE_ID_SIIG_1S_20x_650, | ||
845 | .subvendor = PCI_ANY_ID, | ||
846 | .subdevice = PCI_ANY_ID, | ||
847 | .init = pci_siig20x_init, | ||
848 | .setup = pci_default_setup, | ||
849 | }, | ||
850 | { | ||
851 | .vendor = PCI_VENDOR_ID_SIIG, | ||
852 | .device = PCI_DEVICE_ID_SIIG_1S_20x_850, | ||
853 | .subvendor = PCI_ANY_ID, | ||
854 | .subdevice = PCI_ANY_ID, | ||
855 | .init = pci_siig20x_init, | ||
856 | .setup = pci_default_setup, | ||
857 | }, | ||
858 | { | ||
859 | .vendor = PCI_VENDOR_ID_SIIG, | ||
860 | .device = PCI_DEVICE_ID_SIIG_2S_20x_550, | ||
861 | .subvendor = PCI_ANY_ID, | ||
862 | .subdevice = PCI_ANY_ID, | ||
863 | .init = pci_siig20x_init, | ||
864 | .setup = pci_default_setup, | ||
865 | }, | ||
866 | { .vendor = PCI_VENDOR_ID_SIIG, | ||
867 | .device = PCI_DEVICE_ID_SIIG_2S_20x_650, | ||
868 | .subvendor = PCI_ANY_ID, | ||
869 | .subdevice = PCI_ANY_ID, | ||
870 | .init = pci_siig20x_init, | ||
871 | .setup = pci_default_setup, | ||
872 | }, | ||
873 | { | ||
874 | .vendor = PCI_VENDOR_ID_SIIG, | ||
875 | .device = PCI_DEVICE_ID_SIIG_2S_20x_850, | ||
876 | .subvendor = PCI_ANY_ID, | ||
877 | .subdevice = PCI_ANY_ID, | ||
878 | .init = pci_siig20x_init, | ||
879 | .setup = pci_default_setup, | ||
880 | }, | ||
881 | { | ||
882 | .vendor = PCI_VENDOR_ID_SIIG, | ||
883 | .device = PCI_DEVICE_ID_SIIG_4S_20x_550, | ||
884 | .subvendor = PCI_ANY_ID, | ||
885 | .subdevice = PCI_ANY_ID, | ||
886 | .init = pci_siig20x_init, | ||
887 | .setup = pci_default_setup, | ||
888 | }, | ||
889 | { | ||
890 | .vendor = PCI_VENDOR_ID_SIIG, | ||
891 | .device = PCI_DEVICE_ID_SIIG_4S_20x_650, | ||
892 | .subvendor = PCI_ANY_ID, | ||
893 | .subdevice = PCI_ANY_ID, | ||
894 | .init = pci_siig20x_init, | ||
895 | .setup = pci_default_setup, | ||
896 | }, | ||
897 | { | ||
898 | .vendor = PCI_VENDOR_ID_SIIG, | ||
899 | .device = PCI_DEVICE_ID_SIIG_4S_20x_850, | ||
900 | .subvendor = PCI_ANY_ID, | 736 | .subvendor = PCI_ANY_ID, |
901 | .subdevice = PCI_ANY_ID, | 737 | .subdevice = PCI_ANY_ID, |
902 | .init = pci_siig20x_init, | 738 | .init = pci_siig_init, |
903 | .setup = pci_default_setup, | 739 | .setup = pci_default_setup, |
904 | }, | 740 | }, |
905 | /* | 741 | /* |
@@ -990,7 +826,7 @@ static struct pci_serial_quirk *find_quirk(struct pci_dev *dev) | |||
990 | } | 826 | } |
991 | 827 | ||
992 | static _INLINE_ int | 828 | static _INLINE_ int |
993 | get_pci_irq(struct pci_dev *dev, struct pci_board *board, int idx) | 829 | get_pci_irq(struct pci_dev *dev, struct pciserial_board *board) |
994 | { | 830 | { |
995 | if (board->flags & FL_NOIRQ) | 831 | if (board->flags & FL_NOIRQ) |
996 | return 0; | 832 | return 0; |
@@ -1115,7 +951,7 @@ enum pci_board_num_t { | |||
1115 | * see first lines of serial_in() and serial_out() in 8250.c | 951 | * see first lines of serial_in() and serial_out() in 8250.c |
1116 | */ | 952 | */ |
1117 | 953 | ||
1118 | static struct pci_board pci_boards[] __devinitdata = { | 954 | static struct pciserial_board pci_boards[] __devinitdata = { |
1119 | [pbn_default] = { | 955 | [pbn_default] = { |
1120 | .flags = FL_BASE0, | 956 | .flags = FL_BASE0, |
1121 | .num_ports = 1, | 957 | .num_ports = 1, |
@@ -1575,7 +1411,7 @@ static struct pci_board pci_boards[] __devinitdata = { | |||
1575 | * serial specs. Returns 0 on success, 1 on failure. | 1411 | * serial specs. Returns 0 on success, 1 on failure. |
1576 | */ | 1412 | */ |
1577 | static int __devinit | 1413 | static int __devinit |
1578 | serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board) | 1414 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) |
1579 | { | 1415 | { |
1580 | int num_iomem, num_port, first_port = -1, i; | 1416 | int num_iomem, num_port, first_port = -1, i; |
1581 | 1417 | ||
@@ -1640,7 +1476,8 @@ serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board) | |||
1640 | } | 1476 | } |
1641 | 1477 | ||
1642 | static inline int | 1478 | static inline int |
1643 | serial_pci_matches(struct pci_board *board, struct pci_board *guessed) | 1479 | serial_pci_matches(struct pciserial_board *board, |
1480 | struct pciserial_board *guessed) | ||
1644 | { | 1481 | { |
1645 | return | 1482 | return |
1646 | board->num_ports == guessed->num_ports && | 1483 | board->num_ports == guessed->num_ports && |
@@ -1650,58 +1487,14 @@ serial_pci_matches(struct pci_board *board, struct pci_board *guessed) | |||
1650 | board->first_offset == guessed->first_offset; | 1487 | board->first_offset == guessed->first_offset; |
1651 | } | 1488 | } |
1652 | 1489 | ||
1653 | /* | 1490 | struct serial_private * |
1654 | * Probe one serial board. Unfortunately, there is no rhyme nor reason | 1491 | pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board) |
1655 | * to the arrangement of serial ports on a PCI card. | ||
1656 | */ | ||
1657 | static int __devinit | ||
1658 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | ||
1659 | { | 1492 | { |
1493 | struct uart_port serial_port; | ||
1660 | struct serial_private *priv; | 1494 | struct serial_private *priv; |
1661 | struct pci_board *board, tmp; | ||
1662 | struct pci_serial_quirk *quirk; | 1495 | struct pci_serial_quirk *quirk; |
1663 | int rc, nr_ports, i; | 1496 | int rc, nr_ports, i; |
1664 | 1497 | ||
1665 | if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { | ||
1666 | printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n", | ||
1667 | ent->driver_data); | ||
1668 | return -EINVAL; | ||
1669 | } | ||
1670 | |||
1671 | board = &pci_boards[ent->driver_data]; | ||
1672 | |||
1673 | rc = pci_enable_device(dev); | ||
1674 | if (rc) | ||
1675 | return rc; | ||
1676 | |||
1677 | if (ent->driver_data == pbn_default) { | ||
1678 | /* | ||
1679 | * Use a copy of the pci_board entry for this; | ||
1680 | * avoid changing entries in the table. | ||
1681 | */ | ||
1682 | memcpy(&tmp, board, sizeof(struct pci_board)); | ||
1683 | board = &tmp; | ||
1684 | |||
1685 | /* | ||
1686 | * We matched one of our class entries. Try to | ||
1687 | * determine the parameters of this board. | ||
1688 | */ | ||
1689 | rc = serial_pci_guess_board(dev, board); | ||
1690 | if (rc) | ||
1691 | goto disable; | ||
1692 | } else { | ||
1693 | /* | ||
1694 | * We matched an explicit entry. If we are able to | ||
1695 | * detect this boards settings with our heuristic, | ||
1696 | * then we no longer need this entry. | ||
1697 | */ | ||
1698 | memcpy(&tmp, &pci_boards[pbn_default], sizeof(struct pci_board)); | ||
1699 | rc = serial_pci_guess_board(dev, &tmp); | ||
1700 | if (rc == 0 && serial_pci_matches(board, &tmp)) | ||
1701 | moan_device("Redundant entry in serial pci_table.", | ||
1702 | dev); | ||
1703 | } | ||
1704 | |||
1705 | nr_ports = board->num_ports; | 1498 | nr_ports = board->num_ports; |
1706 | 1499 | ||
1707 | /* | 1500 | /* |
@@ -1718,8 +1511,10 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1718 | */ | 1511 | */ |
1719 | if (quirk->init) { | 1512 | if (quirk->init) { |
1720 | rc = quirk->init(dev); | 1513 | rc = quirk->init(dev); |
1721 | if (rc < 0) | 1514 | if (rc < 0) { |
1722 | goto disable; | 1515 | priv = ERR_PTR(rc); |
1516 | goto err_out; | ||
1517 | } | ||
1723 | if (rc) | 1518 | if (rc) |
1724 | nr_ports = rc; | 1519 | nr_ports = rc; |
1725 | } | 1520 | } |
@@ -1728,27 +1523,26 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1728 | sizeof(unsigned int) * nr_ports, | 1523 | sizeof(unsigned int) * nr_ports, |
1729 | GFP_KERNEL); | 1524 | GFP_KERNEL); |
1730 | if (!priv) { | 1525 | if (!priv) { |
1731 | rc = -ENOMEM; | 1526 | priv = ERR_PTR(-ENOMEM); |
1732 | goto deinit; | 1527 | goto err_deinit; |
1733 | } | 1528 | } |
1734 | 1529 | ||
1735 | memset(priv, 0, sizeof(struct serial_private) + | 1530 | memset(priv, 0, sizeof(struct serial_private) + |
1736 | sizeof(unsigned int) * nr_ports); | 1531 | sizeof(unsigned int) * nr_ports); |
1737 | 1532 | ||
1533 | priv->dev = dev; | ||
1738 | priv->quirk = quirk; | 1534 | priv->quirk = quirk; |
1739 | pci_set_drvdata(dev, priv); | 1535 | |
1536 | memset(&serial_port, 0, sizeof(struct uart_port)); | ||
1537 | serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | ||
1538 | serial_port.uartclk = board->base_baud * 16; | ||
1539 | serial_port.irq = get_pci_irq(dev, board); | ||
1540 | serial_port.dev = &dev->dev; | ||
1740 | 1541 | ||
1741 | for (i = 0; i < nr_ports; i++) { | 1542 | for (i = 0; i < nr_ports; i++) { |
1742 | struct uart_port serial_port; | 1543 | if (quirk->setup(priv, board, &serial_port, i)) |
1743 | memset(&serial_port, 0, sizeof(struct uart_port)); | ||
1744 | |||
1745 | serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | | ||
1746 | UPF_SHARE_IRQ; | ||
1747 | serial_port.uartclk = board->base_baud * 16; | ||
1748 | serial_port.irq = get_pci_irq(dev, board, i); | ||
1749 | serial_port.dev = &dev->dev; | ||
1750 | if (quirk->setup(dev, board, &serial_port, i)) | ||
1751 | break; | 1544 | break; |
1545 | |||
1752 | #ifdef SERIAL_DEBUG_PCI | 1546 | #ifdef SERIAL_DEBUG_PCI |
1753 | printk("Setup PCI port: port %x, irq %d, type %d\n", | 1547 | printk("Setup PCI port: port %x, irq %d, type %d\n", |
1754 | serial_port.iobase, serial_port.irq, serial_port.iotype); | 1548 | serial_port.iobase, serial_port.irq, serial_port.iotype); |
@@ -1763,24 +1557,21 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1763 | 1557 | ||
1764 | priv->nr = i; | 1558 | priv->nr = i; |
1765 | 1559 | ||
1766 | return 0; | 1560 | return priv; |
1767 | 1561 | ||
1768 | deinit: | 1562 | err_deinit: |
1769 | if (quirk->exit) | 1563 | if (quirk->exit) |
1770 | quirk->exit(dev); | 1564 | quirk->exit(dev); |
1771 | disable: | 1565 | err_out: |
1772 | pci_disable_device(dev); | 1566 | return priv; |
1773 | return rc; | ||
1774 | } | 1567 | } |
1568 | EXPORT_SYMBOL_GPL(pciserial_init_ports); | ||
1775 | 1569 | ||
1776 | static void __devexit pciserial_remove_one(struct pci_dev *dev) | 1570 | void pciserial_remove_ports(struct serial_private *priv) |
1777 | { | 1571 | { |
1778 | struct serial_private *priv = pci_get_drvdata(dev); | ||
1779 | struct pci_serial_quirk *quirk; | 1572 | struct pci_serial_quirk *quirk; |
1780 | int i; | 1573 | int i; |
1781 | 1574 | ||
1782 | pci_set_drvdata(dev, NULL); | ||
1783 | |||
1784 | for (i = 0; i < priv->nr; i++) | 1575 | for (i = 0; i < priv->nr; i++) |
1785 | serial8250_unregister_port(priv->line[i]); | 1576 | serial8250_unregister_port(priv->line[i]); |
1786 | 1577 | ||
@@ -1793,25 +1584,123 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev) | |||
1793 | /* | 1584 | /* |
1794 | * Find the exit quirks. | 1585 | * Find the exit quirks. |
1795 | */ | 1586 | */ |
1796 | quirk = find_quirk(dev); | 1587 | quirk = find_quirk(priv->dev); |
1797 | if (quirk->exit) | 1588 | if (quirk->exit) |
1798 | quirk->exit(dev); | 1589 | quirk->exit(priv->dev); |
1590 | |||
1591 | kfree(priv); | ||
1592 | } | ||
1593 | EXPORT_SYMBOL_GPL(pciserial_remove_ports); | ||
1594 | |||
1595 | void pciserial_suspend_ports(struct serial_private *priv) | ||
1596 | { | ||
1597 | int i; | ||
1598 | |||
1599 | for (i = 0; i < priv->nr; i++) | ||
1600 | if (priv->line[i] >= 0) | ||
1601 | serial8250_suspend_port(priv->line[i]); | ||
1602 | } | ||
1603 | EXPORT_SYMBOL_GPL(pciserial_suspend_ports); | ||
1604 | |||
1605 | void pciserial_resume_ports(struct serial_private *priv) | ||
1606 | { | ||
1607 | int i; | ||
1608 | |||
1609 | /* | ||
1610 | * Ensure that the board is correctly configured. | ||
1611 | */ | ||
1612 | if (priv->quirk->init) | ||
1613 | priv->quirk->init(priv->dev); | ||
1614 | |||
1615 | for (i = 0; i < priv->nr; i++) | ||
1616 | if (priv->line[i] >= 0) | ||
1617 | serial8250_resume_port(priv->line[i]); | ||
1618 | } | ||
1619 | EXPORT_SYMBOL_GPL(pciserial_resume_ports); | ||
1620 | |||
1621 | /* | ||
1622 | * Probe one serial board. Unfortunately, there is no rhyme nor reason | ||
1623 | * to the arrangement of serial ports on a PCI card. | ||
1624 | */ | ||
1625 | static int __devinit | ||
1626 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | ||
1627 | { | ||
1628 | struct serial_private *priv; | ||
1629 | struct pciserial_board *board, tmp; | ||
1630 | int rc; | ||
1631 | |||
1632 | if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { | ||
1633 | printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n", | ||
1634 | ent->driver_data); | ||
1635 | return -EINVAL; | ||
1636 | } | ||
1637 | |||
1638 | board = &pci_boards[ent->driver_data]; | ||
1639 | |||
1640 | rc = pci_enable_device(dev); | ||
1641 | if (rc) | ||
1642 | return rc; | ||
1643 | |||
1644 | if (ent->driver_data == pbn_default) { | ||
1645 | /* | ||
1646 | * Use a copy of the pci_board entry for this; | ||
1647 | * avoid changing entries in the table. | ||
1648 | */ | ||
1649 | memcpy(&tmp, board, sizeof(struct pciserial_board)); | ||
1650 | board = &tmp; | ||
1651 | |||
1652 | /* | ||
1653 | * We matched one of our class entries. Try to | ||
1654 | * determine the parameters of this board. | ||
1655 | */ | ||
1656 | rc = serial_pci_guess_board(dev, board); | ||
1657 | if (rc) | ||
1658 | goto disable; | ||
1659 | } else { | ||
1660 | /* | ||
1661 | * We matched an explicit entry. If we are able to | ||
1662 | * detect this boards settings with our heuristic, | ||
1663 | * then we no longer need this entry. | ||
1664 | */ | ||
1665 | memcpy(&tmp, &pci_boards[pbn_default], | ||
1666 | sizeof(struct pciserial_board)); | ||
1667 | rc = serial_pci_guess_board(dev, &tmp); | ||
1668 | if (rc == 0 && serial_pci_matches(board, &tmp)) | ||
1669 | moan_device("Redundant entry in serial pci_table.", | ||
1670 | dev); | ||
1671 | } | ||
1799 | 1672 | ||
1673 | priv = pciserial_init_ports(dev, board); | ||
1674 | if (!IS_ERR(priv)) { | ||
1675 | pci_set_drvdata(dev, priv); | ||
1676 | return 0; | ||
1677 | } | ||
1678 | |||
1679 | rc = PTR_ERR(priv); | ||
1680 | |||
1681 | disable: | ||
1800 | pci_disable_device(dev); | 1682 | pci_disable_device(dev); |
1683 | return rc; | ||
1684 | } | ||
1801 | 1685 | ||
1802 | kfree(priv); | 1686 | static void __devexit pciserial_remove_one(struct pci_dev *dev) |
1687 | { | ||
1688 | struct serial_private *priv = pci_get_drvdata(dev); | ||
1689 | |||
1690 | pci_set_drvdata(dev, NULL); | ||
1691 | |||
1692 | pciserial_remove_ports(priv); | ||
1693 | |||
1694 | pci_disable_device(dev); | ||
1803 | } | 1695 | } |
1804 | 1696 | ||
1805 | static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state) | 1697 | static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state) |
1806 | { | 1698 | { |
1807 | struct serial_private *priv = pci_get_drvdata(dev); | 1699 | struct serial_private *priv = pci_get_drvdata(dev); |
1808 | 1700 | ||
1809 | if (priv) { | 1701 | if (priv) |
1810 | int i; | 1702 | pciserial_suspend_ports(priv); |
1811 | 1703 | ||
1812 | for (i = 0; i < priv->nr; i++) | ||
1813 | serial8250_suspend_port(priv->line[i]); | ||
1814 | } | ||
1815 | pci_save_state(dev); | 1704 | pci_save_state(dev); |
1816 | pci_set_power_state(dev, pci_choose_state(dev, state)); | 1705 | pci_set_power_state(dev, pci_choose_state(dev, state)); |
1817 | return 0; | 1706 | return 0; |
@@ -1825,21 +1714,12 @@ static int pciserial_resume_one(struct pci_dev *dev) | |||
1825 | pci_restore_state(dev); | 1714 | pci_restore_state(dev); |
1826 | 1715 | ||
1827 | if (priv) { | 1716 | if (priv) { |
1828 | int i; | ||
1829 | |||
1830 | /* | 1717 | /* |
1831 | * The device may have been disabled. Re-enable it. | 1718 | * The device may have been disabled. Re-enable it. |
1832 | */ | 1719 | */ |
1833 | pci_enable_device(dev); | 1720 | pci_enable_device(dev); |
1834 | 1721 | ||
1835 | /* | 1722 | pciserial_resume_ports(priv); |
1836 | * Ensure that the board is correctly configured. | ||
1837 | */ | ||
1838 | if (priv->quirk->init) | ||
1839 | priv->quirk->init(dev); | ||
1840 | |||
1841 | for (i = 0; i < priv->nr; i++) | ||
1842 | serial8250_resume_port(priv->line[i]); | ||
1843 | } | 1723 | } |
1844 | return 0; | 1724 | return 0; |
1845 | } | 1725 | } |