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; |