summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/sparc/leon3/Makefile.am7
-rw-r--r--c/src/lib/libbsp/sparc/leon3/console/console.c349
-rw-r--r--c/src/lib/libbsp/sparc/leon3/preinstall.am4
-rw-r--r--c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h40
-rw-r--r--c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c240
5 files changed, 315 insertions, 325 deletions
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index 5dd43c3be9..6da563b609 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -65,6 +65,7 @@ libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_old.c
libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_names.c
libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_show.c
# console
+libbsp_a_SOURCES += ../../shared/console-termios.c
libbsp_a_SOURCES += console/console.c
# debugio
libbsp_a_SOURCES += console/printk_support.c
@@ -109,9 +110,11 @@ libbsp_a_SOURCES += ../../sparc/shared/spw/grspw.c \
# UART
include_HEADERS += ../../sparc/shared/include/apbuart.h \
- ../../sparc/shared/include/apbuart_pci.h
+ ../../sparc/shared/include/apbuart_pci.h \
+ ../../sparc/shared/include/apbuart_termios.h
libbsp_a_SOURCES += ../../sparc/shared/uart/apbuart.c \
- ../../sparc/shared/uart/apbuart_pci.c
+ ../../sparc/shared/uart/apbuart_pci.c \
+ ../../sparc/shared/uart/apbuart_termios.c
# I2CMST
include_HEADERS += ../../sparc/shared/include/i2cmst.h
diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c
index 989d1cf516..9012492bb6 100644
--- a/c/src/lib/libbsp/sparc/leon3/console/console.c
+++ b/c/src/lib/libbsp/sparc/leon3/console/console.c
@@ -28,34 +28,17 @@
#include <bsp.h>
#include <bsp/fatal.h>
-#include <rtems/libio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <rtems/bspIo.h>
-#include <leon.h>
-#include <rtems/termiostypes.h>
-#include <apbuart.h>
+#include <apbuart_termios.h>
int syscon_uart_index __attribute__((weak)) = 0;
/* body is in debugputs.c */
-
-struct apbuart_priv {
- struct apbuart_regs *regs;
- unsigned int freq_hz;
-#if CONSOLE_USE_INTERRUPTS
- int irq;
- void *cookie;
- volatile int sending;
- char *buf;
-#endif
-};
-static struct apbuart_priv apbuarts[BSP_NUMBER_OF_TERMIOS_PORTS];
+static struct apbuart_context apbuarts[BSP_NUMBER_OF_TERMIOS_PORTS];
static int uarts = 0;
-static struct apbuart_priv *leon3_console_get_uart(int minor)
+static struct apbuart_context *leon3_console_get_uart(int minor)
{
- struct apbuart_priv *uart;
+ struct apbuart_context *uart;
if (minor == 0)
uart = &apbuarts[syscon_uart_index];
@@ -65,160 +48,6 @@ static struct apbuart_priv *leon3_console_get_uart(int minor)
return uart;
}
-#if CONSOLE_USE_INTERRUPTS
-
-/* Handle UART interrupts */
-static void leon3_console_isr(void *arg)
-{
- struct apbuart_priv *uart = arg;
- unsigned int status;
- char data;
-
- /* Get all received characters */
- while ((status=uart->regs->status) & APBUART_STATUS_DR) {
- /* Data has arrived, get new data */
- data = uart->regs->data;
-
- /* Tell termios layer about new character */
- rtems_termios_enqueue_raw_characters(uart->cookie, &data, 1);
- }
-
- if (
- (status & APBUART_STATUS_TE)
- && (uart->regs->ctrl & APBUART_CTRL_TI) != 0
- ) {
- /* write_interrupt will get called from this function */
- rtems_termios_dequeue_characters(uart->cookie, 1);
- }
-}
-
-/*
- * Console Termios Write-Buffer Support Entry Point
- *
- */
-static int leon3_console_write_support(int minor, const char *buf, size_t len)
-{
- struct apbuart_priv *uart = leon3_console_get_uart(minor);
- int sending;
-
- if (len > 0) {
- /* Enable TX interrupt (interrupt is edge-triggered) */
- uart->regs->ctrl |= APBUART_CTRL_TI;
-
- /* start UART TX, this will result in an interrupt when done */
- uart->regs->data = *buf;
-
- sending = 1;
- } else {
- /* No more to send, disable TX interrupts */
- uart->regs->ctrl &= ~APBUART_CTRL_TI;
-
- /* Tell close that we sent everything */
- sending = 0;
- }
-
- uart->sending = sending;
-
- return 0;
-}
-
-#else
-
-/*
- * Console Termios Support Entry Points
- */
-static ssize_t leon3_console_write_polled(
- int minor,
- const char *buf,
- size_t len
-)
-{
- struct apbuart_priv *uart = leon3_console_get_uart(minor);
- int nwrite = 0;
-
- while (nwrite < len) {
- apbuart_outbyte_polled(uart->regs, *buf++, 1, 0);
- nwrite++;
- }
- return nwrite;
-}
-
-static int leon3_console_pollRead(int minor)
-{
- struct apbuart_priv *uart = leon3_console_get_uart(minor);
-
- return apbuart_inbyte_nonblocking(uart->regs);
-}
-
-#endif
-
-static int leon3_console_set_attributes(int minor, const struct termios *t)
-{
- struct apbuart_priv *uart = leon3_console_get_uart(minor);
- unsigned int scaler;
- unsigned int ctrl;
- int baud;
-
- switch (t->c_cflag & CSIZE) {
- default:
- case CS5:
- case CS6:
- case CS7:
- /* Hardware doesn't support other than CS8 */
- return -1;
- case CS8:
- break;
- }
-
- /*
- * FIXME: This read-modify-write sequence is broken since interrupts may
- * interfere.
- */
-
- /* Read out current value */
- ctrl = uart->regs->ctrl;
-
- switch (t->c_cflag & (PARENB|PARODD)) {
- case (PARENB|PARODD):
- /* Odd parity */
- ctrl |= APBUART_CTRL_PE|APBUART_CTRL_PS;
- break;
-
- case PARENB:
- /* Even parity */
- ctrl &= ~APBUART_CTRL_PS;
- ctrl |= APBUART_CTRL_PE;
- break;
-
- default:
- case 0:
- case PARODD:
- /* No Parity */
- ctrl &= ~(APBUART_CTRL_PS|APBUART_CTRL_PE);
- }
-
- if (!(t->c_cflag & CLOCAL)) {
- ctrl |= APBUART_CTRL_FL;
- } else {
- ctrl &= ~APBUART_CTRL_FL;
- }
-
- /* Update new settings */
- uart->regs->ctrl = ctrl;
-
- /* Baud rate */
- baud = rtems_termios_baud_to_number(t->c_cflag);
- if (baud > 0) {
- /* Calculate Baud rate generator "scaler" number */
- scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10;
-
- /* Set new baud rate by setting scaler */
- uart->regs->scaler = scaler;
- }
-
- return 0;
-}
-
/* AMBA PP find routine. Extract AMBA PnP information into data structure. */
static int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg)
{
@@ -226,9 +55,7 @@ static int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg)
/* Extract needed information of one APBUART */
apbuarts[uarts].regs = (struct apbuart_regs *)apb->start;
-#if CONSOLE_USE_INTERRUPTS
apbuarts[uarts].irq = apb->irq;
-#endif
/* Get APBUART core frequency, it is assumed that it is the same
* as Bus frequency where the UART is situated
*/
@@ -251,17 +78,18 @@ static void leon3_console_scan_uarts(void)
GAISLER_APBUART, find_matching_apbuart, NULL);
}
-/*
- * Console Device Driver Entry Points
- *
- */
-
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
+ const rtems_termios_device_handler *handler =
+#if CONSOLE_USE_INTERRUPTS
+ &apbuart_handler_interrupt;
+#else
+ &apbuart_handler_polled;
+#endif
rtems_status_code status;
int i;
char console_name[16];
@@ -297,7 +125,14 @@ rtems_device_driver console_initialize(
* On a MP system one should not open UARTs that other OS instances use.
*/
if (syscon_uart_index < uarts) {
- status = rtems_io_register_name("/dev/console", major, 0);
+ minor = 0;
+ status = rtems_termios_device_install(
+ CONSOLE_DEVICE_NAME,
+ major,
+ minor,
+ handler,
+ leon3_console_get_uart(syscon_uart_index)
+ );
if (status != RTEMS_SUCCESSFUL)
bsp_fatal(LEON3_FATAL_CONSOLE_REGISTER_DEV);
}
@@ -306,147 +141,15 @@ rtems_device_driver console_initialize(
if (i == syscon_uart_index)
continue; /* skip UART that is registered as /dev/console */
console_name[13] = 'a' + i;
- rtems_io_register_name( console_name, major, i+1);
+ minor = i + 1;
+ rtems_termios_device_install(
+ console_name,
+ major,
+ minor,
+ handler,
+ leon3_console_get_uart(syscon_uart_index)
+ );
}
return RTEMS_SUCCESSFUL;
}
-
-#if CONSOLE_USE_INTERRUPTS
-static struct rtems_termios_tty *leon3_console_get_tty(
- rtems_libio_open_close_args_t *args
-)
-{
- return args->iop->data1;
-}
-#endif
-
-static int leon3_console_first_open(int major, int minor, void *arg)
-{
- struct apbuart_priv *uart = leon3_console_get_uart(minor);
-
-#if CONSOLE_USE_INTERRUPTS
- rtems_status_code sc;
-
- uart->cookie = leon3_console_get_tty(arg);
-
- /* Register Interrupt handler */
- sc = rtems_interrupt_handler_install(uart->irq, "console",
- RTEMS_INTERRUPT_SHARED,
- leon3_console_isr,
- uart);
- if (sc != RTEMS_SUCCESSFUL)
- return -1;
-
- uart->sending = 0;
- /* Enable Receiver and transmitter and Turn on RX interrupts */
- uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE |
- APBUART_CTRL_RI;
-#else
- /* Initialize UART on opening */
- uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
-#endif
- uart->regs->status = 0;
-
- return 0;
-}
-
-#if CONSOLE_USE_INTERRUPTS
-static int leon3_console_last_close(int major, int minor, void *arg)
-{
- struct rtems_termios_tty *tty = leon3_console_get_tty(arg);
- struct apbuart_priv *uart = leon3_console_get_uart(minor);
- rtems_interrupt_lock_context lock_ctx;
-
- /* Turn off RX interrupts */
- rtems_termios_interrupt_lock_acquire(tty, &lock_ctx);
- uart->regs->ctrl &= ~(APBUART_CTRL_RI);
- rtems_termios_interrupt_lock_release(tty, &lock_ctx);
-
- /**** Flush device ****/
- while (uart->sending) {
- /* Wait until all data has been sent */
- }
-
- /* uninstall ISR */
- rtems_interrupt_handler_remove(uart->irq, leon3_console_isr, uart);
-
- return 0;
-}
-#endif
-
-rtems_device_driver console_open(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
-#if CONSOLE_USE_INTERRUPTS
- /* Interrupt mode routines */
- static const rtems_termios_callbacks Callbacks = {
- leon3_console_first_open, /* firstOpen */
- leon3_console_last_close, /* lastClose */
- NULL, /* pollRead */
- leon3_console_write_support, /* write */
- leon3_console_set_attributes,/* setAttributes */
- NULL, /* stopRemoteTx */
- NULL, /* startRemoteTx */
- 1 /* outputUsesInterrupts */
- };
-#else
- /* Polling mode routines */
- static const rtems_termios_callbacks Callbacks = {
- leon3_console_first_open, /* firstOpen */
- NULL, /* lastClose */
- leon3_console_pollRead, /* pollRead */
- leon3_console_write_polled, /* write */
- leon3_console_set_attributes,/* setAttributes */
- NULL, /* stopRemoteTx */
- NULL, /* startRemoteTx */
- 0 /* outputUsesInterrupts */
- };
-#endif
-
- assert(minor <= uarts);
- if (minor > uarts || minor == (syscon_uart_index + 1))
- return RTEMS_INVALID_NUMBER;
-
- return rtems_termios_open(major, minor, arg, &Callbacks);
-}
-
-rtems_device_driver console_close(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- return rtems_termios_close(arg);
-}
-
-rtems_device_driver console_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- return rtems_termios_read(arg);
-}
-
-rtems_device_driver console_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- return rtems_termios_write(arg);
-}
-
-rtems_device_driver console_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- return rtems_termios_ioctl(arg);
-}
-
diff --git a/c/src/lib/libbsp/sparc/leon3/preinstall.am b/c/src/lib/libbsp/sparc/leon3/preinstall.am
index 33e9041776..210558ebce 100644
--- a/c/src/lib/libbsp/sparc/leon3/preinstall.am
+++ b/c/src/lib/libbsp/sparc/leon3/preinstall.am
@@ -157,6 +157,10 @@ $(PROJECT_INCLUDE)/apbuart_pci.h: ../../sparc/shared/include/apbuart_pci.h $(PRO
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/apbuart_pci.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/apbuart_pci.h
+$(PROJECT_INCLUDE)/apbuart_termios.h: ../../sparc/shared/include/apbuart_termios.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/apbuart_termios.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/apbuart_termios.h
+
$(PROJECT_INCLUDE)/i2cmst.h: ../../sparc/shared/include/i2cmst.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i2cmst.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2cmst.h
diff --git a/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h b/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h
new file mode 100644
index 0000000000..4b54252518
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h
@@ -0,0 +1,40 @@
+/*
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modified for LEON3 BSP.
+ * COPYRIGHT (c) 2004.
+ * Gaisler Research.
+ *
+ * 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.
+ */
+
+#ifndef APBUART_TERMIOS_H
+#define APBUART_TERMIOS_H
+
+#include <rtems/termiostypes.h>
+#include <grlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct apbuart_context {
+ struct apbuart_regs *regs;
+ unsigned int freq_hz;
+ rtems_vector_number irq;
+ volatile int sending;
+ char *buf;
+};
+
+const rtems_termios_device_handler apbuart_handler_interrupt;
+
+const rtems_termios_device_handler apbuart_handler_polled;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* APBUART_TERMIOS_H */
diff --git a/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c b/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c
new file mode 100644
index 0000000000..4b69e1b3d2
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c
@@ -0,0 +1,240 @@
+/*
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modified for LEON3 BSP.
+ * COPYRIGHT (c) 2004.
+ * Gaisler Research.
+ *
+ * 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 <apbuart_termios.h>
+#include <apbuart.h>
+#include <bsp.h>
+
+static void apbuart_isr(void *arg)
+{
+ rtems_termios_tty *tty = arg;
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+ unsigned int status;
+ char data;
+
+ /* Get all received characters */
+ while ((status=uart->regs->status) & APBUART_STATUS_DR) {
+ /* Data has arrived, get new data */
+ data = uart->regs->data;
+
+ /* Tell termios layer about new character */
+ rtems_termios_enqueue_raw_characters(tty, &data, 1);
+ }
+
+ if (
+ (status & APBUART_STATUS_TE)
+ && (uart->regs->ctrl & APBUART_CTRL_TI) != 0
+ ) {
+ /* write_interrupt will get called from this function */
+ rtems_termios_dequeue_characters(tty, 1);
+ }
+}
+
+static void apbuart_write_support(
+ rtems_termios_tty *tty,
+ const char *buf,
+ size_t len
+)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+ int sending;
+
+ if (len > 0) {
+ /* Enable TX interrupt (interrupt is edge-triggered) */
+ uart->regs->ctrl |= APBUART_CTRL_TI;
+
+ /* start UART TX, this will result in an interrupt when done */
+ uart->regs->data = *buf;
+
+ sending = 1;
+ } else {
+ /* No more to send, disable TX interrupts */
+ uart->regs->ctrl &= ~APBUART_CTRL_TI;
+
+ /* Tell close that we sent everything */
+ sending = 0;
+ }
+
+ uart->sending = sending;
+}
+
+static void apbuart_write_polled(
+ rtems_termios_tty *tty,
+ const char *buf,
+ size_t len
+)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+ size_t nwrite = 0;
+
+ while (nwrite < len) {
+ apbuart_outbyte_polled(uart->regs, *buf++, 1, 0);
+ nwrite++;
+ }
+}
+
+static int apbuart_poll_read(rtems_termios_tty *tty)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+
+ return apbuart_inbyte_nonblocking(uart->regs);
+}
+
+static bool apbuart_set_attributes(
+ rtems_termios_tty *tty,
+ const struct termios *t
+)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+ rtems_interrupt_lock_context lock_context;
+ unsigned int scaler;
+ unsigned int ctrl;
+ int baud;
+
+ switch (t->c_cflag & CSIZE) {
+ default:
+ case CS5:
+ case CS6:
+ case CS7:
+ /* Hardware doesn't support other than CS8 */
+ return false;
+ case CS8:
+ break;
+ }
+
+ rtems_termios_interrupt_lock_acquire(tty, &lock_context);
+
+ /* Read out current value */
+ ctrl = uart->regs->ctrl;
+
+ switch (t->c_cflag & (PARENB|PARODD)) {
+ case (PARENB|PARODD):
+ /* Odd parity */
+ ctrl |= APBUART_CTRL_PE|APBUART_CTRL_PS;
+ break;
+
+ case PARENB:
+ /* Even parity */
+ ctrl &= ~APBUART_CTRL_PS;
+ ctrl |= APBUART_CTRL_PE;
+ break;
+
+ default:
+ case 0:
+ case PARODD:
+ /* No Parity */
+ ctrl &= ~(APBUART_CTRL_PS|APBUART_CTRL_PE);
+ }
+
+ if (!(t->c_cflag & CLOCAL)) {
+ ctrl |= APBUART_CTRL_FL;
+ } else {
+ ctrl &= ~APBUART_CTRL_FL;
+ }
+
+ /* Update new settings */
+ uart->regs->ctrl = ctrl;
+
+ rtems_termios_interrupt_lock_release(tty, &lock_context);
+
+ /* Baud rate */
+ baud = rtems_termios_baud_to_number(t->c_cflag);
+ if (baud > 0) {
+ /* Calculate Baud rate generator "scaler" number */
+ scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10;
+
+ /* Set new baud rate by setting scaler */
+ uart->regs->scaler = scaler;
+ }
+
+ return true;
+}
+
+static bool apbuart_first_open_polled(
+ rtems_termios_tty *tty,
+ rtems_libio_open_close_args_t *args
+)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+
+ /* Initialize UART on opening */
+ uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+ uart->regs->status = 0;
+
+ return true;
+}
+
+static bool apbuart_first_open_interrupt(
+ rtems_termios_tty *tty,
+ rtems_libio_open_close_args_t *args
+)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+ rtems_status_code sc;
+
+ /* Register Interrupt handler */
+ sc = rtems_interrupt_handler_install(uart->irq, "console",
+ RTEMS_INTERRUPT_SHARED,
+ apbuart_isr,
+ tty);
+ if (sc != RTEMS_SUCCESSFUL)
+ return false;
+
+ uart->sending = 0;
+ /* Enable Receiver and transmitter and Turn on RX interrupts */
+ uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE |
+ APBUART_CTRL_RI;
+ /* Initialize UART on opening */
+ uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+ uart->regs->status = 0;
+
+ return true;
+}
+
+static void apbuart_last_close_interrupt(
+ rtems_termios_tty *tty,
+ rtems_libio_open_close_args_t *args
+)
+{
+ struct apbuart_context *uart = rtems_termios_get_device_context(tty);
+ rtems_interrupt_lock_context lock_context;
+
+ /* Turn off RX interrupts */
+ rtems_termios_interrupt_lock_acquire(tty, &lock_context);
+ uart->regs->ctrl &= ~(APBUART_CTRL_RI);
+ rtems_termios_interrupt_lock_release(tty, &lock_context);
+
+ /**** Flush device ****/
+ while (uart->sending) {
+ /* Wait until all data has been sent */
+ }
+
+ /* uninstall ISR */
+ rtems_interrupt_handler_remove(uart->irq, apbuart_isr, tty);
+}
+
+const rtems_termios_device_handler apbuart_handler_interrupt = {
+ .first_open = apbuart_first_open_interrupt,
+ .last_close = apbuart_last_close_interrupt,
+ .write = apbuart_write_support,
+ .set_attributes = apbuart_set_attributes,
+ .mode = TERMIOS_IRQ_DRIVEN
+};
+
+const rtems_termios_device_handler apbuart_handler_polled = {
+ .first_open = apbuart_first_open_polled,
+ .poll_read = apbuart_poll_read,
+ .write = apbuart_write_polled,
+ .set_attributes = apbuart_set_attributes,
+ .mode = TERMIOS_POLLED
+};