Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:07

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*  This file contains the TTY driver for the serial ports. The driver
0004  *  is layered so that different UART hardware can be used. It is implemented
0005  *  using the Driver Manager.
0006  *
0007  *  This driver uses the termios pseudo driver.
0008  *
0009  *  COPYRIGHT (c) 2010.
0010  *  Cobham Gaisler AB.
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #include <bsp.h>
0035 #include <string.h>
0036 #include <unistd.h>
0037 #include <grlib/cons.h>
0038 #include <rtems/console.h>
0039 
0040 #ifdef RTEMS_DRVMGR_STARTUP
0041 
0042 /* Note that it is not possible to use the interrupt mode of the driver
0043  * together with the "old" APBUART and -u to GRMON. However the new
0044  * APBUART core (from 1.0.17-b2710) has the GRMON debug bit and can 
0045  * handle interrupts.
0046  */
0047 
0048 static int console_initialized = 0;
0049 
0050 #define FLAG_SYSCON 0x01
0051 struct console_priv {
0052     int flags; /* 0x1=SystemConsole */
0053     int minor;
0054     struct console_dev *dev;
0055 };
0056 
0057 #define CONSOLE_MAX BSP_NUMBER_OF_TERMIOS_PORTS
0058 struct console_priv cons[CONSOLE_MAX] = {{0,0},};
0059 
0060 /* Install Console in TERMIOS layer */
0061 static void console_dev_init(struct console_priv *con)
0062 {
0063     char name[16], *fsname;
0064     rtems_status_code status;
0065     int minor;
0066 
0067     minor = con->minor;
0068     if (!con->dev->fsname) {
0069         strcpy(name, "/dev/console_a");
0070         /* Special console name and MINOR for SYSTEM CONSOLE */
0071         if (minor == 0)
0072             name[12] = '\0'; /* /dev/console */
0073         name[13] += minor; /* when minor=0, this has no effect... */
0074         fsname = name;
0075     } else {
0076         fsname = con->dev->fsname;
0077     }
0078     status = rtems_termios_device_install(
0079         fsname,
0080         con->dev->handler,
0081         NULL,
0082         &con->dev->base
0083     );
0084     if (status != RTEMS_SUCCESSFUL) {
0085         rtems_fatal_error_occurred(status);
0086     }
0087 
0088     if ((con->flags & FLAG_SYSCON) != 0) {
0089         (void) link(fsname, CONSOLE_DEVICE_NAME);
0090     }
0091 }
0092 
0093 /* Called by device driver to register itself to the cons interface. */
0094 void console_dev_register(struct console_dev *dev)
0095 {
0096     int i, minor = 0;
0097     struct console_priv *con = NULL;
0098 
0099     if ((dev->flags & CONSOLE_FLAG_SYSCON) && !cons[0].dev) {
0100         con = &cons[0];
0101         con->flags = FLAG_SYSCON;
0102     } else {
0103         for (i=1; i<CONSOLE_MAX; i++) {
0104             if (!cons[i].dev) {
0105                 con = &cons[i];
0106                 con->flags = 0;
0107                 minor = i;
0108                 break;
0109             }
0110         }
0111     }
0112     if (con == NULL) {
0113         /* Not enough console structures */
0114         return;
0115     }
0116     dev->flags &= ~CONSOLE_FLAG_SYSCON_GRANT;
0117     if (con->flags & FLAG_SYSCON) {
0118         dev->flags |= CONSOLE_FLAG_SYSCON_GRANT;
0119     }
0120 
0121     /* Assign Console */
0122     con->dev = dev;
0123     con->minor = minor;
0124 
0125     if (console_initialized) {
0126         /* Console layer is already initialized, that means that we can
0127          * register termios interface directly.
0128          */
0129         console_dev_init(con);
0130     }
0131 }
0132 
0133 #if 0
0134 void console_dev_unregister(struct console_dev *dev)
0135 {
0136 
0137 }
0138 #endif
0139 
0140 rtems_device_driver console_initialize(
0141     rtems_device_major_number   major,
0142     rtems_device_minor_number   minor,
0143     void                *arg)
0144 {
0145     int i;
0146 
0147     rtems_termios_initialize();
0148 
0149     /* Register all Console a file system device node */
0150     for (i=0; i<CONSOLE_MAX; i++) {
0151         if (cons[i].dev)
0152             console_dev_init(&cons[i]);
0153     }
0154 
0155     console_initialized = 1;
0156 
0157     return RTEMS_SUCCESSFUL;
0158 }
0159 
0160 #endif