diff options
Diffstat (limited to 'bsps/sparc/shared/uart/cons.c')
-rw-r--r-- | bsps/sparc/shared/uart/cons.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/bsps/sparc/shared/uart/cons.c b/bsps/sparc/shared/uart/cons.c new file mode 100644 index 0000000000..37f448cbf1 --- /dev/null +++ b/bsps/sparc/shared/uart/cons.c @@ -0,0 +1,136 @@ +/* This file contains the TTY driver for the serial ports. The driver + * is layered so that different UART hardware can be used. It is implemented + * using the Driver Manager. + * + * This driver uses the termios pseudo driver. + * + * COPYRIGHT (c) 2010. + * Cobham Gaisler AB. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <stdlib.h> +#include <bsp/cons.h> +#include <rtems/console.h> + +#ifdef RTEMS_DRVMGR_STARTUP + +/* Note that it is not possible to use the interrupt mode of the driver + * together with the "old" APBUART and -u to GRMON. However the new + * APBUART core (from 1.0.17-b2710) has the GRMON debug bit and can + * handle interrupts. + */ + +static int console_initialized = 0; + +#define FLAG_SYSCON 0x01 +struct console_priv { + int flags; /* 0x1=SystemConsole */ + int minor; + struct console_dev *dev; +}; + +#define CONSOLE_MAX BSP_NUMBER_OF_TERMIOS_PORTS +struct console_priv cons[CONSOLE_MAX] = {{0,0},}; + +/* Install Console in TERMIOS layer */ +static void console_dev_init(struct console_priv *con) +{ + char name[16], *fsname; + rtems_status_code status; + int minor; + + minor = con->minor; + if (!con->dev->fsname) { + strcpy(name, "/dev/console_a"); + /* Special console name and MINOR for SYSTEM CONSOLE */ + if (minor == 0) + name[12] = '\0'; /* /dev/console */ + name[13] += minor; /* when minor=0, this has no effect... */ + fsname = name; + } else { + fsname = con->dev->fsname; + } + status = rtems_termios_device_install( + fsname, + con->dev->handler, + NULL, + &con->dev->base + ); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } +} + +/* Called by device driver to register itself to the cons interface. */ +void console_dev_register(struct console_dev *dev) +{ + int i, minor = 0; + struct console_priv *con = NULL; + + if ((dev->flags & CONSOLE_FLAG_SYSCON) && !cons[0].dev) { + con = &cons[0]; + con->flags = FLAG_SYSCON; + } else { + for (i=1; i<CONSOLE_MAX; i++) { + if (!cons[i].dev) { + con = &cons[i]; + con->flags = 0; + minor = i; + break; + } + } + } + if (con == NULL) { + /* Not enough console structures */ + return; + } + dev->flags &= ~CONSOLE_FLAG_SYSCON_GRANT; + if (con->flags & FLAG_SYSCON) { + dev->flags |= CONSOLE_FLAG_SYSCON_GRANT; + } + + /* Assign Console */ + con->dev = dev; + con->minor = minor; + + if (console_initialized) { + /* Console layer is already initialized, that means that we can + * register termios interface directly. + */ + console_dev_init(con); + } +} + +#if 0 +void console_dev_unregister(struct console_dev *dev) +{ + +} +#endif + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + int i; + + rtems_termios_initialize(); + + /* Register all Console a file system device node */ + for (i=0; i<CONSOLE_MAX; i++) { + if (cons[i].dev) + console_dev_init(&cons[i]); + } + + console_initialized = 1; + + return RTEMS_SUCCESSFUL; +} + +#endif |