serial8250: Add dl_read()/dl_write() callbacks
authorMagnus Damm <damm@opensource.se>
Wed, 2 May 2012 12:46:51 +0000 (21:46 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 May 2012 21:04:40 +0000 (14:04 -0700)
Convert serial_dl_read() and serial_dl_write() from macro
to 8250 specific callbacks. This change makes it easier to
support 8250 hardware with non-standard DLL and DLM register
configurations such as Alchemy, RM9K and upcoming Emma Mobile
UART hardware.

Signed-off-by: Magnus Damm <damm@opensource.se>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250.h

index c9ac4eabe35a7c76b6b4eb5ce50600be80e37885..590ee85150bf880296015517e81e59f5161a2b8b 100644 (file)
@@ -284,6 +284,66 @@ static const struct serial8250_config uart_config[] = {
        },
 };
 
+/* Uart divisor latch read */
+static int default_dl_read(struct uart_8250_port *up)
+{
+       return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static void default_dl_write(struct uart_8250_port *up, int value)
+{
+       serial_out(up, UART_DLL, value & 0xff);
+       serial_out(up, UART_DLM, value >> 8 & 0xff);
+}
+
+#if defined(CONFIG_MIPS_ALCHEMY)
+/* Au1x00 haven't got a standard divisor latch */
+static int _serial_dl_read(struct uart_8250_port *up)
+{
+       if (up->port.iotype == UPIO_AU)
+               return __raw_readl(up->port.membase + 0x28);
+       else
+               return default_dl_read(up);
+}
+
+static void _serial_dl_write(struct uart_8250_port *up, int value)
+{
+       if (up->port.iotype == UPIO_AU)
+               __raw_writel(value, up->port.membase + 0x28);
+       else
+               default_dl_write(up, value);
+}
+#elif defined(CONFIG_SERIAL_8250_RM9K)
+static int _serial_dl_read(struct uart_8250_port *up)
+{
+       return  (up->port.iotype == UPIO_RM9000) ?
+               (((__raw_readl(up->port.membase + 0x10) << 8) |
+               (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
+               default_dl_read(up);
+}
+
+static void _serial_dl_write(struct uart_8250_port *up, int value)
+{
+       if (up->port.iotype == UPIO_RM9000) {
+               __raw_writel(value, up->port.membase + 0x08);
+               __raw_writel(value >> 8, up->port.membase + 0x10);
+       } else {
+               default_dl_write(up, value);
+       }
+}
+#else
+static int _serial_dl_read(struct uart_8250_port *up)
+{
+       return default_dl_read(up);
+}
+
+static void _serial_dl_write(struct uart_8250_port *up, int value)
+{
+       default_dl_write(up, value);
+}
+#endif
+
 #if defined(CONFIG_MIPS_ALCHEMY)
 
 /* Au1x00 UART hardware has a weird register layout */
@@ -434,6 +494,10 @@ static void set_io_from_upio(struct uart_port *p)
 {
        struct uart_8250_port *up =
                container_of(p, struct uart_8250_port, port);
+
+       up->dl_read = _serial_dl_read;
+       up->dl_write = _serial_dl_write;
+
        switch (p->iotype) {
        case UPIO_HUB6:
                p->serial_in = hub6_serial_in;
@@ -481,59 +545,6 @@ serial_port_out_sync(struct uart_port *p, int offset, int value)
        }
 }
 
-/* Uart divisor latch read */
-static inline int _serial_dl_read(struct uart_8250_port *up)
-{
-       return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
-}
-
-/* Uart divisor latch write */
-static inline void _serial_dl_write(struct uart_8250_port *up, int value)
-{
-       serial_out(up, UART_DLL, value & 0xff);
-       serial_out(up, UART_DLM, value >> 8 & 0xff);
-}
-
-#if defined(CONFIG_MIPS_ALCHEMY)
-/* Au1x00 haven't got a standard divisor latch */
-static int serial_dl_read(struct uart_8250_port *up)
-{
-       if (up->port.iotype == UPIO_AU)
-               return __raw_readl(up->port.membase + 0x28);
-       else
-               return _serial_dl_read(up);
-}
-
-static void serial_dl_write(struct uart_8250_port *up, int value)
-{
-       if (up->port.iotype == UPIO_AU)
-               __raw_writel(value, up->port.membase + 0x28);
-       else
-               _serial_dl_write(up, value);
-}
-#elif defined(CONFIG_SERIAL_8250_RM9K)
-static int serial_dl_read(struct uart_8250_port *up)
-{
-       return  (up->port.iotype == UPIO_RM9000) ?
-               (((__raw_readl(up->port.membase + 0x10) << 8) |
-               (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
-               _serial_dl_read(up);
-}
-
-static void serial_dl_write(struct uart_8250_port *up, int value)
-{
-       if (up->port.iotype == UPIO_RM9000) {
-               __raw_writel(value, up->port.membase + 0x08);
-               __raw_writel(value >> 8, up->port.membase + 0x10);
-       } else {
-               _serial_dl_write(up, value);
-       }
-}
-#else
-#define serial_dl_read(up) _serial_dl_read(up)
-#define serial_dl_write(up, value) _serial_dl_write(up, value)
-#endif
-
 /*
  * For the 16C950
  */
index c9d0ebe952fc69d7583eebb46d32f4171a4cc60d..f9719d167c8d74f3159d995b09899bc52eab8294 100644 (file)
@@ -37,6 +37,10 @@ struct uart_8250_port {
        unsigned char           lsr_saved_flags;
 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
        unsigned char           msr_saved_flags;
+
+       /* 8250 specific callbacks */
+       int                     (*dl_read)(struct uart_8250_port *);
+       void                    (*dl_write)(struct uart_8250_port *, int);
 };
 
 struct old_serial_port {
@@ -98,6 +102,16 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
 
 void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
 
+static inline int serial_dl_read(struct uart_8250_port *up)
+{
+       return up->dl_read(up);
+}
+
+static inline void serial_dl_write(struct uart_8250_port *up, int value)
+{
+       up->dl_write(up, value);
+}
+
 #if defined(__alpha__) && !defined(CONFIG_PCI)
 /*
  * Digital did something really horribly wrong with the OUT1 and OUT2