aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorRyan Bradetich <rbradetich@gmail.com>2006-11-08 23:45:08 -0500
committerKyle McMartin <kyle@ubuntu.com>2006-12-08 00:34:26 -0500
commit752b940359089ee1bcaceeb5c62d626a92586ba2 (patch)
tree7e9b5caf8ea4c384b251e6cce8fe9152b7d3b99c /drivers/serial
parentc380f057269686e17db74d360c923663889ac702 (diff)
[PARISC] [MUX] Detect multiple cards in the correct order
This patch follows the example of the 8250_gsc driver by probing for specific built-in Mux cards first. This allows the system to preserve the correct detection order with multiple Mux cards. Signed-off-by: Ryan Bradetich <rbrad@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/mux.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 5ff7e05a1526..87269cca9c7c 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -453,7 +453,7 @@ static int __init mux_probe(struct parisc_device *dev)
453 } 453 }
454 454
455 port_count = GET_MUX_PORTS(iodc_data); 455 port_count = GET_MUX_PORTS(iodc_data);
456 printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.5\n", port_count); 456 printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.6\n", port_count);
457 457
458 dev_set_drvdata(&dev->dev, (void *)(long)port_count); 458 dev_set_drvdata(&dev->dev, (void *)(long)port_count);
459 request_mem_region(dev->hpa.start + MUX_OFFSET, 459 request_mem_region(dev->hpa.start + MUX_OFFSET,
@@ -491,6 +491,7 @@ static int __init mux_probe(struct parisc_device *dev)
491 */ 491 */
492 port->timeout = HZ / 50; 492 port->timeout = HZ / 50;
493 spin_lock_init(&port->lock); 493 spin_lock_init(&port->lock);
494
494 status = uart_add_one_port(&mux_driver, port); 495 status = uart_add_one_port(&mux_driver, port);
495 BUG_ON(status); 496 BUG_ON(status);
496 } 497 }
@@ -500,12 +501,9 @@ static int __init mux_probe(struct parisc_device *dev)
500 501
501static int __devexit mux_remove(struct parisc_device *dev) 502static int __devexit mux_remove(struct parisc_device *dev)
502{ 503{
503 int i; 504 int i, j;
504 int port_count = (long)dev_get_drvdata(&dev->dev); 505 int port_count = (long)dev_get_drvdata(&dev->dev);
505 506
506 /* Delete the Mux timer. */
507 del_timer(&mux_timer);
508
509 /* Find Port 0 for this card in the mux_ports list. */ 507 /* Find Port 0 for this card in the mux_ports list. */
510 for(i = 0; i < port_cnt; ++i) { 508 for(i = 0; i < port_cnt; ++i) {
511 if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET) 509 if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET)
@@ -514,7 +512,7 @@ static int __devexit mux_remove(struct parisc_device *dev)
514 BUG_ON(i + port_count > port_cnt); 512 BUG_ON(i + port_count > port_cnt);
515 513
516 /* Release the resources associated with each port on the device. */ 514 /* Release the resources associated with each port on the device. */
517 for(; i < port_count; ++i) { 515 for(j = 0; j < port_count; ++j, ++i) {
518 struct uart_port *port = &mux_ports[i].port; 516 struct uart_port *port = &mux_ports[i].port;
519 517
520 uart_remove_one_port(&mux_driver, port); 518 uart_remove_one_port(&mux_driver, port);
@@ -526,13 +524,35 @@ static int __devexit mux_remove(struct parisc_device *dev)
526 return 0; 524 return 0;
527} 525}
528 526
527/* Hack. This idea was taken from the 8250_gsc.c on how to properly order
528 * the serial port detection in the proper order. The idea is we always
529 * want the builtin mux to be detected before addin mux cards, so we
530 * specifically probe for the builtin mux cards first.
531 *
532 * This table only contains the parisc_device_id of known builtin mux
533 * devices. All other mux cards will be detected by the generic mux_tbl.
534 */
535static struct parisc_device_id builtin_mux_tbl[] = {
536 { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
537 { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
538 { 0, }
539};
540
529static struct parisc_device_id mux_tbl[] = { 541static struct parisc_device_id mux_tbl[] = {
530 { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D }, 542 { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
531 { 0, } 543 { 0, }
532}; 544};
533 545
546MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
534MODULE_DEVICE_TABLE(parisc, mux_tbl); 547MODULE_DEVICE_TABLE(parisc, mux_tbl);
535 548
549static struct parisc_driver builtin_serial_mux_driver = {
550 .name = "builtin_serial_mux",
551 .id_table = builtin_mux_tbl,
552 .probe = mux_probe,
553 .remove = __devexit_p(mux_remove),
554};
555
536static struct parisc_driver serial_mux_driver = { 556static struct parisc_driver serial_mux_driver = {
537 .name = "serial_mux", 557 .name = "serial_mux",
538 .id_table = mux_tbl, 558 .id_table = mux_tbl,
@@ -547,7 +567,8 @@ static struct parisc_driver serial_mux_driver = {
547 */ 567 */
548static int __init mux_init(void) 568static int __init mux_init(void)
549{ 569{
550 int status = register_parisc_driver(&serial_mux_driver); 570 register_parisc_driver(&builtin_serial_mux_driver);
571 register_parisc_driver(&serial_mux_driver);
551 572
552 if(port_cnt > 0) { 573 if(port_cnt > 0) {
553 /* Start the Mux timer */ 574 /* Start the Mux timer */
@@ -560,7 +581,7 @@ static int __init mux_init(void)
560#endif 581#endif
561 } 582 }
562 583
563 return status; 584 return 0;
564} 585}
565 586
566/** 587/**
@@ -578,6 +599,7 @@ static void __exit mux_exit(void)
578#endif 599#endif
579 } 600 }
580 601
602 unregister_parisc_driver(&builtin_serial_mux_driver);
581 unregister_parisc_driver(&serial_mux_driver); 603 unregister_parisc_driver(&serial_mux_driver);
582 uart_unregister_driver(&mux_driver); 604 uart_unregister_driver(&mux_driver);
583} 605}