diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2009-09-19 16:13:16 -0400 |
---|---|---|
committer | Live-CD User <linux@linux.site> | 2009-09-19 16:13:16 -0400 |
commit | 3aeea5b92210083c7cffd4f08a0bb141d3f2d574 (patch) | |
tree | 43c1572a397b902513e75ad08f8bdbd51b06d41e /drivers/char/cyclades.c | |
parent | 0d3487294e4e175eb6371c8df8ef44b45964e0f6 (diff) |
cyclades: introduce cyy_readb/writeb
Add helpers for io operations, so that we can eliminate huge
amount of supporting code. It is now centralized in those
helpers and used values are precomputed in the init phase.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char/cyclades.c')
-rw-r--r-- | drivers/char/cyclades.c | 448 |
1 files changed, 164 insertions, 284 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 */ |