Loading drivers/serial/8250.c +70 −3 Original line number Original line Diff line number Diff line Loading @@ -251,9 +251,53 @@ static const struct serial8250_config uart_config[] = { }, }, }; }; #ifdef CONFIG_SERIAL_8250_AU1X00 /* Au1x00 UART hardware has a weird register layout */ static const u8 au_io_in_map[] = { [UART_RX] = 0, [UART_IER] = 2, [UART_IIR] = 3, [UART_LCR] = 5, [UART_MCR] = 6, [UART_LSR] = 7, [UART_MSR] = 8, }; static const u8 au_io_out_map[] = { [UART_TX] = 1, [UART_IER] = 2, [UART_FCR] = 4, [UART_LCR] = 5, [UART_MCR] = 6, }; /* sane hardware needs no mapping */ static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) { if (up->port.iotype != UPIO_AU) return offset; return au_io_in_map[offset]; } static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) { if (up->port.iotype != UPIO_AU) return offset; return au_io_out_map[offset]; } #else /* sane hardware needs no mapping */ #define map_8250_in_reg(up, offset) (offset) #define map_8250_out_reg(up, offset) (offset) #endif static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) { { offset <<= up->port.regshift; offset = map_8250_in_reg(up, offset) << up->port.regshift; switch (up->port.iotype) { switch (up->port.iotype) { case UPIO_HUB6: case UPIO_HUB6: Loading @@ -266,6 +310,11 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) case UPIO_MEM32: case UPIO_MEM32: return readl(up->port.membase + offset); return readl(up->port.membase + offset); #ifdef CONFIG_SERIAL_8250_AU1X00 case UPIO_AU: return __raw_readl(up->port.membase + offset); #endif default: default: return inb(up->port.iobase + offset); return inb(up->port.iobase + offset); } } Loading @@ -274,7 +323,7 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) static _INLINE_ void static _INLINE_ void serial_out(struct uart_8250_port *up, int offset, int value) serial_out(struct uart_8250_port *up, int offset, int value) { { offset <<= up->port.regshift; offset = map_8250_out_reg(up, offset) << up->port.regshift; switch (up->port.iotype) { switch (up->port.iotype) { case UPIO_HUB6: case UPIO_HUB6: Loading @@ -290,6 +339,12 @@ serial_out(struct uart_8250_port *up, int offset, int value) writel(value, up->port.membase + offset); writel(value, up->port.membase + offset); break; break; #ifdef CONFIG_SERIAL_8250_AU1X00 case UPIO_AU: __raw_writel(value, up->port.membase + offset); break; #endif default: default: outb(value, up->port.iobase + offset); outb(value, up->port.iobase + offset); } } Loading Loading @@ -910,6 +965,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) } } } } #endif #endif #ifdef CONFIG_SERIAL_8250_AU1X00 /* if access method is AU, it is a 16550 with a quirk */ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) up->bugs |= UART_BUG_NOMSR; #endif serial_outp(up, UART_LCR, save_lcr); serial_outp(up, UART_LCR, save_lcr); if (up->capabilities != uart_config[up->port.type].flags) { if (up->capabilities != uart_config[up->port.type].flags) { Loading Loading @@ -1057,6 +1119,10 @@ static void serial8250_enable_ms(struct uart_port *port) { { struct uart_8250_port *up = (struct uart_8250_port *)port; struct uart_8250_port *up = (struct uart_8250_port *)port; /* no MSR capabilities */ if (up->bugs & UART_BUG_NOMSR) return; up->ier |= UART_IER_MSI; up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_IER, up->ier); } } Loading Loading @@ -1774,7 +1840,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, * CTS flow control flag and modem status interrupts * CTS flow control flag and modem status interrupts */ */ up->ier &= ~UART_IER_MSI; up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) if (!(up->bugs & UART_BUG_NOMSR) && UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; up->ier |= UART_IER_MSI; if (up->capabilities & UART_CAP_UUE) if (up->capabilities & UART_CAP_UUE) up->ier |= UART_IER_UUE | UART_IER_RTOIE; up->ier |= UART_IER_UUE | UART_IER_RTOIE; Loading drivers/serial/8250.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct serial8250_config { #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ #if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) #if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) #define _INLINE_ inline #define _INLINE_ inline Loading drivers/serial/8250_au1x00.c 0 → 100644 +102 −0 Original line number Original line Diff line number Diff line /* * Serial Device Initialisation for Au1x00 * * (C) Copyright Embedded Alley Solutions, Inc 2005 * Author: Pantelis Antoniou <pantelis@embeddedalley.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/module.h> #include <linux/serial_core.h> #include <linux/signal.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/serial_8250.h> #include <asm/mach-au1x00/au1000.h> #include "8250.h" #define PORT(_base, _irq) \ { \ .iobase = _base, \ .membase = (void __iomem *)_base,\ .mapbase = _base, \ .irq = _irq, \ .uartclk = 0, /* filled */ \ .regshift = 2, \ .iotype = UPIO_AU, \ .flags = UPF_SKIP_TEST | \ UPF_IOREMAP, \ } static struct plat_serial8250_port au1x00_data[] = { #if defined(CONFIG_SOC_AU1000) PORT(UART0_ADDR, AU1000_UART0_INT), PORT(UART1_ADDR, AU1000_UART1_INT), PORT(UART2_ADDR, AU1000_UART2_INT), PORT(UART3_ADDR, AU1000_UART3_INT), #elif defined(CONFIG_SOC_AU1500) PORT(UART0_ADDR, AU1500_UART0_INT), PORT(UART3_ADDR, AU1500_UART3_INT), #elif defined(CONFIG_SOC_AU1100) PORT(UART0_ADDR, AU1100_UART0_INT), PORT(UART1_ADDR, AU1100_UART1_INT), PORT(UART2_ADDR, AU1100_UART2_INT), PORT(UART3_ADDR, AU1100_UART3_INT), #elif defined(CONFIG_SOC_AU1550) PORT(UART0_ADDR, AU1550_UART0_INT), PORT(UART1_ADDR, AU1550_UART1_INT), PORT(UART2_ADDR, AU1550_UART2_INT), PORT(UART3_ADDR, AU1550_UART3_INT), #elif defined(CONFIG_SOC_AU1200) PORT(UART0_ADDR, AU1200_UART0_INT), PORT(UART1_ADDR, AU1200_UART1_INT), #endif { }, }; static struct platform_device au1x00_device = { .name = "serial8250", .id = PLAT8250_DEV_AU1X00, .dev = { .platform_data = au1x00_data, }, }; static int __init au1x00_init(void) { int i; unsigned int uartclk; /* get uart clock */ uartclk = get_au1x00_uart_baud_base() * 16; /* fill up uartclk */ for (i = 0; au1x00_data[i].flags ; i++) au1x00_data[i].uartclk = uartclk; return platform_device_register(&au1x00_device); } /* XXX: Yes, I know this doesn't yet work. */ static void __exit au1x00_exit(void) { platform_device_unregister(&au1x00_device); } module_init(au1x00_init); module_exit(au1x00_exit); MODULE_AUTHOR("Pantelis Antoniou <pantelis@embeddedalley.com>"); MODULE_DESCRIPTION("8250 serial probe module for Au1x000 cards"); MODULE_LICENSE("GPL"); drivers/serial/Kconfig +8 −0 Original line number Original line Diff line number Diff line Loading @@ -207,6 +207,14 @@ config SERIAL_8250_ACORN system, say Y to this option. The driver can handle 1, 2, or 3 port system, say Y to this option. The driver can handle 1, 2, or 3 port cards. If unsure, say N. cards. If unsure, say N. config SERIAL_8250_AU1X00 bool "AU1X00 serial port support" depends on SERIAL_8250 != n && SOC_AU1X00 help If you have an Au1x00 board and want to use the serial port, say Y to this option. The driver can handle 1 or 2 serial ports. If unsure, say N. comment "Non-8250 serial port support" comment "Non-8250 serial port support" config SERIAL_AMBA_PL010 config SERIAL_AMBA_PL010 Loading drivers/serial/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o Loading Loading
drivers/serial/8250.c +70 −3 Original line number Original line Diff line number Diff line Loading @@ -251,9 +251,53 @@ static const struct serial8250_config uart_config[] = { }, }, }; }; #ifdef CONFIG_SERIAL_8250_AU1X00 /* Au1x00 UART hardware has a weird register layout */ static const u8 au_io_in_map[] = { [UART_RX] = 0, [UART_IER] = 2, [UART_IIR] = 3, [UART_LCR] = 5, [UART_MCR] = 6, [UART_LSR] = 7, [UART_MSR] = 8, }; static const u8 au_io_out_map[] = { [UART_TX] = 1, [UART_IER] = 2, [UART_FCR] = 4, [UART_LCR] = 5, [UART_MCR] = 6, }; /* sane hardware needs no mapping */ static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) { if (up->port.iotype != UPIO_AU) return offset; return au_io_in_map[offset]; } static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) { if (up->port.iotype != UPIO_AU) return offset; return au_io_out_map[offset]; } #else /* sane hardware needs no mapping */ #define map_8250_in_reg(up, offset) (offset) #define map_8250_out_reg(up, offset) (offset) #endif static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) { { offset <<= up->port.regshift; offset = map_8250_in_reg(up, offset) << up->port.regshift; switch (up->port.iotype) { switch (up->port.iotype) { case UPIO_HUB6: case UPIO_HUB6: Loading @@ -266,6 +310,11 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) case UPIO_MEM32: case UPIO_MEM32: return readl(up->port.membase + offset); return readl(up->port.membase + offset); #ifdef CONFIG_SERIAL_8250_AU1X00 case UPIO_AU: return __raw_readl(up->port.membase + offset); #endif default: default: return inb(up->port.iobase + offset); return inb(up->port.iobase + offset); } } Loading @@ -274,7 +323,7 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) static _INLINE_ void static _INLINE_ void serial_out(struct uart_8250_port *up, int offset, int value) serial_out(struct uart_8250_port *up, int offset, int value) { { offset <<= up->port.regshift; offset = map_8250_out_reg(up, offset) << up->port.regshift; switch (up->port.iotype) { switch (up->port.iotype) { case UPIO_HUB6: case UPIO_HUB6: Loading @@ -290,6 +339,12 @@ serial_out(struct uart_8250_port *up, int offset, int value) writel(value, up->port.membase + offset); writel(value, up->port.membase + offset); break; break; #ifdef CONFIG_SERIAL_8250_AU1X00 case UPIO_AU: __raw_writel(value, up->port.membase + offset); break; #endif default: default: outb(value, up->port.iobase + offset); outb(value, up->port.iobase + offset); } } Loading Loading @@ -910,6 +965,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) } } } } #endif #endif #ifdef CONFIG_SERIAL_8250_AU1X00 /* if access method is AU, it is a 16550 with a quirk */ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) up->bugs |= UART_BUG_NOMSR; #endif serial_outp(up, UART_LCR, save_lcr); serial_outp(up, UART_LCR, save_lcr); if (up->capabilities != uart_config[up->port.type].flags) { if (up->capabilities != uart_config[up->port.type].flags) { Loading Loading @@ -1057,6 +1119,10 @@ static void serial8250_enable_ms(struct uart_port *port) { { struct uart_8250_port *up = (struct uart_8250_port *)port; struct uart_8250_port *up = (struct uart_8250_port *)port; /* no MSR capabilities */ if (up->bugs & UART_BUG_NOMSR) return; up->ier |= UART_IER_MSI; up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_IER, up->ier); } } Loading Loading @@ -1774,7 +1840,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, * CTS flow control flag and modem status interrupts * CTS flow control flag and modem status interrupts */ */ up->ier &= ~UART_IER_MSI; up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) if (!(up->bugs & UART_BUG_NOMSR) && UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; up->ier |= UART_IER_MSI; if (up->capabilities & UART_CAP_UUE) if (up->capabilities & UART_CAP_UUE) up->ier |= UART_IER_UUE | UART_IER_RTOIE; up->ier |= UART_IER_UUE | UART_IER_RTOIE; Loading
drivers/serial/8250.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct serial8250_config { #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ #if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) #if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) #define _INLINE_ inline #define _INLINE_ inline Loading
drivers/serial/8250_au1x00.c 0 → 100644 +102 −0 Original line number Original line Diff line number Diff line /* * Serial Device Initialisation for Au1x00 * * (C) Copyright Embedded Alley Solutions, Inc 2005 * Author: Pantelis Antoniou <pantelis@embeddedalley.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/module.h> #include <linux/serial_core.h> #include <linux/signal.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/serial_8250.h> #include <asm/mach-au1x00/au1000.h> #include "8250.h" #define PORT(_base, _irq) \ { \ .iobase = _base, \ .membase = (void __iomem *)_base,\ .mapbase = _base, \ .irq = _irq, \ .uartclk = 0, /* filled */ \ .regshift = 2, \ .iotype = UPIO_AU, \ .flags = UPF_SKIP_TEST | \ UPF_IOREMAP, \ } static struct plat_serial8250_port au1x00_data[] = { #if defined(CONFIG_SOC_AU1000) PORT(UART0_ADDR, AU1000_UART0_INT), PORT(UART1_ADDR, AU1000_UART1_INT), PORT(UART2_ADDR, AU1000_UART2_INT), PORT(UART3_ADDR, AU1000_UART3_INT), #elif defined(CONFIG_SOC_AU1500) PORT(UART0_ADDR, AU1500_UART0_INT), PORT(UART3_ADDR, AU1500_UART3_INT), #elif defined(CONFIG_SOC_AU1100) PORT(UART0_ADDR, AU1100_UART0_INT), PORT(UART1_ADDR, AU1100_UART1_INT), PORT(UART2_ADDR, AU1100_UART2_INT), PORT(UART3_ADDR, AU1100_UART3_INT), #elif defined(CONFIG_SOC_AU1550) PORT(UART0_ADDR, AU1550_UART0_INT), PORT(UART1_ADDR, AU1550_UART1_INT), PORT(UART2_ADDR, AU1550_UART2_INT), PORT(UART3_ADDR, AU1550_UART3_INT), #elif defined(CONFIG_SOC_AU1200) PORT(UART0_ADDR, AU1200_UART0_INT), PORT(UART1_ADDR, AU1200_UART1_INT), #endif { }, }; static struct platform_device au1x00_device = { .name = "serial8250", .id = PLAT8250_DEV_AU1X00, .dev = { .platform_data = au1x00_data, }, }; static int __init au1x00_init(void) { int i; unsigned int uartclk; /* get uart clock */ uartclk = get_au1x00_uart_baud_base() * 16; /* fill up uartclk */ for (i = 0; au1x00_data[i].flags ; i++) au1x00_data[i].uartclk = uartclk; return platform_device_register(&au1x00_device); } /* XXX: Yes, I know this doesn't yet work. */ static void __exit au1x00_exit(void) { platform_device_unregister(&au1x00_device); } module_init(au1x00_init); module_exit(au1x00_exit); MODULE_AUTHOR("Pantelis Antoniou <pantelis@embeddedalley.com>"); MODULE_DESCRIPTION("8250 serial probe module for Au1x000 cards"); MODULE_LICENSE("GPL");
drivers/serial/Kconfig +8 −0 Original line number Original line Diff line number Diff line Loading @@ -207,6 +207,14 @@ config SERIAL_8250_ACORN system, say Y to this option. The driver can handle 1, 2, or 3 port system, say Y to this option. The driver can handle 1, 2, or 3 port cards. If unsure, say N. cards. If unsure, say N. config SERIAL_8250_AU1X00 bool "AU1X00 serial port support" depends on SERIAL_8250 != n && SOC_AU1X00 help If you have an Au1x00 board and want to use the serial port, say Y to this option. The driver can handle 1 or 2 serial ports. If unsure, say N. comment "Non-8250 serial port support" comment "Non-8250 serial port support" config SERIAL_AMBA_PL010 config SERIAL_AMBA_PL010 Loading
drivers/serial/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o Loading