Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 085f20e4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/home/rmk/linux-2.6-serial

parents 3c726f8d 21c614a7
Loading
Loading
Loading
Loading
+70 −3
Original line number Original line Diff line number Diff line
@@ -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:
@@ -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);
	}
	}
@@ -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:
@@ -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);
	}
	}
@@ -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) {
@@ -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);
}
}
@@ -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;
+1 −0
Original line number Original line Diff line number Diff line
@@ -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
+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");
+8 −0
Original line number Original line Diff line number Diff line
@@ -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
+1 −0
Original line number Original line Diff line number Diff line
@@ -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