summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/21285.c14
-rw-r--r--drivers/serial/68328serial.c30
-rw-r--r--drivers/serial/68360serial.c52
-rw-r--r--drivers/serial/8250.c45
-rw-r--r--drivers/serial/8250.h3
-rw-r--r--drivers/serial/8250_gsc.c2
-rw-r--r--drivers/serial/8250_pci.c19
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/Kconfig19
-rw-r--r--drivers/serial/Makefile3
-rw-r--r--drivers/serial/amba-pl010.c8
-rw-r--r--drivers/serial/amba-pl011.c4
-rw-r--r--drivers/serial/atmel_serial.c59
-rw-r--r--drivers/serial/bfin_5xx.c12
-rw-r--r--drivers/serial/bfin_sport_uart.c4
-rw-r--r--drivers/serial/clps711x.c11
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h11
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c184
-rw-r--r--drivers/serial/crisv10.c158
-rw-r--r--drivers/serial/crisv10.h3
-rw-r--r--drivers/serial/dz.c28
-rw-r--r--drivers/serial/icom.c2
-rw-r--r--drivers/serial/imx.c33
-rw-r--r--drivers/serial/ioc3_serial.c14
-rw-r--r--drivers/serial/ioc4_serial.c21
-rw-r--r--drivers/serial/ip22zilog.c4
-rw-r--r--drivers/serial/jsm/jsm_neo.c2
-rw-r--r--drivers/serial/jsm/jsm_tty.c8
-rw-r--r--drivers/serial/m32r_sio.c6
-rw-r--r--drivers/serial/mcf.c2
-rw-r--r--drivers/serial/mcfserial.c32
-rw-r--r--drivers/serial/mpc52xx_uart.c2
-rw-r--r--drivers/serial/mpsc.c154
-rw-r--r--drivers/serial/mux.c2
-rw-r--r--drivers/serial/netx-serial.c6
-rw-r--r--drivers/serial/pmac_zilog.c4
-rw-r--r--drivers/serial/pnx8xxx_uart.c4
-rw-r--r--drivers/serial/pxa.c6
-rw-r--r--drivers/serial/s3c2400.c4
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/serial/s3c2412.c4
-rw-r--r--drivers/serial/s3c2440.c4
-rw-r--r--drivers/serial/sa1100.c11
-rw-r--r--drivers/serial/samsung.c6
-rw-r--r--drivers/serial/sb1250-duart.c2
-rw-r--r--drivers/serial/sc26xx.c2
-rw-r--r--drivers/serial/serial_core.c85
-rw-r--r--drivers/serial/serial_ks8695.c6
-rw-r--r--drivers/serial/serial_lh7a40x.c2
-rw-r--r--drivers/serial/serial_txx9.c2
-rw-r--r--drivers/serial/sh-sci.c25
-rw-r--r--drivers/serial/sh-sci.h40
-rw-r--r--drivers/serial/sn_console.c2
-rw-r--r--drivers/serial/sunhv.c4
-rw-r--r--drivers/serial/sunsab.c4
-rw-r--r--drivers/serial/sunsu.c6
-rw-r--r--drivers/serial/sunzilog.c6
-rw-r--r--drivers/serial/uartlite.c4
-rw-r--r--drivers/serial/ucc_uart.c2
-rw-r--r--drivers/serial/v850e_uart.c548
-rw-r--r--drivers/serial/vr41xx_siu.c2
-rw-r--r--drivers/serial/zs.c23
62 files changed, 827 insertions, 944 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 0276471cb25..f31c6698419 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -4,8 +4,6 @@
* Driver for the serial port on the 21285 StrongArm-110 core logic chip.
*
* Based on drivers/char/serial.c
- *
- * $Id: 21285.c,v 1.37 2002/07/28 10:03:27 rmk Exp $
*/
#include <linux/module.h>
#include <linux/tty.h>
@@ -21,7 +19,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware/dec21285.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#define BAUD_BASE (mem_fclk_21285/64)
@@ -88,7 +86,7 @@ static void serial21285_enable_ms(struct uart_port *port)
static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int status, ch, flag, rxs, max_count = 256;
status = *CSR_UARTFLG;
@@ -237,8 +235,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
- if (port->info && port->info->tty) {
- struct tty_struct *tty = port->info->tty;
+ if (port->info && port->info->port.tty) {
+ struct tty_struct *tty = port->info->port.tty;
unsigned int b = port->uartclk / (16 * quot);
tty_encode_baud_rate(tty, b, b);
}
@@ -494,7 +492,7 @@ static int __init serial21285_init(void)
{
int ret;
- printk(KERN_INFO "Serial: 21285 driver $Revision: 1.37 $\n");
+ printk(KERN_INFO "Serial: 21285 driver\n");
serial21285_setup_ports();
@@ -515,5 +513,5 @@ module_init(serial21285_init);
module_exit(serial21285_exit);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver $Revision: 1.37 $");
+MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver");
MODULE_ALIAS_CHARDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index bbf5bc5892c..381b12ac20e 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -249,7 +249,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
{
#if 0
if(status & DCD) {
- if((info->tty->termios->c_cflag & CRTSCTS) &&
+ if((info->port.tty->termios->c_cflag & CRTSCTS) &&
((info->curregs[3] & AUTO_ENAB)==0)) {
info->curregs[3] |= AUTO_ENAB;
info->pendregs[3] |= AUTO_ENAB;
@@ -274,7 +274,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
static void receive_chars(struct m68k_serial *info, unsigned short rx)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
m68328_uart *uart = &uart_addr[info->line];
unsigned char ch, flag;
@@ -345,7 +345,7 @@ static void transmit_chars(struct m68k_serial *info)
goto clear_and_return;
}
- if((info->xmit_cnt <= 0) || info->tty->stopped) {
+ if((info->xmit_cnt <= 0) || info->port.tty->stopped) {
/* That's peculiar... TX ints off */
uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
goto clear_and_return;
@@ -403,7 +403,7 @@ static void do_softint(struct work_struct *work)
struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue);
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
#if 0
@@ -427,7 +427,7 @@ static void do_serial_hangup(struct work_struct *work)
struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup);
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -471,8 +471,8 @@ static int startup(struct m68k_serial * info)
uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
#endif
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/*
@@ -506,8 +506,8 @@ static void shutdown(struct m68k_serial * info)
info->xmit_buf = 0;
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~S_INITIALIZED;
local_irq_restore(flags);
@@ -573,9 +573,9 @@ static void change_speed(struct m68k_serial *info)
unsigned cflag;
int i;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
if (!(port = info->port))
return;
@@ -1131,7 +1131,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
#warning "This is not and has never been valid so fix it"
#if 0
if (tty->ldisc.num != ldiscs[N_TTY].num) {
@@ -1169,7 +1169,7 @@ void rs_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
info->flags &= ~S_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -1286,7 +1286,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
info->count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
@@ -1363,7 +1363,7 @@ rs68328_init(void)
info = &m68k_soft[i];
info->magic = SERIAL_MAGIC;
info->port = (int) &uart_addr[i];
- info->tty = 0;
+ info->port.tty = NULL;
info->irq = uart_irqs[i];
info->custom_divisor = 16;
info->close_delay = 50;
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index d9d4e9552a4..24661cd5e4f 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -393,7 +393,7 @@ static void rs_360_start(struct tty_struct *tty)
static _INLINE_ void receive_chars(ser_info_t *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned char ch, flag, *cp;
/*int ignored = 0;*/
int i;
@@ -514,7 +514,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
static _INLINE_ void receive_break(ser_info_t *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
info->state->icount.brk++;
/* Check to see if there is room in the tty buffer for
@@ -528,7 +528,7 @@ static _INLINE_ void transmit_chars(ser_info_t *info)
{
if ((info->flags & TX_WAKEUP) ||
- (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
+ (info->port.tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
schedule_work(&info->tqueue);
}
@@ -584,12 +584,12 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
}
}
if (info->flags & ASYNC_CTS_FLOW) {
- if (info->tty->hw_stopped) {
+ if (info->port.tty->hw_stopped) {
if (status & UART_MSR_CTS) {
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk("CTS tx start...");
#endif
- info->tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
info->IER |= UART_IER_THRI;
serial_out(info, UART_IER, info->IER);
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
@@ -600,7 +600,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk("CTS tx stop...");
#endif
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
info->IER &= ~UART_IER_THRI;
serial_out(info, UART_IER, info->IER);
}
@@ -670,7 +670,7 @@ static void do_softint(void *private_)
ser_info_t *info = (ser_info_t *) private_;
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -693,7 +693,7 @@ static void do_serial_hangup(void *private_)
struct async_struct *info = (struct async_struct *) private_;
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -721,8 +721,8 @@ static int startup(ser_info_t *info)
#ifdef maybe
if (!state->port || !state->type) {
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
goto errout;
}
#endif
@@ -734,12 +734,12 @@ static int startup(ser_info_t *info)
#ifdef modem_control
info->MCR = 0;
- if (info->tty->termios->c_cflag & CBAUD)
+ if (info->port.tty->termios->c_cflag & CBAUD)
info->MCR = UART_MCR_DTR | UART_MCR_RTS;
#endif
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
/*
* and set the speed of the serial port
@@ -842,8 +842,8 @@ static void shutdown(ser_info_t *info)
smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
local_irq_restore(flags);
@@ -863,9 +863,9 @@ static void change_speed(ser_info_t *info)
volatile struct smc_regs *smcp;
volatile struct scc_regs *sccp;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
state = info->state;
@@ -936,24 +936,24 @@ static void change_speed(ser_info_t *info)
* Set up parity check flag
*/
info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= BD_SC_FR | BD_SC_PR;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= BD_SC_BR;
/*
* Characters to ignore
*/
info->ignore_status_mask = 0;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= BD_SC_BR;
/*
* If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= BD_SC_OV;
}
/*
@@ -1658,7 +1658,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp)
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
if (info->blocked_open) {
if (info->close_delay) {
msleep_interruptible(jiffies_to_msecs(info->close_delay));
@@ -1758,7 +1758,7 @@ static void rs_360_hangup(struct tty_struct *tty)
info->event = 0;
state->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -1919,7 +1919,7 @@ static int rs_360_open(struct tty_struct *tty, struct file * filp)
printk("rs_open %s, count = %d\n", tty->name, info->state->count);
#endif
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
@@ -1976,7 +1976,7 @@ static inline int line_info(char *buf, struct serial_state *state)
info->port = state->port;
info->flags = state->flags;
info->quot = 0;
- info->tty = 0;
+ info->port.tty = NULL;
}
local_irq_disable();
status = serial_in(info, UART_MSR);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index be95e55b228..9ccc563d873 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -12,8 +12,6 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: 8250.c,v 1.90 2002/07/28 10:03:27 rmk Exp $
- *
* A note about mapbase / membase
*
* mapbase is the physical address of the IO port.
@@ -1289,13 +1287,24 @@ static void serial8250_enable_ms(struct uart_port *port)
static void
receive_chars(struct uart_8250_port *up, unsigned int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch, lsr = *status;
int max_count = 256;
char flag;
do {
- ch = serial_inp(up, UART_RX);
+ if (likely(lsr & UART_LSR_DR))
+ ch = serial_inp(up, UART_RX);
+ else
+ /*
+ * Intel 82571 has a Serial Over Lan device that will
+ * set UART_LSR_BI without setting UART_LSR_DR when
+ * it receives a break. To avoid reading from the
+ * receive buffer without UART_LSR_DR bit set, we
+ * just force the read character to be 0
+ */
+ ch = 0;
+
flag = TTY_NORMAL;
up->port.icount.rx++;
@@ -1344,7 +1353,7 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
ignore_char:
lsr = serial_inp(up, UART_LSR);
- } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
+ } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
spin_unlock(&up->port.lock);
tty_flip_buffer_push(tty);
spin_lock(&up->port.lock);
@@ -1427,7 +1436,7 @@ serial8250_handle_port(struct uart_8250_port *up)
DEBUG_INTR("status = %x...", status);
- if (status & UART_LSR_DR)
+ if (status & (UART_LSR_DR | UART_LSR_BI))
receive_chars(up, &status);
check_modem_status(up);
if (status & UART_LSR_THRE)
@@ -1877,6 +1886,8 @@ static int serial8250_startup(struct uart_port *port)
* allow register changes to become visible.
*/
spin_lock_irqsave(&up->port.lock, flags);
+ if (up->port.flags & UPF_SHARE_IRQ)
+ disable_irq_nosync(up->port.irq);
wait_for_xmitr(up, UART_LSR_THRE);
serial_out_sync(up, UART_IER, UART_IER_THRI);
@@ -1888,6 +1899,8 @@ static int serial8250_startup(struct uart_port *port)
iir = serial_in(up, UART_IIR);
serial_out(up, UART_IER, 0);
+ if (up->port.flags & UPF_SHARE_IRQ)
+ enable_irq(up->port.irq);
spin_unlock_irqrestore(&up->port.lock, flags);
/*
@@ -1895,15 +1908,23 @@ static int serial8250_startup(struct uart_port *port)
* kick the UART on a regular basis.
*/
if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
+ up->bugs |= UART_BUG_THRE;
pr_debug("ttyS%d - using backup timer\n", port->line);
- up->timer.function = serial8250_backup_timeout;
- up->timer.data = (unsigned long)up;
- mod_timer(&up->timer, jiffies +
- poll_timeout(up->port.timeout) + HZ / 5);
}
}
/*
+ * The above check will only give an accurate result the first time
+ * the port is opened so this value needs to be preserved.
+ */
+ if (up->bugs & UART_BUG_THRE) {
+ up->timer.function = serial8250_backup_timeout;
+ up->timer.data = (unsigned long)up;
+ mod_timer(&up->timer, jiffies +
+ poll_timeout(up->port.timeout) + HZ / 5);
+ }
+
+ /*
* If the "interrupt" for this port doesn't correspond with any
* hardware interrupt, we use a timer-based system. The original
* driver used to do this with IRQ0.
@@ -2934,7 +2955,7 @@ static int __init serial8250_init(void)
if (nr_uarts > UART_NR)
nr_uarts = UART_NR;
- printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
+ printk(KERN_INFO "Serial: 8250/16550 driver"
"%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");
@@ -2995,7 +3016,7 @@ EXPORT_SYMBOL(serial8250_suspend_port);
EXPORT_SYMBOL(serial8250_resume_port);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $");
+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 91bd28f2bb4..520260326f3 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id: 8250.h,v 1.8 2002/07/21 21:32:30 rmk Exp $
*/
#include <linux/serial_8250.h>
@@ -49,6 +47,7 @@ struct serial8250_config {
#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_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
+#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
#define PROBE_RSA (1 << 0)
#define PROBE_ANY (~0)
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 4eb7437a404..0416ad3bc12 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -119,3 +119,5 @@ int __init probe_serial_gsc(void)
}
module_init(probe_serial_gsc);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 788c3559522..c2f23933155 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -10,8 +10,6 @@
* 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.
- *
- * $Id: 8250_pci.c,v 1.28 2002/11/02 11:14:18 rmk Exp $
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -769,6 +767,9 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board,
#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
+/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
+
/*
* Master list of serial port init/setup/exit quirks.
* This does not describe the general nature of the port.
@@ -884,6 +885,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
},
{
.vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9050,
+ .subvendor = PCI_VENDOR_ID_PLX,
+ .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_plx9050_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_ROMULUS,
.subvendor = PCI_VENDOR_ID_PLX,
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -2199,6 +2209,11 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b2_4_921600 },
+ /* Unknown card - subdevice 0x1584 */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_VENDOR_ID_PLX,
+ PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
+ pbn_b0_4_115200 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 638b68649e7..fde7f9ccf57 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -12,8 +12,6 @@
* 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.
- *
- * $Id: 8250_pnp.c,v 1.10 2002/07/21 21:32:30 rmk Exp $
*/
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 18ca9075e13..77cb34270fc 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1,8 +1,6 @@
#
# Serial device configuration
#
-# $Id: Kconfig,v 1.11 2004/03/11 18:08:04 lethal Exp $
-#
menu "Serial drivers"
depends on HAS_IOMEM
@@ -451,6 +449,7 @@ config SERIAL_CLPS711X_CONSOLE
config SERIAL_SAMSUNG
tristate "Samsung SoC serial support"
depends on ARM && PLAT_S3C24XX
+ select SERIAL_CORE
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
providing /dev/ttySAC0, 1 and 2 (note, some machines may not
@@ -944,22 +943,6 @@ config SERIAL_IP22_ZILOG_CONSOLE
depends on SERIAL_IP22_ZILOG=y
select SERIAL_CORE_CONSOLE
-config V850E_UART
- bool "NEC V850E on-chip UART support"
- depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
- select SERIAL_CORE
- default y
-
-config V850E_UARTB
- bool
- depends on V850E_UART && V850E_ME2
- default y
-
-config V850E_UART_CONSOLE
- bool "Use NEC V850E on-chip UART for console"
- depends on V850E_UART
- select SERIAL_CORE_CONSOLE
-
config SERIAL_SH_SCI
tristate "SuperH SCI(F) serial port support"
depends on SUPERH || H8300
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 7d85c1fbe7e..7e7383e890d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -1,8 +1,6 @@
#
# Makefile for the kernel serial device drivers.
#
-# $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
-#
obj-$(CONFIG_SERIAL_CORE) += serial_core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
@@ -44,7 +42,6 @@ obj-$(CONFIG_SERIAL_68328) += 68328serial.o
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
obj-$(CONFIG_SERIAL_MCF) += mcf.o
-obj-$(CONFIG_V850E_UART) += v850e_uart.o
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
obj-$(CONFIG_SERIAL_DZ) += dz.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index e88da72f830..90b56c2c31e 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -22,8 +22,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $
- *
* This is a generic driver for ARM AMBA-type serial ports. They
* have a lot of 16550-like features, but are not register compatible.
* Note that although they do have CTS, DCD and DSR inputs, they do
@@ -119,7 +117,7 @@ static void pl010_enable_ms(struct uart_port *port)
static void pl010_rx_chars(struct uart_amba_port *uap)
{
- struct tty_struct *tty = uap->port.info->tty;
+ struct tty_struct *tty = uap->port.info->port.tty;
unsigned int status, ch, flag, rsr, max_count = 256;
status = readb(uap->port.membase + UART01x_FR);
@@ -791,7 +789,7 @@ static int __init pl010_init(void)
{
int ret;
- printk(KERN_INFO "Serial: AMBA driver $Revision: 1.41 $\n");
+ printk(KERN_INFO "Serial: AMBA driver\n");
ret = uart_register_driver(&amba_reg);
if (ret == 0) {
@@ -812,5 +810,5 @@ module_init(pl010_init);
module_exit(pl010_exit);
MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("ARM AMBA serial port driver $Revision: 1.41 $");
+MODULE_DESCRIPTION("ARM AMBA serial port driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 08adc1de4a7..9d08f27208a 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -22,8 +22,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $
- *
* This is a generic driver for ARM AMBA-type serial ports. They
* have a lot of 16550-like features, but are not register compatible.
* Note that although they do have CTS, DCD and DSR inputs, they do
@@ -109,7 +107,7 @@ static void pl011_enable_ms(struct uart_port *port)
static void pl011_rx_chars(struct uart_amba_port *uap)
{
- struct tty_struct *tty = uap->port.info->tty;
+ struct tty_struct *tty = uap->port.info->port.tty;
unsigned int status, ch, flag, max_count = 256;
status = readw(uap->port.membase + UART01x_FR);
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 6aeef22bd20..61fb8b6d19a 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -42,11 +42,11 @@
#include <asm/io.h>
#include <asm/mach/serial_at91.h>
-#include <asm/arch/board.h>
+#include <mach/board.h>
#ifdef CONFIG_ARM
-#include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
+#include <mach/cpu.h>
+#include <mach/gpio.h>
#endif
#define PDC_BUFFER_SIZE 512
@@ -131,7 +131,8 @@ struct atmel_uart_char {
struct atmel_uart_port {
struct uart_port uart; /* uart */
struct clk *clk; /* uart clock */
- unsigned short suspended; /* is port suspended? */
+ int may_wakeup; /* cached value of device_may_wakeup for times we need to disable it */
+ u32 backup_imr; /* IMR saved during suspend */
int break_active; /* break being received */
short use_dma_rx; /* enable PDC receiver */
@@ -662,14 +663,14 @@ static void atmel_rx_from_ring(struct uart_port *port)
* uart_start(), which takes the lock.
*/
spin_unlock(&port->lock);
- tty_flip_buffer_push(port->info->tty);
+ tty_flip_buffer_push(port->info->port.tty);
spin_lock(&port->lock);
}
static void atmel_rx_from_dma(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct atmel_dma_buffer *pdc;
int rx_idx = atmel_port->pdc_rx_idx;
unsigned int head;
@@ -794,7 +795,7 @@ static void atmel_tasklet_func(unsigned long data)
static int atmel_startup(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
int retval;
/*
@@ -956,6 +957,20 @@ static void atmel_shutdown(struct uart_port *port)
}
/*
+ * Flush any TX data submitted for DMA. Called when the TX circular
+ * buffer is reset.
+ */
+static void atmel_flush_buffer(struct uart_port *port)
+{
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+ if (atmel_use_dma_tx(port)) {
+ UART_PUT_TCR(port, 0);
+ atmel_port->pdc_tx.ofs = 0;
+ }
+}
+
+/*
* Power / Clock management.
*/
static void atmel_serial_pm(struct uart_port *port, unsigned int state,
@@ -970,8 +985,15 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,
* This is called on uart_open() or a resume event.
*/
clk_enable(atmel_port->clk);
+
+ /* re-enable interrupts if we disabled some on suspend */
+ UART_PUT_IER(port, atmel_port->backup_imr);
break;
case 3:
+ /* Back up the interrupt mask and disable all interrupts */
+ atmel_port->backup_imr = UART_GET_IMR(port);
+ UART_PUT_IDR(port, -1);
+
/*
* Disable the peripheral clock for this serial port.
* This is called on uart_close() or a suspend event.
@@ -1189,6 +1211,7 @@ static struct uart_ops atmel_pops = {
.break_ctl = atmel_break_ctl,
.startup = atmel_startup,
.shutdown = atmel_shutdown,
+ .flush_buffer = atmel_flush_buffer,
.set_termios = atmel_set_termios,
.type = atmel_type,
.release_port = atmel_release_port,
@@ -1460,13 +1483,12 @@ static int atmel_serial_suspend(struct platform_device *pdev,
cpu_relax();
}
- if (device_may_wakeup(&pdev->dev)
- && !atmel_serial_clk_will_stop())
- enable_irq_wake(port->irq);
- else {
- uart_suspend_port(&atmel_uart, port);
- atmel_port->suspended = 1;
- }
+ /* we can not wake up if we're running on slow clock */
+ atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
+ if (atmel_serial_clk_will_stop())
+ device_set_wakeup_enable(&pdev->dev, 0);
+
+ uart_suspend_port(&atmel_uart, port);
return 0;
}
@@ -1476,11 +1498,8 @@ static int atmel_serial_resume(struct platform_device *pdev)
struct uart_port *port = platform_get_drvdata(pdev);
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- if (atmel_port->suspended) {
- uart_resume_port(&atmel_uart, port);
- atmel_port->suspended = 0;
- } else
- disable_irq_wake(port->irq);
+ uart_resume_port(&atmel_uart, port);
+ device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup);
return 0;
}
@@ -1498,6 +1517,8 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE));
port = &atmel_ports[pdev->id];
+ port->backup_imr = 0;
+
atmel_init_port(port, pdev);
if (!atmel_use_dma_rx(&port->uart)) {
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index fd9bb777df2..4a0d30bed9f 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -28,7 +28,7 @@
#endif
#include <asm/gpio.h>
-#include <asm/mach/bfin_serial_5xx.h>
+#include <mach/bfin_serial_5xx.h>
#ifdef CONFIG_SERIAL_BFIN_DMA
#include <linux/dma-mapping.h>
@@ -175,7 +175,7 @@ int kgdb_get_debug_char(void)
#ifdef CONFIG_SERIAL_BFIN_PIO
static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
{
- struct tty_struct *tty = uart->port.info->tty;
+ struct tty_struct *tty = uart->port.info->port.tty;
unsigned int status, ch, flg;
static struct timeval anomaly_start = { .tv_sec = 0 };
@@ -393,7 +393,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
{
- struct tty_struct *tty = uart->port.info->tty;
+ struct tty_struct *tty = uart->port.info->port.tty;
int i, flg, status;
status = UART_GET_LSR(uart);
@@ -552,7 +552,7 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
unsigned int status;
struct uart_info *info = uart->port.info;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
status = bfin_serial_get_mctrl(&uart->port);
uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
@@ -814,10 +814,10 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
int line = port->line;
unsigned short val;
- if (line >= port->info->tty->driver->num)
+ if (line >= port->info->port.tty->driver->num)
return;
- switch (port->info->tty->ldisc.num) {
+ switch (port->info->port.tty->termios->c_line) {
case N_IRDA:
val = UART_GET_GCTL(&bfin_serial_ports[line]);
val |= (IREN | RPOLC);
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index aca1240ad80..dd8564d2505 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -174,7 +174,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
{
struct sport_uart_port *up = dev_id;
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned int ch;
do {
@@ -201,7 +201,7 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
{
struct sport_uart_port *up = dev_id;
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned int stat = SPORT_GET_STAT(up);
/* Overflow in RX FIFO */
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 23827189ec0..459f3420a42 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -21,9 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: clps711x.c,v 1.42 2002/07/28 10:03:28 rmk Exp $
- *
*/
#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -42,7 +39,7 @@
#include <linux/serial_core.h>
#include <linux/serial.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware/clps7111.h>
@@ -96,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int status, ch, flg;
status = clps_readl(SYSFLG(port));
@@ -551,7 +548,7 @@ static int __init clps711xuart_init(void)
{
int ret, i;
- printk(KERN_INFO "Serial: CLPS711x driver $Revision: 1.42 $\n");
+ printk(KERN_INFO "Serial: CLPS711x driver\n");
ret = uart_register_driver(&clps711x_reg);
if (ret)
@@ -577,6 +574,6 @@ module_init(clps711xuart_init);
module_exit(clps711xuart_exit);
MODULE_AUTHOR("Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("CLPS-711x generic serial driver $Revision: 1.42 $");
+MODULE_DESCRIPTION("CLPS-711x generic serial driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR);
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 5c76e0ae058..7274b527a3c 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -50,6 +50,15 @@
#define SCC_WAIT_CLOSING 100
+#define GPIO_CTS 0
+#define GPIO_RTS 1
+#define GPIO_DCD 2
+#define GPIO_DSR 3
+#define GPIO_DTR 4
+#define GPIO_RI 5
+
+#define NUM_GPIOS (GPIO_RI+1)
+
struct uart_cpm_port {
struct uart_port port;
u16 rx_nrfifos;
@@ -68,6 +77,7 @@ struct uart_cpm_port {
unsigned char *rx_buf;
u32 flags;
void (*set_lineif)(struct uart_cpm_port *);
+ struct clk *clk;
u8 brg;
uint dp_addr;
void *mem_addr;
@@ -82,6 +92,7 @@ struct uart_cpm_port {
int wait_closing;
/* value to combine with opcode to form cpm command */
u32 command;
+ int gpios[NUM_GPIOS];
};
extern int cpm_uart_nr;
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index abe129cc927..25efca5a7a1 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -43,6 +43,9 @@
#include <linux/dma-mapping.h>
#include <linux/fs_uart_pd.h>
#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -96,13 +99,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port)
static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- /* Whee. Do nothing. */
+ struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+
+ if (pinfo->gpios[GPIO_RTS] >= 0)
+ gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
+
+ if (pinfo->gpios[GPIO_DTR] >= 0)
+ gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
}
static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
{
- /* Whee. Do nothing. */
- return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+ struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+ unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ if (pinfo->gpios[GPIO_CTS] >= 0) {
+ if (gpio_get_value(pinfo->gpios[GPIO_CTS]))
+ mctrl &= ~TIOCM_CTS;
+ }
+
+ if (pinfo->gpios[GPIO_DSR] >= 0) {
+ if (gpio_get_value(pinfo->gpios[GPIO_DSR]))
+ mctrl &= ~TIOCM_DSR;
+ }
+
+ if (pinfo->gpios[GPIO_DCD] >= 0) {
+ if (gpio_get_value(pinfo->gpios[GPIO_DCD]))
+ mctrl &= ~TIOCM_CAR;
+ }
+
+ if (pinfo->gpios[GPIO_RI] >= 0) {
+ if (!gpio_get_value(pinfo->gpios[GPIO_RI]))
+ mctrl |= TIOCM_RNG;
+ }
+
+ return mctrl;
}
/*
@@ -201,6 +232,10 @@ static void cpm_uart_int_tx(struct uart_port *port)
cpm_uart_tx_pump(port);
}
+#ifdef CONFIG_CONSOLE_POLL
+static int serial_polled;
+#endif
+
/*
* Receive characters
*/
@@ -209,7 +244,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
int i;
unsigned char ch;
u8 *cp;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
cbd_t __iomem *bdp;
u16 status;
@@ -222,6 +257,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
*/
bdp = pinfo->rx_cur;
for (;;) {
+#ifdef CONFIG_CONSOLE_POLL
+ if (unlikely(serial_polled)) {
+ serial_polled = 0;
+ return;
+ }
+#endif
/* get status */
status = in_be16(&bdp->cbd_sc);
/* If this one is empty, return happy */
@@ -253,7 +294,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
goto handle_error;
if (uart_handle_sysrq_char(port, ch))
continue;
-
+#ifdef CONFIG_CONSOLE_POLL
+ if (unlikely(serial_polled)) {
+ serial_polled = 0;
+ return;
+ }
+#endif
error_return:
tty_insert_flip_char(tty, ch, flg);
@@ -420,10 +466,13 @@ static void cpm_uart_shutdown(struct uart_port *port)
}
/* Shut them really down and reinit buffer descriptors */
- if (IS_SMC(pinfo))
+ if (IS_SMC(pinfo)) {
+ out_be16(&pinfo->smcup->smc_brkcr, 0);
cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
- else
+ } else {
+ out_be16(&pinfo->sccup->scc_brkcr, 0);
cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
+ }
cpm_uart_initbd(pinfo);
}
@@ -539,14 +588,19 @@ static void cpm_uart_set_termios(struct uart_port *port,
* enables, because we want to put them back if they were
* present.
*/
- prev_mode = in_be16(&smcp->smc_smcmr);
- out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART);
- setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN)));
+ prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN);
+ /* Output in *one* operation, so we don't interrupt RX/TX if they
+ * were already enabled. */
+ out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval |
+ SMCMR_SM_UART | prev_mode);
} else {
out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
}
- cpm_set_brg(pinfo->brg - 1, baud);
+ if (pinfo->clk)
+ clk_set_rate(pinfo->clk, baud);
+ else
+ cpm_set_brg(pinfo->brg - 1, baud);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -865,6 +919,80 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
cpm_uart_request_port(port);
}
}
+
+#ifdef CONFIG_CONSOLE_POLL
+/* Serial polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+#define GDB_BUF_SIZE 512 /* power of 2, please */
+
+static char poll_buf[GDB_BUF_SIZE];
+static char *pollp;
+static int poll_chars;
+
+static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
+{
+ u_char c, *cp;
+ volatile cbd_t *bdp;
+ int i;
+
+ /* Get the address of the host memory buffer.
+ */
+ bdp = pinfo->rx_cur;
+ while (bdp->cbd_sc & BD_SC_EMPTY)
+ ;
+
+ /* If the buffer address is in the CPM DPRAM, don't
+ * convert it.
+ */
+ cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
+
+ if (obuf) {
+ i = c = bdp->cbd_datlen;
+ while (i-- > 0)
+ *obuf++ = *cp++;
+ } else
+ c = *cp;
+ bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
+ bdp->cbd_sc |= BD_SC_EMPTY;
+
+ if (bdp->cbd_sc & BD_SC_WRAP)
+ bdp = pinfo->rx_bd_base;
+ else
+ bdp++;
+ pinfo->rx_cur = (cbd_t *)bdp;
+
+ return (int)c;
+}
+
+static int cpm_get_poll_char(struct uart_port *port)
+{
+ struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+
+ if (!serial_polled) {
+ serial_polled = 1;
+ poll_chars = 0;
+ }
+ if (poll_chars <= 0) {
+ poll_chars = poll_wait_key(poll_buf, pinfo);
+ pollp = poll_buf;
+ }
+ poll_chars--;
+ return *pollp++;
+}
+
+static void cpm_put_poll_char(struct uart_port *port,
+ unsigned char c)
+{
+ struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+ static char ch[2];
+
+ ch[0] = (char)c;
+ cpm_uart_early_write(pinfo->port.line, ch, 1);
+}
+#endif /* CONFIG_CONSOLE_POLL */
+
static struct uart_ops cpm_uart_pops = {
.tx_empty = cpm_uart_tx_empty,
.set_mctrl = cpm_uart_set_mctrl,
@@ -882,6 +1010,10 @@ static struct uart_ops cpm_uart_pops = {
.request_port = cpm_uart_request_port,
.config_port = cpm_uart_config_port,
.verify_port = cpm_uart_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = cpm_get_poll_char,
+ .poll_put_char = cpm_put_poll_char,
+#endif
};
struct uart_cpm_port cpm_uart_ports[UART_NR];
@@ -893,14 +1025,23 @@ static int cpm_uart_init_port(struct device_node *np,
void __iomem *mem, *pram;
int len;
int ret;
+ int i;
- data = of_get_property(np, "fsl,cpm-brg", &len);
- if (!data || len != 4) {
- printk(KERN_ERR "CPM UART %s has no/invalid "
- "fsl,cpm-brg property.\n", np->name);
- return -EINVAL;
+ data = of_get_property(np, "clock", NULL);
+ if (data) {
+ struct clk *clk = clk_get(NULL, (const char*)data);
+ if (!IS_ERR(clk))
+ pinfo->clk = clk;
+ }
+ if (!pinfo->clk) {
+ data = of_get_property(np, "fsl,cpm-brg", &len);
+ if (!data || len != 4) {
+ printk(KERN_ERR "CPM UART %s has no/invalid "
+ "fsl,cpm-brg property.\n", np->name);
+ return -EINVAL;
+ }
+ pinfo->brg = *data;
}
- pinfo->brg = *data;
data = of_get_property(np, "fsl,cpm-command", &len);
if (!data || len != 4) {
@@ -952,6 +1093,9 @@ static int cpm_uart_init_port(struct device_node *np,
goto out_pram;
}
+ for (i = 0; i < NUM_GPIOS; i++)
+ pinfo->gpios[i] = of_get_gpio(np, i);
+
return cpm_uart_request_port(&pinfo->port);
out_pram:
@@ -1105,12 +1249,14 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
udbg_putc = NULL;
#endif
- cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
-
if (IS_SMC(pinfo)) {
+ out_be16(&pinfo->smcup->smc_brkcr, 0);
+ cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
} else {
+ out_be16(&pinfo->sccup->scc_brkcr, 0);
+ cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 3e0366eab41..bf94a770bb4 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -234,7 +234,7 @@ unsigned long r_alt_ser_baudrate_shadow = 0;
static struct e100_serial rs_table[] = {
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL0_CTRL,
+ .ioport = (unsigned char *)R_SERIAL0_CTRL,
.irq = 1U << 12, /* uses DMA 6 and 7 */
.oclrintradr = R_DMA_CH6_CLR_INTR,
.ofirstadr = R_DMA_CH6_FIRST,
@@ -288,7 +288,7 @@ static struct e100_serial rs_table[] = {
}, /* ttyS0 */
#ifndef CONFIG_SVINTO_SIM
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL1_CTRL,
+ .ioport = (unsigned char *)R_SERIAL1_CTRL,
.irq = 1U << 16, /* uses DMA 8 and 9 */
.oclrintradr = R_DMA_CH8_CLR_INTR,
.ofirstadr = R_DMA_CH8_FIRST,
@@ -344,7 +344,7 @@ static struct e100_serial rs_table[] = {
}, /* ttyS1 */
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL2_CTRL,
+ .ioport = (unsigned char *)R_SERIAL2_CTRL,
.irq = 1U << 4, /* uses DMA 2 and 3 */
.oclrintradr = R_DMA_CH2_CLR_INTR,
.ofirstadr = R_DMA_CH2_FIRST,
@@ -398,7 +398,7 @@ static struct e100_serial rs_table[] = {
}, /* ttyS2 */
{ .baud = DEF_BAUD,
- .port = (unsigned char *)R_SERIAL3_CTRL,
+ .ioport = (unsigned char *)R_SERIAL3_CTRL,
.irq = 1U << 8, /* uses DMA 4 and 5 */
.oclrintradr = R_DMA_CH4_CLR_INTR,
.ofirstadr = R_DMA_CH4_FIRST,
@@ -939,7 +939,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
/* Output */
#define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK)
/* Input */
-#define E100_CTS_GET(info) ((info)->port[REG_STATUS] & E100_CTS_MASK)
+#define E100_CTS_GET(info) ((info)->ioport[REG_STATUS] & E100_CTS_MASK)
/* These are typically PA or PB and 0 means 0V, 1 means 3.3V */
/* Is an output */
@@ -968,7 +968,7 @@ static DEFINE_MUTEX(tmp_buf_mutex);
/* Calculate the chartime depending on baudrate, numbor of bits etc. */
static void update_char_time(struct e100_serial * info)
{
- tcflag_t cflags = info->tty->termios->c_cflag;
+ tcflag_t cflags = info->port.tty->termios->c_cflag;
int bits;
/* calc. number of bits / data byte */
@@ -1092,7 +1092,7 @@ e100_rts(struct e100_serial *info, int set)
local_irq_save(flags);
info->rx_ctrl &= ~E100_RTS_MASK;
info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */
- info->port[REG_REC_CTRL] = info->rx_ctrl;
+ info->ioport[REG_REC_CTRL] = info->rx_ctrl;
local_irq_restore(flags);
#ifdef SERIAL_DEBUG_IO
printk("ser%i rts %i\n", info->line, set);
@@ -1142,7 +1142,7 @@ e100_disable_rx(struct e100_serial *info)
{
#ifndef CONFIG_SVINTO_SIM
/* disable the receiver */
- info->port[REG_REC_CTRL] =
+ info->ioport[REG_REC_CTRL] =
(info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
#endif
}
@@ -1152,7 +1152,7 @@ e100_enable_rx(struct e100_serial *info)
{
#ifndef CONFIG_SVINTO_SIM
/* enable the receiver */
- info->port[REG_REC_CTRL] =
+ info->ioport[REG_REC_CTRL] =
(info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
#endif
}
@@ -1483,13 +1483,14 @@ rs_stop(struct tty_struct *tty)
CIRC_CNT(info->xmit.head,
info->xmit.tail,SERIAL_XMIT_SIZE)));
- xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char,
+ STOP_CHAR(info->port.tty));
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop);
if (tty->termios->c_iflag & IXON ) {
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
- *((unsigned long *)&info->port[REG_XOFF]) = xoff;
+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
local_irq_restore(flags);
}
}
@@ -1512,7 +1513,7 @@ rs_start(struct tty_struct *tty)
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
- *((unsigned long *)&info->port[REG_XOFF]) = xoff;
+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
if (!info->uses_dma_out &&
info->xmit.head != info->xmit.tail && info->xmit.buf)
e100_enable_serial_tx_ready_irq(info);
@@ -1772,7 +1773,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl
info->icount.rx++;
} else {
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
tty_insert_flip_char(tty, data, flag);
info->icount.rx++;
}
@@ -1838,7 +1839,7 @@ static unsigned int handle_all_descr_data(struct e100_serial *info)
descr->status = 0;
DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl);
- if (info->tty->stopped) {
+ if (info->port.tty->stopped) {
unsigned char *buf = phys_to_virt(descr->buf);
DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]);
DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]);
@@ -1872,7 +1873,7 @@ static void receive_chars_dma(struct e100_serial *info)
IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
- tty = info->tty;
+ tty = info->port.tty;
if (!tty) /* Something wrong... */
return;
@@ -1887,7 +1888,7 @@ static void receive_chars_dma(struct e100_serial *info)
handle_all_descr_data(info);
/* Read the status register to detect errors */
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat));
}
@@ -1896,7 +1897,7 @@ static void receive_chars_dma(struct e100_serial *info)
/* If we got an error, we must reset it by reading the
* data_in field
*/
- unsigned char data = info->port[REG_DATA];
+ unsigned char data = info->ioport[REG_DATA];
PROCSTAT(ser_stat[info->line].errors_cnt++);
DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n",
@@ -2076,7 +2077,7 @@ static int force_eop_if_needed(struct e100_serial *info)
/* We check data_avail bit to determine if data has
* arrived since last time
*/
- unsigned char rstat = info->port[REG_STATUS];
+ unsigned char rstat = info->ioport[REG_STATUS];
/* error or datavail? */
if (rstat & SER_ERROR_MASK) {
@@ -2095,7 +2096,7 @@ static int force_eop_if_needed(struct e100_serial *info)
TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n",
rstat | (info->line << 8)));
/* Read data to clear status flags */
- (void)info->port[REG_DATA];
+ (void)info->ioport[REG_DATA];
info->forced_eop = 0;
START_FLUSH_FAST_TIMER(info, "magic");
@@ -2122,7 +2123,7 @@ static void flush_to_flip_buffer(struct e100_serial *info)
unsigned long flags;
local_irq_save(flags);
- tty = info->tty;
+ tty = info->port.tty;
if (!tty) {
local_irq_restore(flags);
@@ -2287,7 +2288,7 @@ static
struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
{
unsigned long data_read;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if (!tty) {
printk("!NO TTY!\n");
@@ -2295,7 +2296,7 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
}
/* Read data and status at the same time */
- data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
+ data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
more_data:
if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) {
DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
@@ -2350,7 +2351,7 @@ more_data:
data_in, data_read);
char flag = TTY_NORMAL;
if (info->errorcode == ERRCODE_INSERT_BREAK) {
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
tty_insert_flip_char(tty, 0, flag);
info->icount.rx++;
}
@@ -2390,13 +2391,13 @@ more_data:
info->icount.rx++;
- data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
+ data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read));
goto more_data;
}
- tty_flip_buffer_push(info->tty);
+ tty_flip_buffer_push(info->port.tty);
return info;
}
@@ -2412,7 +2413,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
return handle_ser_rx_interrupt_no_dma(info);
}
/* DMA is used */
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
}
@@ -2425,7 +2426,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
/* If we got an error, we must reset it by reading the
* data_in field
*/
- data = info->port[REG_DATA];
+ data = info->ioport[REG_DATA];
DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data));
DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat));
if (!data && (rstat & SER_FRAMING_ERR_MASK)) {
@@ -2527,10 +2528,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
unsigned char rstat;
DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char));
local_irq_save(flags);
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
- info->port[REG_TR_DATA] = info->x_char;
+ info->ioport[REG_TR_DATA] = info->x_char;
info->icount.tx++;
info->x_char = 0;
/* We must enable since it is disabled in ser_interrupt */
@@ -2544,11 +2545,11 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
/* We only use normal tx interrupt when sending x_char */
DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0));
local_irq_save(flags);
- rstat = info->port[REG_STATUS];
+ rstat = info->ioport[REG_STATUS];
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
e100_disable_serial_tx_ready_irq(info);
- if (info->tty->stopped)
- rs_stop(info->tty);
+ if (info->port.tty->stopped)
+ rs_stop(info->port.tty);
/* Enable the DMA channel and tell it to continue */
e100_enable_txdma_channel(info);
/* Wait 12 cycles before doing the DMA command */
@@ -2561,9 +2562,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
}
/* Normal char-by-char interrupt */
if (info->xmit.head == info->xmit.tail
- || info->tty->stopped
- || info->tty->hw_stopped) {
- DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->tty->stopped));
+ || info->port.tty->stopped
+ || info->port.tty->hw_stopped) {
+ DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n",
+ info->port.tty->stopped));
e100_disable_serial_tx_ready_irq(info);
info->tr_running = 0;
return;
@@ -2571,7 +2573,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail]));
/* Send a byte, rs485 timing is critical so turn of ints */
local_irq_save(flags);
- info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
+ info->ioport[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
info->icount.tx++;
if (info->xmit.head == info->xmit.tail) {
@@ -2725,7 +2727,7 @@ do_softint(struct work_struct *work)
info = container_of(work, struct e100_serial, work);
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -2767,8 +2769,8 @@ startup(struct e100_serial * info)
/* Bits and pieces collected from below. Better to have them
in one ifdef:ed clause than to mix in a lot of ifdefs,
right? */
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit.head = info->xmit.tail = 0;
info->first_recv_buffer = info->last_recv_buffer = NULL;
@@ -2825,8 +2827,8 @@ startup(struct e100_serial * info)
e100_disable_txdma_channel(info);
}
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit.head = info->xmit.tail = 0;
info->first_recv_buffer = info->last_recv_buffer = NULL;
@@ -2846,7 +2848,7 @@ startup(struct e100_serial * info)
/* dummy read to reset any serial errors */
- (void)info->port[REG_DATA];
+ (void)info->ioport[REG_DATA];
/* enable the interrupts */
if (info->uses_dma_out)
@@ -2895,7 +2897,7 @@ shutdown(struct e100_serial * info)
/* shut down the transmitter and receiver */
DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line));
e100_disable_rx(info);
- info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
+ info->ioport[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
/* disable interrupts, reset dma channels */
if (info->uses_dma_in) {
@@ -2940,14 +2942,14 @@ shutdown(struct e100_serial * info)
descr[i].buf = 0;
}
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
/* hang up DTR and RTS if HUPCL is enabled */
e100_dtr(info, 0);
e100_rts(info, 0); /* could check CRTSCTS before doing this */
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
local_irq_restore(flags);
@@ -2964,12 +2966,12 @@ change_speed(struct e100_serial *info)
unsigned long flags;
/* first some safety checks */
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- if (!info->port)
+ if (!info->ioport)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
/* possibly, the tx/rx should be disabled first to do this safely */
@@ -3035,7 +3037,7 @@ change_speed(struct e100_serial *info)
info->baud = cflag_to_baud(cflag);
#ifndef CONFIG_SVINTO_SIM
- info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
+ info->ioport[REG_BAUD] = cflag_to_etrax_baud(cflag);
#endif /* CONFIG_SVINTO_SIM */
}
@@ -3095,16 +3097,17 @@ change_speed(struct e100_serial *info)
/* actually write the control regs to the hardware */
- info->port[REG_TR_CTRL] = info->tx_ctrl;
- info->port[REG_REC_CTRL] = info->rx_ctrl;
- xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
+ info->ioport[REG_TR_CTRL] = info->tx_ctrl;
+ info->ioport[REG_REC_CTRL] = info->rx_ctrl;
+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty));
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
- if (info->tty->termios->c_iflag & IXON ) {
- DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", STOP_CHAR(info->tty)));
+ if (info->port.tty->termios->c_iflag & IXON ) {
+ DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n",
+ STOP_CHAR(info->port.tty)));
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
- *((unsigned long *)&info->port[REG_XOFF]) = xoff;
+ *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
local_irq_restore(flags);
#endif /* !CONFIG_SVINTO_SIM */
@@ -3153,7 +3156,7 @@ static int rs_raw_write(struct tty_struct *tty,
#ifdef SERIAL_DEBUG_DATA
if (info->line == SERIAL_DEBUG_LINE)
printk("rs_raw_write (%d), status %d\n",
- count, info->port[REG_STATUS]);
+ count, info->ioport[REG_STATUS]);
#endif
#ifdef CONFIG_SVINTO_SIM
@@ -3424,7 +3427,7 @@ get_serial_info(struct e100_serial * info,
memset(&tmp, 0, sizeof(tmp));
tmp.type = info->type;
tmp.line = info->line;
- tmp.port = (int)info->port;
+ tmp.port = (int)info->ioport;
tmp.irq = info->irq;
tmp.flags = info->flags;
tmp.baud_base = info->baud_base;
@@ -3475,7 +3478,7 @@ set_serial_info(struct e100_serial *info,
info->type = new_serial.type;
info->close_delay = new_serial.close_delay;
info->closing_wait = new_serial.closing_wait;
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
check_and_exit:
if (info->flags & ASYNC_INITIALIZED) {
@@ -3554,14 +3557,14 @@ char *get_control_state_str(int MLines, char *s)
}
#endif
-static void
+static int
rs_break(struct tty_struct *tty, int break_state)
{
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
unsigned long flags;
- if (!info->port)
- return;
+ if (!info->ioport)
+ return -EIO;
local_irq_save(flags);
if (break_state == -1) {
@@ -3572,8 +3575,9 @@ rs_break(struct tty_struct *tty, int break_state)
/* Set bit 7 (txd) and 6 (tr_enable) */
info->tx_ctrl |= (0x80 | 0x40);
}
- info->port[REG_TR_CTRL] = info->tx_ctrl;
+ info->ioport[REG_TR_CTRL] = info->tx_ctrl;
local_irq_restore(flags);
+ return 0;
}
static int
@@ -3811,7 +3815,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
if (info->blocked_open) {
if (info->close_delay)
schedule_timeout_interruptible(info->close_delay);
@@ -3915,7 +3919,7 @@ rs_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -4077,9 +4081,9 @@ rs_open(struct tty_struct *tty, struct file * filp)
info->count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
if (!tmp_buf) {
page = get_zeroed_page(GFP_KERNEL);
@@ -4228,9 +4232,9 @@ static int line_info(char *buf, struct e100_serial *info)
unsigned long tmp;
ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d",
- info->line, (unsigned long)info->port, info->irq);
+ info->line, (unsigned long)info->ioport, info->irq);
- if (!info->port || (info->type == PORT_UNKNOWN)) {
+ if (!info->ioport || (info->type == PORT_UNKNOWN)) {
ret += sprintf(buf+ret, "\n");
return ret;
}
@@ -4267,18 +4271,18 @@ static int line_info(char *buf, struct e100_serial *info)
(unsigned long)info->max_recv_cnt);
#if 1
- if (info->tty) {
+ if (info->port.tty) {
- if (info->tty->stopped)
+ if (info->port.tty->stopped)
ret += sprintf(buf+ret, " stopped:%i",
- (int)info->tty->stopped);
- if (info->tty->hw_stopped)
+ (int)info->port.tty->stopped);
+ if (info->port.tty->hw_stopped)
ret += sprintf(buf+ret, " hw_stopped:%i",
- (int)info->tty->hw_stopped);
+ (int)info->port.tty->hw_stopped);
}
{
- unsigned char rstat = info->port[REG_STATUS];
+ unsigned char rstat = info->ioport[REG_STATUS];
if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) )
ret += sprintf(buf+ret, " xoff_detect:1");
}
@@ -4465,7 +4469,7 @@ rs_init(void)
info->uses_dma_in = 0;
info->uses_dma_out = 0;
info->line = i;
- info->tty = 0;
+ info->port.tty = NULL;
info->type = PORT_ETRAX;
info->tr_running = 0;
info->forced_eop = 0;
@@ -4499,7 +4503,7 @@ rs_init(void)
if (info->enabled) {
printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
- serial_driver->name, info->line, (unsigned int)info->port);
+ serial_driver->name, info->line, (unsigned int)info->ioport);
}
}
#ifdef CONFIG_ETRAX_FAST_TIMER
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h
index ccd0f32b737..e3c5c8c3c09 100644
--- a/drivers/serial/crisv10.h
+++ b/drivers/serial/crisv10.h
@@ -36,8 +36,9 @@ struct etrax_recv_buffer {
};
struct e100_serial {
+ struct tty_port port;
int baud;
- volatile u8 *port; /* R_SERIALx_CTRL */
+ volatile u8 *ioport; /* R_SERIALx_CTRL */
u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */
/* Output registers */
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 0dddd68b20d..6042b87797a 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -197,7 +197,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
dport = &mux->dport[LINE(status)];
uport = &dport->port;
- tty = uport->info->tty; /* point to the proper dev */
+ tty = uport->info->port.tty; /* point to the proper dev */
ch = UCHAR(status); /* grab the char */
flag = TTY_NORMAL;
@@ -249,7 +249,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
}
for (i = 0; i < DZ_NB_PORT; i++)
if (lines_rx[i])
- tty_flip_buffer_push(mux->dport[i].port.info->tty);
+ tty_flip_buffer_push(mux->dport[i].port.info->port.tty);
}
/*
@@ -642,6 +642,26 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
spin_unlock_irqrestore(&dport->port.lock, flags);
}
+/*
+ * Hack alert!
+ * Required solely so that the initial PROM-based console
+ * works undisturbed in parallel with this one.
+ */
+static void dz_pm(struct uart_port *uport, unsigned int state,
+ unsigned int oldstate)
+{
+ struct dz_port *dport = to_dport(uport);
+ unsigned long flags;
+
+ spin_lock_irqsave(&dport->port.lock, flags);
+ if (state < 3)
+ dz_start_tx(&dport->port);
+ else
+ dz_stop_tx(&dport->port);
+ spin_unlock_irqrestore(&dport->port.lock, flags);
+}
+
+
static const char *dz_type(struct uart_port *uport)
{
return "DZ";
@@ -738,6 +758,7 @@ static struct uart_ops dz_ops = {
.startup = dz_startup,
.shutdown = dz_shutdown,
.set_termios = dz_set_termios,
+ .pm = dz_pm,
.type = dz_type,
.release_port = dz_release_port,
.request_port = dz_request_port,
@@ -861,7 +882,10 @@ static int __init dz_console_setup(struct console *co, char *options)
if (ret)
return ret;
+ spin_lock_init(&dport->port.lock); /* For dz_pm(). */
+
dz_reset(dport);
+ dz_pm(uport, 0, -1);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 9c2df5c857c..2b7531d9f6a 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -730,7 +730,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
{
short int count, rcv_buff;
- struct tty_struct *tty = icom_port->uart_port.info->tty;
+ struct tty_struct *tty = icom_port->uart_port.info->port.tty;
unsigned short int status;
struct uart_icount *icount;
unsigned long offset;
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 64acb39a51b..3f90f1bbbbc 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -44,8 +44,8 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/arch/imx-uart.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
/* Register definitions */
#define URXD0 0x0 /* Receiver Register */
@@ -127,8 +127,13 @@
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
-#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
-#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
+#ifdef CONFIG_ARCH_IMX
+#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */
+#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */
+#endif
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+#define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */
+#endif
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
#define UCR3_BPEN (1<<0) /* Preset registers enable */
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
@@ -372,7 +377,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
{
struct imx_port *sport = dev_id;
unsigned int rx,flg,ignored = 0;
- struct tty_struct *tty = sport->port.info->tty;
+ struct tty_struct *tty = sport->port.info->port.tty;
unsigned long flags, temp;
spin_lock_irqsave(&sport->port.lock,flags);
@@ -445,7 +450,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
imx_txint(irq, dev_id);
- if (sts & USR1_RTSS)
+ if (sts & USR1_RTSD)
imx_rtsint(irq, dev_id);
return IRQ_HANDLED;
@@ -598,6 +603,12 @@ static int imx_startup(struct uart_port *port)
temp |= (UCR2_RXEN | UCR2_TXEN);
writel(temp, sport->port.membase + UCR2);
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+ temp = readl(sport->port.membase + UCR3);
+ temp |= UCR3_RXDMUXSEL;
+ writel(temp, sport->port.membase + UCR3);
+#endif
+
/*
* Enable modem status interrupts
*/
@@ -1133,13 +1144,19 @@ static int serial_imx_probe(struct platform_device *pdev)
if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
sport->have_rtscts = 1;
- if (pdata->init)
- pdata->init(pdev);
+ if (pdata->init) {
+ ret = pdata->init(pdev);
+ if (ret)
+ goto clkput;
+ }
uart_add_one_port(&imx_reg, &sport->port);
platform_set_drvdata(pdev, &sport->port);
return 0;
+clkput:
+ clk_put(sport->clk);
+ clk_disable(sport->clk);
unmap:
iounmap(sport->port.membase);
free:
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 4f1af71e9a1..6dd98f9fb89 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -905,7 +905,7 @@ static void transmit_chars(struct uart_port *the_port)
return;
info = the_port->info;
- tty = info->tty;
+ tty = info->port.tty;
if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
/* Nothing to do or hw stopped */
@@ -997,14 +997,14 @@ ioc3_change_speed(struct uart_port *the_port,
the_port->ignore_status_mask = N_ALL_INPUT;
- info->tty->low_latency = 1;
+ info->port.tty->low_latency = 1;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
the_port->ignore_status_mask &= ~N_BREAK;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
}
if (!(cflag & CREAD)) {
@@ -1399,14 +1399,14 @@ static int receive_chars(struct uart_port *the_port)
/* Make sure all the pointers are "good" ones */
if (!info)
return 0;
- if (!info->tty)
+ if (!info->port.tty)
return 0;
if (!(port->ip_flags & INPUT_ENABLE))
return 0;
spin_lock_irqsave(&the_port->lock, pflags);
- tty = info->tty;
+ tty = info->port.tty;
read_count = do_read(the_port, ch, MAX_CHARS);
if (read_count > 0) {
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 49b8a82b7b9..6bab63cd5b2 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -1635,7 +1635,7 @@ static void transmit_chars(struct uart_port *the_port)
return;
info = the_port->info;
- tty = info->tty;
+ tty = info->port.tty;
if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
/* Nothing to do or hw stopped */
@@ -1738,14 +1738,14 @@ ioc4_change_speed(struct uart_port *the_port,
the_port->ignore_status_mask = N_ALL_INPUT;
- info->tty->low_latency = 1;
+ info->port.tty->low_latency = 1;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
the_port->ignore_status_mask &= ~N_BREAK;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
}
if (!(cflag & CREAD)) {
@@ -1801,7 +1801,8 @@ static inline int ic4_startup_local(struct uart_port *the_port)
ioc4_set_proto(port, the_port->mapbase);
/* set the speed of the serial port */
- ioc4_change_speed(the_port, info->tty->termios, (struct ktermios *)0);
+ ioc4_change_speed(the_port, info->port.tty->termios,
+ (struct ktermios *)0);
return 0;
}
@@ -2346,11 +2347,11 @@ static void receive_chars(struct uart_port *the_port)
/* Make sure all the pointers are "good" ones */
if (!info)
return;
- if (!info->tty)
+ if (!info->port.tty)
return;
spin_lock_irqsave(&the_port->lock, pflags);
- tty = info->tty;
+ tty = info->port.tty;
request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS);
@@ -2440,8 +2441,8 @@ static void ic4_shutdown(struct uart_port *the_port)
wake_up_interruptible(&info->delta_msr_wait);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
spin_lock_irqsave(&the_port->lock, port_flags);
set_notification(port, N_ALL, 0);
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 9c95bc0398a..0d9acbd0bb7 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -257,8 +257,8 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up
tty = NULL;
if (up->port.info != NULL &&
- up->port.info->tty != NULL)
- tty = up->port.info->tty;
+ up->port.info->port.tty != NULL)
+ tty = up->port.info->port.tty;
for (;;) {
ch = readb(&channel->control);
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index b2d6f5b1a7c..b7584ca55ad 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -998,7 +998,7 @@ static void neo_param(struct jsm_channel *ch)
{ 50, B50 },
};
- cflag = C_BAUD(ch->uart_port.info->tty);
+ cflag = C_BAUD(ch->uart_port.info->port.tty);
baud = 9600;
for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
if (baud_rates[i].cflag == cflag) {
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 94ec6637250..a697914ae3d 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -145,7 +145,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
struct ktermios *termios;
spin_lock_irqsave(&port->lock, lock_flags);
- termios = port->info->tty->termios;
+ termios = port->info->port.tty->termios;
if (ch == termios->c_cc[VSTART])
channel->ch_bd->bd_ops->send_start_character(channel);
@@ -239,7 +239,7 @@ static int jsm_tty_open(struct uart_port *port)
channel->ch_cached_lsr = 0;
channel->ch_stops_sent = 0;
- termios = port->info->tty->termios;
+ termios = port->info->port.tty->termios;
channel->ch_c_cflag = termios->c_cflag;
channel->ch_c_iflag = termios->c_iflag;
channel->ch_c_oflag = termios->c_oflag;
@@ -272,7 +272,7 @@ static void jsm_tty_close(struct uart_port *port)
jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
bd = channel->ch_bd;
- ts = channel->uart_port.info->tty->termios;
+ ts = channel->uart_port.info->port.tty->termios;
channel->ch_flags &= ~(CH_STOPI);
@@ -515,7 +515,7 @@ void jsm_input(struct jsm_channel *ch)
if (!ch)
return;
- tp = ch->uart_port.info->tty;
+ tp = ch->uart_port.info->port.tty;
bd = ch->ch_bd;
if(!bd)
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index c2bb11c02bd..23d03051101 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -325,7 +325,7 @@ static void m32r_sio_enable_ms(struct uart_port *port)
static void receive_chars(struct uart_sio_port *up, int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch;
unsigned char flag;
int max_count = 256;
@@ -1160,7 +1160,7 @@ static int __init m32r_sio_init(void)
{
int ret, i;
- printk(KERN_INFO "Serial: M32R SIO driver $Revision: 1.11 $ ");
+ printk(KERN_INFO "Serial: M32R SIO driver\n");
for (i = 0; i < NR_IRQS; i++)
spin_lock_init(&irq_lists[i].lock);
@@ -1189,4 +1189,4 @@ EXPORT_SYMBOL(m32r_sio_suspend_port);
EXPORT_SYMBOL(m32r_sio_resume_port);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic M32R SIO serial driver $Revision: 1.11 $");
+MODULE_DESCRIPTION("Generic M32R SIO serial driver");
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 7e164e0cd21..b2001c5b145 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -312,7 +312,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
}
- tty_flip_buffer_push(port->info->tty);
+ tty_flip_buffer_push(port->info->port.tty);
}
/****************************************************************************/
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 56007cc8a9b..fbe3835f6b7 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -327,7 +327,7 @@ static void mcfrs_start(struct tty_struct *tty)
static inline void receive_chars(struct mcf_serial *info)
{
volatile unsigned char *uartp;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned char status, ch, flag;
if (!tty)
@@ -382,7 +382,7 @@ static inline void transmit_chars(struct mcf_serial *info)
info->stats.tx++;
}
- if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+ if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
info->imr &= ~MCFUART_UIR_TXREADY;
uartp[MCFUART_UIMR] = info->imr;
return;
@@ -428,7 +428,7 @@ irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
static void mcfrs_offintr(struct work_struct *work)
{
struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue);
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if (tty)
tty_wakeup(tty);
@@ -498,7 +498,7 @@ static void mcfrs_timer(void)
static void do_serial_hangup(struct work_struct *work)
{
struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup);
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if (tty)
tty_hangup(tty);
@@ -532,8 +532,8 @@ static int startup(struct mcf_serial * info)
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
mcfrs_setsignals(info, 1, 1);
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/*
@@ -578,7 +578,7 @@ static void shutdown(struct mcf_serial * info)
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
mcfrs_setsignals(info, 0, 0);
if (info->xmit_buf) {
@@ -586,8 +586,8 @@ static void shutdown(struct mcf_serial * info)
info->xmit_buf = 0;
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
local_irq_restore(flags);
@@ -609,9 +609,9 @@ static void mcfrs_change_speed(struct mcf_serial *info)
unsigned int fraction;
#endif
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
if (info->addr == 0)
return;
@@ -623,7 +623,7 @@ static void mcfrs_change_speed(struct mcf_serial *info)
if (i & CBAUDEX) {
i &= ~CBAUDEX;
if (i < 1 || i > 4)
- info->tty->termios->c_cflag &= ~CBAUDEX;
+ info->port.tty->termios->c_cflag &= ~CBAUDEX;
else
i += 15;
}
@@ -1216,7 +1216,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp)
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
#if 0
if (tty->ldisc.num != ldiscs[N_TTY].num) {
if (tty->ldisc.close)
@@ -1325,7 +1325,7 @@ void mcfrs_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -1452,7 +1452,7 @@ int mcfrs_open(struct tty_struct *tty, struct file * filp)
#endif
info->count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
@@ -1767,7 +1767,7 @@ mcfrs_init(void)
for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) {
info->magic = SERIAL_MAGIC;
info->line = i;
- info->tty = 0;
+ info->port.tty = NULL;
info->custom_divisor = 16;
info->close_delay = 50;
info->closing_wait = 3000;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index efc971d9647..36126070d9a 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -732,7 +732,7 @@ static struct uart_ops mpc52xx_uart_ops = {
static inline int
mpc52xx_uart_int_rx_chars(struct uart_port *port)
{
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned char ch, flag;
unsigned short status;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index e8819c43f57..61d3ade5286 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
return 0;
}
+#ifdef CONFIG_CONSOLE_POLL
+static int serial_polled;
+#endif
+
/*
******************************************************************************
*
@@ -932,7 +936,7 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
static int mpsc_rx_intr(struct mpsc_port_info *pi)
{
struct mpsc_rx_desc *rxre;
- struct tty_struct *tty = pi->port.info->tty;
+ struct tty_struct *tty = pi->port.info->port.tty;
u32 cmdstat, bytes_in, i;
int rc = 0;
u8 *bp;
@@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
& SDMA_DESC_CMDSTAT_O)) {
bytes_in = be16_to_cpu(rxre->bytecnt);
-
+#ifdef CONFIG_CONSOLE_POLL
+ if (unlikely(serial_polled)) {
+ serial_polled = 0;
+ return 0;
+ }
+#endif
/* Following use of tty struct directly is deprecated */
if (unlikely(tty_buffer_request_room(tty, bytes_in)
< bytes_in)) {
@@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
if (uart_handle_sysrq_char(&pi->port, *bp)) {
bp++;
bytes_in--;
+#ifdef CONFIG_CONSOLE_POLL
+ if (unlikely(serial_polled)) {
+ serial_polled = 0;
+ return 0;
+ }
+#endif
goto next_frame;
}
@@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
return rc;
}
+#ifdef CONFIG_CONSOLE_POLL
+/* Serial polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+static char poll_buf[2048];
+static int poll_ptr;
+static int poll_cnt;
+static void mpsc_put_poll_char(struct uart_port *port,
+ unsigned char c);
+
+static int mpsc_get_poll_char(struct uart_port *port)
+{
+ struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+ struct mpsc_rx_desc *rxre;
+ u32 cmdstat, bytes_in, i;
+ u8 *bp;
+
+ if (!serial_polled)
+ serial_polled = 1;
+
+ pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
+
+ if (poll_cnt) {
+ poll_cnt--;
+ return poll_buf[poll_ptr++];
+ }
+ poll_ptr = 0;
+ poll_cnt = 0;
+
+ while (poll_cnt == 0) {
+ rxre = (struct mpsc_rx_desc *)(pi->rxr +
+ (pi->rxr_posn*MPSC_RXRE_SIZE));
+ dma_cache_sync(pi->port.dev, (void *)rxre,
+ MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+ invalidate_dcache_range((ulong)rxre,
+ (ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+ /*
+ * Loop through Rx descriptors handling ones that have
+ * been completed.
+ */
+ while (poll_cnt == 0 &&
+ !((cmdstat = be32_to_cpu(rxre->cmdstat)) &
+ SDMA_DESC_CMDSTAT_O)){
+ bytes_in = be16_to_cpu(rxre->bytecnt);
+ bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
+ dma_cache_sync(pi->port.dev, (void *) bp,
+ MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+ invalidate_dcache_range((ulong)bp,
+ (ulong)bp + MPSC_RXBE_SIZE);
+#endif
+ if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
+ SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
+ !(cmdstat & pi->port.ignore_status_mask)) {
+ poll_buf[poll_cnt] = *bp;
+ poll_cnt++;
+ } else {
+ for (i = 0; i < bytes_in; i++) {
+ poll_buf[poll_cnt] = *bp++;
+ poll_cnt++;
+ }
+ pi->port.icount.rx += bytes_in;
+ }
+ rxre->bytecnt = cpu_to_be16(0);
+ wmb();
+ rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
+ SDMA_DESC_CMDSTAT_EI |
+ SDMA_DESC_CMDSTAT_F |
+ SDMA_DESC_CMDSTAT_L);
+ wmb();
+ dma_cache_sync(pi->port.dev, (void *)rxre,
+ MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+ flush_dcache_range((ulong)rxre,
+ (ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+
+ /* Advance to next descriptor */
+ pi->rxr_posn = (pi->rxr_posn + 1) &
+ (MPSC_RXR_ENTRIES - 1);
+ rxre = (struct mpsc_rx_desc *)(pi->rxr +
+ (pi->rxr_posn * MPSC_RXRE_SIZE));
+ dma_cache_sync(pi->port.dev, (void *)rxre,
+ MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+ invalidate_dcache_range((ulong)rxre,
+ (ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+ }
+
+ /* Restart rx engine, if its stopped */
+ if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
+ mpsc_start_rx(pi);
+ }
+ if (poll_cnt) {
+ poll_cnt--;
+ return poll_buf[poll_ptr++];
+ }
+
+ return 0;
+}
+
+
+static void mpsc_put_poll_char(struct uart_port *port,
+ unsigned char c)
+{
+ struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+ u32 data;
+
+ data = readl(pi->mpsc_base + MPSC_MPCR);
+ writeb(c, pi->mpsc_base + MPSC_CHR_1);
+ mb();
+ data = readl(pi->mpsc_base + MPSC_CHR_2);
+ data |= MPSC_CHR_2_TTCS;
+ writel(data, pi->mpsc_base + MPSC_CHR_2);
+ mb();
+
+ while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS);
+}
+#endif
static struct uart_ops mpsc_pops = {
.tx_empty = mpsc_tx_empty,
@@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = {
.request_port = mpsc_request_port,
.config_port = mpsc_config_port,
.verify_port = mpsc_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = mpsc_get_poll_char,
+ .poll_put_char = mpsc_put_poll_char,
+#endif
};
/*
@@ -1972,7 +2118,7 @@ static int __init mpsc_drv_init(void)
{
int rc;
- printk(KERN_INFO "Serial: MPSC driver $Revision: 1.00 $\n");
+ printk(KERN_INFO "Serial: MPSC driver\n");
memset(mpsc_ports, 0, sizeof(mpsc_ports));
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
@@ -2004,7 +2150,7 @@ module_init(mpsc_drv_init);
module_exit(mpsc_drv_exit);
MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
-MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $");
+MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver");
MODULE_VERSION(MPSC_VERSION);
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR);
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index e94031731a4..953a5ffa9b4 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -243,7 +243,7 @@ static void mux_write(struct uart_port *port)
static void mux_read(struct uart_port *port)
{
int data;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
__u32 start_count = port->icount.rx;
while(1) {
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 81ac9bb4f39..3f489329e8d 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -35,8 +35,8 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/arch/netx-regs.h>
+#include <mach/hardware.h>
+#include <mach/netx-regs.h>
/* We've been assigned a range on the "Low-density serial ports" major */
#define SERIAL_NX_MAJOR 204
@@ -203,7 +203,7 @@ static void netx_txint(struct uart_port *port)
static void netx_rxint(struct uart_port *port)
{
unsigned char rx, flg, status;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
rx = readl(port->membase + UART_DR);
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 794bd0f50d7..317b061f764 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -242,12 +242,12 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
}
/* Sanity check, make sure the old bug is no longer happening */
- if (uap->port.info == NULL || uap->port.info->tty == NULL) {
+ if (uap->port.info == NULL || uap->port.info->port.tty == NULL) {
WARN_ON(1);
(void)read_zsdata(uap);
return NULL;
}
- tty = uap->port.info->tty;
+ tty = uap->port.info->port.tty;
while (1) {
error = 0;
diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c
index d0e5a79ea63..22e30d21225 100644
--- a/drivers/serial/pnx8xxx_uart.c
+++ b/drivers/serial/pnx8xxx_uart.c
@@ -181,7 +181,7 @@ static void pnx8xxx_enable_ms(struct uart_port *port)
static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
{
- struct tty_struct *tty = sport->port.info->tty;
+ struct tty_struct *tty = sport->port.info->port.tty;
unsigned int status, ch, flg;
status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
@@ -824,7 +824,7 @@ static int __init pnx8xxx_serial_init(void)
{
int ret;
- printk(KERN_INFO "Serial: PNX8XXX driver $Revision: 1.2 $\n");
+ printk(KERN_INFO "Serial: PNX8XXX driver\n");
pnx8xxx_init_ports();
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b4f7ffb7688..f7a0d37c422 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -45,9 +45,9 @@
#include <linux/clk.h>
#include <asm/io.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/arch/pxa-regs.h>
+#include <mach/pxa-regs.h>
struct uart_pxa_port {
@@ -101,7 +101,7 @@ static void serial_pxa_stop_rx(struct uart_port *port)
static inline void receive_chars(struct uart_pxa_port *up, int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned int ch, flag;
int max_count = 256;
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c
index a1102053e55..c8b4266ac35 100644
--- a/drivers/serial/s3c2400.c
+++ b/drivers/serial/s3c2400.c
@@ -17,10 +17,10 @@
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index c5f03f41686..40a2531b554 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -19,10 +19,10 @@
#include <linux/serial.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index ce0c220e3e9..d0170319c72 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -19,10 +19,10 @@
#include <linux/serial.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
index 38f954bd39c..d4a2b17b249 100644
--- a/drivers/serial/s3c2440.c
+++ b/drivers/serial/s3c2440.c
@@ -19,10 +19,10 @@
#include <linux/serial.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 62b38582f5e..b24a25ea6bc 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -20,9 +20,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: sa1100.c,v 1.50 2002/07/29 14:41:04 rmk Exp $
- *
*/
#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -42,7 +39,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/mach/serial_sa1100.h>
/* We've been assigned a range on the "Low-density serial ports" major */
@@ -192,7 +189,7 @@ static void sa1100_enable_ms(struct uart_port *port)
static void
sa1100_rx_chars(struct sa1100_port *sport)
{
- struct tty_struct *tty = sport->port.info->tty;
+ struct tty_struct *tty = sport->port.info->port.tty;
unsigned int status, ch, flg;
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
@@ -892,7 +889,7 @@ static int __init sa1100_serial_init(void)
{
int ret;
- printk(KERN_INFO "Serial: SA11x0 driver $Revision: 1.50 $\n");
+ printk(KERN_INFO "Serial: SA11x0 driver\n");
sa1100_init_ports();
@@ -915,7 +912,7 @@ module_init(sa1100_serial_init);
module_exit(sa1100_serial_exit);
MODULE_AUTHOR("Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("SA1100 generic serial port driver $Revision: 1.50 $");
+MODULE_DESCRIPTION("SA1100 generic serial port driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_SA1100_MAJOR);
MODULE_ALIAS("platform:sa11x0-uart");
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 4a3ecaa629e..5a88b3f9fe9 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -45,10 +45,10 @@
#include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
+#include <mach/regs-gpio.h>
#include "samsung.h"
@@ -202,7 +202,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
{
struct s3c24xx_uart_port *ourport = dev_id;
struct uart_port *port = &ourport->port;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int ufcon, ch, flag, ufstat, uerstat;
int max_count = 64;
diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c
index f8e1447a022..a4fb343a08d 100644
--- a/drivers/serial/sb1250-duart.c
+++ b/drivers/serial/sb1250-duart.c
@@ -384,7 +384,7 @@ static void sbd_receive_chars(struct sbd_port *sport)
uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);
}
- tty_flip_buffer_push(uport->info->tty);
+ tty_flip_buffer_push(uport->info->port.tty);
}
static void sbd_transmit_chars(struct sbd_port *sport)
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
index ae2a9e2df77..e0be11ceaa2 100644
--- a/drivers/serial/sc26xx.c
+++ b/drivers/serial/sc26xx.c
@@ -141,7 +141,7 @@ static struct tty_struct *receive_chars(struct uart_port *port)
u8 status;
if (port->info != NULL) /* Unopened serial console */
- tty = port->info->tty;
+ tty = port->info->port.tty;
while (limit-- > 0) {
status = READ_SC_PORT(port, SR);
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 42d2e108b67..f977c98cfa9 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -50,7 +50,7 @@ static struct lock_class_key port_lock_key;
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
+#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->port.blocked_open : 0))
#ifdef CONFIG_SERIAL_CORE_CONSOLE
#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
@@ -113,7 +113,7 @@ static void uart_start(struct tty_struct *tty)
static void uart_tasklet_action(unsigned long data)
{
struct uart_state *state = (struct uart_state *)data;
- tty_wakeup(state->info->tty);
+ tty_wakeup(state->info->port.tty);
}
static inline void
@@ -135,7 +135,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
/*
* Startup the port. This will be called once per open. All calls
- * will be serialised by the per-port semaphore.
+ * will be serialised by the per-port mutex.
*/
static int uart_startup(struct uart_state *state, int init_hw)
{
@@ -152,7 +152,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* once we have successfully opened the port. Also set
* up the tty->alt_speed kludge
*/
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
if (port->type == PORT_UNKNOWN)
return 0;
@@ -162,6 +162,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* buffer.
*/
if (!info->xmit.buf) {
+ /* This is protected by the per port mutex */
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
@@ -182,20 +183,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
* Setup the RTS and DTR signals once the
* port is open and ready to respond.
*/
- if (info->tty->termios->c_cflag & CBAUD)
+ if (info->port.tty->termios->c_cflag & CBAUD)
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
}
if (info->flags & UIF_CTS_FLOW) {
spin_lock_irq(&port->lock);
if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
spin_unlock_irq(&port->lock);
}
info->flags |= UIF_INITIALIZED;
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
}
if (retval && capable(CAP_SYS_ADMIN))
@@ -217,8 +218,8 @@ static void uart_shutdown(struct uart_state *state)
/*
* Set the TTY IO error marker
*/
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
if (info->flags & UIF_INITIALIZED) {
info->flags &= ~UIF_INITIALIZED;
@@ -226,7 +227,7 @@ static void uart_shutdown(struct uart_state *state)
/*
* Turn off DTR and RTS early.
*/
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
/*
@@ -426,7 +427,7 @@ EXPORT_SYMBOL(uart_get_divisor);
static void
uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
{
- struct tty_struct *tty = state->info->tty;
+ struct tty_struct *tty = state->info->port.tty;
struct uart_port *port = state->port;
struct ktermios *termios;
@@ -573,6 +574,8 @@ static void uart_flush_buffer(struct tty_struct *tty)
spin_lock_irqsave(&port->lock, flags);
uart_circ_clear(&state->info->xmit);
+ if (port->ops->flush_buffer)
+ port->ops->flush_buffer(port);
spin_unlock_irqrestore(&port->lock, flags);
tty_wakeup(tty);
}
@@ -834,8 +837,8 @@ static int uart_set_info(struct uart_state *state,
state->closing_wait = closing_wait;
if (new_serial.xmit_fifo_size)
port->fifosize = new_serial.xmit_fifo_size;
- if (state->info->tty)
- state->info->tty->low_latency =
+ if (state->info->port.tty)
+ state->info->port.tty->low_latency =
(port->flags & UPF_LOW_LATENCY) ? 1 : 0;
check_and_exit:
@@ -855,7 +858,7 @@ static int uart_set_info(struct uart_state *state,
printk(KERN_NOTICE
"%s sets custom speed on %s. This "
"is deprecated.\n", current->comm,
- tty_name(state->info->tty, buf));
+ tty_name(state->info->port.tty, buf));
}
uart_change_speed(state, NULL);
}
@@ -887,7 +890,7 @@ static int uart_get_lsr_info(struct uart_state *state,
*/
if (port->x_char ||
((uart_circ_chars_pending(&state->info->xmit) > 0) &&
- !state->info->tty->stopped && !state->info->tty->hw_stopped))
+ !state->info->port.tty->stopped && !state->info->port.tty->hw_stopped))
result &= ~TIOCSER_TEMT;
return put_user(result, value);
@@ -931,7 +934,7 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
return ret;
}
-static void uart_break_ctl(struct tty_struct *tty, int break_state)
+static int uart_break_ctl(struct tty_struct *tty, int break_state)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port;
@@ -942,6 +945,7 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
port->ops->break_ctl(port, break_state);
mutex_unlock(&state->mutex);
+ return 0;
}
static int uart_do_autoconfig(struct uart_state *state)
@@ -1237,7 +1241,7 @@ static void uart_set_termios(struct tty_struct *tty,
*/
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&state->info->open_wait);
+ wake_up_interruptible(&state->info->port.open_wait);
#endif
}
@@ -1318,9 +1322,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
tty_ldisc_flush(tty);
tty->closing = 0;
- state->info->tty = NULL;
+ state->info->port.tty = NULL;
- if (state->info->blocked_open) {
+ if (state->info->port.blocked_open) {
if (state->close_delay)
msleep_interruptible(state->close_delay);
} else if (!uart_console(port)) {
@@ -1331,7 +1335,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* Wake up anyone trying to open this port.
*/
state->info->flags &= ~UIF_NORMAL_ACTIVE;
- wake_up_interruptible(&state->info->open_wait);
+ wake_up_interruptible(&state->info->port.open_wait);
done:
mutex_unlock(&state->mutex);
@@ -1415,8 +1419,8 @@ static void uart_hangup(struct tty_struct *tty)
uart_shutdown(state);
state->count = 0;
state->info->flags &= ~UIF_NORMAL_ACTIVE;
- state->info->tty = NULL;
- wake_up_interruptible(&state->info->open_wait);
+ state->info->port.tty = NULL;
+ wake_up_interruptible(&state->info->port.open_wait);
wake_up_interruptible(&state->info->delta_msr_wait);
}
mutex_unlock(&state->mutex);
@@ -1430,7 +1434,7 @@ static void uart_hangup(struct tty_struct *tty)
*/
static void uart_update_termios(struct uart_state *state)
{
- struct tty_struct *tty = state->info->tty;
+ struct tty_struct *tty = state->info->port.tty;
struct uart_port *port = state->port;
if (uart_console(port) && port->cons->cflag) {
@@ -1469,17 +1473,17 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
struct uart_port *port = state->port;
unsigned int mctrl;
- info->blocked_open++;
+ info->port.blocked_open++;
state->count--;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
/*
* If we have been hung up, tell userspace/restart open.
*/
- if (tty_hung_up_p(filp) || info->tty == NULL)
+ if (tty_hung_up_p(filp) || info->port.tty == NULL)
break;
/*
@@ -1498,8 +1502,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* have set TTY_IO_ERROR for a non-existant port.
*/
if ((filp->f_flags & O_NONBLOCK) ||
- (info->tty->termios->c_cflag & CLOCAL) ||
- (info->tty->flags & (1 << TTY_IO_ERROR)))
+ (info->port.tty->termios->c_cflag & CLOCAL) ||
+ (info->port.tty->flags & (1 << TTY_IO_ERROR)))
break;
/*
@@ -1507,7 +1511,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* not set RTS here - we want to make sure we catch
* the data from the modem.
*/
- if (info->tty->termios->c_cflag & CBAUD)
+ if (info->port.tty->termios->c_cflag & CBAUD)
uart_set_mctrl(port, TIOCM_DTR);
/*
@@ -1529,15 +1533,15 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
break;
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
state->count++;
- info->blocked_open--;
+ info->port.blocked_open--;
if (signal_pending(current))
return -ERESTARTSYS;
- if (!info->tty || tty_hung_up_p(filp))
+ if (!info->port.tty || tty_hung_up_p(filp))
return -EAGAIN;
return 0;
@@ -1560,10 +1564,13 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
goto err_unlock;
}
+ /* BKL: RACE HERE - LEAK */
+ /* We should move this into the uart_state structure and kill off
+ this whole complexity */
if (!state->info) {
state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL);
if (state->info) {
- init_waitqueue_head(&state->info->open_wait);
+ init_waitqueue_head(&state->info->port.open_wait);
init_waitqueue_head(&state->info->delta_msr_wait);
/*
@@ -1620,7 +1627,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
* be re-entered while allocating the info structure, or while we
* request any IRQs that the driver may need. This also has the nice
* side-effect that it delays the action of uart_hangup, so we can
- * guarantee that info->tty will always contain something reasonable.
+ * guarantee that info->port.tty will always contain something reasonable.
*/
state = uart_get(drv, line);
if (IS_ERR(state)) {
@@ -1636,7 +1643,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = state;
tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
tty->alt_speed = 0;
- state->info->tty = tty;
+ state->info->port.tty = tty;
/*
* If the port is in the middle of closing, bail out now.
@@ -2099,8 +2106,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
/*
* If that's unset, use the tty termios setting.
*/
- if (state->info && state->info->tty && termios.c_cflag == 0)
- termios = *state->info->tty->termios;
+ if (state->info && state->info->port.tty && termios.c_cflag == 0)
+ termios = *state->info->port.tty->termios;
uart_change_pm(state, 0);
port->ops->set_termios(port, &termios, NULL);
@@ -2519,8 +2526,8 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
tty_unregister_device(drv->tty_driver, port->line);
info = state->info;
- if (info && info->tty)
- tty_vhangup(info->tty);
+ if (info && info->port.tty)
+ tty_vhangup(info->port.tty);
/*
* All users of this port should now be disconnected from
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 8721afe1ae4..b9cbfc87f61 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -26,8 +26,8 @@
#include <asm/irq.h>
#include <asm/mach/irq.h>
-#include <asm/arch/regs-uart.h>
-#include <asm/arch/regs-irq.h>
+#include <mach/regs-uart.h>
+#include <mach/regs-irq.h>
#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -108,7 +108,7 @@ static void ks8695uart_disable_ms(struct uart_port *port)
static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int status, ch, lsr, flg, max_count = 256;
status = UART_GET_LSR(port); /* clears pending LSR interrupts */
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index eb18d429752..cb49a5ac022 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -137,7 +137,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port)
static void lh7a40xuart_rx_chars (struct uart_port* port)
{
- struct tty_struct* tty = port->info->tty;
+ struct tty_struct* tty = port->info->port.tty;
int cbRxMax = 256; /* (Gross) limit on receive */
unsigned int data; /* Received data and status */
unsigned int flag;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 7ad21925869..8fcb4c5b9a2 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -272,7 +272,7 @@ static void serial_txx9_initialize(struct uart_port *port)
static inline void
receive_chars(struct uart_txx9_port *up, unsigned int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch;
unsigned int disr = *status;
int max_count = 256;
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index ce6ee92b3a1..3df2aaec829 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -410,7 +410,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
static inline int scif_txroom(struct uart_port *port)
@@ -422,6 +421,22 @@ static inline int scif_rxroom(struct uart_port *port)
{
return sci_in(port, SCRFDR) & 0xff;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+static inline int scif_txroom(struct uart_port *port)
+{
+ if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
+ return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
+ else /* SCIF2 */
+ return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
+}
+
+static inline int scif_rxroom(struct uart_port *port)
+{
+ if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
+ return sci_in(port, SCRFDR) & 0xff;
+ else /* SCIF2 */
+ return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
+}
#else
static inline int scif_txroom(struct uart_port *port)
{
@@ -521,7 +536,7 @@ static void sci_transmit_chars(struct uart_port *port)
static inline void sci_receive_chars(struct uart_port *port)
{
struct sci_port *sci_port = (struct sci_port *)port;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
int i, count, copied = 0;
unsigned short status;
unsigned char flag;
@@ -642,7 +657,7 @@ static inline int sci_handle_errors(struct uart_port *port)
{
int copied = 0;
unsigned short status = sci_in(port, SCxSR);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
if (status & SCxSR_ORER(port)) {
/* overrun error */
@@ -692,7 +707,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
{
int copied = 0;
unsigned short status = sci_in(port, SCxSR);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct sci_port *s = &sci_ports[port->line];
if (uart_handle_break(port))
@@ -762,7 +777,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
} else {
#if defined(SCIF_ORER)
if((sci_in(port, SCLSR) & SCIF_ORER) != 0) {
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
sci_out(port, SCLSR, 0);
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index eb84833233f..8a0749e34ca 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -123,8 +123,9 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCSPTR1 0xffe08024 /* 16 bit SCIF */
+# define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */
# define SCIF_ORER 0x0001 /* overrun error bit */
-# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
# define SCSPTR0 0xff923020 /* 16 bit SCIF */
@@ -188,6 +189,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SHX3)
@@ -225,14 +227,21 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define SCIF_ORER 0x0200
-#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
-#define SCIF_RFDC_MASK 0x007f
-#define SCIF_TXROOM_MAX 64
+# define SCIF_ORER 0x0200
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
+# define SCIF_RFDC_MASK 0x007f
+# define SCIF_TXROOM_MAX 64
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK )
+# define SCIF_RFDC_MASK 0x007f
+# define SCIF_TXROOM_MAX 64
+/* SH7763 SCIF2 support */
+# define SCIF2_RFDC_MASK 0x001f
+# define SCIF2_TXROOM_MAX 16
#else
-#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
-#define SCIF_RFDC_MASK 0x001f
-#define SCIF_TXROOM_MAX 16
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
+# define SCIF_RFDC_MASK 0x001f
+# define SCIF_TXROOM_MAX 16
#endif
#if defined(SCI_ONLY)
@@ -442,7 +451,6 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
@@ -450,6 +458,14 @@ SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
+SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16)
+SCIF_FNS(SCLSR2, 0, 0, 0x24, 16)
+SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
+SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
+SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
+SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
#else
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
@@ -652,6 +668,9 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
if (port->mapbase == 0xffe08000)
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffe10000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */
+
return 1;
}
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
@@ -764,8 +783,7 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 019da2e05f0..b73e3c0056c 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -471,7 +471,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
if (port->sc_port.info) {
/* The serial_core stuffs are initilized, use them */
- tty = port->sc_port.info->tty;
+ tty = port->sc_port.info->port.tty;
}
else {
/* Not registered yet - can't pass to tty layer. */
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 2847336742d..e41766d0803 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -17,11 +17,11 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/of_device.h>
#include <asm/hypervisor.h>
#include <asm/spitfire.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#include <asm/irq.h>
#if defined(CONFIG_MAGIC_SYSRQ)
@@ -185,7 +185,7 @@ static struct tty_struct *receive_chars(struct uart_port *port)
struct tty_struct *tty = NULL;
if (port->info != NULL) /* Unopened serial console */
- tty = port->info->tty;
+ tty = port->info->port.tty;
if (sunhv_ops->receive_chars(port, tty))
sun_do_break();
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 9ff5b38f3be..29b4458abf7 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -32,11 +32,11 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#if defined(CONFIG_SERIAL_SUNSAB_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -118,7 +118,7 @@ receive_chars(struct uart_sunsab_port *up,
int i;
if (up->port.info != NULL) /* Unopened serial console */
- tty = up->port.info->tty;
+ tty = up->port.info->port.tty;
/* Read number of BYTES (Character + Status) available. */
if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 03806a93520..a378464f929 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.55 2002/01/08 16:00:16 davem Exp $
+/*
* su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -35,11 +35,11 @@
#include <linux/serial_reg.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -311,7 +311,7 @@ static void sunsu_enable_ms(struct uart_port *port)
static struct tty_struct *
receive_chars(struct uart_sunsu_port *up, unsigned char *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch, flag;
int max_count = 256;
int saw_console_brk = 0;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 7e9fa5ef0eb..3cb4c8aee13 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -32,11 +32,11 @@
#include <linux/serio.h>
#endif
#include <linux/init.h>
+#include <linux/of_device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/of_device.h>
#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -329,8 +329,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
tty = NULL;
if (up->port.info != NULL && /* Unopened serial console */
- up->port.info->tty != NULL) /* Keyboard || mouse */
- tty = up->port.info->tty;
+ up->port.info->port.tty != NULL) /* Keyboard || mouse */
+ tty = up->port.info->port.tty;
for (;;) {
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index b51c24245be..6a3f8fb0c9d 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -75,7 +75,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS];
static int ulite_receive(struct uart_port *port, int stat)
{
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned char ch = 0;
char flag = TTY_NORMAL;
@@ -162,7 +162,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
busy |= ulite_transmit(port, stat);
} while (busy);
- tty_flip_buffer_push(port->info->tty);
+ tty_flip_buffer_push(port->info->port.tty);
return IRQ_HANDLED;
}
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 566a8b42e05..5c5d18dcb6a 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -466,7 +466,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
int i;
unsigned char ch, *cp;
struct uart_port *port = &qe_port->port;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct qe_bd *bdp;
u16 status;
unsigned int flg;
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c
deleted file mode 100644
index dd98aca6ed0..00000000000
--- a/drivers/serial/v850e_uart.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * drivers/serial/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
- *
- * Copyright (C) 2001,02,03 NEC Electronics Corporation
- * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of this
- * archive for more details.
- *
- * Written by Miles Bader <miles@gnu.org>
- */
-
-/* This driver supports both the original V850E UART interface (called
- merely `UART' in the docs) and the newer `UARTB' interface, which is
- roughly a superset of the first one. The selection is made at
- configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
- presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
- can never have both.
-
- The UARTB interface also has a 16-entry FIFO mode, which is not
- yet supported by this driver. */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/console.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-
-#include <asm/v850e_uart.h>
-
-/* Initial UART state. This may be overridden by machine-dependent headers. */
-#ifndef V850E_UART_INIT_BAUD
-#define V850E_UART_INIT_BAUD 115200
-#endif
-#ifndef V850E_UART_INIT_CFLAGS
-#define V850E_UART_INIT_CFLAGS (B115200 | CS8 | CREAD)
-#endif
-
-/* A string used for prefixing printed descriptions; since the same UART
- macro is actually used on other chips than the V850E. This must be a
- constant string. */
-#ifndef V850E_UART_CHIP_NAME
-#define V850E_UART_CHIP_NAME "V850E"
-#endif
-
-#define V850E_UART_MINOR_BASE 64 /* First tty minor number */
-
-
-/* Low-level UART functions. */
-
-/* Configure and turn on uart channel CHAN, using the termios `control
- modes' bits in CFLAGS, and a baud-rate of BAUD. */
-void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
-{
- int flags;
- v850e_uart_speed_t old_speed;
- v850e_uart_config_t old_config;
- v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
- v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);
-
- /* Disable interrupts while we're twiddling the hardware. */
- local_irq_save (flags);
-
-#ifdef V850E_UART_PRE_CONFIGURE
- V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
-#endif
-
- old_config = V850E_UART_CONFIG (chan);
- old_speed = v850e_uart_speed (chan);
-
- if (! v850e_uart_speed_eq (old_speed, new_speed)) {
- /* The baud rate has changed. First, disable the UART. */
- V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
- old_config = 0; /* Force the uart to be re-initialized. */
-
- /* Reprogram the baud-rate generator. */
- v850e_uart_set_speed (chan, new_speed);
- }
-
- if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
- /* If we are using the uart for the first time, start by
- enabling it, which must be done before turning on any
- other bits. */
- V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
- /* See the initial state. */
- old_config = V850E_UART_CONFIG (chan);
- }
-
- if (new_config != old_config) {
- /* Which of the TXE/RXE bits we'll temporarily turn off
- before changing other control bits. */
- unsigned temp_disable = 0;
- /* Which of the TXE/RXE bits will be enabled. */
- unsigned enable = 0;
- unsigned changed_bits = new_config ^ old_config;
-
- /* Which of RX/TX will be enabled in the new configuration. */
- if (new_config & V850E_UART_CONFIG_RX_BITS)
- enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
- if (new_config & V850E_UART_CONFIG_TX_BITS)
- enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);
-
- /* Figure out which of RX/TX needs to be disabled; note
- that this will only happen if they're not already
- disabled. */
- if (changed_bits & V850E_UART_CONFIG_RX_BITS)
- temp_disable
- |= (old_config & V850E_UART_CONFIG_RX_ENABLE);
- if (changed_bits & V850E_UART_CONFIG_TX_BITS)
- temp_disable
- |= (old_config & V850E_UART_CONFIG_TX_ENABLE);
-
- /* We have to turn off RX and/or TX mode before changing
- any associated control bits. */
- if (temp_disable)
- V850E_UART_CONFIG (chan) = old_config & ~temp_disable;
-
- /* Write the new control bits, while RX/TX are disabled. */
- if (changed_bits & ~enable)
- V850E_UART_CONFIG (chan) = new_config & ~enable;
-
- v850e_uart_config_delay (new_config, new_speed);
-
- /* Write the final version, with enable bits turned on. */
- V850E_UART_CONFIG (chan) = new_config;
- }
-
- local_irq_restore (flags);
-}
-
-
-/* Low-level console. */
-
-#ifdef CONFIG_V850E_UART_CONSOLE
-
-static void v850e_uart_cons_write (struct console *co,
- const char *s, unsigned count)
-{
- if (count > 0) {
- unsigned chan = co->index;
- unsigned irq = V850E_UART_TX_IRQ (chan);
- int irq_was_enabled, irq_was_pending, flags;
-
- /* We don't want to get `transmission completed'
- interrupts, since we're busy-waiting, so we disable them
- while sending (we don't disable interrupts entirely
- because sending over a serial line is really slow). We
- save the status of the tx interrupt and restore it when
- we're done so that using printk doesn't interfere with
- normal serial transmission (other than interleaving the
- output, of course!). This should work correctly even if
- this function is interrupted and the interrupt printks
- something. */
-
- /* Disable interrupts while fiddling with tx interrupt. */
- local_irq_save (flags);
- /* Get current tx interrupt status. */
- irq_was_enabled = v850e_intc_irq_enabled (irq);
- irq_was_pending = v850e_intc_irq_pending (irq);
- /* Disable tx interrupt if necessary. */
- if (irq_was_enabled)
- v850e_intc_disable_irq (irq);
- /* Turn interrupts back on. */
- local_irq_restore (flags);
-
- /* Send characters. */
- while (count > 0) {
- int ch = *s++;
-
- if (ch == '\n') {
- /* We don't have the benefit of a tty
- driver, so translate NL into CR LF. */
- v850e_uart_wait_for_xmit_ok (chan);
- v850e_uart_putc (chan, '\r');
- }
-
- v850e_uart_wait_for_xmit_ok (chan);
- v850e_uart_putc (chan, ch);
-
- count--;
- }
-
- /* Restore saved tx interrupt status. */
- if (irq_was_enabled) {
- /* Wait for the last character we sent to be
- completely transmitted (as we'll get an
- interrupt interrupt at that point). */
- v850e_uart_wait_for_xmit_done (chan);
- /* Clear pending interrupts received due
- to our transmission, unless there was already
- one pending, in which case we want the
- handler to be called. */
- if (! irq_was_pending)
- v850e_intc_clear_pending_irq (irq);
- /* ... and then turn back on handling. */
- v850e_intc_enable_irq (irq);
- }
- }
-}
-
-extern struct uart_driver v850e_uart_driver;
-static struct console v850e_uart_cons =
-{
- .name = "ttyS",
- .write = v850e_uart_cons_write,
- .device = uart_console_device,
- .flags = CON_PRINTBUFFER,
- .cflag = V850E_UART_INIT_CFLAGS,
- .index = -1,
- .data = &v850e_uart_driver,
-};
-
-void v850e_uart_cons_init (unsigned chan)
-{
- v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
- V850E_UART_INIT_BAUD);
- v850e_uart_cons.index = chan;
- register_console (&v850e_uart_cons);
- printk ("Console: %s on-chip UART channel %d\n",
- V850E_UART_CHIP_NAME, chan);
-}
-
-/* This is what the init code actually calls. */
-static int v850e_uart_console_init (void)
-{
- v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
- return 0;
-}
-console_initcall(v850e_uart_console_init);
-
-#define V850E_UART_CONSOLE &v850e_uart_cons
-
-#else /* !CONFIG_V850E_UART_CONSOLE */
-#define V850E_UART_CONSOLE 0
-#endif /* CONFIG_V850E_UART_CONSOLE */
-
-/* TX/RX interrupt handlers. */
-
-static void v850e_uart_stop_tx (struct uart_port *port);
-
-void v850e_uart_tx (struct uart_port *port)
-{
- struct circ_buf *xmit = &port->info->xmit;
- int stopped = uart_tx_stopped (port);
-
- if (v850e_uart_xmit_ok (port->line)) {
- int tx_ch;
-
- if (port->x_char) {
- tx_ch = port->x_char;
- port->x_char = 0;
- } else if (!uart_circ_empty (xmit) && !stopped) {
- tx_ch = xmit->buf[xmit->tail];
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- } else
- goto no_xmit;
-
- v850e_uart_putc (port->line, tx_ch);
- port->icount.tx++;
-
- if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
- uart_write_wakeup (port);
- }
-
- no_xmit:
- if (uart_circ_empty (xmit) || stopped)
- v850e_uart_stop_tx (port, stopped);
-}
-
-static irqreturn_t v850e_uart_tx_irq(int irq, void *data)
-{
- struct uart_port *port = data;
- v850e_uart_tx (port);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t v850e_uart_rx_irq(int irq, void *data)
-{
- struct uart_port *port = data;
- unsigned ch_stat = TTY_NORMAL;
- unsigned ch = v850e_uart_getc (port->line);
- unsigned err = v850e_uart_err (port->line);
-
- if (err) {
- if (err & V850E_UART_ERR_OVERRUN) {
- ch_stat = TTY_OVERRUN;
- port->icount.overrun++;
- } else if (err & V850E_UART_ERR_FRAME) {
- ch_stat = TTY_FRAME;
- port->icount.frame++;
- } else if (err & V850E_UART_ERR_PARITY) {
- ch_stat = TTY_PARITY;
- port->icount.parity++;
- }
- }
-
- port->icount.rx++;
-
- tty_insert_flip_char (port->info->tty, ch, ch_stat);
- tty_schedule_flip (port->info->tty);
-
- return IRQ_HANDLED;
-}
-
-
-/* Control functions for the serial framework. */
-
-static void v850e_uart_nop (struct uart_port *port) { }
-static int v850e_uart_success (struct uart_port *port) { return 0; }
-
-static unsigned v850e_uart_tx_empty (struct uart_port *port)
-{
- return TIOCSER_TEMT; /* Can't detect. */
-}
-
-static void v850e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
-{
-#ifdef V850E_UART_SET_RTS
- V850E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
-#endif
-}
-
-static unsigned v850e_uart_get_mctrl (struct uart_port *port)
-{
- /* We don't support DCD or DSR, so consider them permanently active. */
- int mctrl = TIOCM_CAR | TIOCM_DSR;
-
- /* We may support CTS. */
-#ifdef V850E_UART_CTS
- mctrl |= V850E_UART_CTS(port->line) ? TIOCM_CTS : 0;
-#else
- mctrl |= TIOCM_CTS;
-#endif
-
- return mctrl;
-}
-
-static void v850e_uart_start_tx (struct uart_port *port)
-{
- v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
- v850e_uart_tx (port);
- v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
-}
-
-static void v850e_uart_stop_tx (struct uart_port *port)
-{
- v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
-}
-
-static void v850e_uart_start_rx (struct uart_port *port)
-{
- v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->line));
-}
-
-static void v850e_uart_stop_rx (struct uart_port *port)
-{
- v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->line));
-}
-
-static void v850e_uart_break_ctl (struct uart_port *port, int break_ctl)
-{
- /* Umm, do this later. */
-}
-
-static int v850e_uart_startup (struct uart_port *port)
-{
- int err;
-
- /* Alloc RX irq. */
- err = request_irq (V850E_UART_RX_IRQ (port->line), v850e_uart_rx_irq,
- IRQF_DISABLED, "v850e_uart", port);
- if (err)
- return err;
-
- /* Alloc TX irq. */
- err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
- IRQF_DISABLED, "v850e_uart", port);
- if (err) {
- free_irq (V850E_UART_RX_IRQ (port->line), port);
- return err;
- }
-
- v850e_uart_start_rx (port);
-
- return 0;
-}
-
-static void v850e_uart_shutdown (struct uart_port *port)
-{
- /* Disable port interrupts. */
- free_irq (V850E_UART_TX_IRQ (port->line), port);
- free_irq (V850E_UART_RX_IRQ (port->line), port);
-
- /* Turn off xmit/recv enable bits. */
- V850E_UART_CONFIG (port->line)
- &= ~(V850E_UART_CONFIG_TX_ENABLE
- | V850E_UART_CONFIG_RX_ENABLE);
- /* Then reset the channel. */
- V850E_UART_CONFIG (port->line) = 0;
-}
-
-static void
-v850e_uart_set_termios (struct uart_port *port, struct ktermios *termios,
- struct ktermios *old)
-{
- unsigned cflags = termios->c_cflag;
-
- /* Restrict flags to legal values. */
- if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
- /* The new value of CSIZE is invalid, use the old value. */
- cflags = (cflags & ~CSIZE)
- | (old ? (old->c_cflag & CSIZE) : CS8);
-
- termios->c_cflag = cflags;
-
- v850e_uart_configure (port->line, cflags,
- uart_get_baud_rate (port, termios, old,
- v850e_uart_min_baud(),
- v850e_uart_max_baud()));
-}
-
-static const char *v850e_uart_type (struct uart_port *port)
-{
- return port->type == PORT_V850E_UART ? "v850e_uart" : 0;
-}
-
-static void v850e_uart_config_port (struct uart_port *port, int flags)
-{
- if (flags & UART_CONFIG_TYPE)
- port->type = PORT_V850E_UART;
-}
-
-static int
-v850e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
-{
- if (ser->type != PORT_UNKNOWN && ser->type != PORT_V850E_UART)
- return -EINVAL;
- if (ser->irq != V850E_UART_TX_IRQ (port->line))
- return -EINVAL;
- return 0;
-}
-
-static struct uart_ops v850e_uart_ops = {
- .tx_empty = v850e_uart_tx_empty,
- .get_mctrl = v850e_uart_get_mctrl,
- .set_mctrl = v850e_uart_set_mctrl,
- .start_tx = v850e_uart_start_tx,
- .stop_tx = v850e_uart_stop_tx,
- .stop_rx = v850e_uart_stop_rx,
- .enable_ms = v850e_uart_nop,
- .break_ctl = v850e_uart_break_ctl,
- .startup = v850e_uart_startup,
- .shutdown = v850e_uart_shutdown,
- .set_termios = v850e_uart_set_termios,
- .type = v850e_uart_type,
- .release_port = v850e_uart_nop,
- .request_port = v850e_uart_success,
- .config_port = v850e_uart_config_port,
- .verify_port = v850e_uart_verify_port,
-};
-
-/* Initialization and cleanup. */
-
-static struct uart_driver v850e_uart_driver = {
- .owner = THIS_MODULE,
- .driver_name = "v850e_uart",
- .dev_name = "ttyS",
- .major = TTY_MAJOR,
- .minor = V850E_UART_MINOR_BASE,
- .nr = V850E_UART_NUM_CHANNELS,
- .cons = V850E_UART_CONSOLE,
-};
-
-
-static struct uart_port v850e_uart_ports[V850E_UART_NUM_CHANNELS];
-
-static int __init v850e_uart_init (void)
-{
- int rval;
-
- printk (KERN_INFO "%s on-chip UART\n", V850E_UART_CHIP_NAME);
-
- rval = uart_register_driver (&v850e_uart_driver);
- if (rval == 0) {
- unsigned chan;
-
- for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
- struct uart_port *port = &v850e_uart_ports[chan];
-
- memset (port, 0, sizeof *port);
-
- port->ops = &v850e_uart_ops;
- port->line = chan;
- port->iotype = UPIO_MEM;
- port->flags = UPF_BOOT_AUTOCONF;
-
- /* We actually use multiple IRQs, but the serial
- framework seems to mainly use this for
- informational purposes anyway. Here we use the TX
- irq. */
- port->irq = V850E_UART_TX_IRQ (chan);
-
- /* The serial framework doesn't really use these
- membase/mapbase fields for anything useful, but
- it requires that they be something non-zero to
- consider the port `valid', and also uses them
- for informational purposes. */
- port->membase = (void *)V850E_UART_BASE_ADDR (chan);
- port->mapbase = V850E_UART_BASE_ADDR (chan);
-
- /* The framework insists on knowing the uart's master
- clock freq, though it doesn't seem to do anything
- useful for us with it. We must make it at least
- higher than (the maximum baud rate * 16), otherwise
- the framework will puke during its internal
- calculations, and force the baud rate to be 9600.
- To be accurate though, just repeat the calculation
- we use when actually setting the speed. */
- port->uartclk = v850e_uart_max_clock() * 16;
-
- uart_add_one_port (&v850e_uart_driver, port);
- }
- }
-
- return rval;
-}
-
-static void __exit v850e_uart_exit (void)
-{
- unsigned chan;
-
- for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++)
- uart_remove_one_port (&v850e_uart_driver,
- &v850e_uart_ports[chan]);
-
- uart_unregister_driver (&v850e_uart_driver);
-}
-
-module_init (v850e_uart_init);
-module_exit (v850e_uart_exit);
-
-MODULE_AUTHOR ("Miles Bader");
-MODULE_DESCRIPTION ("NEC " V850E_UART_CHIP_NAME " on-chip UART");
-MODULE_LICENSE ("GPL");
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index bb6ce6bba32..0573f3b5175 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -318,7 +318,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status)
char flag;
int max_count = RX_MAX_COUNT;
- tty = port->info->tty;
+ tty = port->info->port.tty;
lsr = *status;
do {
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c
index 65f1294fd27..9e6a873f820 100644
--- a/drivers/serial/zs.c
+++ b/drivers/serial/zs.c
@@ -602,7 +602,7 @@ static void zs_receive_chars(struct zs_port *zport)
uart_insert_char(uport, status, Rx_OVR, ch, flag);
}
- tty_flip_buffer_push(uport->info->tty);
+ tty_flip_buffer_push(uport->info->port.tty);
}
static void zs_raw_transmit_chars(struct zs_port *zport)
@@ -787,7 +787,6 @@ static int zs_startup(struct uart_port *uport)
zport->regs[1] &= ~RxINT_MASK;
zport->regs[1] |= RxINT_ALL | TxINT_ENAB | EXT_INT_ENAB;
zport->regs[3] |= RxENABLE;
- zport->regs[5] |= TxENAB;
zport->regs[15] |= BRKIE;
write_zsreg(zport, R1, zport->regs[1]);
write_zsreg(zport, R3, zport->regs[3]);
@@ -814,7 +813,6 @@ static void zs_shutdown(struct uart_port *uport)
spin_lock_irqsave(&scc->zlock, flags);
- zport->regs[5] &= ~TxENAB;
zport->regs[3] &= ~RxENABLE;
write_zsreg(zport, R5, zport->regs[5]);
write_zsreg(zport, R3, zport->regs[3]);
@@ -959,6 +957,23 @@ static void zs_set_termios(struct uart_port *uport, struct ktermios *termios,
spin_unlock_irqrestore(&scc->zlock, flags);
}
+/*
+ * Hack alert!
+ * Required solely so that the initial PROM-based console
+ * works undisturbed in parallel with this one.
+ */
+static void zs_pm(struct uart_port *uport, unsigned int state,
+ unsigned int oldstate)
+{
+ struct zs_port *zport = to_zport(uport);
+
+ if (state < 3)
+ zport->regs[5] |= TxENAB;
+ else
+ zport->regs[5] &= ~TxENAB;
+ write_zsreg(zport, R5, zport->regs[5]);
+}
+
static const char *zs_type(struct uart_port *uport)
{
@@ -1041,6 +1056,7 @@ static struct uart_ops zs_ops = {
.startup = zs_startup,
.shutdown = zs_shutdown,
.set_termios = zs_set_termios,
+ .pm = zs_pm,
.type = zs_type,
.release_port = zs_release_port,
.request_port = zs_request_port,
@@ -1190,6 +1206,7 @@ static int __init zs_console_setup(struct console *co, char *options)
return ret;
zs_reset(zport);
+ zs_pm(uport, 0, -1);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);