U6715 16550A serial driver support
[linux-2.6.git] / include / linux / serial_core.h
index 1d2faa6..8129ca2 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef LINUX_SERIAL_CORE_H
 #define LINUX_SERIAL_CORE_H
 
+#include <linux/serial.h>
+
 /*
  * The type definitions.  These are from Ted Ts'o's serial.h
  */
@@ -40,7 +42,9 @@
 #define PORT_NS16550A  14
 #define PORT_XSCALE    15
 #define PORT_RM9000    16      /* PMC-Sierra RM9xxx internal UART */
-#define PORT_MAX_8250  16      /* max port ID */
+#define PORT_OCTEON    17      /* Cavium OCTEON internal UART */
+#define PORT_AR7       18      /* Texas Instruments AR7 internal UART */
+#define PORT_MAX_8250  18      /* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
@@ -59,9 +63,6 @@
 #define PORT_SUNZILOG  38
 #define PORT_SUNSAB    39
 
-/* NEC v850.  */
-#define PORT_V850E_UART        40
-
 /* DEC */
 #define PORT_DZ                46
 #define PORT_ZS                47
 
 #define PORT_SC26XX    82
 
+/* SH-SCI */
+#define PORT_SCIFA     83
+
+#define PORT_S3C6400   84
+
+/* NWPSERIAL */
+#define PORT_NWPSERIAL 85
+
+/* MAX3100 */
+#define PORT_MAX3100    86
+
+/* Timberdale UART */
+#define PORT_TIMBUART  87
+
+/* Qualcomm MSM SoCs */
+#define PORT_MSM       88
+
+/* BCM63xx family SoCs */
+#define PORT_BCM63XX   89
+
+/* Aeroflex Gaisler GRLIB APBUART */
+#define PORT_APBUART    90
+
+/* Altera UARTs */
+#define PORT_ALTERA_JTAGUART   91
+#define PORT_ALTERA_UART       92
+
+/* MAX3107 */
+#define PORT_MAX3107   94
+
+/* High Speed UART for Medfield */
+#define PORT_MFD       95
+
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
 #include <linux/sysrq.h>
 
 struct uart_port;
-struct uart_info;
 struct serial_struct;
 struct device;
 
@@ -193,7 +226,7 @@ struct uart_ops {
        void            (*flush_buffer)(struct uart_port *);
        void            (*set_termios)(struct uart_port *, struct ktermios *new,
                                       struct ktermios *old);
-       void            (*set_ldisc)(struct uart_port *);
+       void            (*set_ldisc)(struct uart_port *, int new);
        void            (*pm)(struct uart_port *, unsigned int state,
                              unsigned int oldstate);
        int             (*set_wake)(struct uart_port *, unsigned int state);
@@ -223,6 +256,7 @@ struct uart_ops {
 #endif
 };
 
+#define NO_POLL_CHAR           0x00ff0000
 #define UART_CONFIG_TYPE       (1 << 0)
 #define UART_CONFIG_IRQ                (1 << 1)
 
@@ -244,9 +278,15 @@ typedef unsigned int __bitwise__ upf_t;
 
 struct uart_port {
        spinlock_t              lock;                   /* port lock */
-       unsigned int            iobase;                 /* in/out[bwl] */
+       unsigned long           iobase;                 /* in/out[bwl] */
        unsigned char __iomem   *membase;               /* read/write[bwl] */
+       unsigned int            (*serial_in)(struct uart_port *, int);
+       void                    (*serial_out)(struct uart_port *, int, int);
+       void                    (*set_termios)(struct uart_port *,
+                                              struct ktermios *new,
+                                              struct ktermios *old);
        unsigned int            irq;                    /* irq number */
+       unsigned long           irqflags;               /* irq flags  */
        unsigned int            uartclk;                /* base uart clock */
        unsigned int            fifosize;               /* tx fifo size */
        unsigned char           x_char;                 /* xon/xoff char */
@@ -265,11 +305,11 @@ struct uart_port {
 
        unsigned int            read_status_mask;       /* driver specific */
        unsigned int            ignore_status_mask;     /* driver specific */
-       struct uart_info        *info;                  /* pointer to parent info */
+       struct uart_state       *state;                 /* pointer to parent state */
        struct uart_icount      icount;                 /* statistics */
 
        struct console          *cons;                  /* struct console, if any */
-#ifdef CONFIG_SERIAL_CORE_CONSOLE
+#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)
        unsigned long           sysrq;                  /* sysrq timeout */
 #endif
 
@@ -288,9 +328,12 @@ struct uart_port {
 #define UPF_HARDPPS_CD         ((__force upf_t) (1 << 11))
 #define UPF_LOW_LATENCY                ((__force upf_t) (1 << 13))
 #define UPF_BUGGY_UART         ((__force upf_t) (1 << 14))
+#define UPF_NO_TXEN_TEST       ((__force upf_t) (1 << 15))
 #define UPF_MAGIC_MULTIPLIER   ((__force upf_t) (1 << 16))
 #define UPF_CONS_FLOW          ((__force upf_t) (1 << 23))
 #define UPF_SHARE_IRQ          ((__force upf_t) (1 << 24))
+/* The exact UART type is known and should not be probed.  */
+#define UPF_FIXED_TYPE         ((__force upf_t) (1 << 27))
 #define UPF_BOOT_AUTOCONF      ((__force upf_t) (1 << 28))
 #define UPF_FIXED_PORT         ((__force upf_t) (1 << 29))
 #define UPF_DEAD               ((__force upf_t) (1 << 30))
@@ -315,56 +358,19 @@ struct uart_port {
 
 /*
  * This is the state information which is persistent across opens.
- * The low level driver must not to touch any elements contained
- * within.
  */
 struct uart_state {
-       unsigned int            close_delay;            /* msec */
-       unsigned int            closing_wait;           /* msec */
-
-#define USF_CLOSING_WAIT_INF   (0)
-#define USF_CLOSING_WAIT_NONE  (~0U)
+       struct tty_port         port;
 
-       int                     count;
        int                     pm_state;
-       struct uart_info        *info;
-       struct uart_port        *port;
+       struct circ_buf         xmit;
 
-       struct mutex            mutex;
+       struct tasklet_struct   tlet;
+       struct uart_port        *uart_port;
 };
 
 #define UART_XMIT_SIZE PAGE_SIZE
 
-typedef unsigned int __bitwise__ uif_t;
-
-/*
- * This is the state information which is only valid when the port
- * is open; it may be freed by the core driver once the device has
- * been closed.  Either the low level driver or the core can modify
- * stuff here.
- */
-struct uart_info {
-       struct tty_struct       *tty;
-       struct circ_buf         xmit;
-       uif_t                   flags;
-
-/*
- * Definitions for info->flags.  These are _private_ to serial_core, and
- * are specific to this structure.  They may be queried by low level drivers.
- */
-#define UIF_CHECK_CD           ((__force uif_t) (1 << 25))
-#define UIF_CTS_FLOW           ((__force uif_t) (1 << 26))
-#define UIF_NORMAL_ACTIVE      ((__force uif_t) (1 << 29))
-#define UIF_INITIALIZED                ((__force uif_t) (1 << 31))
-#define UIF_SUSPENDED          ((__force uif_t) (1 << 30))
-
-       int                     blocked_open;
-
-       struct tasklet_struct   tlet;
-
-       wait_queue_head_t       open_wait;
-       wait_queue_head_t       delta_msr_wait;
-};
 
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS           256
@@ -439,8 +445,13 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
 #define uart_circ_chars_free(circ)     \
        (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
 
-#define uart_tx_stopped(port)          \
-       ((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
+static inline int uart_tx_stopped(struct uart_port *port)
+{
+       struct tty_struct *tty = port->state->port.tty;
+       if(tty->stopped || tty->hw_stopped)
+               return 1;
+       return 0;
+}
 
 /*
  * The following are helper functions for the low level drivers.
@@ -451,7 +462,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
 #ifdef SUPPORT_SYSRQ
        if (port->sysrq) {
                if (ch && time_before(jiffies, port->sysrq)) {
-                       handle_sysrq(ch, port->info ? port->info->tty : NULL);
+                       handle_sysrq(ch, port->state->port.tty);
                        port->sysrq = 0;
                        return 1;
                }
@@ -469,7 +480,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
  */
 static inline int uart_handle_break(struct uart_port *port)
 {
-       struct uart_info *info = port->info;
+       struct uart_state *state = port->state;
 #ifdef SUPPORT_SYSRQ
        if (port->cons && port->cons->index == port->line) {
                if (!port->sysrq) {
@@ -480,59 +491,69 @@ static inline int uart_handle_break(struct uart_port *port)
        }
 #endif
        if (port->flags & UPF_SAK)
-               do_SAK(info->tty);
+               do_SAK(state->port.tty);
        return 0;
 }
 
 /**
  *     uart_handle_dcd_change - handle a change of carrier detect state
- *     @port: uart_port structure for the open port
+ *     @uport: uart_port structure for the open port
  *     @status: new carrier detect status, nonzero if active
  */
 static inline void
-uart_handle_dcd_change(struct uart_port *port, unsigned int status)
+uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
 {
-       struct uart_info *info = port->info;
+       struct uart_state *state = uport->state;
+       struct tty_port *port = &state->port;
+       struct tty_ldisc *ld = tty_ldisc_ref(port->tty);
+       struct timespec ts;
 
-       port->icount.dcd++;
+       if (ld && ld->ops->dcd_change)
+               getnstimeofday(&ts);
 
+       uport->icount.dcd++;
 #ifdef CONFIG_HARD_PPS
-       if ((port->flags & UPF_HARDPPS_CD) && status)
+       if ((uport->flags & UPF_HARDPPS_CD) && status)
                hardpps();
 #endif
 
-       if (info->flags & UIF_CHECK_CD) {
+       if (port->flags & ASYNC_CHECK_CD) {
                if (status)
-                       wake_up_interruptible(&info->open_wait);
-               else if (info->tty)
-                       tty_hangup(info->tty);
+                       wake_up_interruptible(&port->open_wait);
+               else if (port->tty)
+                       tty_hangup(port->tty);
        }
+
+       if (ld && ld->ops->dcd_change)
+               ld->ops->dcd_change(port->tty, status, &ts);
+       if (ld)
+               tty_ldisc_deref(ld);
 }
 
 /**
  *     uart_handle_cts_change - handle a change of clear-to-send state
- *     @port: uart_port structure for the open port
+ *     @uport: uart_port structure for the open port
  *     @status: new clear to send status, nonzero if active
  */
 static inline void
-uart_handle_cts_change(struct uart_port *port, unsigned int status)
+uart_handle_cts_change(struct uart_port *uport, unsigned int status)
 {
-       struct uart_info *info = port->info;
-       struct tty_struct *tty = info->tty;
+       struct tty_port *port = &uport->state->port;
+       struct tty_struct *tty = port->tty;
 
-       port->icount.cts++;
+       uport->icount.cts++;
 
-       if (info->flags & UIF_CTS_FLOW) {
+       if (port->flags & ASYNC_CTS_FLOW) {
                if (tty->hw_stopped) {
                        if (status) {
                                tty->hw_stopped = 0;
-                               port->ops->start_tx(port);
-                               uart_write_wakeup(port);
+                               uport->ops->start_tx(uport);
+                               uart_write_wakeup(uport);
                        }
                } else {
                        if (!status) {
                                tty->hw_stopped = 1;
-                               port->ops->stop_tx(port);
+                               uport->ops->stop_tx(uport);
                        }
                }
        }
@@ -544,7 +565,7 @@ static inline void
 uart_insert_char(struct uart_port *port, unsigned int status,
                 unsigned int overrun, unsigned int ch, unsigned int flag)
 {
-       struct tty_struct *tty = port->info->tty;
+       struct tty_struct *tty = port->state->port.tty;
 
        if ((status & port->ignore_status_mask & ~overrun) == 0)
                tty_insert_flip_char(tty, ch, flag);