diff options
| -rw-r--r-- | drivers/char/cyclades.c | 448 | ||||
| -rw-r--r-- | include/linux/cyclades.h | 2 |
2 files changed, 165 insertions, 285 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index ed66c3ab230d..cf2874a89c8c 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
| @@ -90,7 +90,6 @@ | |||
| 90 | #include <linux/proc_fs.h> | 90 | #include <linux/proc_fs.h> |
| 91 | #include <linux/seq_file.h> | 91 | #include <linux/seq_file.h> |
| 92 | 92 | ||
| 93 | static void cy_throttle(struct tty_struct *tty); | ||
| 94 | static void cy_send_xchar(struct tty_struct *tty, char ch); | 93 | static void cy_send_xchar(struct tty_struct *tty, char ch); |
| 95 | 94 | ||
| 96 | #ifndef SERIAL_XMIT_SIZE | 95 | #ifndef SERIAL_XMIT_SIZE |
| @@ -298,6 +297,20 @@ static void cyz_rx_restart(unsigned long); | |||
| 298 | static struct timer_list cyz_rx_full_timer[NR_PORTS]; | 297 | static struct timer_list cyz_rx_full_timer[NR_PORTS]; |
| 299 | #endif /* CONFIG_CYZ_INTR */ | 298 | #endif /* CONFIG_CYZ_INTR */ |
| 300 | 299 | ||
| 300 | static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val) | ||
| 301 | { | ||
| 302 | struct cyclades_card *card = port->card; | ||
| 303 | |||
| 304 | cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val); | ||
| 305 | } | ||
| 306 | |||
| 307 | static inline u8 cyy_readb(struct cyclades_port *port, u32 reg) | ||
| 308 | { | ||
| 309 | struct cyclades_card *card = port->card; | ||
| 310 | |||
| 311 | return readb(port->u.cyy.base_addr + (reg << card->bus_index)); | ||
| 312 | } | ||
| 313 | |||
| 301 | static inline bool cy_is_Z(struct cyclades_card *card) | 314 | static inline bool cy_is_Z(struct cyclades_card *card) |
| 302 | { | 315 | { |
| 303 | return card->num_chips == (unsigned int)-1; | 316 | return card->num_chips == (unsigned int)-1; |
| @@ -350,13 +363,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
| 350 | 363 | ||
| 351 | This function is only called from inside spinlock-protected code. | 364 | This function is only called from inside spinlock-protected code. |
| 352 | */ | 365 | */ |
| 353 | static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index) | 366 | static int __cyy_issue_cmd(void __iomem *base_addr, u8 cmd, int index) |
| 354 | { | 367 | { |
| 368 | void __iomem *ccr = base_addr + (CyCCR << index); | ||
| 355 | unsigned int i; | 369 | unsigned int i; |
| 356 | 370 | ||
| 357 | /* Check to see that the previous command has completed */ | 371 | /* Check to see that the previous command has completed */ |
| 358 | for (i = 0; i < 100; i++) { | 372 | for (i = 0; i < 100; i++) { |
| 359 | if (readb(base_addr + (CyCCR << index)) == 0) | 373 | if (readb(ccr) == 0) |
| 360 | break; | 374 | break; |
| 361 | udelay(10L); | 375 | udelay(10L); |
| 362 | } | 376 | } |
| @@ -366,10 +380,16 @@ static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index) | |||
| 366 | return -1; | 380 | return -1; |
| 367 | 381 | ||
| 368 | /* Issue the new command */ | 382 | /* Issue the new command */ |
| 369 | cy_writeb(base_addr + (CyCCR << index), cmd); | 383 | cy_writeb(ccr, cmd); |
| 370 | 384 | ||
| 371 | return 0; | 385 | return 0; |
| 372 | } /* cyy_issue_cmd */ | 386 | } |
| 387 | |||
| 388 | static inline int cyy_issue_cmd(struct cyclades_port *port, u8 cmd) | ||
| 389 | { | ||
| 390 | return __cyy_issue_cmd(port->u.cyy.base_addr, cmd, | ||
| 391 | port->card->bus_index); | ||
| 392 | } | ||
| 373 | 393 | ||
| 374 | #ifdef CONFIG_ISA | 394 | #ifdef CONFIG_ISA |
| 375 | /* ISA interrupt detection code */ | 395 | /* ISA interrupt detection code */ |
| @@ -394,7 +414,7 @@ static unsigned detect_isa_irq(void __iomem *address) | |||
| 394 | /* Enable the Tx interrupts on the CD1400 */ | 414 | /* Enable the Tx interrupts on the CD1400 */ |
| 395 | local_irq_save(flags); | 415 | local_irq_save(flags); |
| 396 | cy_writeb(address + (CyCAR << index), 0); | 416 | cy_writeb(address + (CyCAR << index), 0); |
| 397 | cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index); | 417 | __cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index); |
| 398 | 418 | ||
| 399 | cy_writeb(address + (CyCAR << index), 0); | 419 | cy_writeb(address + (CyCAR << index), 0); |
| 400 | cy_writeb(address + (CySRER << index), | 420 | cy_writeb(address + (CySRER << index), |
| @@ -428,7 +448,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 428 | struct cyclades_port *info; | 448 | struct cyclades_port *info; |
| 429 | struct tty_struct *tty; | 449 | struct tty_struct *tty; |
| 430 | int len, index = cinfo->bus_index; | 450 | int len, index = cinfo->bus_index; |
| 431 | u8 save_xir, channel, save_car, data, char_count; | 451 | u8 ivr, save_xir, channel, save_car, data, char_count; |
| 432 | 452 | ||
| 433 | #ifdef CY_DEBUG_INTERRUPTS | 453 | #ifdef CY_DEBUG_INTERRUPTS |
| 434 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); | 454 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); |
| @@ -437,26 +457,25 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 437 | save_xir = readb(base_addr + (CyRIR << index)); | 457 | save_xir = readb(base_addr + (CyRIR << index)); |
| 438 | channel = save_xir & CyIRChannel; | 458 | channel = save_xir & CyIRChannel; |
| 439 | info = &cinfo->ports[channel + chip * 4]; | 459 | info = &cinfo->ports[channel + chip * 4]; |
| 440 | save_car = readb(base_addr + (CyCAR << index)); | 460 | save_car = cyy_readb(info, CyCAR); |
| 441 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 461 | cyy_writeb(info, CyCAR, save_xir); |
| 462 | ivr = cyy_readb(info, CyRIVR) & CyIVRMask; | ||
| 442 | 463 | ||
| 443 | tty = tty_port_tty_get(&info->port); | 464 | tty = tty_port_tty_get(&info->port); |
| 444 | /* if there is nowhere to put the data, discard it */ | 465 | /* if there is nowhere to put the data, discard it */ |
| 445 | if (tty == NULL) { | 466 | if (tty == NULL) { |
| 446 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == | 467 | if (ivr == CyIVRRxEx) { /* exception */ |
| 447 | CyIVRRxEx) { /* exception */ | 468 | data = cyy_readb(info, CyRDSR); |
| 448 | data = readb(base_addr + (CyRDSR << index)); | ||
| 449 | } else { /* normal character reception */ | 469 | } else { /* normal character reception */ |
| 450 | char_count = readb(base_addr + (CyRDCR << index)); | 470 | char_count = cyy_readb(info, CyRDCR); |
| 451 | while (char_count--) | 471 | while (char_count--) |
| 452 | data = readb(base_addr + (CyRDSR << index)); | 472 | data = cyy_readb(info, CyRDSR); |
| 453 | } | 473 | } |
| 454 | goto end; | 474 | goto end; |
| 455 | } | 475 | } |
| 456 | /* there is an open port for this data */ | 476 | /* there is an open port for this data */ |
| 457 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == | 477 | if (ivr == CyIVRRxEx) { /* exception */ |
| 458 | CyIVRRxEx) { /* exception */ | 478 | data = cyy_readb(info, CyRDSR); |
| 459 | data = readb(base_addr + (CyRDSR << index)); | ||
| 460 | 479 | ||
| 461 | /* For statistics only */ | 480 | /* For statistics only */ |
| 462 | if (data & CyBREAK) | 481 | if (data & CyBREAK) |
| @@ -477,22 +496,22 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 477 | if (data & info->read_status_mask) { | 496 | if (data & info->read_status_mask) { |
| 478 | if (data & CyBREAK) { | 497 | if (data & CyBREAK) { |
| 479 | tty_insert_flip_char(tty, | 498 | tty_insert_flip_char(tty, |
| 480 | readb(base_addr + (CyRDSR << | 499 | cyy_readb(info, CyRDSR), |
| 481 | index)), TTY_BREAK); | 500 | TTY_BREAK); |
| 482 | info->icount.rx++; | 501 | info->icount.rx++; |
| 483 | if (info->port.flags & ASYNC_SAK) | 502 | if (info->port.flags & ASYNC_SAK) |
| 484 | do_SAK(tty); | 503 | do_SAK(tty); |
| 485 | } else if (data & CyFRAME) { | 504 | } else if (data & CyFRAME) { |
| 486 | tty_insert_flip_char(tty, | 505 | tty_insert_flip_char(tty, |
| 487 | readb(base_addr + (CyRDSR << | 506 | cyy_readb(info, CyRDSR), |
| 488 | index)), TTY_FRAME); | 507 | TTY_FRAME); |
| 489 | info->icount.rx++; | 508 | info->icount.rx++; |
| 490 | info->idle_stats.frame_errs++; | 509 | info->idle_stats.frame_errs++; |
| 491 | } else if (data & CyPARITY) { | 510 | } else if (data & CyPARITY) { |
| 492 | /* Pieces of seven... */ | 511 | /* Pieces of seven... */ |
| 493 | tty_insert_flip_char(tty, | 512 | tty_insert_flip_char(tty, |
| 494 | readb(base_addr + (CyRDSR << | 513 | cyy_readb(info, CyRDSR), |
| 495 | index)), TTY_PARITY); | 514 | TTY_PARITY); |
| 496 | info->icount.rx++; | 515 | info->icount.rx++; |
| 497 | info->idle_stats.parity_errs++; | 516 | info->idle_stats.parity_errs++; |
| 498 | } else if (data & CyOVERRUN) { | 517 | } else if (data & CyOVERRUN) { |
| @@ -504,8 +523,8 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 504 | the next incoming character. | 523 | the next incoming character. |
| 505 | */ | 524 | */ |
| 506 | tty_insert_flip_char(tty, | 525 | tty_insert_flip_char(tty, |
| 507 | readb(base_addr + (CyRDSR << | 526 | cyy_readb(info, CyRDSR), |
| 508 | index)), TTY_FRAME); | 527 | TTY_FRAME); |
| 509 | info->icount.rx++; | 528 | info->icount.rx++; |
| 510 | info->idle_stats.overruns++; | 529 | info->idle_stats.overruns++; |
| 511 | /* These two conditions may imply */ | 530 | /* These two conditions may imply */ |
| @@ -529,7 +548,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 529 | } | 548 | } |
| 530 | } else { /* normal character reception */ | 549 | } else { /* normal character reception */ |
| 531 | /* load # chars available from the chip */ | 550 | /* load # chars available from the chip */ |
| 532 | char_count = readb(base_addr + (CyRDCR << index)); | 551 | char_count = cyy_readb(info, CyRDCR); |
| 533 | 552 | ||
| 534 | #ifdef CY_ENABLE_MONITORING | 553 | #ifdef CY_ENABLE_MONITORING |
| 535 | ++info->mon.int_count; | 554 | ++info->mon.int_count; |
| @@ -540,7 +559,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 540 | #endif | 559 | #endif |
| 541 | len = tty_buffer_request_room(tty, char_count); | 560 | len = tty_buffer_request_room(tty, char_count); |
| 542 | while (len--) { | 561 | while (len--) { |
| 543 | data = readb(base_addr + (CyRDSR << index)); | 562 | data = cyy_readb(info, CyRDSR); |
| 544 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 563 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
| 545 | info->idle_stats.recv_bytes++; | 564 | info->idle_stats.recv_bytes++; |
| 546 | info->icount.rx++; | 565 | info->icount.rx++; |
| @@ -554,8 +573,8 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
| 554 | tty_kref_put(tty); | 573 | tty_kref_put(tty); |
| 555 | end: | 574 | end: |
| 556 | /* end of service */ | 575 | /* end of service */ |
| 557 | cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f); | 576 | cyy_writeb(info, CyRIR, save_xir & 0x3f); |
| 558 | cy_writeb(base_addr + (CyCAR << index), save_car); | 577 | cyy_writeb(info, CyCAR, save_car); |
| 559 | } | 578 | } |
| 560 | 579 | ||
| 561 | static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | 580 | static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, |
| @@ -588,8 +607,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | |||
| 588 | info = &cinfo->ports[channel + chip * 4]; | 607 | info = &cinfo->ports[channel + chip * 4]; |
| 589 | tty = tty_port_tty_get(&info->port); | 608 | tty = tty_port_tty_get(&info->port); |
| 590 | if (tty == NULL) { | 609 | if (tty == NULL) { |
| 591 | cy_writeb(base_addr + (CySRER << index), | 610 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy); |
| 592 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); | ||
| 593 | goto end; | 611 | goto end; |
| 594 | } | 612 | } |
| 595 | 613 | ||
| @@ -598,7 +616,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | |||
| 598 | 616 | ||
| 599 | if (info->x_char) { /* send special char */ | 617 | if (info->x_char) { /* send special char */ |
| 600 | outch = info->x_char; | 618 | outch = info->x_char; |
| 601 | cy_writeb(base_addr + (CyTDR << index), outch); | 619 | cyy_writeb(info, CyTDR, outch); |
| 602 | char_count--; | 620 | char_count--; |
| 603 | info->icount.tx++; | 621 | info->icount.tx++; |
| 604 | info->x_char = 0; | 622 | info->x_char = 0; |
| @@ -606,14 +624,14 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | |||
| 606 | 624 | ||
| 607 | if (info->breakon || info->breakoff) { | 625 | if (info->breakon || info->breakoff) { |
| 608 | if (info->breakon) { | 626 | if (info->breakon) { |
| 609 | cy_writeb(base_addr + (CyTDR << index), 0); | 627 | cyy_writeb(info, CyTDR, 0); |
| 610 | cy_writeb(base_addr + (CyTDR << index), 0x81); | 628 | cyy_writeb(info, CyTDR, 0x81); |
| 611 | info->breakon = 0; | 629 | info->breakon = 0; |
| 612 | char_count -= 2; | 630 | char_count -= 2; |
| 613 | } | 631 | } |
| 614 | if (info->breakoff) { | 632 | if (info->breakoff) { |
| 615 | cy_writeb(base_addr + (CyTDR << index), 0); | 633 | cyy_writeb(info, CyTDR, 0); |
| 616 | cy_writeb(base_addr + (CyTDR << index), 0x83); | 634 | cyy_writeb(info, CyTDR, 0x83); |
| 617 | info->breakoff = 0; | 635 | info->breakoff = 0; |
| 618 | char_count -= 2; | 636 | char_count -= 2; |
| 619 | } | 637 | } |
| @@ -621,27 +639,23 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | |||
| 621 | 639 | ||
| 622 | while (char_count-- > 0) { | 640 | while (char_count-- > 0) { |
| 623 | if (!info->xmit_cnt) { | 641 | if (!info->xmit_cnt) { |
| 624 | if (readb(base_addr + (CySRER << index)) & CyTxMpty) { | 642 | if (cyy_readb(info, CySRER) & CyTxMpty) { |
| 625 | cy_writeb(base_addr + (CySRER << index), | 643 | cyy_writeb(info, CySRER, |
| 626 | readb(base_addr + (CySRER << index)) & | 644 | cyy_readb(info, CySRER) & ~CyTxMpty); |
| 627 | ~CyTxMpty); | ||
| 628 | } else { | 645 | } else { |
| 629 | cy_writeb(base_addr + (CySRER << index), | 646 | cyy_writeb(info, CySRER, CyTxMpty | |
| 630 | (readb(base_addr + (CySRER << index)) & | 647 | (cyy_readb(info, CySRER) & ~CyTxRdy)); |
| 631 | ~CyTxRdy) | CyTxMpty); | ||
| 632 | } | 648 | } |
| 633 | goto done; | 649 | goto done; |
| 634 | } | 650 | } |
| 635 | if (info->port.xmit_buf == NULL) { | 651 | if (info->port.xmit_buf == NULL) { |
| 636 | cy_writeb(base_addr + (CySRER << index), | 652 | cyy_writeb(info, CySRER, |
| 637 | readb(base_addr + (CySRER << index)) & | 653 | cyy_readb(info, CySRER) & ~CyTxRdy); |
| 638 | ~CyTxRdy); | ||
| 639 | goto done; | 654 | goto done; |
| 640 | } | 655 | } |
| 641 | if (tty->stopped || tty->hw_stopped) { | 656 | if (tty->stopped || tty->hw_stopped) { |
| 642 | cy_writeb(base_addr + (CySRER << index), | 657 | cyy_writeb(info, CySRER, |
| 643 | readb(base_addr + (CySRER << index)) & | 658 | cyy_readb(info, CySRER) & ~CyTxRdy); |
| 644 | ~CyTxRdy); | ||
| 645 | goto done; | 659 | goto done; |
| 646 | } | 660 | } |
| 647 | /* Because the Embedded Transmit Commands have been enabled, | 661 | /* Because the Embedded Transmit Commands have been enabled, |
| @@ -658,15 +672,15 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | |||
| 658 | info->xmit_cnt--; | 672 | info->xmit_cnt--; |
| 659 | info->xmit_tail = (info->xmit_tail + 1) & | 673 | info->xmit_tail = (info->xmit_tail + 1) & |
| 660 | (SERIAL_XMIT_SIZE - 1); | 674 | (SERIAL_XMIT_SIZE - 1); |
| 661 | cy_writeb(base_addr + (CyTDR << index), outch); | 675 | cyy_writeb(info, CyTDR, outch); |
| 662 | info->icount.tx++; | 676 | info->icount.tx++; |
| 663 | } else { | 677 | } else { |
| 664 | if (char_count > 1) { | 678 | if (char_count > 1) { |
| 665 | info->xmit_cnt--; | 679 | info->xmit_cnt--; |
| 666 | info->xmit_tail = (info->xmit_tail + 1) & | 680 | info->xmit_tail = (info->xmit_tail + 1) & |
| 667 | (SERIAL_XMIT_SIZE - 1); | 681 | (SERIAL_XMIT_SIZE - 1); |
| 668 | cy_writeb(base_addr + (CyTDR << index), outch); | 682 | cyy_writeb(info, CyTDR, outch); |
| 669 | cy_writeb(base_addr + (CyTDR << index), 0); | 683 | cyy_writeb(info, CyTDR, 0); |
| 670 | info->icount.tx++; | 684 | info->icount.tx++; |
| 671 | char_count--; | 685 | char_count--; |
| 672 | } | 686 | } |
| @@ -678,8 +692,8 @@ done: | |||
| 678 | tty_kref_put(tty); | 692 | tty_kref_put(tty); |
| 679 | end: | 693 | end: |
| 680 | /* end of service */ | 694 | /* end of service */ |
| 681 | cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); | 695 | cyy_writeb(info, CyTIR, save_xir & 0x3f); |
| 682 | cy_writeb(base_addr + (CyCAR << index), save_car); | 696 | cyy_writeb(info, CyCAR, save_car); |
| 683 | } | 697 | } |
| 684 | 698 | ||
| 685 | static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | 699 | static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, |
| @@ -694,11 +708,11 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
| 694 | save_xir = readb(base_addr + (CyMIR << index)); | 708 | save_xir = readb(base_addr + (CyMIR << index)); |
| 695 | channel = save_xir & CyIRChannel; | 709 | channel = save_xir & CyIRChannel; |
| 696 | info = &cinfo->ports[channel + chip * 4]; | 710 | info = &cinfo->ports[channel + chip * 4]; |
| 697 | save_car = readb(base_addr + (CyCAR << index)); | 711 | save_car = cyy_readb(info, CyCAR); |
| 698 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 712 | cyy_writeb(info, CyCAR, save_xir); |
| 699 | 713 | ||
| 700 | mdm_change = readb(base_addr + (CyMISR << index)); | 714 | mdm_change = cyy_readb(info, CyMISR); |
| 701 | mdm_status = readb(base_addr + (CyMSVR1 << index)); | 715 | mdm_status = cyy_readb(info, CyMSVR1); |
| 702 | 716 | ||
| 703 | tty = tty_port_tty_get(&info->port); | 717 | tty = tty_port_tty_get(&info->port); |
| 704 | if (!tty) | 718 | if (!tty) |
| @@ -730,9 +744,8 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
| 730 | /* cy_start isn't used | 744 | /* cy_start isn't used |
| 731 | because... !!! */ | 745 | because... !!! */ |
| 732 | tty->hw_stopped = 0; | 746 | tty->hw_stopped = 0; |
| 733 | cy_writeb(base_addr + (CySRER << index), | 747 | cyy_writeb(info, CySRER, |
| 734 | readb(base_addr + (CySRER << index)) | | 748 | cyy_readb(info, CySRER) | CyTxRdy); |
| 735 | CyTxRdy); | ||
| 736 | tty_wakeup(tty); | 749 | tty_wakeup(tty); |
| 737 | } | 750 | } |
| 738 | } else { | 751 | } else { |
| @@ -740,9 +753,8 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
| 740 | /* cy_stop isn't used | 753 | /* cy_stop isn't used |
| 741 | because ... !!! */ | 754 | because ... !!! */ |
| 742 | tty->hw_stopped = 1; | 755 | tty->hw_stopped = 1; |
| 743 | cy_writeb(base_addr + (CySRER << index), | 756 | cyy_writeb(info, CySRER, |
| 744 | readb(base_addr + (CySRER << index)) & | 757 | cyy_readb(info, CySRER) & ~CyTxRdy); |
| 745 | ~CyTxRdy); | ||
| 746 | } | 758 | } |
| 747 | } | 759 | } |
| 748 | } | 760 | } |
| @@ -753,8 +765,8 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
| 753 | tty_kref_put(tty); | 765 | tty_kref_put(tty); |
| 754 | end: | 766 | end: |
| 755 | /* end of service */ | 767 | /* end of service */ |
| 756 | cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f); | 768 | cyy_writeb(info, CyMIR, save_xir & 0x3f); |
| 757 | cy_writeb(base_addr + (CyCAR << index), save_car); | 769 | cyy_writeb(info, CyCAR, save_car); |
| 758 | } | 770 | } |
| 759 | 771 | ||
| 760 | /* The real interrupt service routine is called | 772 | /* The real interrupt service routine is called |
| @@ -829,15 +841,10 @@ static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set, | |||
| 829 | unsigned int clear) | 841 | unsigned int clear) |
| 830 | { | 842 | { |
| 831 | struct cyclades_card *card = info->card; | 843 | struct cyclades_card *card = info->card; |
| 832 | void __iomem *base_addr; | 844 | int channel = info->line - card->first_line; |
| 833 | int chip, channel, index; | ||
| 834 | u32 rts, dtr, msvrr, msvrd; | 845 | u32 rts, dtr, msvrr, msvrd; |
| 835 | 846 | ||
| 836 | channel = info->line - card->first_line; | ||
| 837 | chip = channel >> 2; | ||
| 838 | channel &= 0x03; | 847 | channel &= 0x03; |
| 839 | index = card->bus_index; | ||
| 840 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 841 | 848 | ||
| 842 | if (info->rtsdtr_inv) { | 849 | if (info->rtsdtr_inv) { |
| 843 | msvrr = CyMSVR2; | 850 | msvrr = CyMSVR2; |
| @@ -851,31 +858,31 @@ static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set, | |||
| 851 | dtr = CyDTR; | 858 | dtr = CyDTR; |
| 852 | } | 859 | } |
| 853 | if (set & TIOCM_RTS) { | 860 | if (set & TIOCM_RTS) { |
| 854 | cy_writeb(base_addr + (CyCAR << index), (u8)channel); | 861 | cyy_writeb(info, CyCAR, channel); |
| 855 | cy_writeb(base_addr + (msvrr << index), rts); | 862 | cyy_writeb(info, msvrr, rts); |
| 856 | } | 863 | } |
| 857 | if (clear & TIOCM_RTS) { | 864 | if (clear & TIOCM_RTS) { |
| 858 | cy_writeb(base_addr + (CyCAR << index), (u8)channel); | 865 | cyy_writeb(info, CyCAR, channel); |
| 859 | cy_writeb(base_addr + (msvrr << index), ~rts); | 866 | cyy_writeb(info, msvrr, ~rts); |
| 860 | } | 867 | } |
| 861 | if (set & TIOCM_DTR) { | 868 | if (set & TIOCM_DTR) { |
| 862 | cy_writeb(base_addr + (CyCAR << index), (u8)channel); | 869 | cyy_writeb(info, CyCAR, channel); |
| 863 | cy_writeb(base_addr + (msvrd << index), dtr); | 870 | cyy_writeb(info, msvrd, dtr); |
| 864 | #ifdef CY_DEBUG_DTR | 871 | #ifdef CY_DEBUG_DTR |
| 865 | printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); | 872 | printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); |
| 866 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", | 873 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
| 867 | readb(base_addr + (CyMSVR1 << index)), | 874 | cyy_readb(info, CyMSVR1), |
| 868 | readb(base_addr + (CyMSVR2 << index))); | 875 | cyy_readb(info, CyMSVR2)); |
| 869 | #endif | 876 | #endif |
| 870 | } | 877 | } |
| 871 | if (clear & TIOCM_DTR) { | 878 | if (clear & TIOCM_DTR) { |
| 872 | cy_writeb(base_addr + (CyCAR << index), (u8)channel); | 879 | cyy_writeb(info, CyCAR, channel); |
| 873 | cy_writeb(base_addr + (msvrd << index), ~dtr); | 880 | cyy_writeb(info, msvrd, ~dtr); |
| 874 | #ifdef CY_DEBUG_DTR | 881 | #ifdef CY_DEBUG_DTR |
| 875 | printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); | 882 | printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); |
| 876 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", | 883 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
| 877 | readb(base_addr + (CyMSVR1 << index)), | 884 | cyy_readb(info, CyMSVR1), |
| 878 | readb(base_addr + (CyMSVR2 << index))); | 885 | cyy_readb(info, CyMSVR2)); |
| 879 | #endif | 886 | #endif |
| 880 | } | 887 | } |
| 881 | } | 888 | } |
| @@ -1290,7 +1297,6 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1290 | struct cyclades_card *card; | 1297 | struct cyclades_card *card; |
| 1291 | unsigned long flags; | 1298 | unsigned long flags; |
| 1292 | int retval = 0; | 1299 | int retval = 0; |
| 1293 | void __iomem *base_addr; | ||
| 1294 | int channel; | 1300 | int channel; |
| 1295 | unsigned long page; | 1301 | unsigned long page; |
| 1296 | 1302 | ||
| @@ -1321,31 +1327,21 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1321 | cy_set_line_char(info, tty); | 1327 | cy_set_line_char(info, tty); |
| 1322 | 1328 | ||
| 1323 | if (!cy_is_Z(card)) { | 1329 | if (!cy_is_Z(card)) { |
| 1324 | int chip = channel >> 2; | ||
| 1325 | int index = card->bus_index; | ||
| 1326 | channel &= 0x03; | 1330 | channel &= 0x03; |
| 1327 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 1328 | 1331 | ||
| 1329 | #ifdef CY_DEBUG_OPEN | ||
| 1330 | printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, " | ||
| 1331 | "base_addr %p\n", | ||
| 1332 | card, chip, channel, base_addr); | ||
| 1333 | #endif | ||
| 1334 | spin_lock_irqsave(&card->card_lock, flags); | 1332 | spin_lock_irqsave(&card->card_lock, flags); |
| 1335 | 1333 | ||
| 1336 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 1334 | cyy_writeb(info, CyCAR, channel); |
| 1337 | 1335 | ||
| 1338 | cy_writeb(base_addr + (CyRTPR << index), | 1336 | cyy_writeb(info, CyRTPR, |
| 1339 | (info->default_timeout ? info->default_timeout : 0x02)); | 1337 | (info->default_timeout ? info->default_timeout : 0x02)); |
| 1340 | /* 10ms rx timeout */ | 1338 | /* 10ms rx timeout */ |
| 1341 | 1339 | ||
| 1342 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR, | 1340 | cyy_issue_cmd(info, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR); |
| 1343 | index); | ||
| 1344 | 1341 | ||
| 1345 | cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0); | 1342 | cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0); |
| 1346 | 1343 | ||
| 1347 | cy_writeb(base_addr + (CySRER << index), | 1344 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyRxData); |
| 1348 | readb(base_addr + (CySRER << index)) | CyRxData); | ||
| 1349 | } else { | 1345 | } else { |
| 1350 | struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; | 1346 | struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; |
| 1351 | 1347 | ||
| @@ -1423,23 +1419,14 @@ errout: | |||
| 1423 | 1419 | ||
| 1424 | static void start_xmit(struct cyclades_port *info) | 1420 | static void start_xmit(struct cyclades_port *info) |
| 1425 | { | 1421 | { |
| 1426 | struct cyclades_card *card; | 1422 | struct cyclades_card *card = info->card; |
| 1427 | unsigned long flags; | 1423 | unsigned long flags; |
| 1428 | void __iomem *base_addr; | 1424 | int channel = info->line - card->first_line; |
| 1429 | int chip, channel, index; | ||
| 1430 | 1425 | ||
| 1431 | card = info->card; | ||
| 1432 | channel = info->line - card->first_line; | ||
| 1433 | if (!cy_is_Z(card)) { | 1426 | if (!cy_is_Z(card)) { |
| 1434 | chip = channel >> 2; | ||
| 1435 | channel &= 0x03; | ||
| 1436 | index = card->bus_index; | ||
| 1437 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 1438 | |||
| 1439 | spin_lock_irqsave(&card->card_lock, flags); | 1427 | spin_lock_irqsave(&card->card_lock, flags); |
| 1440 | cy_writeb(base_addr + (CyCAR << index), channel); | 1428 | cyy_writeb(info, CyCAR, channel & 0x03); |
| 1441 | cy_writeb(base_addr + (CySRER << index), | 1429 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy); |
| 1442 | readb(base_addr + (CySRER << index)) | CyTxRdy); | ||
| 1443 | spin_unlock_irqrestore(&card->card_lock, flags); | 1430 | spin_unlock_irqrestore(&card->card_lock, flags); |
| 1444 | } else { | 1431 | } else { |
| 1445 | #ifdef CONFIG_CYZ_INTR | 1432 | #ifdef CONFIG_CYZ_INTR |
| @@ -1466,8 +1453,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1466 | { | 1453 | { |
| 1467 | struct cyclades_card *card; | 1454 | struct cyclades_card *card; |
| 1468 | unsigned long flags; | 1455 | unsigned long flags; |
| 1469 | void __iomem *base_addr; | 1456 | int channel; |
| 1470 | int chip, channel, index; | ||
| 1471 | 1457 | ||
| 1472 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1458 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
| 1473 | return; | 1459 | return; |
| @@ -1475,17 +1461,6 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1475 | card = info->card; | 1461 | card = info->card; |
| 1476 | channel = info->line - card->first_line; | 1462 | channel = info->line - card->first_line; |
| 1477 | if (!cy_is_Z(card)) { | 1463 | if (!cy_is_Z(card)) { |
| 1478 | chip = channel >> 2; | ||
| 1479 | channel &= 0x03; | ||
| 1480 | index = card->bus_index; | ||
| 1481 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 1482 | |||
| 1483 | #ifdef CY_DEBUG_OPEN | ||
| 1484 | printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, " | ||
| 1485 | "channel %d, base_addr %p\n", | ||
| 1486 | card, chip, channel, base_addr); | ||
| 1487 | #endif | ||
| 1488 | |||
| 1489 | spin_lock_irqsave(&card->card_lock, flags); | 1464 | spin_lock_irqsave(&card->card_lock, flags); |
| 1490 | 1465 | ||
| 1491 | /* Clear delta_msr_wait queue to avoid mem leaks. */ | 1466 | /* Clear delta_msr_wait queue to avoid mem leaks. */ |
| @@ -1500,7 +1475,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1500 | if (tty->termios->c_cflag & HUPCL) | 1475 | if (tty->termios->c_cflag & HUPCL) |
| 1501 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); | 1476 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); |
| 1502 | 1477 | ||
| 1503 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); | 1478 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); |
| 1504 | /* it may be appropriate to clear _XMIT at | 1479 | /* it may be appropriate to clear _XMIT at |
| 1505 | some later date (after testing)!!! */ | 1480 | some later date (after testing)!!! */ |
| 1506 | 1481 | ||
| @@ -1677,8 +1652,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
| 1677 | { | 1652 | { |
| 1678 | struct cyclades_card *card; | 1653 | struct cyclades_card *card; |
| 1679 | struct cyclades_port *info = tty->driver_data; | 1654 | struct cyclades_port *info = tty->driver_data; |
| 1680 | void __iomem *base_addr; | ||
| 1681 | int chip, channel, index; | ||
| 1682 | unsigned long orig_jiffies; | 1655 | unsigned long orig_jiffies; |
| 1683 | int char_time; | 1656 | int char_time; |
| 1684 | 1657 | ||
| @@ -1722,13 +1695,8 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
| 1722 | timeout, char_time, jiffies); | 1695 | timeout, char_time, jiffies); |
| 1723 | #endif | 1696 | #endif |
| 1724 | card = info->card; | 1697 | card = info->card; |
| 1725 | channel = (info->line) - (card->first_line); | ||
| 1726 | if (!cy_is_Z(card)) { | 1698 | if (!cy_is_Z(card)) { |
| 1727 | chip = channel >> 2; | 1699 | while (cyy_readb(info, CySRER) & CyTxRdy) { |
| 1728 | channel &= 0x03; | ||
| 1729 | index = card->bus_index; | ||
| 1730 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 1731 | while (readb(base_addr + (CySRER << index)) & CyTxRdy) { | ||
| 1732 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 1700 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
| 1733 | printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); | 1701 | printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); |
| 1734 | #endif | 1702 | #endif |
| @@ -1790,6 +1758,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
| 1790 | struct cyclades_port *info = tty->driver_data; | 1758 | struct cyclades_port *info = tty->driver_data; |
| 1791 | struct cyclades_card *card; | 1759 | struct cyclades_card *card; |
| 1792 | unsigned long flags; | 1760 | unsigned long flags; |
| 1761 | int channel; | ||
| 1793 | 1762 | ||
| 1794 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) | 1763 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) |
| 1795 | return; | 1764 | return; |
| @@ -1799,18 +1768,13 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
| 1799 | if (!tty_port_close_start(&info->port, tty, filp)) | 1768 | if (!tty_port_close_start(&info->port, tty, filp)) |
| 1800 | return; | 1769 | return; |
| 1801 | 1770 | ||
| 1771 | channel = info->line - card->first_line; | ||
| 1802 | spin_lock_irqsave(&card->card_lock, flags); | 1772 | spin_lock_irqsave(&card->card_lock, flags); |
| 1803 | 1773 | ||
| 1804 | if (!cy_is_Z(card)) { | 1774 | if (!cy_is_Z(card)) { |
| 1805 | int channel = info->line - card->first_line; | ||
| 1806 | int index = card->bus_index; | ||
| 1807 | void __iomem *base_addr = card->base_addr + | ||
| 1808 | (cy_chip_offset[channel >> 2] << index); | ||
| 1809 | /* Stop accepting input */ | 1775 | /* Stop accepting input */ |
| 1810 | channel &= 0x03; | 1776 | cyy_writeb(info, CyCAR, channel & 0x03); |
| 1811 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 1777 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData); |
| 1812 | cy_writeb(base_addr + (CySRER << index), | ||
| 1813 | readb(base_addr + (CySRER << index)) & ~CyRxData); | ||
| 1814 | if (info->port.flags & ASYNC_INITIALIZED) { | 1778 | if (info->port.flags & ASYNC_INITIALIZED) { |
| 1815 | /* Waiting for on-board buffers to be empty before | 1779 | /* Waiting for on-board buffers to be empty before |
| 1816 | closing the port */ | 1780 | closing the port */ |
| @@ -1823,7 +1787,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
| 1823 | /* Waiting for on-board buffers to be empty before closing | 1787 | /* Waiting for on-board buffers to be empty before closing |
| 1824 | the port */ | 1788 | the port */ |
| 1825 | struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; | 1789 | struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; |
| 1826 | int channel = info->line - card->first_line; | ||
| 1827 | int retval; | 1790 | int retval; |
| 1828 | 1791 | ||
| 1829 | if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) { | 1792 | if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) { |
| @@ -2064,8 +2027,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
| 2064 | { | 2027 | { |
| 2065 | struct cyclades_card *card; | 2028 | struct cyclades_card *card; |
| 2066 | unsigned long flags; | 2029 | unsigned long flags; |
| 2067 | void __iomem *base_addr; | 2030 | int channel; |
| 2068 | int chip, channel, index; | ||
| 2069 | unsigned cflag, iflag; | 2031 | unsigned cflag, iflag; |
| 2070 | int baud, baud_rate = 0; | 2032 | int baud, baud_rate = 0; |
| 2071 | int i; | 2033 | int i; |
| @@ -2095,9 +2057,6 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
| 2095 | channel = info->line - card->first_line; | 2057 | channel = info->line - card->first_line; |
| 2096 | 2058 | ||
| 2097 | if (!cy_is_Z(card)) { | 2059 | if (!cy_is_Z(card)) { |
| 2098 | |||
| 2099 | index = card->bus_index; | ||
| 2100 | |||
| 2101 | /* baud rate */ | 2060 | /* baud rate */ |
| 2102 | baud = tty_get_baud_rate(tty); | 2061 | baud = tty_get_baud_rate(tty); |
| 2103 | if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == | 2062 | if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == |
| @@ -2208,70 +2167,67 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
| 2208 | cable. Contact Marcio Saito for details. | 2167 | cable. Contact Marcio Saito for details. |
| 2209 | ***********************************************/ | 2168 | ***********************************************/ |
| 2210 | 2169 | ||
| 2211 | chip = channel >> 2; | ||
| 2212 | channel &= 0x03; | 2170 | channel &= 0x03; |
| 2213 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2214 | 2171 | ||
| 2215 | spin_lock_irqsave(&card->card_lock, flags); | 2172 | spin_lock_irqsave(&card->card_lock, flags); |
| 2216 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 2173 | cyy_writeb(info, CyCAR, channel); |
| 2217 | 2174 | ||
| 2218 | /* tx and rx baud rate */ | 2175 | /* tx and rx baud rate */ |
| 2219 | 2176 | ||
| 2220 | cy_writeb(base_addr + (CyTCOR << index), info->tco); | 2177 | cyy_writeb(info, CyTCOR, info->tco); |
| 2221 | cy_writeb(base_addr + (CyTBPR << index), info->tbpr); | 2178 | cyy_writeb(info, CyTBPR, info->tbpr); |
| 2222 | cy_writeb(base_addr + (CyRCOR << index), info->rco); | 2179 | cyy_writeb(info, CyRCOR, info->rco); |
| 2223 | cy_writeb(base_addr + (CyRBPR << index), info->rbpr); | 2180 | cyy_writeb(info, CyRBPR, info->rbpr); |
| 2224 | 2181 | ||
| 2225 | /* set line characteristics according configuration */ | 2182 | /* set line characteristics according configuration */ |
| 2226 | 2183 | ||
| 2227 | cy_writeb(base_addr + (CySCHR1 << index), START_CHAR(tty)); | 2184 | cyy_writeb(info, CySCHR1, START_CHAR(tty)); |
| 2228 | cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(tty)); | 2185 | cyy_writeb(info, CySCHR2, STOP_CHAR(tty)); |
| 2229 | cy_writeb(base_addr + (CyCOR1 << index), info->cor1); | 2186 | cyy_writeb(info, CyCOR1, info->cor1); |
| 2230 | cy_writeb(base_addr + (CyCOR2 << index), info->cor2); | 2187 | cyy_writeb(info, CyCOR2, info->cor2); |
| 2231 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); | 2188 | cyy_writeb(info, CyCOR3, info->cor3); |
| 2232 | cy_writeb(base_addr + (CyCOR4 << index), info->cor4); | 2189 | cyy_writeb(info, CyCOR4, info->cor4); |
| 2233 | cy_writeb(base_addr + (CyCOR5 << index), info->cor5); | 2190 | cyy_writeb(info, CyCOR5, info->cor5); |
| 2234 | 2191 | ||
| 2235 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | | 2192 | cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | |
| 2236 | CyCOR3ch, index); | 2193 | CyCOR3ch); |
| 2237 | 2194 | ||
| 2238 | /* !!! Is this needed? */ | 2195 | /* !!! Is this needed? */ |
| 2239 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 2196 | cyy_writeb(info, CyCAR, channel); |
| 2240 | cy_writeb(base_addr + (CyRTPR << index), | 2197 | cyy_writeb(info, CyRTPR, |
| 2241 | (info->default_timeout ? info->default_timeout : 0x02)); | 2198 | (info->default_timeout ? info->default_timeout : 0x02)); |
| 2242 | /* 10ms rx timeout */ | 2199 | /* 10ms rx timeout */ |
| 2243 | 2200 | ||
| 2244 | if (C_CLOCAL(tty)) { | 2201 | if (C_CLOCAL(tty)) { |
| 2245 | /* without modem intr */ | 2202 | /* without modem intr */ |
| 2246 | cy_writeb(base_addr + (CySRER << index), | 2203 | cyy_writeb(info, CySRER, |
| 2247 | readb(base_addr + (CySRER << index)) | CyMdmCh); | 2204 | cyy_readb(info, CySRER) | CyMdmCh); |
| 2248 | /* act on 1->0 modem transitions */ | 2205 | /* act on 1->0 modem transitions */ |
| 2249 | if ((cflag & CRTSCTS) && info->rflow) { | 2206 | if ((cflag & CRTSCTS) && info->rflow) { |
| 2250 | cy_writeb(base_addr + (CyMCOR1 << index), | 2207 | cyy_writeb(info, CyMCOR1, |
| 2251 | (CyCTS | rflow_thr[i])); | 2208 | (CyCTS | rflow_thr[i])); |
| 2252 | } else { | 2209 | } else { |
| 2253 | cy_writeb(base_addr + (CyMCOR1 << index), | 2210 | cyy_writeb(info, CyMCOR1, |
| 2254 | CyCTS); | 2211 | CyCTS); |
| 2255 | } | 2212 | } |
| 2256 | /* act on 0->1 modem transitions */ | 2213 | /* act on 0->1 modem transitions */ |
| 2257 | cy_writeb(base_addr + (CyMCOR2 << index), CyCTS); | 2214 | cyy_writeb(info, CyMCOR2, CyCTS); |
| 2258 | } else { | 2215 | } else { |
| 2259 | /* without modem intr */ | 2216 | /* without modem intr */ |
| 2260 | cy_writeb(base_addr + (CySRER << index), | 2217 | cyy_writeb(info, CySRER, |
| 2261 | readb(base_addr + | 2218 | cyy_readb(info, CySRER) | CyMdmCh); |
| 2262 | (CySRER << index)) | CyMdmCh); | ||
| 2263 | /* act on 1->0 modem transitions */ | 2219 | /* act on 1->0 modem transitions */ |
| 2264 | if ((cflag & CRTSCTS) && info->rflow) { | 2220 | if ((cflag & CRTSCTS) && info->rflow) { |
| 2265 | cy_writeb(base_addr + (CyMCOR1 << index), | 2221 | cyy_writeb(info, CyMCOR1, |
| 2266 | (CyDSR | CyCTS | CyRI | CyDCD | | 2222 | (CyDSR | CyCTS | CyRI | CyDCD | |
| 2267 | rflow_thr[i])); | 2223 | rflow_thr[i])); |
| 2268 | } else { | 2224 | } else { |
| 2269 | cy_writeb(base_addr + (CyMCOR1 << index), | 2225 | cyy_writeb(info, CyMCOR1, |
| 2270 | CyDSR | CyCTS | CyRI | CyDCD); | 2226 | CyDSR | CyCTS | CyRI | CyDCD); |
| 2271 | } | 2227 | } |
| 2272 | /* act on 0->1 modem transitions */ | 2228 | /* act on 0->1 modem transitions */ |
| 2273 | cy_writeb(base_addr + (CyMCOR2 << index), | 2229 | cyy_writeb(info, CyMCOR2, |
| 2274 | CyDSR | CyCTS | CyRI | CyDCD); | 2230 | CyDSR | CyCTS | CyRI | CyDCD); |
| 2275 | } | 2231 | } |
| 2276 | 2232 | ||
| 2277 | if (i == 0) /* baud rate is zero, turn off line */ | 2233 | if (i == 0) /* baud rate is zero, turn off line */ |
| @@ -2482,24 +2438,14 @@ check_and_exit: | |||
| 2482 | */ | 2438 | */ |
| 2483 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) | 2439 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) |
| 2484 | { | 2440 | { |
| 2485 | struct cyclades_card *card; | 2441 | struct cyclades_card *card = info->card; |
| 2486 | int chip, channel, index; | ||
| 2487 | unsigned char status; | ||
| 2488 | unsigned int result; | 2442 | unsigned int result; |
| 2489 | unsigned long flags; | 2443 | unsigned long flags; |
| 2490 | void __iomem *base_addr; | 2444 | u8 status; |
| 2491 | 2445 | ||
| 2492 | card = info->card; | ||
| 2493 | channel = (info->line) - (card->first_line); | ||
| 2494 | if (!cy_is_Z(card)) { | 2446 | if (!cy_is_Z(card)) { |
| 2495 | chip = channel >> 2; | ||
| 2496 | channel &= 0x03; | ||
| 2497 | index = card->bus_index; | ||
| 2498 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2499 | |||
| 2500 | spin_lock_irqsave(&card->card_lock, flags); | 2447 | spin_lock_irqsave(&card->card_lock, flags); |
| 2501 | status = readb(base_addr + (CySRER << index)) & | 2448 | status = cyy_readb(info, CySRER) & (CyTxRdy | CyTxMpty); |
| 2502 | (CyTxRdy | CyTxMpty); | ||
| 2503 | spin_unlock_irqrestore(&card->card_lock, flags); | 2449 | spin_unlock_irqrestore(&card->card_lock, flags); |
| 2504 | result = (status ? 0 : TIOCSER_TEMT); | 2450 | result = (status ? 0 : TIOCSER_TEMT); |
| 2505 | } else { | 2451 | } else { |
| @@ -2513,29 +2459,23 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
| 2513 | { | 2459 | { |
| 2514 | struct cyclades_port *info = tty->driver_data; | 2460 | struct cyclades_port *info = tty->driver_data; |
| 2515 | struct cyclades_card *card; | 2461 | struct cyclades_card *card; |
| 2516 | void __iomem *base_addr; | 2462 | int result; |
| 2517 | int result, channel; | ||
| 2518 | 2463 | ||
| 2519 | if (serial_paranoia_check(info, tty->name, __func__)) | 2464 | if (serial_paranoia_check(info, tty->name, __func__)) |
| 2520 | return -ENODEV; | 2465 | return -ENODEV; |
| 2521 | 2466 | ||
| 2522 | card = info->card; | 2467 | card = info->card; |
| 2523 | channel = info->line - card->first_line; | ||
| 2524 | 2468 | ||
| 2525 | lock_kernel(); | 2469 | lock_kernel(); |
| 2526 | if (!cy_is_Z(card)) { | 2470 | if (!cy_is_Z(card)) { |
| 2527 | unsigned long flags; | 2471 | unsigned long flags; |
| 2528 | unsigned char status; | 2472 | int channel = info->line - card->first_line; |
| 2529 | int chip = channel >> 2; | 2473 | u8 status; |
| 2530 | int index = card->bus_index; | ||
| 2531 | |||
| 2532 | channel &= 0x03; | ||
| 2533 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2534 | 2474 | ||
| 2535 | spin_lock_irqsave(&card->card_lock, flags); | 2475 | spin_lock_irqsave(&card->card_lock, flags); |
| 2536 | cy_writeb(base_addr + (CyCAR << index), (u8)channel); | 2476 | cyy_writeb(info, CyCAR, channel & 0x03); |
| 2537 | status = readb(base_addr + (CyMSVR1 << index)); | 2477 | status = cyy_readb(info, CyMSVR1); |
| 2538 | status |= readb(base_addr + (CyMSVR2 << index)); | 2478 | status |= cyy_readb(info, CyMSVR2); |
| 2539 | spin_unlock_irqrestore(&card->card_lock, flags); | 2479 | spin_unlock_irqrestore(&card->card_lock, flags); |
| 2540 | 2480 | ||
| 2541 | if (info->rtsdtr_inv) { | 2481 | if (info->rtsdtr_inv) { |
| @@ -2689,26 +2629,16 @@ static int cy_break(struct tty_struct *tty, int break_state) | |||
| 2689 | 2629 | ||
| 2690 | static int set_threshold(struct cyclades_port *info, unsigned long value) | 2630 | static int set_threshold(struct cyclades_port *info, unsigned long value) |
| 2691 | { | 2631 | { |
| 2692 | struct cyclades_card *card; | 2632 | struct cyclades_card *card = info->card; |
| 2693 | void __iomem *base_addr; | ||
| 2694 | int channel, chip, index; | ||
| 2695 | unsigned long flags; | 2633 | unsigned long flags; |
| 2696 | 2634 | ||
| 2697 | card = info->card; | ||
| 2698 | channel = info->line - card->first_line; | ||
| 2699 | if (!cy_is_Z(card)) { | 2635 | if (!cy_is_Z(card)) { |
| 2700 | chip = channel >> 2; | ||
| 2701 | channel &= 0x03; | ||
| 2702 | index = card->bus_index; | ||
| 2703 | base_addr = | ||
| 2704 | card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2705 | |||
| 2706 | info->cor3 &= ~CyREC_FIFO; | 2636 | info->cor3 &= ~CyREC_FIFO; |
| 2707 | info->cor3 |= value & CyREC_FIFO; | 2637 | info->cor3 |= value & CyREC_FIFO; |
| 2708 | 2638 | ||
| 2709 | spin_lock_irqsave(&card->card_lock, flags); | 2639 | spin_lock_irqsave(&card->card_lock, flags); |
| 2710 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); | 2640 | cyy_writeb(info, CyCOR3, info->cor3); |
| 2711 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); | 2641 | cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR3ch); |
| 2712 | spin_unlock_irqrestore(&card->card_lock, flags); | 2642 | spin_unlock_irqrestore(&card->card_lock, flags); |
| 2713 | } | 2643 | } |
| 2714 | return 0; | 2644 | return 0; |
| @@ -2717,20 +2647,10 @@ static int set_threshold(struct cyclades_port *info, unsigned long value) | |||
| 2717 | static int get_threshold(struct cyclades_port *info, | 2647 | static int get_threshold(struct cyclades_port *info, |
| 2718 | unsigned long __user *value) | 2648 | unsigned long __user *value) |
| 2719 | { | 2649 | { |
| 2720 | struct cyclades_card *card; | 2650 | struct cyclades_card *card = info->card; |
| 2721 | void __iomem *base_addr; | ||
| 2722 | int channel, chip, index; | ||
| 2723 | unsigned long tmp; | ||
| 2724 | 2651 | ||
| 2725 | card = info->card; | ||
| 2726 | channel = info->line - card->first_line; | ||
| 2727 | if (!cy_is_Z(card)) { | 2652 | if (!cy_is_Z(card)) { |
| 2728 | chip = channel >> 2; | 2653 | u8 tmp = cyy_readb(info, CyCOR3) & CyREC_FIFO; |
| 2729 | channel &= 0x03; | ||
| 2730 | index = card->bus_index; | ||
| 2731 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2732 | |||
| 2733 | tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; | ||
| 2734 | return put_user(tmp, value); | 2654 | return put_user(tmp, value); |
| 2735 | } | 2655 | } |
| 2736 | return 0; | 2656 | return 0; |
| @@ -2738,21 +2658,12 @@ static int get_threshold(struct cyclades_port *info, | |||
| 2738 | 2658 | ||
| 2739 | static int set_timeout(struct cyclades_port *info, unsigned long value) | 2659 | static int set_timeout(struct cyclades_port *info, unsigned long value) |
| 2740 | { | 2660 | { |
| 2741 | struct cyclades_card *card; | 2661 | struct cyclades_card *card = info->card; |
| 2742 | void __iomem *base_addr; | ||
| 2743 | int channel, chip, index; | ||
| 2744 | unsigned long flags; | 2662 | unsigned long flags; |
| 2745 | 2663 | ||
| 2746 | card = info->card; | ||
| 2747 | channel = info->line - card->first_line; | ||
| 2748 | if (!cy_is_Z(card)) { | 2664 | if (!cy_is_Z(card)) { |
| 2749 | chip = channel >> 2; | ||
| 2750 | channel &= 0x03; | ||
| 2751 | index = card->bus_index; | ||
| 2752 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2753 | |||
| 2754 | spin_lock_irqsave(&card->card_lock, flags); | 2665 | spin_lock_irqsave(&card->card_lock, flags); |
| 2755 | cy_writeb(base_addr + (CyRTPR << index), value & 0xff); | 2666 | cyy_writeb(info, CyRTPR, value & 0xff); |
| 2756 | spin_unlock_irqrestore(&card->card_lock, flags); | 2667 | spin_unlock_irqrestore(&card->card_lock, flags); |
| 2757 | } | 2668 | } |
| 2758 | return 0; | 2669 | return 0; |
| @@ -2761,20 +2672,10 @@ static int set_timeout(struct cyclades_port *info, unsigned long value) | |||
| 2761 | static int get_timeout(struct cyclades_port *info, | 2672 | static int get_timeout(struct cyclades_port *info, |
| 2762 | unsigned long __user *value) | 2673 | unsigned long __user *value) |
| 2763 | { | 2674 | { |
| 2764 | struct cyclades_card *card; | 2675 | struct cyclades_card *card = info->card; |
| 2765 | void __iomem *base_addr; | ||
| 2766 | int channel, chip, index; | ||
| 2767 | unsigned long tmp; | ||
| 2768 | 2676 | ||
| 2769 | card = info->card; | ||
| 2770 | channel = info->line - card->first_line; | ||
| 2771 | if (!cy_is_Z(card)) { | 2677 | if (!cy_is_Z(card)) { |
| 2772 | chip = channel >> 2; | 2678 | u8 tmp = cyy_readb(info, CyRTPR); |
| 2773 | channel &= 0x03; | ||
| 2774 | index = card->bus_index; | ||
| 2775 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); | ||
| 2776 | |||
| 2777 | tmp = readb(base_addr + (CyRTPR << index)); | ||
| 2778 | return put_user(tmp, value); | 2679 | return put_user(tmp, value); |
| 2779 | } | 2680 | } |
| 2780 | return 0; | 2681 | return 0; |
| @@ -3101,8 +3002,7 @@ static void cy_stop(struct tty_struct *tty) | |||
| 3101 | { | 3002 | { |
| 3102 | struct cyclades_card *cinfo; | 3003 | struct cyclades_card *cinfo; |
| 3103 | struct cyclades_port *info = tty->driver_data; | 3004 | struct cyclades_port *info = tty->driver_data; |
| 3104 | void __iomem *base_addr; | 3005 | int channel; |
| 3105 | int chip, channel, index; | ||
| 3106 | unsigned long flags; | 3006 | unsigned long flags; |
| 3107 | 3007 | ||
| 3108 | #ifdef CY_DEBUG_OTHER | 3008 | #ifdef CY_DEBUG_OTHER |
| @@ -3115,16 +3015,9 @@ static void cy_stop(struct tty_struct *tty) | |||
| 3115 | cinfo = info->card; | 3015 | cinfo = info->card; |
| 3116 | channel = info->line - cinfo->first_line; | 3016 | channel = info->line - cinfo->first_line; |
| 3117 | if (!cy_is_Z(cinfo)) { | 3017 | if (!cy_is_Z(cinfo)) { |
| 3118 | index = cinfo->bus_index; | ||
| 3119 | chip = channel >> 2; | ||
| 3120 | channel &= 0x03; | ||
| 3121 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); | ||
| 3122 | |||
| 3123 | spin_lock_irqsave(&cinfo->card_lock, flags); | 3018 | spin_lock_irqsave(&cinfo->card_lock, flags); |
| 3124 | cy_writeb(base_addr + (CyCAR << index), | 3019 | cyy_writeb(info, CyCAR, channel & 0x03); |
| 3125 | (u_char)(channel & 0x0003)); /* index channel */ | 3020 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy); |
| 3126 | cy_writeb(base_addr + (CySRER << index), | ||
| 3127 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); | ||
| 3128 | spin_unlock_irqrestore(&cinfo->card_lock, flags); | 3021 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
| 3129 | } | 3022 | } |
| 3130 | } /* cy_stop */ | 3023 | } /* cy_stop */ |
| @@ -3133,8 +3026,7 @@ static void cy_start(struct tty_struct *tty) | |||
| 3133 | { | 3026 | { |
| 3134 | struct cyclades_card *cinfo; | 3027 | struct cyclades_card *cinfo; |
| 3135 | struct cyclades_port *info = tty->driver_data; | 3028 | struct cyclades_port *info = tty->driver_data; |
| 3136 | void __iomem *base_addr; | 3029 | int channel; |
| 3137 | int chip, channel, index; | ||
| 3138 | unsigned long flags; | 3030 | unsigned long flags; |
| 3139 | 3031 | ||
| 3140 | #ifdef CY_DEBUG_OTHER | 3032 | #ifdef CY_DEBUG_OTHER |
| @@ -3146,17 +3038,10 @@ static void cy_start(struct tty_struct *tty) | |||
| 3146 | 3038 | ||
| 3147 | cinfo = info->card; | 3039 | cinfo = info->card; |
| 3148 | channel = info->line - cinfo->first_line; | 3040 | channel = info->line - cinfo->first_line; |
| 3149 | index = cinfo->bus_index; | ||
| 3150 | if (!cy_is_Z(cinfo)) { | 3041 | if (!cy_is_Z(cinfo)) { |
| 3151 | chip = channel >> 2; | ||
| 3152 | channel &= 0x03; | ||
| 3153 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); | ||
| 3154 | |||
| 3155 | spin_lock_irqsave(&cinfo->card_lock, flags); | 3042 | spin_lock_irqsave(&cinfo->card_lock, flags); |
| 3156 | cy_writeb(base_addr + (CyCAR << index), | 3043 | cyy_writeb(info, CyCAR, channel & 0x03); |
| 3157 | (u_char) (channel & 0x0003)); /* index channel */ | 3044 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy); |
| 3158 | cy_writeb(base_addr + (CySRER << index), | ||
| 3159 | readb(base_addr + (CySRER << index)) | CyTxRdy); | ||
| 3160 | spin_unlock_irqrestore(&cinfo->card_lock, flags); | 3045 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
| 3161 | } | 3046 | } |
| 3162 | } /* cy_start */ | 3047 | } /* cy_start */ |
| @@ -3185,18 +3070,13 @@ static int cyy_carrier_raised(struct tty_port *port) | |||
| 3185 | struct cyclades_port *info = container_of(port, struct cyclades_port, | 3070 | struct cyclades_port *info = container_of(port, struct cyclades_port, |
| 3186 | port); | 3071 | port); |
| 3187 | struct cyclades_card *cinfo = info->card; | 3072 | struct cyclades_card *cinfo = info->card; |
| 3188 | void __iomem *base = cinfo->base_addr; | ||
| 3189 | unsigned long flags; | 3073 | unsigned long flags; |
| 3190 | int channel = info->line - cinfo->first_line; | 3074 | int channel = info->line - cinfo->first_line; |
| 3191 | int chip = channel >> 2, index = cinfo->bus_index; | ||
| 3192 | u32 cd; | 3075 | u32 cd; |
| 3193 | 3076 | ||
| 3194 | channel &= 0x03; | ||
| 3195 | base += cy_chip_offset[chip] << index; | ||
| 3196 | |||
| 3197 | spin_lock_irqsave(&cinfo->card_lock, flags); | 3077 | spin_lock_irqsave(&cinfo->card_lock, flags); |
| 3198 | cy_writeb(base + (CyCAR << index), (u8)channel); | 3078 | cyy_writeb(info, CyCAR, channel & 0x03); |
| 3199 | cd = readb(base + (CyMSVR1 << index)) & CyDCD; | 3079 | cd = cyy_readb(info, CyMSVR1) & CyDCD; |
| 3200 | spin_unlock_irqrestore(&cinfo->card_lock, flags); | 3080 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
| 3201 | 3081 | ||
| 3202 | return cd; | 3082 | return cd; |
| @@ -3326,9 +3206,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
| 3326 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | 3206 | info->cor3 = 0x08; /* _very_ small rcv threshold */ |
| 3327 | 3207 | ||
| 3328 | chip_number = channel / CyPORTS_PER_CHIP; | 3208 | chip_number = channel / CyPORTS_PER_CHIP; |
| 3329 | info->chip_rev = readb(cinfo->base_addr + | 3209 | info->u.cyy.base_addr = cinfo->base_addr + |
| 3330 | (cy_chip_offset[chip_number] << index) + | 3210 | (cy_chip_offset[chip_number] << index); |
| 3331 | (CyGFRCR << index)); | 3211 | info->chip_rev = cyy_readb(info, CyGFRCR); |
| 3332 | 3212 | ||
| 3333 | if (info->chip_rev >= CD1400_REV_J) { | 3213 | if (info->chip_rev >= CD1400_REV_J) { |
| 3334 | /* It is a CD1400 rev. J or later */ | 3214 | /* It is a CD1400 rev. J or later */ |
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h index 1eb87a6a2f6b..bbebef7713b3 100644 --- a/include/linux/cyclades.h +++ b/include/linux/cyclades.h | |||
| @@ -544,7 +544,7 @@ struct cyclades_port { | |||
| 544 | struct cyclades_card *card; | 544 | struct cyclades_card *card; |
| 545 | union { | 545 | union { |
| 546 | struct { | 546 | struct { |
| 547 | int filler; | 547 | void __iomem *base_addr; |
| 548 | } cyy; | 548 | } cyy; |
| 549 | struct { | 549 | struct { |
| 550 | struct CH_CTRL __iomem *ch_ctrl; | 550 | struct CH_CTRL __iomem *ch_ctrl; |
