diff options
author | Jens Taprogge <jens.taprogge@taprogge.org> | 2012-09-12 08:55:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-12 12:54:15 -0400 |
commit | ef79de031437ead308093289604eeb3b5b9d924f (patch) | |
tree | e10e53583e787bfaea82b3c71a36cc71f676fb3e | |
parent | 459e6d7c93d47af0c0829b97bb17239eae79e3d6 (diff) |
Staging: ipack/devices/ipoctal: put ipoctal_channel into tty->driver_data.
Each tty's driver_data is now pointing to the channel it is talking to. struct
ipoctal_channel contains all the information the callbacks require to do their
work.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/ipack/devices/ipoctal.c | 52 |
1 files changed, 21 insertions, 31 deletions
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index c963456ad8b7..70dc7a236d49 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c | |||
@@ -42,6 +42,8 @@ struct ipoctal_channel { | |||
42 | struct tty_port tty_port; | 42 | struct tty_port tty_port; |
43 | union scc2698_channel __iomem *regs; | 43 | union scc2698_channel __iomem *regs; |
44 | union scc2698_block __iomem *block_regs; | 44 | union scc2698_block __iomem *block_regs; |
45 | unsigned int board_id; | ||
46 | unsigned char *board_write; | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | struct ipoctal { | 49 | struct ipoctal { |
@@ -104,7 +106,7 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file) | |||
104 | if (atomic_read(&channel->open)) | 106 | if (atomic_read(&channel->open)) |
105 | return -EBUSY; | 107 | return -EBUSY; |
106 | 108 | ||
107 | tty->driver_data = ipoctal; | 109 | tty->driver_data = channel; |
108 | 110 | ||
109 | res = tty_port_open(&channel->tty_port, tty, file); | 111 | res = tty_port_open(&channel->tty_port, tty, file); |
110 | if (res) | 112 | if (res) |
@@ -124,15 +126,8 @@ static void ipoctal_reset_stats(struct ipoctal_stats *stats) | |||
124 | stats->parity_err = 0; | 126 | stats->parity_err = 0; |
125 | } | 127 | } |
126 | 128 | ||
127 | static void ipoctal_free_channel(struct tty_struct *tty) | 129 | static void ipoctal_free_channel(struct ipoctal_channel *channel) |
128 | { | 130 | { |
129 | struct ipoctal *ipoctal = tty->driver_data; | ||
130 | struct ipoctal_channel *channel; | ||
131 | |||
132 | if (ipoctal == NULL) | ||
133 | return; | ||
134 | channel = &ipoctal->channel[tty->index]; | ||
135 | |||
136 | ipoctal_reset_stats(&channel->stats); | 131 | ipoctal_reset_stats(&channel->stats); |
137 | channel->pointer_read = 0; | 132 | channel->pointer_read = 0; |
138 | channel->pointer_write = 0; | 133 | channel->pointer_write = 0; |
@@ -141,20 +136,18 @@ static void ipoctal_free_channel(struct tty_struct *tty) | |||
141 | 136 | ||
142 | static void ipoctal_close(struct tty_struct *tty, struct file *filp) | 137 | static void ipoctal_close(struct tty_struct *tty, struct file *filp) |
143 | { | 138 | { |
144 | struct ipoctal *ipoctal = tty->driver_data; | 139 | struct ipoctal_channel *channel = tty->driver_data; |
145 | struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; | ||
146 | 140 | ||
147 | tty_port_close(&channel->tty_port, tty, filp); | 141 | tty_port_close(&channel->tty_port, tty, filp); |
148 | 142 | ||
149 | if (atomic_dec_and_test(&channel->open)) | 143 | if (atomic_dec_and_test(&channel->open)) |
150 | ipoctal_free_channel(tty); | 144 | ipoctal_free_channel(channel); |
151 | } | 145 | } |
152 | 146 | ||
153 | static int ipoctal_get_icount(struct tty_struct *tty, | 147 | static int ipoctal_get_icount(struct tty_struct *tty, |
154 | struct serial_icounter_struct *icount) | 148 | struct serial_icounter_struct *icount) |
155 | { | 149 | { |
156 | struct ipoctal *ipoctal = tty->driver_data; | 150 | struct ipoctal_channel *channel = tty->driver_data; |
157 | struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; | ||
158 | 151 | ||
159 | icount->cts = 0; | 152 | icount->cts = 0; |
160 | icount->dsr = 0; | 153 | icount->dsr = 0; |
@@ -370,6 +363,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, | |||
370 | struct ipoctal_channel *channel = &ipoctal->channel[i]; | 363 | struct ipoctal_channel *channel = &ipoctal->channel[i]; |
371 | channel->regs = chan_regs + i; | 364 | channel->regs = chan_regs + i; |
372 | channel->block_regs = block_regs + (i >> 1); | 365 | channel->block_regs = block_regs + (i >> 1); |
366 | channel->board_write = &ipoctal->write; | ||
367 | channel->board_id = ipoctal->board_id; | ||
373 | 368 | ||
374 | iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); | 369 | iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); |
375 | iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); | 370 | iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); |
@@ -492,17 +487,16 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, | |||
492 | return i; | 487 | return i; |
493 | } | 488 | } |
494 | 489 | ||
495 | static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel, | 490 | static int ipoctal_write(struct ipoctal_channel *channel, |
496 | const unsigned char *buf, int count) | 491 | const unsigned char *buf, int count) |
497 | { | 492 | { |
498 | struct ipoctal_channel *channel = &ipoctal->channel[ichannel]; | ||
499 | channel->nb_bytes = 0; | 493 | channel->nb_bytes = 0; |
500 | channel->count_wr = 0; | 494 | channel->count_wr = 0; |
501 | 495 | ||
502 | ipoctal_copy_write_buffer(channel, buf, count); | 496 | ipoctal_copy_write_buffer(channel, buf, count); |
503 | 497 | ||
504 | /* As the IP-OCTAL 485 only supports half duplex, do it manually */ | 498 | /* As the IP-OCTAL 485 only supports half duplex, do it manually */ |
505 | if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { | 499 | if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { |
506 | iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); | 500 | iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); |
507 | iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); | 501 | iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); |
508 | } | 502 | } |
@@ -512,33 +506,31 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel, | |||
512 | * operations | 506 | * operations |
513 | */ | 507 | */ |
514 | iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); | 508 | iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); |
515 | wait_event_interruptible(channel->queue, ipoctal->write); | 509 | wait_event_interruptible(channel->queue, *channel->board_write); |
516 | iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); | 510 | iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); |
517 | 511 | ||
518 | ipoctal->write = 0; | 512 | *channel->board_write = 0; |
519 | return channel->count_wr; | 513 | return channel->count_wr; |
520 | } | 514 | } |
521 | 515 | ||
522 | static int ipoctal_write_tty(struct tty_struct *tty, | 516 | static int ipoctal_write_tty(struct tty_struct *tty, |
523 | const unsigned char *buf, int count) | 517 | const unsigned char *buf, int count) |
524 | { | 518 | { |
525 | struct ipoctal *ipoctal = tty->driver_data; | 519 | struct ipoctal_channel *channel = tty->driver_data; |
526 | 520 | ||
527 | return ipoctal_write(ipoctal, tty->index, buf, count); | 521 | return ipoctal_write(channel, buf, count); |
528 | } | 522 | } |
529 | 523 | ||
530 | static int ipoctal_write_room(struct tty_struct *tty) | 524 | static int ipoctal_write_room(struct tty_struct *tty) |
531 | { | 525 | { |
532 | struct ipoctal *ipoctal = tty->driver_data; | 526 | struct ipoctal_channel *channel = tty->driver_data; |
533 | struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; | ||
534 | 527 | ||
535 | return PAGE_SIZE - channel->nb_bytes; | 528 | return PAGE_SIZE - channel->nb_bytes; |
536 | } | 529 | } |
537 | 530 | ||
538 | static int ipoctal_chars_in_buffer(struct tty_struct *tty) | 531 | static int ipoctal_chars_in_buffer(struct tty_struct *tty) |
539 | { | 532 | { |
540 | struct ipoctal *ipoctal = tty->driver_data; | 533 | struct ipoctal_channel *channel = tty->driver_data; |
541 | struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; | ||
542 | 534 | ||
543 | return channel->nb_bytes; | 535 | return channel->nb_bytes; |
544 | } | 536 | } |
@@ -550,8 +542,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
550 | unsigned char mr1 = 0; | 542 | unsigned char mr1 = 0; |
551 | unsigned char mr2 = 0; | 543 | unsigned char mr2 = 0; |
552 | unsigned char csr = 0; | 544 | unsigned char csr = 0; |
553 | struct ipoctal *ipoctal = tty->driver_data; | 545 | struct ipoctal_channel *channel = tty->driver_data; |
554 | struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; | ||
555 | speed_t baud; | 546 | speed_t baud; |
556 | 547 | ||
557 | cflag = tty->termios->c_cflag; | 548 | cflag = tty->termios->c_cflag; |
@@ -598,7 +589,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
598 | mr2 |= MR2_STOP_BITS_LENGTH_1; | 589 | mr2 |= MR2_STOP_BITS_LENGTH_1; |
599 | 590 | ||
600 | /* Set the flow control */ | 591 | /* Set the flow control */ |
601 | switch (ipoctal->board_id) { | 592 | switch (channel->board_id) { |
602 | case IPACK1_DEVICE_ID_SBS_OCTAL_232: | 593 | case IPACK1_DEVICE_ID_SBS_OCTAL_232: |
603 | if (cflag & CRTSCTS) { | 594 | if (cflag & CRTSCTS) { |
604 | mr1 |= MR1_RxRTS_CONTROL_ON; | 595 | mr1 |= MR1_RxRTS_CONTROL_ON; |
@@ -685,10 +676,9 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
685 | static void ipoctal_hangup(struct tty_struct *tty) | 676 | static void ipoctal_hangup(struct tty_struct *tty) |
686 | { | 677 | { |
687 | unsigned long flags; | 678 | unsigned long flags; |
688 | struct ipoctal *ipoctal = tty->driver_data; | 679 | struct ipoctal_channel *channel = tty->driver_data; |
689 | struct ipoctal_channel *channel = &ipoctal->channel[tty->index]; | ||
690 | 680 | ||
691 | if (ipoctal == NULL) | 681 | if (channel == NULL) |
692 | return; | 682 | return; |
693 | 683 | ||
694 | spin_lock_irqsave(&channel->lock, flags); | 684 | spin_lock_irqsave(&channel->lock, flags); |