aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/vme_scc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/vme_scc.c')
-rw-r--r--drivers/char/vme_scc.c193
1 files changed, 152 insertions, 41 deletions
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index 1718b3c481db..994e1a58b987 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -69,7 +69,7 @@ static void scc_disable_tx_interrupts(void * ptr);
69static void scc_enable_tx_interrupts(void * ptr); 69static void scc_enable_tx_interrupts(void * ptr);
70static void scc_disable_rx_interrupts(void * ptr); 70static void scc_disable_rx_interrupts(void * ptr);
71static void scc_enable_rx_interrupts(void * ptr); 71static void scc_enable_rx_interrupts(void * ptr);
72static int scc_get_CD(void * ptr); 72static int scc_carrier_raised(struct tty_port *port);
73static void scc_shutdown_port(void * ptr); 73static void scc_shutdown_port(void * ptr);
74static int scc_set_real_termios(void *ptr); 74static int scc_set_real_termios(void *ptr);
75static void scc_hungup(void *ptr); 75static void scc_hungup(void *ptr);
@@ -100,7 +100,6 @@ static struct real_driver scc_real_driver = {
100 scc_enable_tx_interrupts, 100 scc_enable_tx_interrupts,
101 scc_disable_rx_interrupts, 101 scc_disable_rx_interrupts,
102 scc_enable_rx_interrupts, 102 scc_enable_rx_interrupts,
103 scc_get_CD,
104 scc_shutdown_port, 103 scc_shutdown_port,
105 scc_set_real_termios, 104 scc_set_real_termios,
106 scc_chars_in_buffer, 105 scc_chars_in_buffer,
@@ -129,6 +128,10 @@ static const struct tty_operations scc_ops = {
129 .break_ctl = scc_break_ctl, 128 .break_ctl = scc_break_ctl,
130}; 129};
131 130
131static const struct tty_port_operations scc_port_ops = {
132 .carrier_raised = scc_carrier_raised,
133};
134
132/*---------------------------------------------------------------------------- 135/*----------------------------------------------------------------------------
133 * vme_scc_init() and support functions 136 * vme_scc_init() and support functions
134 *---------------------------------------------------------------------------*/ 137 *---------------------------------------------------------------------------*/
@@ -176,6 +179,8 @@ static void scc_init_portstructs(void)
176 179
177 for (i = 0; i < 2; i++) { 180 for (i = 0; i < 2; i++) {
178 port = scc_ports + i; 181 port = scc_ports + i;
182 tty_port_init(&port->gs.port);
183 port->gs.port.ops = &scc_port_ops;
179 port->gs.magic = SCC_MAGIC; 184 port->gs.magic = SCC_MAGIC;
180 port->gs.close_delay = HZ/2; 185 port->gs.close_delay = HZ/2;
181 port->gs.closing_wait = 30 * HZ; 186 port->gs.closing_wait = 30 * HZ;
@@ -193,6 +198,7 @@ static void scc_init_portstructs(void)
193static int mvme147_scc_init(void) 198static int mvme147_scc_init(void)
194{ 199{
195 struct scc_port *port; 200 struct scc_port *port;
201 int error;
196 202
197 printk(KERN_INFO "SCC: MVME147 Serial Driver\n"); 203 printk(KERN_INFO "SCC: MVME147 Serial Driver\n");
198 /* Init channel A */ 204 /* Init channel A */
@@ -202,14 +208,23 @@ static int mvme147_scc_init(void)
202 port->datap = port->ctrlp + 1; 208 port->datap = port->ctrlp + 1;
203 port->port_a = &scc_ports[0]; 209 port->port_a = &scc_ports[0];
204 port->port_b = &scc_ports[1]; 210 port->port_b = &scc_ports[1];
205 request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, 211 error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
206 "SCC-A TX", port); 212 "SCC-A TX", port);
207 request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, 213 if (error)
214 goto fail;
215 error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
208 "SCC-A status", port); 216 "SCC-A status", port);
209 request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, 217 if (error)
218 goto fail_free_a_tx;
219 error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
210 "SCC-A RX", port); 220 "SCC-A RX", port);
211 request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED, 221 if (error)
212 "SCC-A special cond", port); 222 goto fail_free_a_stat;
223 error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int,
224 IRQF_DISABLED, "SCC-A special cond", port);
225 if (error)
226 goto fail_free_a_rx;
227
213 { 228 {
214 SCC_ACCESS_INIT(port); 229 SCC_ACCESS_INIT(port);
215 230
@@ -229,14 +244,23 @@ static int mvme147_scc_init(void)
229 port->datap = port->ctrlp + 1; 244 port->datap = port->ctrlp + 1;
230 port->port_a = &scc_ports[0]; 245 port->port_a = &scc_ports[0];
231 port->port_b = &scc_ports[1]; 246 port->port_b = &scc_ports[1];
232 request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, 247 error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
233 "SCC-B TX", port); 248 "SCC-B TX", port);
234 request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, 249 if (error)
250 goto fail_free_a_spcond;
251 error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
235 "SCC-B status", port); 252 "SCC-B status", port);
236 request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, 253 if (error)
254 goto fail_free_b_tx;
255 error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
237 "SCC-B RX", port); 256 "SCC-B RX", port);
238 request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED, 257 if (error)
239 "SCC-B special cond", port); 258 goto fail_free_b_stat;
259 error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int,
260 IRQF_DISABLED, "SCC-B special cond", port);
261 if (error)
262 goto fail_free_b_rx;
263
240 { 264 {
241 SCC_ACCESS_INIT(port); 265 SCC_ACCESS_INIT(port);
242 266
@@ -252,6 +276,23 @@ static int mvme147_scc_init(void)
252 scc_init_drivers(); 276 scc_init_drivers();
253 277
254 return 0; 278 return 0;
279
280fail_free_b_rx:
281 free_irq(MVME147_IRQ_SCCB_RX, port);
282fail_free_b_stat:
283 free_irq(MVME147_IRQ_SCCB_STAT, port);
284fail_free_b_tx:
285 free_irq(MVME147_IRQ_SCCB_TX, port);
286fail_free_a_spcond:
287 free_irq(MVME147_IRQ_SCCA_SPCOND, port);
288fail_free_a_rx:
289 free_irq(MVME147_IRQ_SCCA_RX, port);
290fail_free_a_stat:
291 free_irq(MVME147_IRQ_SCCA_STAT, port);
292fail_free_a_tx:
293 free_irq(MVME147_IRQ_SCCA_TX, port);
294fail:
295 return error;
255} 296}
256#endif 297#endif
257 298
@@ -260,6 +301,7 @@ static int mvme147_scc_init(void)
260static int mvme162_scc_init(void) 301static int mvme162_scc_init(void)
261{ 302{
262 struct scc_port *port; 303 struct scc_port *port;
304 int error;
263 305
264 if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA)) 306 if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA))
265 return (-ENODEV); 307 return (-ENODEV);
@@ -272,14 +314,23 @@ static int mvme162_scc_init(void)
272 port->datap = port->ctrlp + 2; 314 port->datap = port->ctrlp + 2;
273 port->port_a = &scc_ports[0]; 315 port->port_a = &scc_ports[0];
274 port->port_b = &scc_ports[1]; 316 port->port_b = &scc_ports[1];
275 request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, 317 error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
276 "SCC-A TX", port); 318 "SCC-A TX", port);
277 request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, 319 if (error)
320 goto fail;
321 error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
278 "SCC-A status", port); 322 "SCC-A status", port);
279 request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, 323 if (error)
324 goto fail_free_a_tx;
325 error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
280 "SCC-A RX", port); 326 "SCC-A RX", port);
281 request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED, 327 if (error)
282 "SCC-A special cond", port); 328 goto fail_free_a_stat;
329 error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int,
330 IRQF_DISABLED, "SCC-A special cond", port);
331 if (error)
332 goto fail_free_a_rx;
333
283 { 334 {
284 SCC_ACCESS_INIT(port); 335 SCC_ACCESS_INIT(port);
285 336
@@ -299,14 +350,22 @@ static int mvme162_scc_init(void)
299 port->datap = port->ctrlp + 2; 350 port->datap = port->ctrlp + 2;
300 port->port_a = &scc_ports[0]; 351 port->port_a = &scc_ports[0];
301 port->port_b = &scc_ports[1]; 352 port->port_b = &scc_ports[1];
302 request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, 353 error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
303 "SCC-B TX", port); 354 "SCC-B TX", port);
304 request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, 355 if (error)
356 goto fail_free_a_spcond;
357 error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
305 "SCC-B status", port); 358 "SCC-B status", port);
306 request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, 359 if (error)
360 goto fail_free_b_tx;
361 error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
307 "SCC-B RX", port); 362 "SCC-B RX", port);
308 request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED, 363 if (error)
309 "SCC-B special cond", port); 364 goto fail_free_b_stat;
365 error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int,
366 IRQF_DISABLED, "SCC-B special cond", port);
367 if (error)
368 goto fail_free_b_rx;
310 369
311 { 370 {
312 SCC_ACCESS_INIT(port); /* Either channel will do */ 371 SCC_ACCESS_INIT(port); /* Either channel will do */
@@ -323,6 +382,23 @@ static int mvme162_scc_init(void)
323 scc_init_drivers(); 382 scc_init_drivers();
324 383
325 return 0; 384 return 0;
385
386fail_free_b_rx:
387 free_irq(MVME162_IRQ_SCCB_RX, port);
388fail_free_b_stat:
389 free_irq(MVME162_IRQ_SCCB_STAT, port);
390fail_free_b_tx:
391 free_irq(MVME162_IRQ_SCCB_TX, port);
392fail_free_a_spcond:
393 free_irq(MVME162_IRQ_SCCA_SPCOND, port);
394fail_free_a_rx:
395 free_irq(MVME162_IRQ_SCCA_RX, port);
396fail_free_a_stat:
397 free_irq(MVME162_IRQ_SCCA_STAT, port);
398fail_free_a_tx:
399 free_irq(MVME162_IRQ_SCCA_TX, port);
400fail:
401 return error;
326} 402}
327#endif 403#endif
328 404
@@ -331,6 +407,7 @@ static int mvme162_scc_init(void)
331static int bvme6000_scc_init(void) 407static int bvme6000_scc_init(void)
332{ 408{
333 struct scc_port *port; 409 struct scc_port *port;
410 int error;
334 411
335 printk(KERN_INFO "SCC: BVME6000 Serial Driver\n"); 412 printk(KERN_INFO "SCC: BVME6000 Serial Driver\n");
336 /* Init channel A */ 413 /* Init channel A */
@@ -340,14 +417,23 @@ static int bvme6000_scc_init(void)
340 port->datap = port->ctrlp + 4; 417 port->datap = port->ctrlp + 4;
341 port->port_a = &scc_ports[0]; 418 port->port_a = &scc_ports[0];
342 port->port_b = &scc_ports[1]; 419 port->port_b = &scc_ports[1];
343 request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, 420 error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
344 "SCC-A TX", port); 421 "SCC-A TX", port);
345 request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, 422 if (error)
423 goto fail;
424 error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
346 "SCC-A status", port); 425 "SCC-A status", port);
347 request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, 426 if (error)
427 goto fail_free_a_tx;
428 error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
348 "SCC-A RX", port); 429 "SCC-A RX", port);
349 request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED, 430 if (error)
350 "SCC-A special cond", port); 431 goto fail_free_a_stat;
432 error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int,
433 IRQF_DISABLED, "SCC-A special cond", port);
434 if (error)
435 goto fail_free_a_rx;
436
351 { 437 {
352 SCC_ACCESS_INIT(port); 438 SCC_ACCESS_INIT(port);
353 439
@@ -367,14 +453,22 @@ static int bvme6000_scc_init(void)
367 port->datap = port->ctrlp + 4; 453 port->datap = port->ctrlp + 4;
368 port->port_a = &scc_ports[0]; 454 port->port_a = &scc_ports[0];
369 port->port_b = &scc_ports[1]; 455 port->port_b = &scc_ports[1];
370 request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, 456 error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
371 "SCC-B TX", port); 457 "SCC-B TX", port);
372 request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, 458 if (error)
459 goto fail_free_a_spcond;
460 error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
373 "SCC-B status", port); 461 "SCC-B status", port);
374 request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, 462 if (error)
463 goto fail_free_b_tx;
464 error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
375 "SCC-B RX", port); 465 "SCC-B RX", port);
376 request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED, 466 if (error)
377 "SCC-B special cond", port); 467 goto fail_free_b_stat;
468 error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int,
469 IRQF_DISABLED, "SCC-B special cond", port);
470 if (error)
471 goto fail_free_b_rx;
378 472
379 { 473 {
380 SCC_ACCESS_INIT(port); /* Either channel will do */ 474 SCC_ACCESS_INIT(port); /* Either channel will do */
@@ -388,6 +482,23 @@ static int bvme6000_scc_init(void)
388 scc_init_drivers(); 482 scc_init_drivers();
389 483
390 return 0; 484 return 0;
485
486fail:
487 free_irq(BVME_IRQ_SCCA_STAT, port);
488fail_free_a_tx:
489 free_irq(BVME_IRQ_SCCA_RX, port);
490fail_free_a_stat:
491 free_irq(BVME_IRQ_SCCA_SPCOND, port);
492fail_free_a_rx:
493 free_irq(BVME_IRQ_SCCB_TX, port);
494fail_free_a_spcond:
495 free_irq(BVME_IRQ_SCCB_STAT, port);
496fail_free_b_tx:
497 free_irq(BVME_IRQ_SCCB_RX, port);
498fail_free_b_stat:
499 free_irq(BVME_IRQ_SCCB_SPCOND, port);
500fail_free_b_rx:
501 return error;
391} 502}
392#endif 503#endif
393 504
@@ -624,10 +735,10 @@ static void scc_enable_rx_interrupts(void *ptr)
624} 735}
625 736
626 737
627static int scc_get_CD(void *ptr) 738static int scc_carrier_raised(struct tty_port *port)
628{ 739{
629 struct scc_port *port = ptr; 740 struct scc_port *sc = container_of(port, struct scc_port, gs.port);
630 unsigned channel = port->channel; 741 unsigned channel = sc->channel;
631 742
632 return !!(scc_last_status_reg[channel] & SR_DCD); 743 return !!(scc_last_status_reg[channel] & SR_DCD);
633} 744}
@@ -638,7 +749,7 @@ static void scc_shutdown_port(void *ptr)
638 struct scc_port *port = ptr; 749 struct scc_port *port = ptr;
639 750
640 port->gs.port.flags &= ~ GS_ACTIVE; 751 port->gs.port.flags &= ~ GS_ACTIVE;
641 if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { 752 if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) {
642 scc_setsignals (port, 0, 0); 753 scc_setsignals (port, 0, 0);
643 } 754 }
644} 755}
@@ -779,7 +890,7 @@ static void scc_setsignals(struct scc_port *port, int dtr, int rts)
779 890
780static void scc_send_xchar(struct tty_struct *tty, char ch) 891static void scc_send_xchar(struct tty_struct *tty, char ch)
781{ 892{
782 struct scc_port *port = (struct scc_port *)tty->driver_data; 893 struct scc_port *port = tty->driver_data;
783 894
784 port->x_char = ch; 895 port->x_char = ch;
785 if (ch) 896 if (ch)
@@ -896,7 +1007,7 @@ static int scc_open (struct tty_struct * tty, struct file * filp)
896 return retval; 1007 return retval;
897 } 1008 }
898 1009
899 port->c_dcd = scc_get_CD (port); 1010 port->c_dcd = tty_port_carrier_raised(&port->gs.port);
900 1011
901 scc_enable_rx_interrupts(port); 1012 scc_enable_rx_interrupts(port);
902 1013
@@ -906,7 +1017,7 @@ static int scc_open (struct tty_struct * tty, struct file * filp)
906 1017
907static void scc_throttle (struct tty_struct * tty) 1018static void scc_throttle (struct tty_struct * tty)
908{ 1019{
909 struct scc_port *port = (struct scc_port *)tty->driver_data; 1020 struct scc_port *port = tty->driver_data;
910 unsigned long flags; 1021 unsigned long flags;
911 SCC_ACCESS_INIT(port); 1022 SCC_ACCESS_INIT(port);
912 1023
@@ -922,7 +1033,7 @@ static void scc_throttle (struct tty_struct * tty)
922 1033
923static void scc_unthrottle (struct tty_struct * tty) 1034static void scc_unthrottle (struct tty_struct * tty)
924{ 1035{
925 struct scc_port *port = (struct scc_port *)tty->driver_data; 1036 struct scc_port *port = tty->driver_data;
926 unsigned long flags; 1037 unsigned long flags;
927 SCC_ACCESS_INIT(port); 1038 SCC_ACCESS_INIT(port);
928 1039
@@ -945,7 +1056,7 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
945 1056
946static int scc_break_ctl(struct tty_struct *tty, int break_state) 1057static int scc_break_ctl(struct tty_struct *tty, int break_state)
947{ 1058{
948 struct scc_port *port = (struct scc_port *)tty->driver_data; 1059 struct scc_port *port = tty->driver_data;
949 unsigned long flags; 1060 unsigned long flags;
950 SCC_ACCESS_INIT(port); 1061 SCC_ACCESS_INIT(port);
951 1062