Changeset 1e744ef in rtems
- Timestamp:
- 11/26/13 07:47:37 (10 years ago)
- Branches:
- 4.11, 5, master
- Children:
- 6fe6d017
- Parents:
- 022851a
- git-author:
- Sebastian Huber <sebastian.huber@…> (11/26/13 07:47:37)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (02/04/14 13:54:26)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/sparc/leon3/console/console.c
r022851a r1e744ef 86 86 87 87 /* Handle UART interrupts */ 88 voidconsole_isr(void *arg)88 static void leon3_console_isr(void *arg) 89 89 { 90 90 struct apbuart_priv *uart = arg; … … 101 101 } 102 102 103 if (status & LEON_REG_UART_STATUS_THE) { 104 /* Sent the one char, we disable TX interrupts */ 105 uart->regs->ctrl &= ~LEON_REG_UART_CTRL_TI; 106 107 /* Tell close that we sent everything */ 108 uart->sending = 0; 109 103 if ( 104 (status & LEON_REG_UART_STATUS_THE) 105 && (uart->regs->ctrl & LEON_REG_UART_CTRL_TI) != 0 106 ) { 110 107 /* write_interrupt will get called from this function */ 111 108 rtems_termios_dequeue_characters(uart->cookie, 1); … … 117 114 * 118 115 */ 119 int console_write_interrupt(int minor, const char *buf, int len) 120 { 116 static int leon3_console_write_support(int minor, const char *buf, size_t len) 117 { 118 struct apbuart_priv *uart; 119 int sending; 120 121 if (minor == 0) 122 uart = &apbuarts[syscon_uart_index]; 123 else 124 uart = &apbuarts[minor - 1]; 125 121 126 if (len > 0) { 122 struct apbuart_priv *uart; 123 124 if (minor == 0) 125 uart = &apbuarts[syscon_uart_index]; 126 else 127 uart = &apbuarts[minor - 1]; 128 129 /* Remember what position in buffer */ 130 131 /* Enable TX interrupt */ 127 /* Enable TX interrupt (interrupt is edge-triggered) */ 132 128 uart->regs->ctrl |= LEON_REG_UART_CTRL_TI; 133 129 … … 135 131 uart->regs->data = *buf; 136 132 137 uart->sending = 1; 138 } 133 sending = 1; 134 } else { 135 /* No more to send, disable TX interrupts */ 136 uart->regs->ctrl &= ~LEON_REG_UART_CTRL_TI; 137 138 /* Tell close that we sent everything */ 139 sending = 0; 140 } 141 142 uart->sending = sending; 139 143 140 144 return 0; … … 212 216 else 213 217 uart = &apbuarts[minor - 1]; 218 219 /* 220 * FIXME: This read-modify-write sequence is broken since interrupts may 221 * interfere. 222 */ 214 223 215 224 /* Read out current value */ … … 352 361 } 353 362 363 #if CONSOLE_USE_INTERRUPTS 364 static struct rtems_termios_tty *leon3_console_get_tty( 365 rtems_libio_open_close_args_t *args 366 ) 367 { 368 return args->iop->data1; 369 } 370 #endif 371 372 static int leon3_console_first_open(int major, int minor, void *arg) 373 { 374 struct apbuart_priv *uart; 375 rtems_status_code sc; 376 377 if (minor == 0) 378 uart = &apbuarts[syscon_uart_index]; 379 else 380 uart = &apbuarts[minor - 1]; 381 382 #if CONSOLE_USE_INTERRUPTS 383 uart->cookie = leon3_console_get_tty(arg); 384 385 /* Register Interrupt handler */ 386 sc = rtems_interrupt_handler_install(uart->irq, "console", 387 RTEMS_INTERRUPT_SHARED, 388 leon3_console_isr, 389 uart); 390 if (sc != RTEMS_SUCCESSFUL) 391 return -1; 392 393 uart->sending = 0; 394 /* Enable Receiver and transmitter and Turn on RX interrupts */ 395 uart->regs->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE | 396 LEON_REG_UART_CTRL_RI; 397 #else 398 /* Initialize UART on opening */ 399 uart->regs->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; 400 #endif 401 uart->regs->status = 0; 402 403 return 0; 404 } 405 406 #if CONSOLE_USE_INTERRUPTS 407 static int leon3_console_last_close(int major, int minor, void *arg) 408 { 409 struct rtems_termios_tty *tty = leon3_console_get_tty(arg); 410 struct apbuart_priv *uart; 411 rtems_interrupt_level level; 412 413 if (minor == 0) 414 uart = &apbuarts[syscon_uart_index]; 415 else 416 uart = &apbuarts[minor - 1]; 417 418 /* Turn off RX interrupts */ 419 rtems_termios_interrupt_lock_acquire(tty, level); 420 uart->regs->ctrl &= ~(LEON_REG_UART_CTRL_RI); 421 rtems_termios_interrupt_lock_release(tty, level); 422 423 /**** Flush device ****/ 424 while (uart->sending) { 425 /* Wait until all data has been sent */ 426 } 427 428 /* uninstall ISR */ 429 rtems_interrupt_handler_remove(uart->irq, leon3_console_isr, uart); 430 431 return 0; 432 } 433 #endif 434 354 435 rtems_device_driver console_open( 355 436 rtems_device_major_number major, … … 358 439 ) 359 440 { 360 rtems_status_code sc; 361 struct apbuart_priv *uart; 362 #if CONSOLE_USE_INTERRUPTS 363 rtems_libio_open_close_args_t *priv = arg; 364 441 #if CONSOLE_USE_INTERRUPTS 365 442 /* Interrupt mode routines */ 366 443 static const rtems_termios_callbacks Callbacks = { 367 NULL,/* firstOpen */368 NULL,/* lastClose */444 leon3_console_first_open, /* firstOpen */ 445 leon3_console_last_close, /* lastClose */ 369 446 NULL, /* pollRead */ 370 console_write_interrupt,/* write */447 leon3_console_write_support, /* write */ 371 448 console_set_attributes, /* setAttributes */ 372 449 NULL, /* stopRemoteTx */ … … 377 454 /* Polling mode routines */ 378 455 static const rtems_termios_callbacks Callbacks = { 379 NULL,/* firstOpen */456 leon3_console_first_open, /* firstOpen */ 380 457 NULL, /* lastClose */ 381 458 console_pollRead, /* pollRead */ … … 392 469 return RTEMS_INVALID_NUMBER; 393 470 394 sc = rtems_termios_open(major, minor, arg, &Callbacks); 395 if (sc != RTEMS_SUCCESSFUL) 396 return sc; 397 398 if (minor == 0) 399 uart = &apbuarts[syscon_uart_index]; 400 else 401 uart = &apbuarts[minor - 1]; 402 403 #if CONSOLE_USE_INTERRUPTS 404 if (priv && priv->iop) 405 uart->cookie = priv->iop->data1; 406 else 407 uart->cookie = NULL; 408 409 /* Register Interrupt handler */ 410 sc = rtems_interrupt_handler_install(uart->irq, "console", 411 RTEMS_INTERRUPT_SHARED, console_isr, 412 uart); 413 if (sc != RTEMS_SUCCESSFUL) 414 return sc; 415 416 uart->sending = 0; 417 /* Enable Receiver and transmitter and Turn on RX interrupts */ 418 uart->regs->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE | 419 LEON_REG_UART_CTRL_RI; 420 #else 421 /* Initialize UART on opening */ 422 uart->regs->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; 423 #endif 424 uart->regs->status = 0; 425 426 return RTEMS_SUCCESSFUL; 471 return rtems_termios_open(major, minor, arg, &Callbacks); 427 472 } 428 473 … … 433 478 ) 434 479 { 435 #if CONSOLE_USE_INTERRUPTS436 struct apbuart_priv *uart;437 438 if (minor == 0)439 uart = &apbuarts[syscon_uart_index];440 else441 uart = &apbuarts[minor - 1];442 443 /* Turn off RX interrupts */444 uart->regs->ctrl &= ~(LEON_REG_UART_CTRL_RI);445 446 /**** Flush device ****/447 while (uart->sending) {448 /* Wait until all data has been sent */449 }450 451 /* uninstall ISR */452 rtems_interrupt_handler_remove(uart->irq, console_isr, uart);453 #endif454 480 return rtems_termios_close(arg); 455 481 }
Note: See TracChangeset
for help on using the changeset viewer.