diff options
| -rw-r--r-- | drivers/serial/mux.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 6408b9b1561a..f21faf163955 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
| @@ -66,6 +66,13 @@ static struct uart_driver mux_driver = { | |||
| 66 | .nr = MUX_NR, | 66 | .nr = MUX_NR, |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | struct mux_card { | ||
| 70 | int port_count; | ||
| 71 | struct parisc_device *dev; | ||
| 72 | struct mux_card *next; | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct mux_card *mux_card_head; | ||
| 69 | static struct timer_list mux_timer; | 76 | static struct timer_list mux_timer; |
| 70 | 77 | ||
| 71 | #define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET) | 78 | #define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET) |
| @@ -434,6 +441,37 @@ static struct uart_ops mux_pops = { | |||
| 434 | }; | 441 | }; |
| 435 | 442 | ||
| 436 | /** | 443 | /** |
| 444 | * get_new_mux_card - Allocate and return a new mux card. | ||
| 445 | * | ||
| 446 | * This function is used to allocate and return a new mux card. | ||
| 447 | */ | ||
| 448 | static struct mux_card * __init get_new_mux_card(void) | ||
| 449 | { | ||
| 450 | struct mux_card *card = mux_card_head; | ||
| 451 | |||
| 452 | if(card == NULL) { | ||
| 453 | mux_card_head = kzalloc(sizeof(struct mux_card), GFP_KERNEL); | ||
| 454 | if(!mux_card_head) { | ||
| 455 | printk(KERN_ERR "MUX: Unable to allocate memory.\n"); | ||
| 456 | return NULL; | ||
| 457 | } | ||
| 458 | return mux_card_head; | ||
| 459 | } | ||
| 460 | |||
| 461 | while(card->next) { | ||
| 462 | card = card->next; | ||
| 463 | } | ||
| 464 | |||
| 465 | card->next = kzalloc(sizeof(struct mux_card), GFP_KERNEL); | ||
| 466 | if(!card->next) { | ||
| 467 | printk(KERN_ERR "MUX: Unable to allocate memory.\n"); | ||
| 468 | return NULL; | ||
| 469 | } | ||
| 470 | |||
| 471 | return card->next; | ||
| 472 | } | ||
| 473 | |||
| 474 | /** | ||
| 437 | * mux_probe - Determine if the Serial Mux should claim this device. | 475 | * mux_probe - Determine if the Serial Mux should claim this device. |
| 438 | * @dev: The parisc device. | 476 | * @dev: The parisc device. |
| 439 | * | 477 | * |
| @@ -446,6 +484,7 @@ static int __init mux_probe(struct parisc_device *dev) | |||
| 446 | u8 iodc_data[32]; | 484 | u8 iodc_data[32]; |
| 447 | unsigned long bytecnt; | 485 | unsigned long bytecnt; |
| 448 | struct uart_port *port; | 486 | struct uart_port *port; |
| 487 | struct mux_card *card; | ||
| 449 | 488 | ||
| 450 | status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32); | 489 | status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32); |
| 451 | if(status != PDC_OK) { | 490 | if(status != PDC_OK) { |
| @@ -454,7 +493,16 @@ static int __init mux_probe(struct parisc_device *dev) | |||
| 454 | } | 493 | } |
| 455 | 494 | ||
| 456 | ports = GET_MUX_PORTS(iodc_data); | 495 | ports = GET_MUX_PORTS(iodc_data); |
| 457 | printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.3\n", ports); | 496 | printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.4\n", ports); |
| 497 | |||
| 498 | card = get_new_mux_card(); | ||
| 499 | if(card == NULL) | ||
| 500 | return 1; | ||
| 501 | |||
| 502 | card->dev = dev; | ||
| 503 | card->port_count = ports; | ||
| 504 | request_mem_region(card->dev->hpa.start + MUX_OFFSET, | ||
| 505 | card->port_count * MUX_LINE_OFFSET, "Mux"); | ||
| 458 | 506 | ||
| 459 | if(!port_cnt) { | 507 | if(!port_cnt) { |
| 460 | mux_driver.cons = MUX_CONSOLE; | 508 | mux_driver.cons = MUX_CONSOLE; |
| @@ -534,6 +582,8 @@ static int __init mux_init(void) | |||
| 534 | static void __exit mux_exit(void) | 582 | static void __exit mux_exit(void) |
| 535 | { | 583 | { |
| 536 | int i; | 584 | int i; |
| 585 | struct mux_card *next; | ||
| 586 | struct mux_card *card = mux_card_head; | ||
| 537 | 587 | ||
| 538 | for (i = 0; i < port_cnt; i++) { | 588 | for (i = 0; i < port_cnt; i++) { |
| 539 | uart_remove_one_port(&mux_driver, &mux_ports[i].port); | 589 | uart_remove_one_port(&mux_driver, &mux_ports[i].port); |
| @@ -541,6 +591,15 @@ static void __exit mux_exit(void) | |||
| 541 | iounmap(mux_ports[i].port.membase); | 591 | iounmap(mux_ports[i].port.membase); |
| 542 | } | 592 | } |
| 543 | 593 | ||
| 594 | while(card != NULL) { | ||
| 595 | release_mem_region(card->dev->hpa.start + MUX_OFFSET, | ||
| 596 | card->port_count * MUX_LINE_OFFSET); | ||
| 597 | |||
| 598 | next = card->next; | ||
| 599 | kfree(card); | ||
| 600 | card = next; | ||
| 601 | } | ||
| 602 | |||
| 544 | uart_unregister_driver(&mux_driver); | 603 | uart_unregister_driver(&mux_driver); |
| 545 | } | 604 | } |
| 546 | 605 | ||
