aboutsummaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/68360serial.c51
-rw-r--r--drivers/serial/8250.c71
-rw-r--r--drivers/serial/Kconfig14
-rw-r--r--drivers/serial/altera_uart.c156
-rw-r--r--drivers/serial/bfin_sport_uart.c9
-rw-r--r--drivers/serial/bfin_sport_uart.h2
-rw-r--r--drivers/serial/imx.c5
-rw-r--r--drivers/serial/ioc3_serial.c4
-rw-r--r--drivers/serial/jsm/jsm_driver.c4
-rw-r--r--drivers/serial/kgdboc.c2
-rw-r--r--drivers/serial/max3107.c34
-rw-r--r--drivers/serial/mfd.c49
-rw-r--r--drivers/serial/mrst_max3110.c358
-rw-r--r--drivers/serial/mrst_max3110.h1
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/serial/serial_core.c49
-rw-r--r--drivers/serial/serial_cs.c205
-rw-r--r--drivers/serial/uartlite.c28
18 files changed, 608 insertions, 436 deletions
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index 0dff3bbddc8..88b13356ec1 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -1381,6 +1381,30 @@ static void send_break(ser_info_t *info, unsigned int duration)
}
+/*
+ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+ * Return: write counters to the user passed counter struct
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+static int rs_360_get_icount(struct tty_struct *tty,
+ struct serial_icounter_struct *icount)
+{
+ ser_info_t *info = (ser_info_t *)tty->driver_data;
+ struct async_icount cnow;
+
+ local_irq_disable();
+ cnow = info->state->icount;
+ local_irq_enable();
+
+ icount->cts = cnow.cts;
+ icount->dsr = cnow.dsr;
+ icount->rng = cnow.rng;
+ icount->dcd = cnow.dcd;
+
+ return 0;
+}
+
static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{
@@ -1394,7 +1418,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
- if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+ if (cmd != TIOCMIWAIT) {
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
}
@@ -1477,31 +1501,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
return 0;
#endif
- /*
- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
- * Return: write counters to the user passed counter struct
- * NB: both 1->0 and 0->1 transitions are counted except for
- * RI where only 0->1 is counted.
- */
- case TIOCGICOUNT:
- local_irq_disable();
- cnow = info->state->icount;
- local_irq_enable();
- p_cuser = (struct serial_icounter_struct *) arg;
-/* error = put_user(cnow.cts, &p_cuser->cts); */
-/* if (error) return error; */
-/* error = put_user(cnow.dsr, &p_cuser->dsr); */
-/* if (error) return error; */
-/* error = put_user(cnow.rng, &p_cuser->rng); */
-/* if (error) return error; */
-/* error = put_user(cnow.dcd, &p_cuser->dcd); */
-/* if (error) return error; */
-
- put_user(cnow.cts, &p_cuser->cts);
- put_user(cnow.dsr, &p_cuser->dsr);
- put_user(cnow.rng, &p_cuser->rng);
- put_user(cnow.dcd, &p_cuser->dcd);
- return 0;
default:
return -ENOIOCTLCMD;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 24110f6f61e..4d8e14b7aa9 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -31,6 +31,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
+#include <linux/ratelimit.h>
#include <linux/tty_flip.h>
#include <linux/serial_reg.h>
#include <linux/serial_core.h>
@@ -154,12 +155,6 @@ struct uart_8250_port {
unsigned char lsr_saved_flags;
#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
unsigned char msr_saved_flags;
-
- /*
- * We provide a per-port pm hook.
- */
- void (*pm)(struct uart_port *port,
- unsigned int state, unsigned int old);
};
struct irq_info {
@@ -924,7 +919,7 @@ static int broken_efr(struct uart_8250_port *up)
/*
* Exar ST16C2550 "A2" devices incorrectly detect as
* having an EFR, and report an ID of 0x0201. See
- * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf
+ * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html
*/
if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
return 1;
@@ -1606,8 +1601,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
if (l == i->head && pass_counter++ > PASS_LIMIT) {
/* If we hit this, we're dead. */
- printk(KERN_ERR "serial8250: too much work for "
- "irq%d\n", irq);
+ printk_ratelimited(KERN_ERR
+ "serial8250: too much work for irq%d\n", irq);
break;
}
} while (l != end);
@@ -1722,12 +1717,6 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
mutex_unlock(&hash_mutex);
}
-/* Base timer interval for polling */
-static inline int poll_timeout(int timeout)
-{
- return timeout > 6 ? (timeout / 2 - 2) : 1;
-}
-
/*
* This function is used to handle ports that do not have an
* interrupt. This doesn't work very well for 16450's, but gives
@@ -1742,7 +1731,7 @@ static void serial8250_timeout(unsigned long data)
iir = serial_in(up, UART_IIR);
if (!(iir & UART_IIR_NO_INT))
serial8250_handle_port(up);
- mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
+ mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
}
static void serial8250_backup_timeout(unsigned long data)
@@ -1787,7 +1776,7 @@ static void serial8250_backup_timeout(unsigned long data)
/* Standard timer interval plus 0.2s to keep the port running */
mod_timer(&up->timer,
- jiffies + poll_timeout(up->port.timeout) + HZ / 5);
+ jiffies + uart_poll_timeout(&up->port) + HZ / 5);
}
static unsigned int serial8250_tx_empty(struct uart_port *port)
@@ -1867,15 +1856,17 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
unsigned int status, tmout = 10000;
/* Wait up to 10ms for the character(s) to be sent. */
- do {
+ for (;;) {
status = serial_in(up, UART_LSR);
up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
+ if ((status & bits) == bits)
+ break;
if (--tmout == 0)
break;
udelay(1);
- } while ((status & bits) != bits);
+ }
/* Wait up to 1s for flow control if necessary */
if (up->port.flags & UPF_CONS_FLOW) {
@@ -2069,7 +2060,7 @@ static int serial8250_startup(struct uart_port *port)
up->timer.function = serial8250_backup_timeout;
up->timer.data = (unsigned long)up;
mod_timer(&up->timer, jiffies +
- poll_timeout(up->port.timeout) + HZ / 5);
+ uart_poll_timeout(port) + HZ / 5);
}
/*
@@ -2079,7 +2070,7 @@ static int serial8250_startup(struct uart_port *port)
*/
if (!is_real_interrupt(up->port.irq)) {
up->timer.data = (unsigned long)up;
- mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
+ mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
} else {
retval = serial_link_irq_chain(up);
if (retval)
@@ -2440,16 +2431,24 @@ serial8250_set_ldisc(struct uart_port *port, int new)
port->flags &= ~UPF_HARDPPS_CD;
}
-static void
-serial8250_pm(struct uart_port *port, unsigned int state,
- unsigned int oldstate)
+
+void serial8250_do_pm(struct uart_port *port, unsigned int state,
+ unsigned int oldstate)
{
struct uart_8250_port *p = (struct uart_8250_port *)port;
serial8250_set_sleep(p, state != 0);
+}
+EXPORT_SYMBOL(serial8250_do_pm);
- if (p->pm)
- p->pm(port, state, oldstate);
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+ unsigned int oldstate)
+{
+ if (port->pm)
+ port->pm(port, state, oldstate);
+ else
+ serial8250_do_pm(port, state, oldstate);
}
static unsigned int serial8250_port_size(struct uart_8250_port *pt)
@@ -2674,6 +2673,16 @@ static struct uart_ops serial8250_pops = {
static struct uart_8250_port serial8250_ports[UART_NR];
+static void (*serial8250_isa_config)(int port, struct uart_port *up,
+ unsigned short *capabilities);
+
+void serial8250_set_isa_configurator(
+ void (*v)(int port, struct uart_port *up, unsigned short *capabilities))
+{
+ serial8250_isa_config = v;
+}
+EXPORT_SYMBOL(serial8250_set_isa_configurator);
+
static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
@@ -2719,6 +2728,9 @@ static void __init serial8250_isa_init_ports(void)
up->port.regshift = old_serial_port[i].iomem_reg_shift;
set_io_from_upio(&up->port);
up->port.irqflags |= irqflag;
+ if (serial8250_isa_config != NULL)
+ serial8250_isa_config(i, &up->port, &up->capabilities);
+
}
}
@@ -3010,6 +3022,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
port.serial_in = p->serial_in;
port.serial_out = p->serial_out;
port.set_termios = p->set_termios;
+ port.pm = p->pm;
port.dev = &dev->dev;
port.irqflags |= irqflag;
ret = serial8250_register_port(&port);
@@ -3176,6 +3189,12 @@ int serial8250_register_port(struct uart_port *port)
/* Possibly override set_termios call */
if (port->set_termios)
uart->port.set_termios = port->set_termios;
+ if (port->pm)
+ uart->port.pm = port->pm;
+
+ if (serial8250_isa_config != NULL)
+ serial8250_isa_config(0, &uart->port,
+ &uart->capabilities);
ret = uart_add_one_port(&serial8250_reg, &uart->port);
if (ret == 0)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 12900f7083b..92781648439 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -458,6 +458,7 @@ config SERIAL_SAMSUNG_UARTS
int
depends on ARM && PLAT_SAMSUNG
default 2 if ARCH_S3C2400
+ default 6 if ARCH_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4
default 3
help
@@ -526,12 +527,12 @@ config SERIAL_S3C24A0
Serial port support for the Samsung S3C24A0 SoC
config SERIAL_S3C6400
- tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100)
+ tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
select SERIAL_SAMSUNG_UARTS_4
default y
help
- Serial port support for the Samsung S3C6400, S3C6410, S5P6440
+ Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
and S5PC100 SoCs
config SERIAL_S5PV210
@@ -717,13 +718,6 @@ config SERIAL_MRST_MAX3110
the Intel Moorestown platform. On other systems use the max3100
driver.
-config MRST_MAX3110_IRQ
- boolean "Enable GPIO IRQ for Max3110 over Moorestown"
- default n
- depends on SERIAL_MRST_MAX3110 && GPIO_LANGWELL
- help
- This has to be enabled after Moorestown GPIO driver is loaded
-
config SERIAL_MFD_HSU
tristate "Medfield High Speed UART support"
depends on PCI
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index f8d8a00554d..721216292a5 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/console.h>
@@ -27,6 +28,8 @@
#include <linux/altera_uart.h>
#define DRV_NAME "altera_uart"
+#define SERIAL_ALTERA_MAJOR 204
+#define SERIAL_ALTERA_MINOR 213
/*
* Altera UART register definitions according to the Nios UART datasheet:
@@ -76,13 +79,28 @@
*/
struct altera_uart {
struct uart_port port;
+ struct timer_list tmr;
unsigned int sigs; /* Local copy of line sigs */
unsigned short imr; /* Local IMR mirror */
};
+static u32 altera_uart_readl(struct uart_port *port, int reg)
+{
+ struct altera_uart_platform_uart *platp = port->private_data;
+
+ return readl(port->membase + (reg << platp->bus_shift));
+}
+
+static void altera_uart_writel(struct uart_port *port, u32 dat, int reg)
+{
+ struct altera_uart_platform_uart *platp = port->private_data;
+
+ writel(dat, port->membase + (reg << platp->bus_shift));
+}
+
static unsigned int altera_uart_tx_empty(struct uart_port *port)
{
- return (readl(port->membase + ALTERA_UART_STATUS_REG) &
+ return (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0;
}
@@ -91,8 +109,7 @@ static unsigned int altera_uart_get_mctrl(struct uart_port *port)
struct altera_uart *pp = container_of(port, struct altera_uart, port);
unsigned int sigs;
- sigs =
- (readl(port->membase + ALTERA_UART_STATUS_REG) &
+ sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
sigs |= (pp->sigs & TIOCM_RTS);
@@ -108,7 +125,7 @@ static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs)
pp->imr |= ALTERA_UART_CONTROL_RTS_MSK;
else
pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK;
- writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
}
static void altera_uart_start_tx(struct uart_port *port)
@@ -116,7 +133,7 @@ static void altera_uart_start_tx(struct uart_port *port)
struct altera_uart *pp = container_of(port, struct altera_uart, port);
pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK;
- writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
}
static void altera_uart_stop_tx(struct uart_port *port)
@@ -124,7 +141,7 @@ static void altera_uart_stop_tx(struct uart_port *port)
struct altera_uart *pp = container_of(port, struct altera_uart, port);
pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
- writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
}
static void altera_uart_stop_rx(struct uart_port *port)
@@ -132,7 +149,7 @@ static void altera_uart_stop_rx(struct uart_port *port)
struct altera_uart *pp = container_of(port, struct altera_uart, port);
pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK;
- writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
}
static void altera_uart_break_ctl(struct uart_port *port, int break_state)
@@ -145,7 +162,7 @@ static void altera_uart_break_ctl(struct uart_port *port, int break_state)
pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK;
else
pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK;
- writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -168,7 +185,8 @@ static void altera_uart_set_termios(struct uart_port *port,
tty_termios_encode_baud_rate(termios, baud, baud);
spin_lock_irqsave(&port->lock, flags);
- writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG);
+ uart_update_timeout(port, termios->c_cflag, baud);
+ altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -178,14 +196,15 @@ static void altera_uart_rx_chars(struct altera_uart *pp)
unsigned char ch, flag;
unsigned short status;
- while ((status = readl(port->membase + ALTERA_UART_STATUS_REG)) &
+ while ((status = altera_uart_readl(port, ALTERA_UART_STATUS_REG)) &
ALTERA_UART_STATUS_RRDY_MSK) {
- ch = readl(port->membase + ALTERA_UART_RXDATA_REG);
+ ch = altera_uart_readl(port, ALTERA_UART_RXDATA_REG);
flag = TTY_NORMAL;
port->icount.rx++;
if (status & ALTERA_UART_STATUS_E_MSK) {
- writel(status, port->membase + ALTERA_UART_STATUS_REG);
+ altera_uart_writel(port, status,
+ ALTERA_UART_STATUS_REG);
if (status & ALTERA_UART_STATUS_BRK_MSK) {
port->icount.brk++;
@@ -225,18 +244,18 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
if (port->x_char) {
/* Send special char - probably flow control */
- writel(port->x_char, port->membase + ALTERA_UART_TXDATA_REG);
+ altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG);
port->x_char = 0;
port->icount.tx++;
return;
}
- while (readl(port->membase + ALTERA_UART_STATUS_REG) &
+ while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
ALTERA_UART_STATUS_TRDY_MSK) {
if (xmit->head == xmit->tail)
break;
- writel(xmit->buf[xmit->tail],
- port->membase + ALTERA_UART_TXDATA_REG);
+ altera_uart_writel(port, xmit->buf[xmit->tail],
+ ALTERA_UART_TXDATA_REG);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
}
@@ -246,7 +265,7 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
if (xmit->head == xmit->tail) {
pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
- writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
}
}
@@ -256,7 +275,7 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
struct altera_uart *pp = container_of(port, struct altera_uart, port);
unsigned int isr;
- isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr;
+ isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
spin_lock(&port->lock);
if (isr & ALTERA_UART_STATUS_RRDY_MSK)
@@ -268,14 +287,23 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
return IRQ_RETVAL(isr);
}
+static void altera_uart_timer(unsigned long data)
+{
+ struct uart_port *port = (void *)data;
+ struct altera_uart *pp = container_of(port, struct altera_uart, port);
+
+ altera_uart_interrupt(0, port);
+ mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port));
+}
+
static void altera_uart_config_port(struct uart_port *port, int flags)
{
port->type = PORT_ALTERA_UART;
/* Clear mask, so no surprise interrupts. */
- writel(0, port->membase + ALTERA_UART_CONTROL_REG);
+ altera_uart_writel(port, 0, ALTERA_UART_CONTROL_REG);
/* Clear status register */
- writel(0, port->membase + ALTERA_UART_STATUS_REG);
+ altera_uart_writel(port, 0, ALTERA_UART_STATUS_REG);
}
static int altera_uart_startup(struct uart_port *port)
@@ -284,6 +312,12 @@ static int altera_uart_startup(struct uart_port *port)
unsigned long flags;
int ret;
+ if (!port->irq) {
+ setup_timer(&pp->tmr, altera_uart_timer, (unsigned long)port);
+ mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port));
+ return 0;
+ }
+
ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED,
DRV_NAME, port);
if (ret) {
@@ -316,7 +350,10 @@ static void altera_uart_shutdown(struct uart_port *port)
spin_unlock_irqrestore(&port->lock, flags);
- free_irq(port->irq, port);
+ if (port->irq)
+ free_irq(port->irq, port);
+ else
+ del_timer_sync(&pp->tmr);
}
static const char *altera_uart_type(struct uart_port *port)
@@ -384,8 +421,9 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
port->iotype = SERIAL_IO_MEM;
port->irq = platp[i].irq;
port->uartclk = platp[i].uartclk;
- port->flags = ASYNC_BOOT_AUTOCONF;
+ port->flags = UPF_BOOT_AUTOCONF;
port->ops = &altera_uart_ops;
+ port->private_data = platp;
}
return 0;
@@ -393,7 +431,7 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
static void altera_uart_console_putc(struct uart_port *port, const char c)
{
- while (!(readl(port->membase + ALTERA_UART_STATUS_REG) &
+ while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
ALTERA_UART_STATUS_TRDY_MSK))
cpu_relax();
@@ -423,7 +461,7 @@ static int __init altera_uart_console_setup(struct console *co, char *options)
if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
return -EINVAL;
port = &altera_uart_ports[co->index].port;
- if (port->membase == 0)
+ if (!port->membase)
return -ENODEV;
if (options)
@@ -435,7 +473,7 @@ static int __init altera_uart_console_setup(struct console *co, char *options)
static struct uart_driver altera_uart_driver;
static struct console altera_uart_console = {
- .name = "ttyS",
+ .name = "ttyAL",
.write = altera_uart_console_write,
.device = uart_console_device,
.setup = altera_uart_console_setup,
@@ -466,9 +504,9 @@ console_initcall(altera_uart_console_init);
static struct uart_driver altera_uart_driver = {
.owner = THIS_MODULE,
.driver_name = DRV_NAME,
- .dev_name = "ttyS",
- .major = TTY_MAJOR,
- .minor = 64,
+ .dev_name = "ttyAL",
+ .major = SERIAL_ALTERA_MAJOR,
+ .minor = SERIAL_ALTERA_MINOR,
.nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS,
.cons = ALTERA_UART_CONSOLE,
};
@@ -477,38 +515,55 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
{
struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
struct uart_port *port;
- int i;
+ struct resource *res_mem;
+ struct resource *res_irq;
+ int i = pdev->id;
- for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) {
- port = &altera_uart_ports[i].port;
+ /* -1 emphasizes that the platform must have one port, no .N suffix */
+ if (i == -1)
+ i = 0;
- port->line = i;
- port->type = PORT_ALTERA_UART;
- port->mapbase = platp[i].mapbase;
- port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
- port->iotype = SERIAL_IO_MEM;
- port->irq = platp[i].irq;
- port->uartclk = platp[i].uartclk;
- port->ops = &altera_uart_ops;
- port->flags = ASYNC_BOOT_AUTOCONF;
+ if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
+ return -EINVAL;
- uart_add_one_port(&altera_uart_driver, port);
- }
+ port = &altera_uart_ports[i].port;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res_mem)
+ port->mapbase = res_mem->start;
+ else if (platp->mapbase)
+ port->mapbase = platp->mapbase;
+ else
+ return -EINVAL;
+
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res_irq)
+ port->irq = res_irq->start;
+ else if (platp->irq)
+ port->irq = platp->irq;
+
+ port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
+ if (!port->membase)
+ return -ENOMEM;
+
+ port->line = i;
+ port->type = PORT_ALTERA_UART;
+ port->iotype = SERIAL_IO_MEM;
+ port->uartclk = platp->uartclk;
+ port->ops = &altera_uart_ops;
+ port->flags = UPF_BOOT_AUTOCONF;
+ port->private_data = platp;
+
+ uart_add_one_port(&altera_uart_driver, port);
return 0;
}
static int __devexit altera_uart_remove(struct platform_device *pdev)
{
- struct uart_port *port;
- int i;
-
- for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) {
- port = &altera_uart_ports[i].port;
- if (port)
- uart_remove_one_port(&altera_uart_driver, port);
- }
+ struct uart_port *port = &altera_uart_ports[pdev->id].port;
+ uart_remove_one_port(&altera_uart_driver, port);
return 0;
}
@@ -550,3 +605,4 @@ MODULE_DESCRIPTION("Altera UART driver");
MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_ALTERA_MAJOR);
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index 5318dd3774a..e95c524d9d1 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -10,7 +10,7 @@
/*
* This driver and the hardware supported are in term of EE-191 of ADI.
- * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
+ * http://www.analog.com/static/imported-files/application_notes/EE191.pdf
* This application note describe how to implement a UART on a Sharc DSP,
* but this driver is implemented on Blackfin Processor.
* Transmit Frame Sync is not used by this driver to transfer data out.
@@ -131,7 +131,12 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate)
pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up));
tclkdiv = sclk / (2 * baud_rate) - 1;
- rclkdiv = sclk / (2 * baud_rate * 2) - 1;
+ /* The actual uart baud rate of devices vary between +/-2%. The sport
+ * RX sample rate should be faster than the double of the worst case,
+ * otherwise, wrong data are received. So, set sport RX clock to be
+ * 3% faster.
+ */
+ rclkdiv = sclk / (2 * baud_rate * 2 * 97 / 100) - 1;
SPORT_PUT_TCLKDIV(up, tclkdiv);
SPORT_PUT_RCLKDIV(up, rclkdiv);
SSYNC();
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h
index 9ce253e381d..6d06ce1d567 100644
--- a/drivers/serial/bfin_sport_uart.h
+++ b/drivers/serial/bfin_sport_uart.h
@@ -10,7 +10,7 @@
/*
* This driver and the hardware supported are in term of EE-191 of ADI.
- * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
+ * http://www.analog.com/static/imported-files/application_notes/EE191.pdf
* This application note describe how to implement a UART on a Sharc DSP,
* but this driver is implemented on Blackfin Processor.
* Transmit Frame Sync is not used by this driver to transfer data out.
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 66ecc7ab6da..dfcf4b1878a 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -327,14 +327,13 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
{
struct circ_buf *xmit = &sport->port.state->xmit;
- while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
+ while (!uart_circ_empty(xmit) &&
+ !(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
/* send xmit->buf[xmit->tail]
* out the port here */
writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
sport->port.icount.tx++;
- if (uart_circ_empty(xmit))
- break;
}
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 800c5460233..ee43efc7bdc 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -2017,6 +2017,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
struct ioc3_port *port;
struct ioc3_port *ports[PORTS_PER_CARD];
int phys_port;
+ int cnt;
DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd));
@@ -2147,6 +2148,9 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
/* error exits that give back resources */
out4:
+ for (cnt = 0; cnt < phys_port; cnt++)
+ kfree(ports[cnt]);
+
kfree(card_ptr);
return ret;
}
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index eaf54501411..18f548449c6 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -172,13 +172,15 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
jsm_uart_port_init here! */
dev_err(&pdev->dev, "memory allocation for flipbuf failed\n");
rc = -ENOMEM;
- goto out_free_irq;
+ goto out_free_uart;
}
pci_set_drvdata(pdev, brd);
pci_save_state(pdev);
return 0;
+ out_free_uart:
+ jsm_remove_uart_port(brd);
out_free_irq:
jsm_remove_uart_port(brd);
free_irq(brd->irq, brd);
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 39f9a1adaa7..d4b711c9a41 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -243,7 +243,7 @@ static struct kgdb_io kgdboc_io_ops = {
#ifdef CONFIG_KGDB_SERIAL_CONSOLE
/* This is only available if kgdboc is a built in for early debugging */
-int __init kgdboc_early_init(char *opt)
+static int __init kgdboc_early_init(char *opt)
{
/* save the first character of the config string because the
* init routine can destroy it.
diff --git a/drivers/serial/max3107.c b/drivers/serial/max3107.c
index 67283c1a57f..910870edf70 100644
--- a/drivers/serial/max3107.c
+++ b/drivers/serial/max3107.c
@@ -986,12 +986,14 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)
s->rxbuf = kzalloc(sizeof(u16) * (MAX3107_RX_FIFO_SIZE+2), GFP_KERNEL);
if (!s->rxbuf) {
pr_err("Allocating RX buffer failed\n");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err_free4;
}
s->rxstr = kzalloc(sizeof(u8) * MAX3107_RX_FIFO_SIZE, GFP_KERNEL);
if (!s->rxstr) {
pr_err("Allocating RX buffer failed\n");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err_free3;
}
/* SPI Tx buffer
* SPI transfer buffer
@@ -1002,7 +1004,8 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)
s->txbuf = kzalloc(sizeof(u16) * MAX3107_TX_FIFO_SIZE + 3, GFP_KERNEL);
if (!s->txbuf) {
pr_err("Allocating TX buffer failed\n");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err_free2;
}
/* Initialize shared data lock */
spin_lock_init(&s->data_lock);
@@ -1021,13 +1024,15 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)
buf[0] = MAX3107_REVID_REG;
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
dev_err(&s->spi->dev, "SPI transfer for REVID read failed\n");
- return -EIO;
+ retval = -EIO;
+ goto err_free1;
}
if ((buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID1 &&
(buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID2) {
dev_err(&s->spi->dev, "REVID %x does not match\n",
(buf[0] & MAX3107_SPI_RX_DATA_MASK));
- return -ENODEV;
+ retval = -ENODEV;
+ goto err_free1;
}
/* Disable all interrupts */
@@ -1047,7 +1052,8 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)
/* Perform SPI transfer */
if (max3107_rw(s, (u8 *)buf, NULL, 4)) {
dev_err(&s->spi->dev, "SPI transfer for init failed\n");
- return -EIO;
+ retval = -EIO;
+ goto err_free1;
}
/* Register UART driver */
@@ -1055,7 +1061,7 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)
retval = uart_register_driver(&max3107_uart_driver);
if (retval) {
dev_err(&s->spi->dev, "Registering UART driver failed\n");
- return retval;
+ goto err_free1;
}
driver_registered = 1;
}
@@ -1074,13 +1080,13 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)
retval = uart_add_one_port(&max3107_uart_driver, &s->port);
if (retval < 0) {
dev_err(&s->spi->dev, "Adding UART port failed\n");
- return retval;
+ goto err_free1;
}
if (pdata->configure) {
retval = pdata->configure(s);
if (retval < 0)
- return retval;
+ goto err_free1;
}
/* Go to suspend mode */
@@ -1088,6 +1094,16 @@ int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata)