summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/68328serial.c71
-rw-r--r--drivers/serial/68360serial.c7
-rw-r--r--drivers/serial/8250.c118
-rw-r--r--drivers/serial/8250_early.c127
-rw-r--r--drivers/serial/8250_hp300.c1
-rw-r--r--drivers/serial/8250_pci.c212
-rw-r--r--drivers/serial/Kconfig130
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/amba-pl011.c3
-rw-r--r--drivers/serial/atmel_serial.c32
-rw-r--r--drivers/serial/bfin_5xx.c182
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.h2
-rw-r--r--drivers/serial/imx.c2
-rw-r--r--drivers/serial/ip22zilog.c3
-rw-r--r--drivers/serial/jsm/jsm_driver.c2
-rw-r--r--drivers/serial/mpsc.c711
-rw-r--r--drivers/serial/of_serial.c33
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/serial_core.c22
-rw-r--r--drivers/serial/serial_cs.c5
-rw-r--r--drivers/serial/serial_txx9.c19
-rw-r--r--drivers/serial/sh-sci.c13
-rw-r--r--drivers/serial/sh-sci.h116
-rw-r--r--drivers/serial/sn_console.c4
-rw-r--r--drivers/serial/suncore.c123
-rw-r--r--drivers/serial/suncore.h2
-rw-r--r--drivers/serial/sunhv.c25
-rw-r--r--drivers/serial/sunsab.c131
-rw-r--r--drivers/serial/sunsu.c28
-rw-r--r--drivers/serial/sunzilog.c38
-rw-r--r--drivers/serial/vr41xx_siu.c150
32 files changed, 1254 insertions, 1064 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index cad426c9711e..aad4012bbb30 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -33,7 +33,6 @@
#include <linux/keyboard.h>
#include <linux/init.h>
#include <linux/pm.h>
-#include <linux/pm_legacy.h>
#include <linux/bitops.h>
#include <linux/delay.h>
@@ -401,9 +400,9 @@ irqreturn_t rs_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void do_softint(void *private)
+static void do_softint(struct work_struct *work)
{
- struct m68k_serial *info = (struct m68k_serial *) private;
+ struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue);
struct tty_struct *tty;
tty = info->tty;
@@ -425,9 +424,9 @@ static void do_softint(void *private)
* do_serial_hangup() -> tty->hangup() -> rs_hangup()
*
*/
-static void do_serial_hangup(void *private)
+static void do_serial_hangup(struct work_struct *work)
{
- struct m68k_serial *info = (struct m68k_serial *) private;
+ struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup);
struct tty_struct *tty;
tty = info->tty;
@@ -1324,59 +1323,6 @@ static void show_serial_version(void)
printk("MC68328 serial driver version 1.00\n");
}
-#ifdef CONFIG_PM_LEGACY
-/* Serial Power management
- * The console (currently fixed at line 0) is a special case for power
- * management because the kernel is so chatty. The console will be
- * explicitly disabled my our power manager as the last minute, so we won't
- * mess with it here.
- */
-static struct pm_dev *serial_pm[NR_PORTS];
-
-static int serial_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
-{
- struct m68k_serial *info = (struct m68k_serial *)dev->data;
-
- if(info == NULL)
- return -1;
-
- /* special case for line 0 - pm restores it */
- if(info->line == 0)
- return 0;
-
- switch (request) {
- case PM_SUSPEND:
- shutdown(info);
- break;
-
- case PM_RESUME:
- startup(info);
- break;
- }
- return 0;
-}
-
-void shutdown_console(void)
-{
- struct m68k_serial *info = &m68k_soft[0];
-
- /* HACK: wait a bit for any pending printk's to be dumped */
- {
- int i = 10000;
- while(i--);
- }
-
- shutdown(info);
-}
-
-void startup_console(void)
-{
- struct m68k_serial *info = &m68k_soft[0];
- startup(info);
-}
-#endif /* CONFIG_PM_LEGACY */
-
-
static const struct tty_operations rs_ops = {
.open = rs_open,
.close = rs_close,
@@ -1444,8 +1390,8 @@ rs68328_init(void)
info->event = 0;
info->count = 0;
info->blocked_open = 0;
- INIT_WORK(&info->tqueue, do_softint, info);
- INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
+ INIT_WORK(&info->tqueue, do_softint);
+ INIT_WORK(&info->tqueue_hangup, do_serial_hangup);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
info->line = i;
@@ -1467,11 +1413,6 @@ rs68328_init(void)
IRQ_FLG_STD,
"M68328_UART", NULL))
panic("Unable to attach 68328 serial interrupt\n");
-#ifdef CONFIG_PM_LEGACY
- serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback);
- if (serial_pm[i])
- serial_pm[i]->data = info;
-#endif
}
local_irq_restore(flags);
return 0;
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index 68817a7d8c0d..2aa6bfe8fdb3 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -934,8 +934,6 @@ static void change_speed(ser_info_t *info)
/*
* Set up parity check flag
*/
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
if (I_INPCK(info->tty))
info->read_status_mask |= BD_SC_FR | BD_SC_PR;
@@ -1527,11 +1525,6 @@ static void rs_360_set_termios(struct tty_struct *tty, struct ktermios *old_term
{
ser_info_t *info = (ser_info_t *)tty->driver_data;
- if ( (tty->termios->c_cflag == old_termios->c_cflag)
- && ( RELEVANT_IFLAG(tty->termios->c_iflag)
- == RELEVANT_IFLAG(old_termios->c_iflag)))
- return;
-
change_speed(info);
#ifdef modem_control
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 616da2cc8121..48185a82a393 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -129,7 +129,16 @@ struct uart_8250_port {
unsigned char mcr;
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
- unsigned char lsr_break_flag;
+
+ /*
+ * Some bits in registers are cleared on a read, so they must
+ * be saved whenever the register is read but the bits will not
+ * be immediately processed.
+ */
+#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
+ unsigned char lsr_saved_flags;
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+ unsigned char msr_saved_flags;
/*
* We provide a per-port pm hook.
@@ -1243,6 +1252,7 @@ static void serial8250_start_tx(struct uart_port *port)
if (up->bugs & UART_BUG_TXEN) {
unsigned char lsr, iir;
lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
iir = serial_in(up, UART_IIR) & 0x0f;
if ((up->port.type == PORT_RM9000) ?
(lsr & UART_LSR_THRE &&
@@ -1295,18 +1305,10 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
flag = TTY_NORMAL;
up->port.icount.rx++;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- /*
- * Recover the break flag from console xmit
- */
- if (up->port.line == up->port.cons->index) {
- lsr |= up->lsr_break_flag;
- up->lsr_break_flag = 0;
- }
-#endif
+ lsr |= up->lsr_saved_flags;
+ up->lsr_saved_flags = 0;
- if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE |
- UART_LSR_FE | UART_LSR_OE))) {
+ if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
/*
* For statistics only
*/
@@ -1402,6 +1404,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
{
unsigned int status = serial_in(up, UART_MSR);
+ status |= up->msr_saved_flags;
+ up->msr_saved_flags = 0;
if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
up->port.info != NULL) {
if (status & UART_MSR_TERI)
@@ -1601,7 +1605,8 @@ static void serial8250_timeout(unsigned long data)
static void serial8250_backup_timeout(unsigned long data)
{
struct uart_8250_port *up = (struct uart_8250_port *)data;
- unsigned int iir, ier = 0;
+ unsigned int iir, ier = 0, lsr;
+ unsigned long flags;
/*
* Must disable interrupts or else we risk racing with the interrupt
@@ -1620,9 +1625,13 @@ static void serial8250_backup_timeout(unsigned long data)
* the "Diva" UART used on the management processor on many HP
* ia64 and parisc boxes.
*/
+ spin_lock_irqsave(&up->port.lock, flags);
+ lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+ spin_unlock_irqrestore(&up->port.lock, flags);
if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
(!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
- (serial_in(up, UART_LSR) & UART_LSR_THRE)) {
+ (lsr & UART_LSR_THRE)) {
iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
iir |= UART_IIR_THRI;
}
@@ -1641,13 +1650,14 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
- unsigned int ret;
+ unsigned int lsr;
spin_lock_irqsave(&up->port.lock, flags);
- ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+ lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
spin_unlock_irqrestore(&up->port.lock, flags);
- return ret;
+ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
}
static unsigned int serial8250_get_mctrl(struct uart_port *port)
@@ -1718,8 +1728,7 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
do {
status = serial_in(up, UART_LSR);
- if (status & UART_LSR_BI)
- up->lsr_break_flag = UART_LSR_BI;
+ up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
if (--tmout == 0)
break;
@@ -1728,8 +1737,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
/* Wait up to 1s for flow control if necessary */
if (up->port.flags & UPF_CONS_FLOW) {
- tmout = 1000000;
- while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
+ unsigned int tmout;
+ for (tmout = 1000000; tmout; tmout--) {
+ unsigned int msr = serial_in(up, UART_MSR);
+ up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
+ if (msr & UART_MSR_CTS)
+ break;
udelay(1);
touch_nmi_watchdog();
}
@@ -1899,6 +1912,18 @@ static int serial8250_startup(struct uart_port *port)
spin_unlock_irqrestore(&up->port.lock, flags);
/*
+ * Clear the interrupt registers again for luck, and clear the
+ * saved flags to avoid getting false values from polling
+ * routines or the previous session.
+ */
+ serial_inp(up, UART_LSR);
+ serial_inp(up, UART_RX);
+ serial_inp(up, UART_IIR);
+ serial_inp(up, UART_MSR);
+ up->lsr_saved_flags = 0;
+ up->msr_saved_flags = 0;
+
+ /*
* Finally, enable interrupts. Note: Modem status interrupts
* are set via set_termios(), which will be occurring imminently
* anyway, so we don't enable them here.
@@ -1916,14 +1941,6 @@ static int serial8250_startup(struct uart_port *port)
(void) inb_p(icp);
}
- /*
- * And clear the interrupt registers again for luck.
- */
- (void) serial_inp(up, UART_LSR);
- (void) serial_inp(up, UART_RX);
- (void) serial_inp(up, UART_IIR);
- (void) serial_inp(up, UART_MSR);
-
return 0;
}
@@ -2494,6 +2511,16 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
wait_for_xmitr(up, BOTH_EMPTY);
serial_out(up, UART_IER, ier);
+ /*
+ * The receive handling will happen properly because the
+ * receive ready bit will still be set; it is not cleared
+ * on read. However, modem control will not, we must
+ * call it if we have saved something in the saved flags
+ * while processing with interrupts off.
+ */
+ if (up->msr_saved_flags)
+ check_modem_status(up);
+
if (locked)
spin_unlock(&up->port.lock);
local_irq_restore(flags);
@@ -2524,12 +2551,18 @@ static int __init serial8250_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
+static int serial8250_console_early_setup(void)
+{
+ return serial8250_find_port_for_earlycon();
+}
+
static struct uart_driver serial8250_reg;
static struct console serial8250_console = {
.name = "ttyS",
.write = serial8250_console_write,
.device = uart_console_device,
.setup = serial8250_console_setup,
+ .early_setup = serial8250_console_early_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
.data = &serial8250_reg,
@@ -2543,7 +2576,7 @@ static int __init serial8250_console_init(void)
}
console_initcall(serial8250_console_init);
-static int __init find_port(struct uart_port *p)
+int serial8250_find_port(struct uart_port *p)
{
int line;
struct uart_port *port;
@@ -2556,26 +2589,6 @@ static int __init find_port(struct uart_port *p)
return -ENODEV;
}
-int __init serial8250_start_console(struct uart_port *port, char *options)
-{
- int line;
-
- line = find_port(port);
- if (line < 0)
- return -ENODEV;
-
- add_preferred_console("ttyS", line, options);
- printk("Adding console on ttyS%d at %s 0x%lx (options '%s')\n",
- line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port",
- port->iotype == UPIO_MEM ? (unsigned long) port->mapbase :
- (unsigned long) port->iobase, options);
- if (!(serial8250_console.flags & CON_ENABLED)) {
- serial8250_console.flags &= ~CON_PRINTBUFFER;
- register_console(&serial8250_console);
- }
- return line;
-}
-
#define SERIAL8250_CONSOLE &serial8250_console
#else
#define SERIAL8250_CONSOLE NULL
@@ -2674,8 +2687,9 @@ static int __devinit serial8250_probe(struct platform_device *dev)
ret = serial8250_register_port(&port);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
- "(IO%lx MEM%lx IRQ%d): %d\n", i,
- p->iobase, p->mapbase, p->irq, ret);
+ "(IO%lx MEM%llx IRQ%d): %d\n", i,
+ p->iobase, (unsigned long long)p->mapbase,
+ p->irq, ret);
}
}
return 0;
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index 7e511199b4c5..4d4c9f01be8d 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -17,13 +17,11 @@
* we locate the device directly by its MMIO or I/O port address.
*
* The user can specify the device directly, e.g.,
- * console=uart,io,0x3f8,9600n8
- * console=uart,mmio,0xff5e0000,115200n8
- * or platform code can call early_uart_console_init() to set
- * the early UART device.
- *
- * After the normal serial driver starts, we try to locate the
- * matching ttyS device and start a console there.
+ * earlycon=uart8250,io,0x3f8,9600n8
+ * earlycon=uart8250,mmio,0xff5e0000,115200n8
+ * or
+ * console=uart8250,io,0x3f8,9600n8
+ * console=uart8250,mmio,0xff5e0000,115200n8
*/
#include <linux/tty.h>
@@ -32,17 +30,21 @@
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
+#include <linux/serial_8250.h>
#include <asm/io.h>
#include <asm/serial.h>
+#ifdef CONFIG_FIX_EARLYCON_MEM
+#include <asm/pgtable.h>
+#include <asm/fixmap.h>
+#endif
-struct early_uart_device {
+struct early_serial8250_device {
struct uart_port port;
char options[16]; /* e.g., 115200n8 */
unsigned int baud;
};
-static struct early_uart_device early_device __initdata;
-static int early_uart_registered __initdata;
+static struct early_serial8250_device early_device;
static unsigned int __init serial_in(struct uart_port *port, int offset)
{
@@ -80,7 +82,7 @@ static void __init putc(struct uart_port *port, int c)
serial_out(port, UART_TX, c);
}
-static void __init early_uart_write(struct console *console, const char *s, unsigned int count)
+static void __init early_serial8250_write(struct console *console, const char *s, unsigned int count)
{
struct uart_port *port = &early_device.port;
unsigned int ier;
@@ -111,7 +113,7 @@ static unsigned int __init probe_baud(struct uart_port *port)
return (port->uartclk / 16) / quot;
}
-static void __init init_port(struct early_uart_device *device)
+static void __init init_port(struct early_serial8250_device *device)
{
struct uart_port *port = &device->port;
unsigned int divisor;
@@ -130,10 +132,9 @@ static void __init init_port(struct early_uart_device *device)
serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
}
-static int __init parse_options(struct early_uart_device *device, char *options)
+static int __init parse_options(struct early_serial8250_device *device, char *options)
{
struct uart_port *port = &device->port;
- int mapsize = 64;
int mmio, length;
if (!options)
@@ -143,12 +144,19 @@ static int __init parse_options(struct early_uart_device *device, char *options)
if (!strncmp(options, "mmio,", 5)) {
port->iotype = UPIO_MEM;
port->mapbase = simple_strtoul(options + 5, &options, 0);
- port->membase = ioremap(port->mapbase, mapsize);
+#ifdef CONFIG_FIX_EARLYCON_MEM
+ set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, port->mapbase & PAGE_MASK);
+ port->membase = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
+ port->membase += port->mapbase & ~PAGE_MASK;
+#else
+ port->membase = ioremap(port->mapbase, 64);
if (!port->membase) {
- printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
- __FUNCTION__, port->mapbase);
+ printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
+ __FUNCTION__,
+ (unsigned long long)port->mapbase);
return -ENOMEM;
}
+#endif
mmio = 1;
} else if (!strncmp(options, "io,", 3)) {
port->iotype = UPIO_PORT;
@@ -168,16 +176,24 @@ static int __init parse_options(struct early_uart_device *device, char *options)
device->baud);
}
- printk(KERN_INFO "Early serial console at %s 0x%lx (options '%s')\n",
+ printk(KERN_INFO "Early serial console at %s 0x%llx (options '%s')\n",
mmio ? "MMIO" : "I/O port",
- mmio ? port->mapbase : (unsigned long) port->iobase,
+ mmio ? (unsigned long long) port->mapbase
+ : (unsigned long long) port->iobase,
device->options);
return 0;
}
-static int __init early_uart_setup(struct console *console, char *options)
+static struct console early_serial8250_console __initdata = {
+ .name = "uart",
+ .write = early_serial8250_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1,
+};
+
+static int __init early_serial8250_setup(char *options)
{
- struct early_uart_device *device = &early_device;
+ struct early_serial8250_device *device = &early_device;
int err;
if (device->port.membase || device->port.iobase)
@@ -190,61 +206,48 @@ static int __init early_uart_setup(struct console *console, char *options)
return 0;
}
-static struct console early_uart_console __initdata = {
- .name = "uart",
- .write = early_uart_write,
- .setup = early_uart_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-static int __init early_uart_console_init(void)
-{
- if (!early_uart_registered) {
- register_console(&early_uart_console);
- early_uart_registered = 1;
- }
- return 0;
-}
-console_initcall(early_uart_console_init);
-
-int __init early_serial_console_init(char *cmdline)
+int __init setup_early_serial8250_console(char *cmdline)
{
char *options;
int err;
- options = strstr(cmdline, "console=uart,");
- if (!options)
- return -ENODEV;
+ options = strstr(cmdline, "uart8250,");
+ if (!options) {
+ options = strstr(cmdline, "uart,");
+ if (!options)
+ return 0;
+ }
options = strchr(cmdline, ',') + 1;
- if ((err = early_uart_setup(NULL, options)) < 0)
+ if ((err = early_serial8250_setup(options)) < 0)
return err;
- return early_uart_console_init();
+
+ register_console(&early_serial8250_console);
+
+ return 0;
}
-static int __init early_uart_console_switch(void)
+int serial8250_find_port_for_earlycon(void)
{
- struct early_uart_device *device = &early_device;
+ struct early_serial8250_device *device = &early_device;
struct uart_port *port = &device->port;
- int mmio, line;
+ int line;
+ int ret;
- if (!(early_uart_console.flags & CON_ENABLED))
- return 0;
+ if (!device->port.membase && !device->port.iobase)
+ return -ENODEV;
- /* Try to start the normal driver on a matching line. */
- mmio = (port->iotype == UPIO_MEM);
- line = serial8250_start_console(port, device->options);
+ line = serial8250_find_port(port);
if (line < 0)
- printk("No ttyS device at %s 0x%lx for console\n",
- mmio ? "MMIO" : "I/O port",
- mmio ? port->mapbase :
- (unsigned long) port->iobase);
+ return -ENODEV;
- unregister_console(&early_uart_console);
- if (mmio)
- iounmap(port->membase);
+ ret = update_console_cmdline("uart", 8250,
+ "ttyS", line, device->options);
+ if (ret < 0)
+ ret = update_console_cmdline("uart", 0,
+ "ttyS", line, device->options);
- return 0;
+ return ret;
}
-late_initcall(early_uart_console_switch);
+
+early_param("earlycon", setup_early_serial8250_console);
diff --git a/drivers/serial/8250_hp300.c b/drivers/serial/8250_hp300.c
index 53e81a44c1a3..2cf0953fe0ec 100644
--- a/drivers/serial/8250_hp300.c
+++ b/drivers/serial/8250_hp300.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
#include <linux/delay.h>
#include <linux/dio.h>
#include <linux/console.h>
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 6d7d616e9ccd..1ea1ed82c352 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -580,6 +580,138 @@ static int pci_netmos_init(struct pci_dev *dev)
return num_serial;
}
+/*
+ * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com>
+ *
+ * These chips are available with optionally one parallel port and up to
+ * two serial ports. Unfortunately they all have the same product id.
+ *
+ * Basic configuration is done over a region of 32 I/O ports. The base
+ * ioport is called INTA or INTC, depending on docs/other drivers.
+ *
+ * The region of the 32 I/O ports is configured in POSIO0R...
+ */
+
+/* registers */
+#define ITE_887x_MISCR 0x9c
+#define ITE_887x_INTCBAR 0x78
+#define ITE_887x_UARTBAR 0x7c
+#define ITE_887x_PS0BAR 0x10
+#define ITE_887x_POSIO0 0x60
+
+/* I/O space size */
+#define ITE_887x_IOSIZE 32
+/* I/O space size (bits 26-24; 8 bytes = 011b) */
+#define ITE_887x_POSIO_IOSIZE_8 (3 << 24)
+/* I/O space size (bits 26-24; 32 bytes = 101b) */
+#define ITE_887x_POSIO_IOSIZE_32 (5 << 24)
+/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */
+#define ITE_887x_POSIO_SPEED (3 << 29)
+/* enable IO_Space bit */
+#define ITE_887x_POSIO_ENABLE (1 << 31)
+
+static int pci_ite887x_init(struct pci_dev *dev)
+{
+ /* inta_addr are the configuration addresses of the ITE */
+ static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0,
+ 0x200, 0x280, 0 };
+ int ret, i, type;
+ struct resource *iobase = NULL;
+ u32 miscr, uartbar, ioport;
+
+ /* search for the base-ioport */
+ i = 0;
+ while (inta_addr[i] && iobase == NULL) {
+ iobase = request_region(inta_addr[i], ITE_887x_IOSIZE,
+ "ite887x");
+ if (iobase != NULL) {
+ /* write POSIO0R - speed | size | ioport */
+ pci_write_config_dword(dev, ITE_887x_POSIO0,
+ ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+ ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]);
+ /* write INTCBAR - ioport */
+ pci_write_config_dword(dev, ITE_887x_INTCBAR, inta_addr[i]);
+ ret = inb(inta_addr[i]);
+ if (ret != 0xff) {
+ /* ioport connected */
+ break;
+ }
+ release_region(iobase->start, ITE_887x_IOSIZE);
+ iobase = NULL;
+ }
+ i++;
+ }
+
+ if (!inta_addr[i]) {
+ printk(KERN_ERR "ite887x: could not find iobase\n");
+ return -ENODEV;
+ }
+
+ /* start of undocumented type checking (see parport_pc.c) */
+ type = inb(iobase->start + 0x18) & 0x0f;
+
+ switch (type) {
+ case 0x2: /* ITE8871 (1P) */
+ case 0xa: /* ITE8875 (1P) */
+ ret = 0;
+ break;
+ case 0xe: /* ITE8872 (2S1P) */
+ ret = 2;
+ break;
+ case 0x6: /* ITE8873 (1S) */
+ ret = 1;
+ break;
+ case 0x8: /* ITE8874 (2S) */
+ ret = 2;
+ break;
+ default:
+ moan_device("Unknown ITE887x", dev);
+ ret = -ENODEV;
+ }
+
+ /* configure all serial ports */
+ for (i = 0; i < ret; i++) {
+ /* read the I/O port from the device */
+ pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)),
+ &ioport);
+ ioport &= 0x0000FF00; /* the actual base address */
+ pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)),
+ ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+ ITE_887x_POSIO_IOSIZE_8 | ioport);
+
+ /* write the ioport to the UARTBAR */
+ pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar);
+ uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */
+ uartbar |= (ioport << (16 * i)); /* set the ioport */
+ pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar);
+
+ /* get current config */
+ pci_read_config_dword(dev, ITE_887x_MISCR, &miscr);
+ /* disable interrupts (UARTx_Routing[3:0]) */
+ miscr &= ~(0xf << (12 - 4 * i));
+ /* activate the UART (UARTx_En) */
+ miscr |= 1 << (23 - i);
+ /* write new config with activated UART */
+ pci_write_config_dword(dev, ITE_887x_MISCR, miscr);
+ }
+
+ if (ret <= 0) {
+ /* the device has no UARTs if we get here */
+ release_region(iobase->start, ITE_887x_IOSIZE);
+ }
+
+ return ret;
+}
+
+static void __devexit pci_ite887x_exit(struct pci_dev *dev)
+{
+ u32 ioport;
+ /* the ioport is bit 0-15 in POSIO0R */
+ pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport);
+ ioport &= 0xffff;
+ release_region(ioport, ITE_887x_IOSIZE);
+}
+
static int
pci_default_setup(struct serial_private *priv, struct pciserial_board *board,
struct uart_port *port, int idx)
@@ -653,6 +785,18 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
.setup = pci_default_setup,
},
/*
+ * ITE
+ */
+ {
+ .vendor = PCI_VENDOR_ID_ITE,
+ .device = PCI_DEVICE_ID_ITE_8872,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ite887x_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ite887x_exit),
+ },
+ /*
* Panacom
*/
{
@@ -933,6 +1077,7 @@ enum pci_board_num_t {
pbn_b1_2_1250000,
+ pbn_b1_bt_1_115200,
pbn_b1_bt_2_921600,
pbn_b1_1_1382400,
@@ -976,7 +1121,6 @@ enum pci_board_num_t {
pbn_oxsemi,
pbn_intel_i960,
pbn_sgi_ioc3,
- pbn_nec_nile4,
pbn_computone_4,
pbn_computone_6,
pbn_computone_8,
@@ -984,6 +1128,7 @@ enum pci_board_num_t {
pbn_exar_XR17C152,
pbn_exar_XR17C154,
pbn_exar_XR17C158,
+ pbn_pasemi_1682M,
};
/*
@@ -1212,6 +1357,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.uart_offset = 8,
},
+ [pbn_b1_bt_1_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
[pbn_b1_bt_2_921600] = {
.flags = FL_BASE1|FL_BASE_BARS,
.num_ports = 2,
@@ -1443,18 +1595,6 @@ static struct pciserial_board pci_boards[] __devinitdata = {
},
/*
- * NEC Vrc-5074 (Nile 4) builtin UART.
- */
- [pbn_nec_nile4] = {
- .flags = FL_BASE0,
- .num_ports = 1,
- .base_baud = 520833,
- .uart_offset = 8 << 3,
- .reg_shift = 3,
- .first_offset = 0x300,
- },
-
- /*
* Computone - uses IOMEM.
*/
[pbn_computone_4] = {
@@ -1511,6 +1651,18 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 921600,
.uart_offset = 0x200,
},
+ /*
+ * PA Semi PWRficient PA6T-1682M on-chip UART
+ */
+ [pbn_pasemi_1682M] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 8333333,
+ },
+};
+
+static const struct pci_device_id softmodem_blacklist[] = {
+ { PCI_VDEVICE ( AL, 0x5457 ), }, /* ALi Corporation M5457 AC'97 Modem */
};
/*
@@ -1521,6 +1673,7 @@ static struct pciserial_board pci_boards[] __devinitdata = {
static int __devinit
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{
+ const struct pci_device_id *blacklist;
int num_iomem, num_port, first_port = -1, i;
/*
@@ -1535,6 +1688,18 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
(dev->class & 0xff) > 6)
return -ENODEV;
+ /*
+ * Do not access blacklisted devices that are known not to
+ * feature serial ports.
+ */
+ for (blacklist = softmodem_blacklist;
+ blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist);
+ blacklist++) {
+ if (dev->vendor == blacklist->vendor &&
+ dev->device == blacklist->device)
+ return -ENODEV;
+ }
+
num_iomem = num_port = 0;
for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
@@ -2345,13 +2510,6 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b2_1_115200 },
- /*
- * NEC Vrc-5074 (Nile 4) builtin UART.
- */
- { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- pbn_nec_nile4 },
-
{ PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b3_2_115200 },
@@ -2384,6 +2542,13 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_1_115200 },
+ /*
+ * ITE
+ */
+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b1_bt_1_115200 },
/*
* IntaShield IS-200
@@ -2402,6 +2567,13 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
0, 0, pbn_b2_8_921600 },
/*
+ * PA Semi PA6T-1682M on-chip UART
+ */
+ { PCI_VENDOR_ID_PASEMI, 0xa004,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pasemi_1682M },
+
+ /*
* These entries match devices with class COMMUNICATION_SERIAL,
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
*/
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 8104fdf02681..a427e6fef050 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -62,8 +62,22 @@ config SERIAL_8250_CONSOLE
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
+ you can set that using a kernel command line option such as
+ "console=uart8250,io,0x3f8,9600n8"
+ "console=uart8250,mmio,0xff5e0000,115200n8".
+ and it will switch to normal serial console when correponding port is
+ ready.
+ "earlycon=uart8250,io,0x3f8,9600n8"
+ "earlycon=uart8250,mmio,0xff5e0000,115200n8".
+ it will not only setup early console.
+
If unsure, say N.
+config FIX_EARLYCON_MEM
+ bool
+ depends on X86
+ default y
+
config SERIAL_8250_GSC
tristate
depends on SERIAL_8250 && GSC
@@ -345,6 +359,34 @@ config SERIAL_AMBA_PL011_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
+config SERIAL_SB1250_DUART
+ tristate "BCM1xxx on-chip DUART serial support"
+ depends on SIBYTE_SB1xxx_SOC=y
+ select SERIAL_CORE
+ default y
+ ---help---
+ Support for the asynchronous serial interface (DUART) included in
+ the BCM1250 and derived System-On-a-Chip (SOC) devices. Note that
+ the letter D in DUART stands for "dual", which is how the device
+ is implemented. Depending on the SOC configuration there may be
+ one or more DUARTs available of which all are handled.
+
+ If unsure, say Y. To compile this driver as a module, choose M here:
+ the module will be called sb1250-duart.
+
+config SERIAL_SB1250_DUART_CONSOLE
+ bool "Support for console on a BCM1xxx DUART serial port"
+ depends on SERIAL_SB1250_DUART=y
+ select SERIAL_CORE_CONSOLE
+ default y
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+ kernel messages and warnings and which allows logins in single user
+ mode).
+
+ If unsure, say Y.
+
config SERIAL_ATMEL
bool "AT91 / AT32 on-chip serial port support"
depends on (ARM && ARCH_AT91) || AVR32
@@ -465,6 +507,36 @@ config SERIAL_DZ_CONSOLE
If unsure, say Y.
+config SERIAL_ZS
+ tristate "DECstation Z85C30 serial support"
+ depends on MACH_DECSTATION
+ select SERIAL_CORE
+ default y
+ ---help---
+ Support for the Zilog 85C350 serial communications controller used
+ for serial ports in newer DECstation systems. These include the
+ DECsystem 5900 and all models of the DECstation and DECsystem 5000
+ systems except from model 200.
+
+ If unsure, say Y. To compile this driver as a module, choose M here:
+ the module will be called zs.
+
+config SERIAL_ZS_CONSOLE
+ bool "Support for console on a DECstation Z85C30 serial port"
+ depends on SERIAL_ZS=y
+ select SERIAL_CORE_CONSOLE
+ default y
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+ kernel messages and warnings and which allows logins in single user
+ mode).
+
+ Note that the firmware uses ttyS1 as the serial console on the
+ Maxine and ttyS3 on the others using this driver.
+
+ If unsure, say Y.
+
config SERIAL_21285
tristate "DC21285 serial port support"
depends on ARM && FOOTBRIDGE
@@ -564,7 +636,7 @@ config SERIAL_BFIN
config SERIAL_BFIN_CONSOLE
bool "Console on Blackfin serial port"
- depends on SERIAL_BFIN
+ depends on SERIAL_BFIN=y
select SERIAL_CORE_CONSOLE
choice
@@ -577,7 +649,7 @@ choice
config SERIAL_BFIN_DMA
bool "DMA mode"
- depends on DMA_UNCACHED_1M
+ depends on DMA_UNCACHED_1M && !KGDB_UART
help
This driver works under DMA mode. If this option is selected, the
blackfin simple dma driver is also enabled.
@@ -620,7 +692,7 @@ config UART0_RTS_PIN
config SERIAL_BFIN_UART1
bool "Enable UART1"
- depends on SERIAL_BFIN && (BF534 || BF536 || BF537)
+ depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x)
help
Enable UART1
@@ -633,18 +705,58 @@ config BFIN_UART1_CTSRTS
config UART1_CTS_PIN
int "UART1 CTS pin"
- depends on BFIN_UART1_CTSRTS
+ depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
config UART1_RTS_PIN
int "UART1 RTS pin"
- depends on BFIN_UART1_CTSRTS
+ depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
+ default -1
+ help
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART2
+ bool "Enable UART2"
+ depends on SERIAL_BFIN && (BF54x)
+ help
+ Enable UART2
+
+config BFIN_UART2_CTSRTS
+ bool "Enable UART2 hardware flow control"
+ depends on SERIAL_BFIN_UART2
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART2_CTS_PIN
+ int "UART2 CTS pin"
+ depends on BFIN_UART2_CTSRTS
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+config UART2_RTS_PIN
+ int "UART2 RTS pin"
+ depends on BFIN_UART2_CTSRTS
+ default -1
+ help
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART3
+ bool "Enable UART3"
+ depends on SERIAL_BFIN && (BF54x)
+ help
+ Enable UART3
+
+config BFIN_UART3_CTSRTS
+ bool "Enable UART3 hardware flow control"
+ depends on SERIAL_BFIN_UART3
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
config SERIAL_IMX
bool "IMX serial port support"
depends on ARM && ARCH_IMX
@@ -745,10 +857,10 @@ config SERIAL_MUX
4. Change the kernel command console parameter to: console=ttyB0
config SERIAL_MUX_CONSOLE
- bool "Support for console on serial MUX"
- depends on SERIAL_MUX
+ bool "Support for console on serial MUX"
+ depends on SERIAL_MUX=y
select SERIAL_CORE_CONSOLE
- default y
+ default y
config PDC_CONSOLE
bool "PDC software console support"
@@ -1104,7 +1216,7 @@ config SERIAL_VR41XX
config SERIAL_VR41XX_CONSOLE
bool "Enable NEC VR4100 series Serial Interface Unit console"
- depends on SERIAL_VR41XX
+ depends on SERIAL_VR41XX=y
select SERIAL_CORE_CONSOLE
help
If you have a NEC VR4100 series processor and you want to use
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index af736ba5a4f0..122f32d77e71 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -43,6 +43,7 @@ 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
+obj-$(CONFIG_SERIAL_ZS) += zs.o
obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o
obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
@@ -51,6 +52,7 @@ obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
obj-$(CONFIG_SERIAL_ICOM) += icom.o
obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o
obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
+obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
obj-$(CONFIG_SERIAL_JSM) += jsm/
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 954073c6ce3a..72229df9dc11 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -716,7 +716,7 @@ static int pl011_probe(struct amba_device *dev, void *id)
goto out;
}
- uap = kmalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
+ uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
if (uap == NULL) {
ret = -ENOMEM;
goto out;
@@ -728,7 +728,6 @@ static int pl011_probe(struct amba_device *dev, void *id)
goto free;
}
- memset(uap, 0, sizeof(struct uart_amba_port));
uap->clk = clk_get(&dev->dev, "UARTCLK");
if (IS_ERR(uap->clk)) {
ret = PTR_ERR(uap->clk);
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 3320bcd92c0a..4d6b3c56d20e 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -114,6 +114,7 @@ struct atmel_uart_port {
struct uart_port uart; /* uart */
struct clk *clk; /* uart clock */
unsigned short suspended; /* is port suspended? */
+ int break_active; /* break being received */
};
static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
@@ -252,6 +253,7 @@ static void atmel_break_ctl(struct uart_port *port, int break_state)
*/
static void atmel_rx_chars(struct uart_port *port)
{
+ struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
struct tty_struct *tty = port->info->tty;
unsigned int status, ch, flg;
@@ -267,13 +269,29 @@ static void atmel_rx_chars(struct uart_port *port)
* note that the error handling code is
* out of the main execution path
*/
- if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME | ATMEL_US_OVRE | ATMEL_US_RXBRK))) {
+ if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME
+ | ATMEL_US_OVRE | ATMEL_US_RXBRK)
+ || atmel_port->break_active)) {
UART_PUT_CR(port, ATMEL_US_RSTSTA); /* clear error */
- if (status & ATMEL_US_RXBRK) {
+ if (status & ATMEL_US_RXBRK
+ && !atmel_port->break_active) {
status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME); /* ignore side-effect */
port->icount.brk++;
+ atmel_port->break_active = 1;
+ UART_PUT_IER(port, ATMEL_US_RXBRK);
if (uart_handle_break(port))
goto ignore_char;
+ } else {
+ /*
+ * This is either the end-of-break
+ * condition or we've received at
+ * least one character without RXBRK
+ * being set. In both cases, the next
+ * RXBRK will indicate start-of-break.
+ */
+ UART_PUT_IDR(port, ATMEL_US_RXBRK);
+ status &= ~ATMEL_US_RXBRK;
+ atmel_port->break_active = 0;
}
if (status & ATMEL_US_PARE)
port->icount.parity++;
@@ -352,6 +370,16 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
/* Interrupt receive */
if (pending & ATMEL_US_RXRDY)
atmel_rx_chars(port);
+ else if (pending & ATMEL_US_RXBRK) {
+ /*
+ * End of break detected. If it came along
+ * with a character, atmel_rx_chars will
+ * handle it.
+ */
+ UART_PUT_CR(port, ATMEL_US_RSTSTA);
+ UART_PUT_IDR(port, ATMEL_US_RXBRK);
+ atmel_port->break_active = 0;
+ }
// TODO: All reads to CSR will clear these interrupts!
if (pending & ATMEL_US_RIIC) port->icount.rng++;
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 22569bd5d821..66c92bc36f3d 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -41,6 +41,11 @@
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
+#ifdef CONFIG_KGDB_UART
+#include <linux/kgdb.h>
+#include <asm/irq_regs.h>
+#endif
+
#include <asm/gpio.h>
#include <asm/mach/bfin_serial_5xx.h>
@@ -81,15 +86,29 @@ static void bfin_serial_stop_tx(struct uart_port *port)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+#ifdef CONFIG_BF54x
+ while (!(UART_GET_LSR(uart) & TEMT))
+ continue;
+#endif
+
#ifdef CONFIG_SERIAL_BFIN_DMA
disable_dma(uart->tx_dma_channel);
#else
+#ifdef CONFIG_BF54x
+ /* Waiting for Transmission Finished */
+ while (!(UART_GET_LSR(uart) & TFI))
+ continue;
+ /* Clear TFI bit */
+ UART_PUT_LSR(uart, TFI);
+ UART_CLEAR_IER(uart, ETBEI);
+#else
unsigned short ier;
ier = UART_GET_IER(uart);
ier &= ~ETBEI;
UART_PUT_IER(uart, ier);
#endif
+#endif
}
/*
@@ -102,12 +121,16 @@ static void bfin_serial_start_tx(struct uart_port *port)
#ifdef CONFIG_SERIAL_BFIN_DMA
bfin_serial_dma_tx_chars(uart);
#else
+#ifdef CONFIG_BF54x
+ UART_SET_IER(uart, ETBEI);
+#else
unsigned short ier;
ier = UART_GET_IER(uart);
ier |= ETBEI;
UART_PUT_IER(uart, ier);
bfin_serial_tx_chars(uart);
#endif
+#endif
}
/*
@@ -116,11 +139,18 @@ static void bfin_serial_start_tx(struct uart_port *port)
static void bfin_serial_stop_rx(struct uart_port *port)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+#ifdef CONFIG_BF54x
+ UART_CLEAR_IER(uart, ERBFI);
+#else
unsigned short ier;
ier = UART_GET_IER(uart);
+#ifdef CONFIG_KGDB_UART
+ if (uart->port.line != CONFIG_KGDB_UART_PORT)
+#endif
ier &= ~ERBFI;
UART_PUT_IER(uart, ier);
+#endif
}
/*
@@ -130,6 +160,49 @@ static void bfin_serial_enable_ms(struct uart_port *port)
{
}
+#ifdef CONFIG_KGDB_UART
+static int kgdb_entry_state;
+
+void kgdb_put_debug_char(int chr)
+{
+ struct bfin_serial_port *uart;
+
+ if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
+ uart = &bfin_serial_ports[0];
+ else
+ uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+
+ while (!(UART_GET_LSR(uart) & THRE)) {
+ __builtin_bfin_ssync();
+ }
+ UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
+ __builtin_bfin_ssync();
+ UART_PUT_CHAR(uart, (unsigned char)chr);
+ __builtin_bfin_ssync();
+}
+
+int kgdb_get_debug_char(void)
+{
+ struct bfin_serial_port *uart;
+ unsigned char chr;
+
+ if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
+ uart = &bfin_serial_ports[0];
+ else
+ uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+
+ while(!(UART_GET_LSR(uart) & DR)) {
+ __builtin_bfin_ssync();
+ }
+ UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
+ __builtin_bfin_ssync();
+ chr = UART_GET_CHAR(uart);
+ __builtin_bfin_ssync();
+
+ return chr;
+}
+#endif
+
#ifdef CONFIG_SERIAL_BFIN_PIO
static void local_put_char(struct bfin_serial_port *uart, char ch)
{
@@ -152,6 +225,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
{
struct tty_struct *tty = uart->port.info->tty;
unsigned int status, ch, flg;
+#ifdef CONFIG_KGDB_UART
+ struct pt_regs *regs = get_irq_regs();
+#endif
#ifdef BF533_FAMILY
static int in_break = 0;
#endif
@@ -160,6 +236,27 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
ch = UART_GET_CHAR(uart);
uart->port.icount.rx++;
+#ifdef CONFIG_KGDB_UART
+ if (uart->port.line == CONFIG_KGDB_UART_PORT) {
+ if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */
+ kgdb_breakkey_pressed(regs);
+ return;
+ } else if (kgdb_entry_state == 0 && ch == '$') {/* connection from KGDB */
+ kgdb_entry_state = 1;
+ } else if (kgdb_entry_state == 1 && ch == 'q') {
+ kgdb_entry_state = 0;
+ kgdb_breakkey_pressed(regs);
+ return;
+ } else if (ch == 0x3) {/* Ctrl + C */
+ kgdb_entry_state = 0;
+ kgdb_breakkey_pressed(regs);
+ return;
+ } else {
+ kgdb_entry_state = 0;
+ }
+ }
+#endif
+
#ifdef BF533_FAMILY
/* The BF533 family of processors have a nice misbehavior where
* they continuously generate characters for a "single" break.
@@ -250,10 +347,21 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
+#ifdef CONFIG_BF54x
+ unsigned short status;
+ spin_lock(&uart->port.lock);
+ status = UART_GET_LSR(uart);
+ while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) {
+ bfin_serial_rx_chars(uart);
+ status = UART_GET_LSR(uart);
+ }
+ spin_unlock(&uart->port.lock);
+#else
spin_lock(&uart->port.lock);
while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY)
bfin_serial_rx_chars(uart);
spin_unlock(&uart->port.lock);
+#endif
return IRQ_HANDLED;
}
@@ -261,10 +369,21 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
+#ifdef CONFIG_BF54x
+ unsigned short status;
+ spin_lock(&uart->port.lock);
+ status = UART_GET_LSR(uart);
+ while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) {
+ bfin_serial_tx_chars(uart);
+ status = UART_GET_LSR(uart);
+ }
+ spin_unlock(&uart->port.lock);
+#else
spin_lock(&uart->port.lock);
while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY)
bfin_serial_tx_chars(uart);
spin_unlock(&uart->port.lock);
+#endif
return IRQ_HANDLED;
}
@@ -275,7 +394,6 @@ static void bfin_serial_do_work(struct work_struct *work)
bfin_serial_mctrl_check(uart);
}
-
#endif
#ifdef CONFIG_SERIAL_BFIN_DMA
@@ -324,9 +442,13 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
set_dma_x_modify(uart->tx_dma_channel, 1);
enable_dma(uart->tx_dma_channel);
+#ifdef CONFIG_BF54x
+ UART_SET_IER(uart, ETBEI);
+#else
ier = UART_GET_IER(uart);
ier |= ETBEI;
UART_PUT_IER(uart, ier);
+#endif
spin_unlock_irqrestore(&uart->port.lock, flags);
}
@@ -406,9 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
clear_dma_irqstat(uart->tx_dma_channel);
disable_dma(uart->tx_dma_channel);
+#ifdef CONFIG_BF54x
+ UART_CLEAR_IER(uart, ETBEI);
+#else
ier = UART_GET_IER(uart);
ier &= ~ETBEI;
UART_PUT_IER(uart, ier);
+#endif
xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1);
uart->port.icount.tx+=uart->tx_count;
@@ -571,7 +697,11 @@ static int bfin_serial_startup(struct uart_port *port)
uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
add_timer(&(uart->rx_dma_timer));
#else
+# ifdef CONFIG_KGDB_UART
+ if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq
+# else
if (request_irq
+# endif
(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
"BFIN_UART_RX", uart)) {
printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
@@ -586,7 +716,11 @@ static int bfin_serial_startup(struct uart_port *port)
return -EBUSY;
}
#endif
+#ifdef CONFIG_BF54x
+ UART_SET_IER(uart, ERBFI);
+#else
UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+#endif
return 0;
}
@@ -601,6 +735,9 @@ static void bfin_serial_shutdown(struct uart_port *port)
free_dma(uart->rx_dma_channel);
del_timer(&(uart->rx_dma_timer));
#else
+#ifdef CONFIG_KGDB_UART
+ if (uart->port.line != CONFIG_KGDB_UART_PORT)
+#endif
free_irq(uart->port.irq, uart);
free_irq(uart->port.irq+1, uart);
#endif
@@ -674,29 +811,41 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
/* Disable UART */
ier = UART_GET_IER(uart);
+#ifdef CONFIG_BF54x
+ UART_CLEAR_IER(uart, 0xF);
+#else
UART_PUT_IER(uart, 0);
+#endif
+#ifndef CONFIG_BF54x
/* Set DLAB in LCR to Access DLL and DLH */
val = UART_GET_LCR(uart);
val |= DLAB;
UART_PUT_LCR(uart, val);
SSYNC();
+#endif
UART_PUT_DLL(uart, quot & 0xFF);
SSYNC();
UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
SSYNC();
+#ifndef CONFIG_BF54x
/* Clear DLAB in LCR to Access THR RBR IER */
val = UART_GET_LCR(uart);
val &= ~DLAB;
UART_PUT_LCR(uart, val);
SSYNC();
+#endif
UART_PUT_LCR(uart, lcr);
/* Enable UART */
+#ifdef CONFIG_BF54x
+ UART_SET_IER(uart, ier);
+#else
UART_PUT_IER(uart, ier);
+#endif
val = UART_GET_GCTL(uart);
val |= UCEN;
@@ -808,15 +957,15 @@ static void __init bfin_serial_init_ports(void)
bfin_serial_resource[i].uart_rts_pin;
#endif
bfin_serial_hw_init(&bfin_serial_ports[i]);
-
}
+
}
#ifdef CONFIG_SERIAL_BFIN_CONSOLE
static void bfin_serial_console_putchar(struct uart_port *port, int ch)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- while (!(UART_GET_LSR(uart)))
+ while (!(UART_GET_LSR(uart) & THRE))
barrier();
UART_PUT_CHAR(uart, ch);
SSYNC();
@@ -868,18 +1017,22 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
case 2: *bits = 7; break;
case 3: *bits = 8; break;
}
+#ifndef CONFIG_BF54x
/* Set DLAB in LCR to Access DLL and DLH */
val = UART_GET_LCR(uart);
val |= DLAB;
UART_PUT_LCR(uart, val);
+#endif
dll = UART_GET_DLL(uart);
dlh = UART_GET_DLH(uart);
+#ifndef CONFIG_BF54x
/* Clear DLAB in LCR to Access THR RBR IER */
val = UART_GET_LCR(uart);
val &= ~DLAB;
UART_PUT_LCR(uart, val);
+#endif
*baud = get_sclk() / (16*(dll | dlh << 8));
}
@@ -931,6 +1084,10 @@ static int __init bfin_serial_rs_console_init(void)
{
bfin_serial_init_ports();
register_console(&bfin_serial_console);
+#ifdef CONFIG_KGDB_UART
+ kgdb_entry_state = 0;
+ init_kgdb_uart();
+#endif
return 0;
}
console_initcall(bfin_serial_rs_console_init);
@@ -1023,6 +1180,10 @@ static struct platform_driver bfin_serial_driver = {
static int __init bfin_serial_init(void)
{
int ret;
+#ifdef CONFIG_KGDB_UART
+ struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+ struct termios t;
+#endif
pr_info("Serial: Blackfin serial driver\n");
@@ -1036,6 +1197,21 @@ static int __init bfin_serial_init(void)
uart_unregister_driver(&bfin_serial_reg);
}
}
+#ifdef CONFIG_KGDB_UART
+ if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {
+ request_irq(uart->port.irq, bfin_serial_int,
+ IRQF_DISABLED, "BFIN_UART_RX", uart);
+ pr_info("Request irq for kgdb uart port\n");
+ UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+ __builtin_bfin_ssync();
+ t.c_cflag = CS8|B57600;
+ t.c_iflag = 0;
+ t.c_oflag = 0;
+ t.c_lflag = ICANON;
+ t.c_line = CONFIG_KGDB_UART_PORT;
+ bfin_serial_set_termios(&uart->port, &t, &t);
+ }
+#endif
return ret;
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index b63ff8dd7304..cefde58dbad2 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -678,7 +678,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
}
bdp->cbd_datlen = count;
bdp->cbd_sc |= BD_SC_READY;
- __asm__("eieio");
+ eieio();
/* Get next BD. */
if (bdp->cbd_sc & BD_SC_WRAP)
bdp = pinfo->tx_bd_base;
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
index a99e45e2b6d8..2a6477834c3e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
@@ -37,6 +37,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
up->smc_tfcr = SMC_EB;
}
-#define DPRAM_BASE ((unsigned char *)&cpmp->cp_dpmem[0])
+#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0))
#endif
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index e42faa4e4282..dc1967176fe2 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -1114,8 +1114,8 @@ static int __init imx_serial_init(void)
static void __exit imx_serial_exit(void)
{
- uart_unregister_driver(&imx_reg);
platform_driver_unregister(&serial_imx_driver);
+ uart_unregister_driver(&imx_reg);
}
module_init(imx_serial_init);
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index c3abfb39f316..f3257f708ef9 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -862,6 +862,7 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,
up->cflag = termios->c_cflag;
ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
+ uart_update_timeout(port, termios->c_cflag, baud);
spin_unlock_irqrestore(&up->port.lock, flags);
}
@@ -1017,6 +1018,8 @@ ip22serial_console_termios(struct console *con, char *options)
}
con->cflag = cflag | CS8; /* 8N1 */
+
+ uart_update_timeout(&ip22zilog_port_table[con->index].port, cflag, baud);
}
static int __init ip22zilog_console_setup(struct console *con, char *options)
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index 81792e6eeb2d..6767ee381cd1 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -88,7 +88,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
spin_lock_init(&brd->bd_intr_lock);
/* store which revision we have */
- pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);
+ brd->rev = pdev->revision;
brd->irq = pdev->irq;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 00924feaf621..4d643c926657 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -74,10 +74,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
#define MPSC_NUM_CTLRS 2
/*
@@ -97,9 +93,8 @@
#define MPSC_TXBE_SIZE dma_get_cache_alignment()
#define MPSC_TXB_SIZE (MPSC_TXR_ENTRIES * MPSC_TXBE_SIZE)
-#define MPSC_DMA_ALLOC_SIZE (MPSC_RXR_SIZE + MPSC_RXB_SIZE + \
- MPSC_TXR_SIZE + MPSC_TXB_SIZE + \
- dma_get_cache_alignment() /* for alignment */)
+#define MPSC_DMA_ALLOC_SIZE (MPSC_RXR_SIZE + MPSC_RXB_SIZE + MPSC_TXR_SIZE \
+ + MPSC_TXB_SIZE + dma_get_cache_alignment() /* for alignment */)
/* Rx and Tx Ring entry descriptors -- assume entry size is <= cacheline size */
struct mpsc_rx_desc {
@@ -270,8 +265,8 @@ struct mpsc_port_info *mpsc_device_remove(int index);
#define SDMA_DESC_CMDSTAT_EI (1<<23)
#define SDMA_DESC_CMDSTAT_O (1<<31)
-#define SDMA_DESC_DFLT (SDMA_DESC_CMDSTAT_O | \
- SDMA_DESC_CMDSTAT_EI)
+#define SDMA_DESC_DFLT (SDMA_DESC_CMDSTAT_O \
+ | SDMA_DESC_CMDSTAT_EI)
#define SDMA_SDC_RFT (1<<0)
#define SDMA_SDC_SFM (1<<1)
@@ -295,10 +290,10 @@ struct mpsc_port_info *mpsc_device_remove(int index);
#define SDMA_1_CAUSE_TXBUF (1<<10)
#define SDMA_1_CAUSE_TXEND (1<<11)
-#define SDMA_CAUSE_RX_MASK (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \
- SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
-#define SDMA_CAUSE_TX_MASK (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \
- SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
+#define SDMA_CAUSE_RX_MASK (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR \
+ | SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
+#define SDMA_CAUSE_TX_MASK (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND \
+ | SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
/* SDMA Interrupt registers */
#define SDMA_INTR_CAUSE 0x0000
@@ -312,11 +307,11 @@ struct mpsc_port_info *mpsc_device_remove(int index);
* Define how this driver is known to the outside (we've been assigned a
* range on the "Low-density serial ports" major).
*/
-#define MPSC_MAJOR 204
-#define MPSC_MINOR_START 44
-#define MPSC_DRIVER_NAME "MPSC"
-#define MPSC_DEV_NAME "ttyMM"
-#define MPSC_VERSION "1.00"
+#define MPSC_MAJOR 204
+#define MPSC_MINOR_START 44
+#define MPSC_DRIVER_NAME "MPSC"
+#define MPSC_DEV_NAME "ttyMM"
+#define MPSC_VERSION "1.00"
static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
static struct mpsc_shared_regs mpsc_shared_regs;
@@ -332,8 +327,7 @@ static void mpsc_release_port(struct uart_port *port);
*
******************************************************************************
*/
-static void
-mpsc_brg_init(struct mpsc_port_info *pi, u32 clk_src)
+static void mpsc_brg_init(struct mpsc_port_info *pi, u32 clk_src)
{
u32 v;
@@ -349,11 +343,9 @@ mpsc_brg_init(struct mpsc_port_info *pi, u32 clk_src)
writel(readl(pi->brg_base + BRG_BTR) & 0xffff0000,
pi->brg_base + BRG_BTR);
- return;
}
-static void
-mpsc_brg_enable(struct mpsc_port_info *pi)
+static void mpsc_brg_enable(struct mpsc_port_info *pi)
{
u32 v;
@@ -363,11 +355,9 @@ mpsc_brg_enable(struct mpsc_port_info *pi)
if (pi->mirror_regs)
pi->BRG_BCR_m = v;
writel(v, pi->brg_base + BRG_BCR);
- return;
}
-static void
-mpsc_brg_disable(struct mpsc_port_info *pi)
+static void mpsc_brg_disable(struct mpsc_port_info *pi)
{
u32 v;
@@ -377,21 +367,19 @@ mpsc_brg_disable(struct mpsc_port_info *pi)
if (pi->mirror_regs)
pi->BRG_BCR_m = v;
writel(v, pi->brg_base + BRG_BCR);
- return;
}
-static inline void
-mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
+/*
+ * To set the baud, we adjust the CDV field in the BRG_BCR reg.
+ * From manual: Baud = clk / ((CDV+1)*2) ==> CDV = (clk / (baud*2)) - 1.
+ * However, the input clock is divided by 16 in the MPSC b/c of how
+ * 'MPSC_MMCRH' was set up so we have to divide the 'clk' used in our
+ * calculation by 16 to account for that. So the real calculation
+ * that accounts for the way the mpsc is set up is:
+ * CDV = (clk / (baud*2*16)) - 1 ==> CDV = (clk / (baud << 5)) - 1.
+ */
+static void mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
{
- /*
- * To set the baud, we adjust the CDV field in the BRG_BCR reg.
- * From manual: Baud = clk / ((CDV+1)*2) ==> CDV = (clk / (baud*2)) - 1.
- * However, the input clock is divided by 16 in the MPSC b/c of how
- * 'MPSC_MMCRH' was set up so we have to divide the 'clk' used in our
- * calculation by 16 to account for that. So the real calculation
- * that accounts for the way the mpsc is set up is:
- * CDV = (clk / (baud*2*16)) - 1 ==> CDV = (clk / (baud << 5)) - 1.
- */
u32 cdv = (pi->port.uartclk / (baud << 5)) - 1;
u32 v;
@@ -403,8 +391,6 @@ mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
pi->BRG_BCR_m = v;
writel(v, pi->brg_base + BRG_BCR);
mpsc_brg_enable(pi);
-
- return;
}
/*
@@ -415,13 +401,12 @@ mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
******************************************************************************
*/
-static void
-mpsc_sdma_burstsize(struct mpsc_port_info *pi, u32 burst_size)
+static void mpsc_sdma_burstsize(struct mpsc_port_info *pi, u32 burst_size)
{
u32 v;
pr_debug("mpsc_sdma_burstsize[%d]: burst_size: %d\n",
- pi->port.line, burst_size);
+ pi->port.line, burst_size);
burst_size >>= 3; /* Divide by 8 b/c reg values are 8-byte chunks */
@@ -436,11 +421,9 @@ mpsc_sdma_burstsize(struct mpsc_port_info *pi, u32 burst_size)
writel((readl(pi->sdma_base + SDMA_SDC) & (0x3 << 12)) | (v << 12),
pi->sdma_base + SDMA_SDC);
- return;
}
-static void
-mpsc_sdma_init(struct mpsc_port_info *pi, u32 burst_size)
+static void mpsc_sdma_init(struct mpsc_port_info *pi, u32 burst_size)
{
pr_debug("mpsc_sdma_init[%d]: burst_size: %d\n", pi->port.line,
burst_size);
@@ -448,11 +431,9 @@ mpsc_sdma_init(struct mpsc_port_info *pi, u32 burst_size)
writel((readl(pi->sdma_base + SDMA_SDC) & 0x3ff) | 0x03f,
pi->sdma_base + SDMA_SDC);
mpsc_sdma_burstsize(pi, burst_size);
- return;
}
-static inline u32
-mpsc_sdma_intr_mask(struct mpsc_port_info *pi, u32 mask)
+static u32 mpsc_sdma_intr_mask(struct mpsc_port_info *pi, u32 mask)
{
u32 old, v;
@@ -475,15 +456,14 @@ mpsc_sdma_intr_mask(struct mpsc_port_info *pi, u32 mask)
return old & 0xf;
}
-static inline void
-mpsc_sdma_intr_unmask(struct mpsc_port_info *pi, u32 mask)
+static void mpsc_sdma_intr_unmask(struct mpsc_port_info *pi, u32 mask)
{
u32 v;
pr_debug("mpsc_sdma_intr_unmask[%d]: mask: 0x%x\n", pi->port.line,mask);
- v = (pi->mirror_regs) ? pi->shared_regs->SDMA_INTR_MASK_m :
- readl(pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
+ v = (pi->mirror_regs) ? pi->shared_regs->SDMA_INTR_MASK_m
+ : readl(pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
mask &= 0xf;
if (pi->port.line)
@@ -493,41 +473,35 @@ mpsc_sdma_intr_unmask(struct mpsc_port_info *pi, u32 mask)
if (pi->mirror_regs)
pi->shared_regs->SDMA_INTR_MASK_m = v;
writel(v, pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
- return;
}
-static inline void
-mpsc_sdma_intr_ack(struct mpsc_port_info *pi)
+static void mpsc_sdma_intr_ack(struct mpsc_port_info *pi)
{
pr_debug("mpsc_sdma_intr_ack[%d]: Acknowledging IRQ\n", pi->port.line);
if (pi->mirror_regs)
pi->shared_regs->SDMA_INTR_CAUSE_m = 0;
- writeb(0x00, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE +
- pi->port.line);
- return;
+ writeb(0x00, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE
+ + pi->port.line);
}
-static inline void
-mpsc_sdma_set_rx_ring(struct mpsc_port_info *pi, struct mpsc_rx_desc *rxre_p)
+static void mpsc_sdma_set_rx_ring(struct mpsc_port_info *pi,
+ struct mpsc_rx_desc *rxre_p)
{
pr_debug("mpsc_sdma_set_rx_ring[%d]: rxre_p: 0x%x\n",
- pi->port.line, (u32) rxre_p);
+ pi->port.line, (u32)rxre_p);
writel((u32)rxre_p, pi->sdma_base + SDMA_SCRDP);
- return;
}
-static inline void
-mpsc_sdma_set_tx_ring(struct mpsc_port_info *pi, struct mpsc_tx_desc *txre_p)
+static void mpsc_sdma_set_tx_ring(struct mpsc_port_info *pi,
+ struct mpsc_tx_desc *txre_p)
{
writel((u32)txre_p, pi->sdma_base + SDMA_SFTDP);
writel((u32)txre_p, pi->sdma_base + SDMA_SCTDP);
- return;
}
-static inline void
-mpsc_sdma_cmd(struct mpsc_port_info *pi, u32 val)
+static void mpsc_sdma_cmd(struct mpsc_port_info *pi, u32 val)
{
u32 v;
@@ -539,46 +513,40 @@ mpsc_sdma_cmd(struct mpsc_port_info *pi, u32 val)
wmb();
writel(v, pi->sdma_base + SDMA_SDCM);
wmb();
- return;
}
-static inline uint
-mpsc_sdma_tx_active(struct mpsc_port_info *pi)
+static uint mpsc_sdma_tx_active(struct mpsc_port_info *pi)
{
return readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_TXD;
}
-static inline void
-mpsc_sdma_start_tx(struct mpsc_port_info *pi)
+static void mpsc_sdma_start_tx(struct mpsc_port_info *pi)
{
struct mpsc_tx_desc *txre, *txre_p;
/* If tx isn't running & there's a desc ready to go, start it */
if (!mpsc_sdma_tx_active(pi)) {
- txre = (struct mpsc_tx_desc *)(pi->txr +
- (pi->txr_tail * MPSC_TXRE_SIZE));
- dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+ txre = (struct mpsc_tx_desc *)(pi->txr
+ + (pi->txr_tail * MPSC_TXRE_SIZE));
+ dma_cache_sync(pi->port.dev, (void *)txre, MPSC_TXRE_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)txre,
- (ulong)txre + MPSC_TXRE_SIZE);
+ (ulong)txre + MPSC_TXRE_SIZE);
#endif
if (be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O) {
- txre_p = (struct mpsc_tx_desc *)(pi->txr_p +
- (pi->txr_tail *
- MPSC_TXRE_SIZE));
+ txre_p = (struct mpsc_tx_desc *)
+ (pi->txr_p + (pi->txr_tail * MPSC_TXRE_SIZE));
mpsc_sdma_set_tx_ring(pi, txre_p);
mpsc_sdma_cmd(pi, SDMA_SDCM_STD | SDMA_SDCM_TXD);
}
}
-
- return;
}
-static inline void
-mpsc_sdma_stop(struct mpsc_port_info *pi)
+static void mpsc_sdma_stop(struct mpsc_port_info *pi)
{
pr_debug("mpsc_sdma_stop[%d]: Stopping SDMA\n", pi->port.line);
@@ -593,8 +561,6 @@ mpsc_sdma_stop(struct mpsc_port_info *pi)
/* Disable interrupts */
mpsc_sdma_intr_mask(pi, 0xf);
mpsc_sdma_intr_ack(pi);
-
- return;
}
/*
@@ -605,8 +571,7 @@ mpsc_sdma_stop(struct mpsc_port_info *pi)
******************************************************************************
*/
-static void
-mpsc_hw_init(struct mpsc_port_info *pi)
+static void mpsc_hw_init(struct mpsc_port_info *pi)
{
u32 v;
@@ -628,8 +593,7 @@ mpsc_hw_init(struct mpsc_port_info *pi)
v = (v & ~0xf0f) | 0x100;
pi->shared_regs->MPSC_TCRR_m = v;
writel(v, pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
- }
- else {
+ } else {
v = readl(pi->shared_regs->mpsc_routing_base + MPSC_MRR);
v &= ~0x1c7;
writel(v, pi->shared_regs->mpsc_routing_base + MPSC_MRR);
@@ -646,7 +610,7 @@ mpsc_hw_init(struct mpsc_port_info *pi)
/* Put MPSC in UART mode & enabel Tx/Rx egines */
writel(0x000004c4, pi->mpsc_base + MPSC_MMCRL);
- /* No preamble, 16x divider, low-latency, */
+ /* No preamble, 16x divider, low-latency, */
writel(0x04400400, pi->mpsc_base + MPSC_MMCRH);
if (pi->mirror_regs) {
@@ -663,12 +627,9 @@ mpsc_hw_init(struct mpsc_port_info *pi)
writel(0, pi->mpsc_base + MPSC_CHR_8);
writel(0, pi->mpsc_base + MPSC_CHR_9);
writel(0, pi->mpsc_base + MPSC_CHR_10);
-
- return;
}
-static inline void
-mpsc_enter_hunt(struct mpsc_port_info *pi)
+static void mpsc_enter_hunt(struct mpsc_port_info *pi)
{
pr_debug("mpsc_enter_hunt[%d]: Hunting...\n", pi->port.line);
@@ -677,20 +638,16 @@ mpsc_enter_hunt(struct mpsc_port_info *pi)
pi->mpsc_base + MPSC_CHR_2);
/* Erratum prevents reading CHR_2 so just delay for a while */
udelay(100);
- }
- else {
+ } else {
writel(readl(pi->mpsc_base + MPSC_CHR_2) | MPSC_CHR_2_EH,
- pi->mpsc_base + MPSC_CHR_2);
+ pi->mpsc_base + MPSC_CHR_2);
while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_EH)
udelay(10);
}
-
- return;
}
-static inline void
-mpsc_freeze(struct mpsc_port_info *pi)
+static void mpsc_freeze(struct mpsc_port_info *pi)
{
u32 v;
@@ -703,11 +660,9 @@ mpsc_freeze(struct mpsc_port_info *pi)
if (pi->mirror_regs)
pi->MPSC_MPCR_m = v;
writel(v, pi->mpsc_base + MPSC_MPCR);
- return;
}
-static inline void
-mpsc_unfreeze(struct mpsc_port_info *pi)
+static void mpsc_unfreeze(struct mpsc_port_info *pi)
{
u32 v;
@@ -720,11 +675,9 @@ mpsc_unfreeze(struct mpsc_port_info *pi)
writel(v, pi->mpsc_base + MPSC_MPCR);
pr_debug("mpsc_unfreeze[%d]: Unfrozen\n", pi->port.line);
- return;
}
-static inline void
-mpsc_set_char_length(struct mpsc_port_info *pi, u32 len)
+static void mpsc_set_char_length(struct mpsc_port_info *pi, u32 len)
{
u32 v;
@@ -737,11 +690,9 @@ mpsc_set_char_length(struct mpsc_port_info *pi, u32 len)
if (pi->mirror_regs)
pi->MPSC_MPCR_m = v;
writel(v, pi->mpsc_base + MPSC_MPCR);
- return;
}
-static inline void
-mpsc_set_stop_bit_length(struct mpsc_port_info *pi, u32 len)
+static void mpsc_set_stop_bit_length(struct mpsc_port_info *pi, u32 len)
{
u32 v;
@@ -756,11 +707,9 @@ mpsc_set_stop_bit_length(struct mpsc_port_info *pi, u32 len)
if (pi->mirror_regs)
pi->MPSC_MPCR_m = v;
writel(v, pi->mpsc_base + MPSC_MPCR);
- return;
}
-static inline void
-mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
+static void mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
{
u32 v;
@@ -775,7 +724,6 @@ mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
if (pi->mirror_regs)
pi->MPSC_CHR_2_m = v;
writel(v, pi->mpsc_base + MPSC_CHR_2);
- return;
}
/*
@@ -786,8 +734,7 @@ mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
******************************************************************************
*/
-static void
-mpsc_init_hw(struct mpsc_port_info *pi)
+static void mpsc_init_hw(struct mpsc_port_info *pi)
{
pr_debug("mpsc_init_hw[%d]: Initializing\n", pi->port.line);
@@ -796,12 +743,9 @@ mpsc_init_hw(struct mpsc_port_info *pi)
mpsc_sdma_init(pi, dma_get_cache_alignment()); /* burst a cacheline */
mpsc_sdma_stop(pi);
mpsc_hw_init(pi);
-
- return;
}
-static int
-mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
+static int mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
{
int rc = 0;
@@ -812,11 +756,10 @@ mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
if (!dma_supported(pi->port.dev, 0xffffffff)) {
printk(KERN_ERR "MPSC: Inadequate DMA support\n");
rc = -ENXIO;
- }
- else if ((pi->dma_region = dma_alloc_noncoherent(pi->port.dev,
- MPSC_DMA_ALLOC_SIZE, &pi->dma_region_p, GFP_KERNEL))
- == NULL) {
-
+ } else if ((pi->dma_region = dma_alloc_noncoherent(pi->port.dev,
+ MPSC_DMA_ALLOC_SIZE,
+ &pi->dma_region_p, GFP_KERNEL))
+ == NULL) {
printk(KERN_ERR "MPSC: Can't alloc Desc region\n");
rc = -ENOMEM;
}
@@ -825,23 +768,19 @@ mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
return rc;
}
-static void
-mpsc_free_ring_mem(struct mpsc_port_info *pi)
+static void mpsc_free_ring_mem(struct mpsc_port_info *pi)
{
pr_debug("mpsc_free_ring_mem[%d]: Freeing ring mem\n", pi->port.line);
if (pi->dma_region) {
dma_free_noncoherent(pi->port.dev, MPSC_DMA_ALLOC_SIZE,
- pi->dma_region, pi->dma_region_p);
+ pi->dma_region, pi->dma_region_p);
pi->dma_region = NULL;
- pi->dma_region_p = (dma_addr_t) NULL;
+ pi->dma_region_p = (dma_addr_t)NULL;
}
-
- return;
}
-static void
-mpsc_init_rings(struct mpsc_port_info *pi)
+static void mpsc_init_rings(struct mpsc_port_info *pi)
{
struct mpsc_rx_desc *rxre;
struct mpsc_tx_desc *txre;
@@ -859,8 +798,8 @@ mpsc_init_rings(struct mpsc_port_info *pi)
* Descriptors & buffers are multiples of cacheline size and must be
* cacheline aligned.
*/
- dp = ALIGN((u32) pi->dma_region, dma_get_cache_alignment());
- dp_p = ALIGN((u32) pi->dma_region_p, dma_get_cache_alignment());
+ dp = ALIGN((u32)pi->dma_region, dma_get_cache_alignment());
+ dp_p = ALIGN((u32)pi->dma_region_p, dma_get_cache_alignment());
/*
* Partition dma region into rx ring descriptor, rx buffers,
@@ -871,8 +810,8 @@ mpsc_init_rings(struct mpsc_port_info *pi)
dp += MPSC_RXR_SIZE;
dp_p += MPSC_RXR_SIZE;
- pi->rxb = (u8 *) dp;
- pi->rxb_p = (u8 *) dp_p;
+ pi->rxb = (u8 *)dp;
+ pi->rxb_p = (u8 *)dp_p;
dp += MPSC_RXB_SIZE;
dp_p += MPSC_RXB_SIZE;
@@ -883,8 +822,8 @@ mpsc_init_rings(struct mpsc_port_info *pi)
dp += MPSC_TXR_SIZE;
dp_p += MPSC_TXR_SIZE;
- pi->txb = (u8 *) dp;
- pi->txb_p = (u8 *) dp_p;
+ pi->txb = (u8 *)dp;
+ pi->txb_p = (u8 *)dp_p;
pi->txr_head = 0;
pi->txr_tail = 0;
@@ -900,10 +839,9 @@ mpsc_init_rings(struct mpsc_port_info *pi)
rxre->bufsize = cpu_to_be16(MPSC_RXBE_SIZE);
rxre->bytecnt = cpu_to_be16(0);
- rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
- SDMA_DESC_CMDSTAT_EI |
- SDMA_DESC_CMDSTAT_F |
- SDMA_DESC_CMDSTAT_L);
+ rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O
+ | SDMA_DESC_CMDSTAT_EI | SDMA_DESC_CMDSTAT_F
+ | SDMA_DESC_CMDSTAT_L);
rxre->link = cpu_to_be32(dp_p + MPSC_RXRE_SIZE);
rxre->buf_ptr = cpu_to_be32(bp_p);
@@ -933,19 +871,19 @@ mpsc_init_rings(struct mpsc_port_info *pi)
}
txre->link = cpu_to_be32(pi->txr_p); /* Wrap last back to first */
- dma_cache_sync(pi->port.dev, (void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE,
- DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *)pi->dma_region,
+ MPSC_DMA_ALLOC_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)pi->dma_region,
- (ulong)pi->dma_region + MPSC_DMA_ALLOC_SIZE);
+ (ulong)pi->dma_region
+ + MPSC_DMA_ALLOC_SIZE);
#endif
return;
}
-static void
-mpsc_uninit_rings(struct mpsc_port_info *pi)
+static void mpsc_uninit_rings(struct mpsc_port_info *pi)
{
pr_debug("mpsc_uninit_rings[%d]: Uninitializing rings\n",pi->port.line);
@@ -963,12 +901,9 @@ mpsc_uninit_rings(struct mpsc_port_info *pi)
pi->txb_p = NULL;
pi->txr_head = 0;
pi->txr_tail = 0;
-
- return;
}
-static int
-mpsc_make_ready(struct mpsc_port_info *pi)
+static int mpsc_make_ready(struct mpsc_port_info *pi)
{
int rc;
@@ -993,8 +928,7 @@ mpsc_make_ready(struct mpsc_port_info *pi)
******************************************************************************
*/
-static inline int
-mpsc_rx_intr(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;
@@ -1007,21 +941,24 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
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);
+ 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);
+ (ulong)rxre + MPSC_RXRE_SIZE);
#endif
/*
* Loop through Rx descriptors handling ones that have been completed.
*/
- while (!((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)){
+ while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
+ & SDMA_DESC_CMDSTAT_O)) {
bytes_in = be16_to_cpu(rxre->bytecnt);
/* Following use of tty struct directly is deprecated */
- if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) {
+ if (unlikely(tty_buffer_request_room(tty, bytes_in)
+ < bytes_in)) {
if (tty->low_latency)
tty_flip_buffer_push(tty);
/*
@@ -1031,11 +968,12 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
}
bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
- dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
+ 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);
+ (ulong)bp + MPSC_RXBE_SIZE);
#endif
/*
@@ -1046,8 +984,9 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
* we'll assume there is no data in the buffer.
* If there is...it gets lost.
*/
- if (unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
- SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) {
+ if (unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR
+ | SDMA_DESC_CMDSTAT_FR
+ | SDMA_DESC_CMDSTAT_OR))) {
pi->port.icount.rx++;
@@ -1056,11 +995,11 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
if (uart_handle_break(&pi->port))
goto next_frame;
- }
- else if (cmdstat & SDMA_DESC_CMDSTAT_FR)/* Framing */
+ } else if (cmdstat & SDMA_DESC_CMDSTAT_FR) {
pi->port.icount.frame++;
- else if (cmdstat & SDMA_DESC_CMDSTAT_OR) /* Overrun */
+ } else if (cmdstat & SDMA_DESC_CMDSTAT_OR) {
pi->port.icount.overrun++;
+ }
cmdstat &= pi->port.read_status_mask;
@@ -1080,12 +1019,12 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
goto next_frame;
}
- if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
- SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
- !(cmdstat & pi->port.ignore_status_mask))
-
+ if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR
+ | SDMA_DESC_CMDSTAT_FR
+ | SDMA_DESC_CMDSTAT_OR)))
+ && !(cmdstat & pi->port.ignore_status_mask)) {
tty_insert_flip_char(tty, *bp, flag);
- else {
+ } else {
for (i=0; i<bytes_in; i++)
tty_insert_flip_char(tty, *bp++, TTY_NORMAL);
@@ -1095,29 +1034,29 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
next_frame:
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);
+ 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);
+ 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);
+ (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);
+ 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);
+ (ulong)rxre + MPSC_RXRE_SIZE);
#endif
-
rc = 1;
}
@@ -1129,42 +1068,38 @@ next_frame:
return rc;
}
-static inline void
-mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
+static void mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
{
struct mpsc_tx_desc *txre;
- txre = (struct mpsc_tx_desc *)(pi->txr +
- (pi->txr_head * MPSC_TXRE_SIZE));
+ txre = (struct mpsc_tx_desc *)(pi->txr
+ + (pi->txr_head * MPSC_TXRE_SIZE));
txre->bytecnt = cpu_to_be16(count);
txre->shadow = txre->bytecnt;
wmb(); /* ensure cmdstat is last field updated */
- txre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_F |
- SDMA_DESC_CMDSTAT_L | ((intr) ?
- SDMA_DESC_CMDSTAT_EI
- : 0));
+ txre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_F
+ | SDMA_DESC_CMDSTAT_L
+ | ((intr) ? SDMA_DESC_CMDSTAT_EI : 0));
wmb();
- dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *)txre, MPSC_TXRE_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)txre,
- (ulong)txre + MPSC_TXRE_SIZE);
+ (ulong)txre + MPSC_TXRE_SIZE);
#endif
-
- return;
}
-static inline void
-mpsc_copy_tx_data(struct mpsc_port_info *pi)
+static void mpsc_copy_tx_data(struct mpsc_port_info *pi)
{
struct circ_buf *xmit = &pi->port.info->xmit;
u8 *bp;
u32 i;
/* Make sure the desc ring isn't full */
- while (CIRC_CNT(pi->txr_head, pi->txr_tail, MPSC_TXR_ENTRIES) <
- (MPSC_TXR_ENTRIES - 1)) {
+ while (CIRC_CNT(pi->txr_head, pi->txr_tail, MPSC_TXR_ENTRIES)
+ < (MPSC_TXR_ENTRIES - 1)) {
if (pi->port.x_char) {
/*
* Ideally, we should use the TCS field in
@@ -1178,11 +1113,11 @@ mpsc_copy_tx_data(struct mpsc_port_info *pi)
*bp = pi->port.x_char;
pi->port.x_char = 0;
i = 1;
- }
- else if (!uart_circ_empty(xmit) && !uart_tx_stopped(&pi->port)){
- i = min((u32) MPSC_TXBE_SIZE,
- (u32) uart_circ_chars_pending(xmit));
- i = min(i, (u32) CIRC_CNT_TO_END(xmit->head, xmit->tail,
+ } else if (!uart_circ_empty(xmit)
+ && !uart_tx_stopped(&pi->port)) {
+ i = min((u32)MPSC_TXBE_SIZE,
+ (u32)uart_circ_chars_pending(xmit));
+ i = min(i, (u32)CIRC_CNT_TO_END(xmit->head, xmit->tail,
UART_XMIT_SIZE));
bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
memcpy(bp, &xmit->buf[xmit->tail], i);
@@ -1190,27 +1125,25 @@ mpsc_copy_tx_data(struct mpsc_port_info *pi)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&pi->port);
- }
- else /* All tx data copied into ring bufs */
+ } else { /* All tx data copied into ring bufs */
return;
+ }
- dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *)bp, MPSC_TXBE_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)bp,
- (ulong)bp + MPSC_TXBE_SIZE);
+ (ulong)bp + MPSC_TXBE_SIZE);
#endif
mpsc_setup_tx_desc(pi, i, 1);
/* Advance to next descriptor */
pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
}
-
- return;
}
-static inline int
-mpsc_tx_intr(struct mpsc_port_info *pi)
+static int mpsc_tx_intr(struct mpsc_port_info *pi)
{
struct mpsc_tx_desc *txre;
int rc = 0;
@@ -1219,14 +1152,15 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
spin_lock_irqsave(&pi->tx_lock, iflags);
if (!mpsc_sdma_tx_active(pi)) {
- txre = (struct mpsc_tx_desc *)(pi->txr +
- (pi->txr_tail * MPSC_TXRE_SIZE));
+ txre = (struct mpsc_tx_desc *)(pi->txr
+ + (pi->txr_tail * MPSC_TXRE_SIZE));
- dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(pi->port.dev, (void *)txre, MPSC_TXRE_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)txre,
- (ulong)txre + MPSC_TXRE_SIZE);
+ (ulong)txre + MPSC_TXRE_SIZE);
#endif
while (!(be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O)) {
@@ -1238,14 +1172,14 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
if (pi->txr_head == pi->txr_tail)
break;
- txre = (struct mpsc_tx_desc *)(pi->txr +
- (pi->txr_tail * MPSC_TXRE_SIZE));
- dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE,
- DMA_FROM_DEVICE);
+ txre = (struct mpsc_tx_desc *)(pi->txr
+ + (pi->txr_tail * MPSC_TXRE_SIZE));
+ dma_cache_sync(pi->port.dev, (void *)txre,
+ MPSC_TXRE_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)txre,
- (ulong)txre + MPSC_TXRE_SIZE);
+ (ulong)txre + MPSC_TXRE_SIZE);
#endif
}
@@ -1262,8 +1196,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
* the interrupt, then handle any completed Rx/Tx descriptors. When done
* handling those descriptors, we restart the Rx/Tx engines if they're stopped.
*/
-static irqreturn_t
-mpsc_sdma_intr(int irq, void *dev_id)
+static irqreturn_t mpsc_sdma_intr(int irq, void *dev_id)
{
struct mpsc_port_info *pi = dev_id;
ulong iflags;
@@ -1290,8 +1223,7 @@ mpsc_sdma_intr(int irq, void *dev_id)
*
******************************************************************************
*/
-static uint
-mpsc_tx_empty(struct uart_port *port)
+static uint mpsc_tx_empty(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
ulong iflags;
@@ -1304,21 +1236,18 @@ mpsc_tx_empty(struct uart_port *port)
return rc;
}
-static void
-mpsc_set_mctrl(struct uart_port *port, uint mctrl)
+static void mpsc_set_mctrl(struct uart_port *port, uint mctrl)
{
/* Have no way to set modem control lines AFAICT */
- return;
}
-static uint
-mpsc_get_mctrl(struct uart_port *port)
+static uint mpsc_get_mctrl(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
u32 mflags, status;
- status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
- readl(pi->mpsc_base + MPSC_CHR_10);
+ status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m
+ : readl(pi->mpsc_base + MPSC_CHR_10);
mflags = 0;
if (status & 0x1)
@@ -1329,19 +1258,16 @@ mpsc_get_mctrl(struct uart_port *port)
return mflags | TIOCM_DSR; /* No way to tell if DSR asserted */
}
-static void
-mpsc_stop_tx(struct uart_port *port)
+static void mpsc_stop_tx(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
pr_debug("mpsc_stop_tx[%d]\n", port->line);
mpsc_freeze(pi);
- return;
}
-static void
-mpsc_start_tx(struct uart_port *port)
+static void mpsc_start_tx(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
unsigned long iflags;
@@ -1355,42 +1281,45 @@ mpsc_start_tx(struct uart_port *port)
spin_unlock_irqrestore(&pi->tx_lock, iflags);
pr_debug("mpsc_start_tx[%d]\n", port->line);
- return;
}
-static void
-mpsc_start_rx(struct mpsc_port_info *pi)
+static void mpsc_start_rx(struct mpsc_port_info *pi)
{
pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
- /* Issue a Receive Abort to clear any receive errors */
- writel(MPSC_CHR_2_RA, pi->mpsc_base + MPSC_CHR_2);
if (pi->rcv_data) {
mpsc_enter_hunt(pi);
mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
}
- return;
}
-static void
-mpsc_stop_rx(struct uart_port *port)
+static void mpsc_stop_rx(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
pr_debug("mpsc_stop_rx[%d]: Stopping...\n", port->line);
+ if (pi->mirror_regs) {
+ writel(pi->MPSC_CHR_2_m | MPSC_CHR_2_RA,
+ pi->mpsc_base + MPSC_CHR_2);
+ /* Erratum prevents reading CHR_2 so just delay for a while */
+ udelay(100);
+ } else {
+ writel(readl(pi->mpsc_base + MPSC_CHR_2) | MPSC_CHR_2_RA,
+ pi->mpsc_base + MPSC_CHR_2);
+
+ while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_RA)
+ udelay(10);
+ }
+
mpsc_sdma_cmd(pi, SDMA_SDCM_AR);
- return;
}
-static void
-mpsc_enable_ms(struct uart_port *port)
+static void mpsc_enable_ms(struct uart_port *port)
{
- return; /* Not supported */
}
-static void
-mpsc_break_ctl(struct uart_port *port, int ctl)
+static void mpsc_break_ctl(struct uart_port *port, int ctl)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
ulong flags;
@@ -1403,12 +1332,9 @@ mpsc_break_ctl(struct uart_port *port, int ctl)
pi->MPSC_CHR_1_m = v;
writel(v, pi->mpsc_base + MPSC_CHR_1);
spin_unlock_irqrestore(&pi->port.lock, flags);
-
- return;
}
-static int
-mpsc_startup(struct uart_port *port)
+static int mpsc_startup(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
u32 flag = 0;
@@ -1426,20 +1352,19 @@ mpsc_startup(struct uart_port *port)
flag = IRQF_SHARED;
if (request_irq(pi->port.irq, mpsc_sdma_intr, flag,
- "mpsc-sdma", pi))
+ "mpsc-sdma", pi))
printk(KERN_ERR "MPSC: Can't get SDMA IRQ %d\n",
- pi->port.irq);
+ pi->port.irq);
mpsc_sdma_intr_unmask(pi, 0xf);
- mpsc_sdma_set_rx_ring(pi, (struct mpsc_rx_desc *)(pi->rxr_p +
- (pi->rxr_posn * MPSC_RXRE_SIZE)));
+ mpsc_sdma_set_rx_ring(pi, (struct mpsc_rx_desc *)(pi->rxr_p
+ + (pi->rxr_posn * MPSC_RXRE_SIZE)));
}
return rc;
}
-static void
-mpsc_shutdown(struct uart_port *port)
+static void mpsc_shutdown(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
@@ -1447,11 +1372,9 @@ mpsc_shutdown(struct uart_port *port)
mpsc_sdma_stop(pi);
free_irq(pi->port.irq, pi);
- return;
}
-static void
-mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
+static void mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
@@ -1508,12 +1431,11 @@ mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
mpsc_set_baudrate(pi, baud);
/* Characters/events to read */
- pi->rcv_data = 1;
pi->port.read_status_mask = SDMA_DESC_CMDSTAT_OR;
if (termios->c_iflag & INPCK)
- pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_PE |
- SDMA_DESC_CMDSTAT_FR;
+ pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_PE
+ | SDMA_DESC_CMDSTAT_FR;
if (termios->c_iflag & (BRKINT | PARMRK))
pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_BR;
@@ -1522,8 +1444,8 @@ mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
pi->port.ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
- pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_PE |
- SDMA_DESC_CMDSTAT_FR;
+ pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_PE
+ | SDMA_DESC_CMDSTAT_FR;
if (termios->c_iflag & IGNBRK) {
pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_BR;
@@ -1532,32 +1454,32 @@ mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_OR;
}
- /* Ignore all chars if CREAD not set */
- if (!(termios->c_cflag & CREAD))
+ if ((termios->c_cflag & CREAD)) {
+ if (!pi->rcv_data) {
+ pi->rcv_data = 1;
+ mpsc_start_rx(pi);
+ }
+ } else if (pi->rcv_data) {
+ mpsc_stop_rx(port);
pi->rcv_data = 0;
- else
- mpsc_start_rx(pi);
+ }
spin_unlock_irqrestore(&pi->port.lock, flags);
- return;
}
-static const char *
-mpsc_type(struct uart_port *port)
+static const char *mpsc_type(struct uart_port *port)
{
pr_debug("mpsc_type[%d]: port type: %s\n", port->line,MPSC_DRIVER_NAME);
return MPSC_DRIVER_NAME;
}
-static int
-mpsc_request_port(struct uart_port *port)
+static int mpsc_request_port(struct uart_port *port)
{
/* Should make chip/platform specific call */
return 0;
}
-static void
-mpsc_release_port(struct uart_port *port)
+static void mpsc_release_port(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
@@ -1566,18 +1488,13 @@ mpsc_release_port(struct uart_port *port)
mpsc_free_ring_mem(pi);
pi->ready = 0;
}
-
- return;
}
-static void
-mpsc_config_port(struct uart_port *port, int flags)
+static void mpsc_config_port(struct uart_port *port, int flags)
{
- return;
}
-static int
-mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
+static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
int rc = 0;
@@ -1603,22 +1520,22 @@ mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
}
static struct uart_ops mpsc_pops = {
- .tx_empty = mpsc_tx_empty,
- .set_mctrl = mpsc_set_mctrl,
- .get_mctrl = mpsc_get_mctrl,
- .stop_tx = mpsc_stop_tx,
- .start_tx = mpsc_start_tx,
- .stop_rx = mpsc_stop_rx,
- .enable_ms = mpsc_enable_ms,
- .break_ctl = mpsc_break_ctl,
- .startup = mpsc_startup,
- .shutdown = mpsc_shutdown,
- .set_termios = mpsc_set_termios,
- .type = mpsc_type,
- .release_port = mpsc_release_port,
- .request_port = mpsc_request_port,
- .config_port = mpsc_config_port,
- .verify_port = mpsc_verify_port,
+ .tx_empty = mpsc_tx_empty,
+ .set_mctrl = mpsc_set_mctrl,
+ .get_mctrl = mpsc_get_mctrl,
+ .stop_tx = mpsc_stop_tx,
+ .start_tx = mpsc_start_tx,
+ .stop_rx = mpsc_stop_rx,
+ .enable_ms = mpsc_enable_ms,
+ .break_ctl = mpsc_break_ctl,
+ .startup = mpsc_startup,
+ .shutdown = mpsc_shutdown,
+ .set_termios = mpsc_set_termios,
+ .type = mpsc_type,
+ .release_port = mpsc_release_port,
+ .request_port = mpsc_request_port,
+ .config_port = mpsc_config_port,
+ .verify_port = mpsc_verify_port,
};
/*
@@ -1630,8 +1547,7 @@ static struct uart_ops mpsc_pops = {
*/
#ifdef CONFIG_SERIAL_MPSC_CONSOLE
-static void
-mpsc_console_write(struct console *co, const char *s, uint count)
+static void mpsc_console_write(struct console *co, const char *s, uint count)
{
struct mpsc_port_info *pi = &mpsc_ports[co->index];
u8 *bp, *dp, add_cr = 0;
@@ -1660,8 +1576,7 @@ mpsc_console_write(struct console *co, const char *s, uint count)
if (add_cr) {
*(dp++) = '\r';
add_cr = 0;
- }
- else {
+ } else {
*(dp++) = *s;
if (*(s++) == '\n') { /* add '\r' after '\n' */
@@ -1673,11 +1588,12 @@ mpsc_console_write(struct console *co, const char *s, uint count)
count--;
}
- dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *)bp, MPSC_TXBE_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)bp,
- (ulong)bp + MPSC_TXBE_SIZE);
+ (ulong)bp + MPSC_TXBE_SIZE);
#endif
mpsc_setup_tx_desc(pi, i, 0);
pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
@@ -1690,11 +1606,9 @@ mpsc_console_write(struct console *co, const char *s, uint count)
}
spin_unlock_irqrestore(&pi->tx_lock, iflags);
- return;
}
-static int __init
-mpsc_console_setup(struct console *co, char *options)
+static int __init mpsc_console_setup(struct console *co, char *options)
{
struct mpsc_port_info *pi;
int baud, bits, parity, flow;
@@ -1723,17 +1637,16 @@ mpsc_console_setup(struct console *co, char *options)
}
static struct console mpsc_console = {
- .name = MPSC_DEV_NAME,
- .write = mpsc_console_write,
- .device = uart_console_device,
- .setup = mpsc_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .data = &mpsc_reg,
+ .name = MPSC_DEV_NAME,
+ .write = mpsc_console_write,
+ .device = uart_console_device,
+ .setup = mpsc_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &mpsc_reg,
};
-static int __init
-mpsc_late_console_init(void)
+static int __init mpsc_late_console_init(void)
{
pr_debug("mpsc_late_console_init: Enter\n");
@@ -1755,43 +1668,40 @@ late_initcall(mpsc_late_console_init);
*
******************************************************************************
*/
-static void
-mpsc_resource_err(char *s)
+static void mpsc_resource_err(char *s)
{
printk(KERN_WARNING "MPSC: Platform device resource error in %s\n", s);
- return;
}
-static int
-mpsc_shared_map_regs(struct platform_device *pd)
+static int mpsc_shared_map_regs(struct platform_device *pd)
{
struct resource *r;
if ((r = platform_get_resource(pd, IORESOURCE_MEM,
- MPSC_ROUTING_BASE_ORDER)) && request_mem_region(r->start,
- MPSC_ROUTING_REG_BLOCK_SIZE, "mpsc_routing_regs")) {
-
+ MPSC_ROUTING_BASE_ORDER))
+ && request_mem_region(r->start,
+ MPSC_ROUTING_REG_BLOCK_SIZE,
+ "mpsc_routing_regs")) {
mpsc_shared_regs.mpsc_routing_base = ioremap(r->start,
- MPSC_ROUTING_REG_BLOCK_SIZE);
+ MPSC_ROUTING_REG_BLOCK_SIZE);
mpsc_shared_regs.mpsc_routing_base_p = r->start;
- }
- else {
+ } else {
mpsc_resource_err("MPSC routing base");
return -ENOMEM;
}
if ((r = platform_get_resource(pd, IORESOURCE_MEM,
- MPSC_SDMA_INTR_BASE_ORDER)) && request_mem_region(r->start,
- MPSC_SDMA_INTR_REG_BLOCK_SIZE, "sdma_intr_regs")) {
-
+ MPSC_SDMA_INTR_BASE_ORDER))
+ && request_mem_region(r->start,
+ MPSC_SDMA_INTR_REG_BLOCK_SIZE,
+ "sdma_intr_regs")) {
mpsc_shared_regs.sdma_intr_base = ioremap(r->start,
MPSC_SDMA_INTR_REG_BLOCK_SIZE);
mpsc_shared_regs.sdma_intr_base_p = r->start;
- }
- else {
+ } else {
iounmap(mpsc_shared_regs.mpsc_routing_base);
release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
- MPSC_ROUTING_REG_BLOCK_SIZE);
+ MPSC_ROUTING_REG_BLOCK_SIZE);
mpsc_resource_err("SDMA intr base");
return -ENOMEM;
}
@@ -1799,18 +1709,17 @@ mpsc_shared_map_regs(struct platform_device *pd)
return 0;
}
-static void
-mpsc_shared_unmap_regs(void)
+static void mpsc_shared_unmap_regs(void)
{
if (!mpsc_shared_regs.mpsc_routing_base) {
iounmap(mpsc_shared_regs.mpsc_routing_base);
release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
- MPSC_ROUTING_REG_BLOCK_SIZE);
+ MPSC_ROUTING_REG_BLOCK_SIZE);
}
if (!mpsc_shared_regs.sdma_intr_base) {
iounmap(mpsc_shared_regs.sdma_intr_base);
release_mem_region(mpsc_shared_regs.sdma_intr_base_p,
- MPSC_SDMA_INTR_REG_BLOCK_SIZE);
+ MPSC_SDMA_INTR_REG_BLOCK_SIZE);
}
mpsc_shared_regs.mpsc_routing_base = NULL;
@@ -1818,19 +1727,17 @@ mpsc_shared_unmap_regs(void)
mpsc_shared_regs.mpsc_routing_base_p = 0;
mpsc_shared_regs.sdma_intr_base_p = 0;
-
- return;
}
-static int
-mpsc_shared_drv_probe(struct platform_device *dev)
+static int mpsc_shared_drv_probe(struct platform_device *dev)
{
struct mpsc_shared_pdata *pdata;
int rc = -ENODEV;
if (dev->id == 0) {
- if (!(rc = mpsc_shared_map_regs(dev))) {
- pdata = (struct mpsc_shared_pdata *)dev->dev.platform_data;
+ if (!(rc = mpsc_shared_map_regs(dev))) {
+ pdata = (struct mpsc_shared_pdata *)
+ dev->dev.platform_data;
mpsc_shared_regs.MPSC_MRR_m = pdata->mrr_val;
mpsc_shared_regs.MPSC_RCRR_m= pdata->rcrr_val;
@@ -1847,8 +1754,7 @@ mpsc_shared_drv_probe(struct platform_device *dev)
return rc;
}
-static int
-mpsc_shared_drv_remove(struct platform_device *dev)
+static int mpsc_shared_drv_remove(struct platform_device *dev)
{
int rc = -ENODEV;
@@ -1869,7 +1775,7 @@ static struct platform_driver mpsc_shared_driver = {
.probe = mpsc_shared_drv_probe,
.remove = mpsc_shared_drv_remove,
.driver = {
- .name = MPSC_SHARED_NAME,
+ .name = MPSC_SHARED_NAME,
},
};
@@ -1881,55 +1787,51 @@ static struct platform_driver mpsc_shared_driver = {
******************************************************************************
*/
static struct uart_driver mpsc_reg = {
- .owner = THIS_MODULE,
- .driver_name = MPSC_DRIVER_NAME,
- .dev_name = MPSC_DEV_NAME,
- .major = MPSC_MAJOR,
- .minor = MPSC_MINOR_START,
- .nr = MPSC_NUM_CTLRS,
- .cons = MPSC_CONSOLE,
+ .owner = THIS_MODULE,
+ .driver_name = MPSC_DRIVER_NAME,
+ .dev_name = MPSC_DEV_NAME,
+ .major = MPSC_MAJOR,
+ .minor = MPSC_MINOR_START,
+ .nr = MPSC_NUM_CTLRS,
+ .cons = MPSC_CONSOLE,
};
-static int
-mpsc_drv_map_regs(struct mpsc_port_info *pi, struct platform_device *pd)
+static int mpsc_drv_map_regs(struct mpsc_port_info *pi,
+ struct platform_device *pd)
{
struct resource *r;
- if ((r = platform_get_resource(pd, IORESOURCE_MEM, MPSC_BASE_ORDER)) &&
- request_mem_region(r->start, MPSC_REG_BLOCK_SIZE, "mpsc_regs")){
-
+ if ((r = platform_get_resource(pd, IORESOURCE_MEM, MPSC_BASE_ORDER))
+ && request_mem_region(r->start, MPSC_REG_BLOCK_SIZE,
+ "mpsc_regs")) {
pi->mpsc_base = ioremap(r->start, MPSC_REG_BLOCK_SIZE);
pi->mpsc_base_p = r->start;
- }
- else {
+ } else {
mpsc_resource_err("MPSC base");
- return -ENOMEM;
+ goto err;
}
if ((r = platform_get_resource(pd, IORESOURCE_MEM,
- MPSC_SDMA_BASE_ORDER)) && request_mem_region(r->start,
- MPSC_SDMA_REG_BLOCK_SIZE, "sdma_regs")) {
-
+ MPSC_SDMA_BASE_ORDER))
+ && request_mem_region(r->start,
+ MPSC_SDMA_REG_BLOCK_SIZE, "sdma_regs")) {
pi->sdma_base = ioremap(r->start,MPSC_SDMA_REG_BLOCK_SIZE);
pi->sdma_base_p = r->start;
- }
- else {
+ } else {
mpsc_resource_err("SDMA base");
if (pi->mpsc_base) {
iounmap(pi->mpsc_base);
pi->mpsc_base = NULL;
}
- return -ENOMEM;
+ goto err;
}
if ((r = platform_get_resource(pd,IORESOURCE_MEM,MPSC_BRG_BASE_ORDER))
- && request_mem_region(r->start, MPSC_BRG_REG_BLOCK_SIZE,
- "brg_regs")) {
-
+ && request_mem_region(r->start,
+ MPSC_BRG_REG_BLOCK_SIZE, "brg_regs")) {
pi->brg_base = ioremap(r->start, MPSC_BRG_REG_BLOCK_SIZE);
pi->brg_base_p = r->start;
- }
- else {
+ } else {
mpsc_resource_err("BRG base");
if (pi->mpsc_base) {
iounmap(pi->mpsc_base);
@@ -1939,14 +1841,15 @@ mpsc_drv_map_regs(struct mpsc_port_info *pi, struct platform_device *pd)
iounmap(pi->sdma_base);
pi->sdma_base = NULL;
}
- return -ENOMEM;
+ goto err;
}
-
return 0;
+
+err:
+ return -ENOMEM;
}
-static void
-mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
+static void mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
{
if (!pi->mpsc_base) {
iounmap(pi->mpsc_base);
@@ -1968,13 +1871,10 @@ mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
pi->mpsc_base_p = 0;
pi->sdma_base_p = 0;
pi->brg_base_p = 0;
-
- return;
}
-static void
-mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
- struct platform_device *pd, int num)
+static void mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
+ struct platform_device *pd, int num)
{
struct mpsc_pdata *pdata;
@@ -2009,12 +1909,9 @@ mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
pi->shared_regs = &mpsc_shared_regs;
pi->port.irq = platform_get_irq(pd, 0);
-
- return;
}
-static int
-mpsc_drv_probe(struct platform_device *dev)
+static int mpsc_drv_probe(struct platform_device *dev)
{
struct mpsc_port_info *pi;
int rc = -ENODEV;
@@ -2030,47 +1927,46 @@ mpsc_drv_probe(struct platform_device *dev)
if (!(rc = mpsc_make_ready(pi))) {
spin_lock_init(&pi->tx_lock);
if (!(rc = uart_add_one_port(&mpsc_reg,
- &pi->port)))
+ &pi->port))) {
rc = 0;
- else {
- mpsc_release_port(
- (struct uart_port *)pi);
+ } else {
+ mpsc_release_port((struct uart_port *)
+ pi);
mpsc_drv_unmap_regs(pi);
}
- }
- else
+ } else {
mpsc_drv_unmap_regs(pi);
+ }
}
}
return rc;
}
-static int
-mpsc_drv_remove(struct platform_device *dev)
+static int mpsc_drv_remove(struct platform_device *dev)
{
pr_debug("mpsc_drv_exit: Removing MPSC %d\n", dev->id);
if (dev->id < MPSC_NUM_CTLRS) {
uart_remove_one_port(&mpsc_reg, &mpsc_ports[dev->id].port);
- mpsc_release_port((struct uart_port *)&mpsc_ports[dev->id].port);
+ mpsc_release_port((struct uart_port *)
+ &mpsc_ports[dev->id].port);
mpsc_drv_unmap_regs(&mpsc_ports[dev->id]);
return 0;
- }
- else
+ } else {
return -ENODEV;
+ }
}
static struct platform_driver mpsc_driver = {
.probe = mpsc_drv_probe,
.remove = mpsc_drv_remove,
.driver = {
- .name = MPSC_CTLR_NAME,
+ .name = MPSC_CTLR_NAME,
},
};
-static int __init
-mpsc_drv_init(void)
+static int __init mpsc_drv_init(void)
{
int rc;
@@ -2085,24 +1981,21 @@ mpsc_drv_init(void)
platform_driver_unregister(&mpsc_shared_driver);
uart_unregister_driver(&mpsc_reg);
}
- }
- else
+ } else {
uart_unregister_driver(&mpsc_reg);
+ }
}
return rc;
-
}
-static void __exit
-mpsc_drv_exit(void)
+static void __exit mpsc_drv_exit(void)
{
platform_driver_unregister(&mpsc_driver);
platform_driver_unregister(&mpsc_shared_driver);
uart_unregister_driver(&mpsc_reg);
memset(mpsc_ports, 0, sizeof(mpsc_ports));
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
- return;
}
module_init(mpsc_drv_init);
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index 7ffdaeaf0545..a64d85821996 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -17,6 +17,11 @@
#include <asm/of_platform.h>
#include <asm/prom.h>
+struct of_serial_info {
+ int type;
+ int line;
+};
+
/*
* Fill a struct uart_port for a given device node
*/
@@ -62,6 +67,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
static int __devinit of_platform_serial_probe(struct of_device *ofdev,
const struct of_device_id *id)
{
+ struct of_serial_info *info;
struct uart_port port;
int port_type;
int ret;
@@ -69,30 +75,35 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev,
if (of_find_property(ofdev->node, "used-by-rtas", NULL))
return -EBUSY;
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (info == NULL)
+ return -ENOMEM;
+
port_type = (unsigned long)id->data;
ret = of_platform_serial_setup(ofdev, port_type, &port);
if (ret)
goto out;
switch (port_type) {
- case PORT_UNKNOWN:
- dev_info(&ofdev->dev, "Unknown serial port found, "
- "attempting to use 8250 driver\n");
- /* fallthrough */
case PORT_8250 ... PORT_MAX_8250:
ret = serial8250_register_port(&port);
break;
default:
/* need to add code for these */
+ case PORT_UNKNOWN:
+ dev_info(&ofdev->dev, "Unknown serial port found, ignored\n");
ret = -ENODEV;
break;
}
if (ret < 0)
goto out;
- ofdev->dev.driver_data = (void *)(unsigned long)ret;
+ info->type = port_type;
+ info->line = ret;
+ ofdev->dev.driver_data = info;
return 0;
out:
+ kfree(info);
irq_dispose_mapping(port.irq);
return ret;
}
@@ -102,8 +113,16 @@ out:
*/
static int of_platform_serial_remove(struct of_device *ofdev)
{
- int line = (unsigned long)ofdev->dev.driver_data;
- serial8250_unregister_port(line);
+ struct of_serial_info *info = ofdev->dev.driver_data;
+ switch (info->type) {
+ case PORT_8250 ... PORT_MAX_8250:
+ serial8250_unregister_port(info->line);
+ break;
+ default:
+ /* need to add code for these */
+ break;
+ }
+ kfree(info);
return 0;
}
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 10bc0209cd66..3f26c4b2f322 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -78,7 +78,7 @@
#include <asm/hardware.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
#include <asm/arch/regs-gpio.h>
/* structures */
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 326020f86f75..a055f58f342f 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -626,7 +626,7 @@ static int uart_get_info(struct uart_state *state,
tmp.hub6 = port->hub6;
tmp.io_type = port->iotype;
tmp.iomem_reg_shift = port->regshift;
- tmp.iomem_base = (void *)port->mapbase;
+ tmp.iomem_base = (void *)(unsigned long)port->mapbase;
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
@@ -1146,11 +1146,14 @@ static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termio
/*
* These are the bits that are used to setup various
- * flags in the low level driver.
+ * flags in the low level driver. We can ignore the Bfoo
+ * bits in c_cflag; c_[io]speed will always be set
+ * appropriately by set_termios() in tty_ioctl.c
*/
#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
if ((cflag ^ old_termios->c_cflag) == 0 &&
+ tty->termios->c_ospeed == old_termios->c_ospeed &&
+ tty->termios->c_ispeed == old_termios->c_ispeed &&
RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
return;
@@ -1666,10 +1669,11 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
return 0;
mmio = port->iotype >= UPIO_MEM;
- ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
+ ret = sprintf(buf, "%d: uart:%s %s%08llX irq:%d",
port->line, uart_type(port),
mmio ? "mmio:0x" : "port:",
- mmio ? port->mapbase : (unsigned long) port->iobase,
+ mmio ? (unsigned long long)port->mapbase
+ : (unsigned long long) port->iobase,
port->irq);
if (port->type == PORT_UNKNOWN) {
@@ -1910,6 +1914,12 @@ uart_set_options(struct uart_port *port, struct console *co,
if (flow == 'r')
termios.c_cflag |= CRTSCTS;
+ /*
+ * some uarts on other side don't support no flow control.
+ * So we set * DTR in host uart to make them happy
+ */
+ port->mctrl |= TIOCM_DTR;
+
port->ops->set_termios(port, &termios, NULL);
co->cflag = termios.c_cflag;
@@ -2063,7 +2073,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
case UPIO_TSI:
case UPIO_DWAPB:
snprintf(address, sizeof(address),
- "MMIO 0x%lx", port->mapbase);
+ "MMIO 0x%llx", (unsigned long long)port->mapbase);
break;
default:
strlcpy(address, "*unknown*", sizeof(address));
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 6b76babc7fbf..7c8d78fbbbfb 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -842,12 +842,16 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
@@ -939,6 +943,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
+ PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
/* too generic */
/* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
/* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 1deb5764326d..0930e2a85514 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -37,7 +37,7 @@
#include <asm/io.h>
-static char *serial_version = "1.09";
+static char *serial_version = "1.10";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -436,8 +436,10 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
unsigned int ret;
- ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
- | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
+ /* no modem control lines */
+ ret = TIOCM_CAR | TIOCM_DSR;
+ ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS;
+ ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS;
return ret;
}
@@ -557,6 +559,12 @@ serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned long flags;
unsigned int baud, quot;
+ /*
+ * We don't support modem control lines.
+ */
+ termios->c_cflag &= ~(HUPCL | CMSPAR);
+ termios->c_cflag |= CLOCAL;
+
cval = sio_in(up, TXX9_SILCR);
/* byte size and parity */
cval &= ~TXX9_SILCR_UMODE_MASK;
@@ -1043,8 +1051,9 @@ static int __devinit serial_txx9_probe(struct platform_device *dev)
ret = serial_txx9_register_port(&port);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
- "(IO%x MEM%lx IRQ%d): %d\n", i,
- p->iobase, p->mapbase, p->irq, ret);
+ "(IO%x MEM%llx IRQ%d): %d\n", i,
+ p->iobase, (unsigned long long)p->mapbase,
+ p->irq, ret);
}
}
return 0;
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 1f89496d530e..053fca41b08a 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -12,6 +12,7 @@
* Modified to support multiple serial ports. Stuart Menefy (May 2000).
* Modified to support SecureEdge. David McCullough (2002)
* Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003).
+ * Removed SH7300 support (Jul 2007).
*
* 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
@@ -289,13 +290,7 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag)
#endif
#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-/* SH7300 doesn't use RTS/CTS */
-static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
-{
- sci_out(port, SCFCR, 0);
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag)
{
unsigned int fcr_val = 0;
@@ -367,7 +362,9 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
} else {
#ifdef CONFIG_CPU_SUBTYPE_SH7343
/* Nothing */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SHX3)
ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */
#else
ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index fb04fb5f9843..cf75466ebf57 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -9,6 +9,7 @@
* Modified to support multiple serial ports. Stuart Menefy (May 2000).
* Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003).
* Modified to support H8/300 Series Yoshinori Sato (Feb 2004).
+ * Removed SH7300 support (Jul 2007).
*/
#include <linux/serial_core.h>
#include <asm/io.h>
@@ -23,13 +24,10 @@
#endif
#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7708)
-# define SCSPTR 0xffffff7c /* 8 bit */
-# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
-# define SCI_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_SH7707) || \
- defined(CONFIG_CPU_SUBTYPE_SH7709) || \
- defined(CONFIG_CPU_SUBTYPE_SH7706)
+#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7708) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7709)
# define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */
# define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */
# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
@@ -53,7 +51,12 @@
# define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7091) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751R)
# define SCSPTR1 0xffe0001c /* 8 bit SCI */
# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
@@ -68,12 +71,7 @@
# define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
-# define SCPCR 0xA4050116 /* 16 bit SCIF */
-# define SCPDR 0xA4050136 /* 16 bit SCIF */
-# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
-# define SCIF_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
# define SCSPTR0 0xA4400000 /* 16 bit SCIF */
# define SCI_NPORTS 2
# define SCIF_ORER 0x0001 /* overrun error bit */
@@ -81,12 +79,6 @@
# define PBCR 0xa4050102
# define SCSCR_INIT(port) 0x3B
# define SCIF_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_SH73180)
-# define SCPDR 0xA4050138 /* 16 bit SCIF */
-# define SCSPTR2 SCPDR
-# define SCIF_ORER 0x0001 /* overrun error bit */
-# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1 */
-# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
# define SCSPTR0 0xffe00010 /* 16 bit SCIF */
# define SCSPTR1 0xffe10010 /* 16 bit SCIF */
@@ -168,6 +160,14 @@
# define SCIF_ORER 0x0001 /* overrun error bit */
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
+# define SCSPTR0 0xffc30020 /* 16 bit SCIF */
+# define SCSPTR1 0xffc40020 /* 16 bit SCIF */
+# define SCSPTR2 0xffc50020 /* 16 bit SCIF */
+# define SCSPTR3 0xffc60020 /* 16 bit SCIF */
+# define SCIF_ORER 0x0001 /* Overrun error bit */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
#else
# error CPU subtype not defined
#endif
@@ -177,10 +177,15 @@
#define SCI_CTRL_FLAGS_RIE 0x40 /* all */
#define SCI_CTRL_FLAGS_TE 0x20 /* all */
#define SCI_CTRL_FLAGS_RE 0x10 /* all */
-#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
- defined(CONFIG_CPU_SUBTYPE_SH7751) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7785)
+#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7091) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SHX3)
#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
#else
#define SCI_CTRL_FLAGS_REIE 0
@@ -212,7 +217,7 @@
#define SCIF_RDF 0x0002 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_DR 0x0001 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
#define SCIF_ORER 0x0200
#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
#define SCIF_RFDC_MASK 0x007f
@@ -241,7 +246,7 @@
# define SCxSR_ERRORS(port) SCIF_ERRORS
# define SCxSR_RDxF(port) SCIF_RDF
# define SCxSR_TDxE(port) SCIF_TDFE
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
# define SCxSR_ORER(port) SCIF_ORER
#else
# define SCxSR_ORER(port) 0x0000
@@ -249,13 +254,13 @@
# define SCxSR_FER(port) SCIF_FER
# define SCxSR_PER(port) SCIF_PER
# define SCxSR_BRK(port) SCIF_BRK
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
# define SCxSR_RDxF_CLEAR(port) (sci_in(port,SCxSR)&0xfffc)
# define SCxSR_ERROR_CLEAR(port) (sci_in(port,SCxSR)&0xfd73)
# define SCxSR_TDxE_CLEAR(port) (sci_in(port,SCxSR)&0xffdf)
# define SCxSR_BREAK_CLEAR(port) (sci_in(port,SCxSR)&0xffe3)
#else
-/* SH7705 can also use this, clearing is same between 7705 and 7709 and 7300 */
+/* SH7705 can also use this, clearing is same between 7705 and 7709 */
# define SCxSR_RDxF_CLEAR(port) 0x00fc
# define SCxSR_ERROR_CLEAR(port) 0x0073
# define SCxSR_TDxE_CLEAR(port) 0x00df
@@ -357,8 +362,7 @@
CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \
- defined(CONFIG_CPU_SUBTYPE_SH7705)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#else
@@ -384,8 +388,7 @@
CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \
- defined(CONFIG_CPU_SUBTYPE_SH7705)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
@@ -467,16 +470,10 @@ static const struct __attribute__((packed)) {
};
#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7708)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xfffffe80)
- return ctrl_inb(SCSPTR)&0x01 ? 1 : 0; /* SCI */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7707) || \
- defined(CONFIG_CPU_SUBTYPE_SH7709) || \
- defined(CONFIG_CPU_SUBTYPE_SH7706)
+#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7708) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7709)
static inline int sci_rxd_in(struct uart_port *port)
{
if (port->mapbase == 0xfffffe80)
@@ -514,8 +511,12 @@ static inline void set_sh771x_scif_pfc(struct uart_port *port)
}
}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
- defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7091) || \
defined(CONFIG_CPU_SUBTYPE_SH4_202)
static inline int sci_rxd_in(struct uart_port *port)
{
@@ -540,18 +541,6 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
return 1;
}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xa4430000)
- return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCIF0 */
- return 1;
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH73180)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCIF0 */
-}
#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
static inline int sci_rxd_in(struct uart_port *port)
{
@@ -653,6 +642,18 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
return 1;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+ if (port->mapbase == 0xffc30000)
+ return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffc40000)
+ return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffc50000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffc60000)
+ return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
+}
#endif
/*
@@ -687,8 +688,7 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \
- 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 a27e9e92cb5e..41fc61264443 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -759,7 +759,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
*/
static void sn_sal_console_write(struct console *, const char *, unsigned);
-static int __init sn_sal_console_setup(struct console *, char *);
+static int sn_sal_console_setup(struct console *, char *);
static struct uart_driver sal_console_uart;
extern struct tty_driver *uart_console_device(struct console *, int *);
@@ -1006,7 +1006,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
* here so providing it is easier.
*
*/
-static int __init sn_sal_console_setup(struct console *co, char *options)
+static int sn_sal_console_setup(struct console *co, char *options)
{
return 0;
}
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index b45ba5392dd3..70a09a3d5af0 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -16,9 +16,10 @@
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/serial_core.h>
#include <linux/init.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
#include "suncore.h"
@@ -26,92 +27,60 @@ int sunserial_current_minor = 64;
EXPORT_SYMBOL(sunserial_current_minor);
-void
-sunserial_console_termios(struct console *con)
+int sunserial_console_match(struct console *con, struct device_node *dp,
+ struct uart_driver *drv, int line)
{
- char mode[16], buf[16], *s;
- char mode_prop[] = "ttyX-mode";
- char cd_prop[] = "ttyX-ignore-cd";
- char dtr_prop[] = "ttyX-rts-dtr-off";
- char *ssp_console_modes_prop = "ssp-console-modes";
- int baud, bits, stop, cflag;
- char parity;
- int carrier = 0;
- int rtsdtr = 1;
- int topnd, nd;
-
- if (!serial_console)
- return;
-
- switch (serial_console) {
- case PROMDEV_OTTYA:
- mode_prop[3] = 'a';
- cd_prop[3] = 'a';
- dtr_prop[3] = 'a';
- break;
-
- case PROMDEV_OTTYB:
- mode_prop[3] = 'b';
- cd_prop[3] = 'b';
- dtr_prop[3] = 'b';
- break;
-
- case PROMDEV_ORSC:
-
- nd = prom_pathtoinode("rsc");
- if (!nd) {
- strcpy(mode, "115200,8,n,1,-");
- goto no_options;
- }
+ int off;
- if (!prom_node_has_property(nd, ssp_console_modes_prop)) {
- strcpy(mode, "115200,8,n,1,-");
- goto no_options;
- }
+ if (!con || of_console_device != dp)
+ return 0;
- memset(mode, 0, sizeof(mode));
- prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode));
- goto no_options;
+ off = 0;
+ if (of_console_options &&
+ *of_console_options == 'b')
+ off = 1;
- default:
- strcpy(mode, "9600,8,n,1,-");
- goto no_options;
- }
+ if ((line & 1) != off)
+ return 0;
- topnd = prom_getchild(prom_root_node);
- nd = prom_searchsiblings(topnd, "options");
- if (!nd) {
- strcpy(mode, "9600,8,n,1,-");
- goto no_options;
- }
-
- if (!prom_node_has_property(nd, mode_prop)) {
- strcpy(mode, "9600,8,n,1,-");
- goto no_options;
- }
+ con->index = line;
+ drv->cons = con;
+ add_preferred_console(con->name, line, NULL);
- memset(mode, 0, sizeof(mode));
- prom_getstring(nd, mode_prop, mode, sizeof(mode));
-
- if (prom_node_has_property(nd, cd_prop)) {
- memset(buf, 0, sizeof(buf));
- prom_getstring(nd, cd_prop, buf, sizeof(buf));
- if (!strcmp(buf, "false"))
- carrier = 1;
-
- /* XXX: this is unused below. */
- }
+ return 1;
+}
+EXPORT_SYMBOL(sunserial_console_match);
- if (prom_node_has_property(nd, dtr_prop)) {
- memset(buf, 0, sizeof(buf));
- prom_getstring(nd, dtr_prop, buf, sizeof(buf));
- if (!strcmp(buf, "false"))
- rtsdtr = 0;
+void
+sunserial_console_termios(struct console *con)
+{
+ struct device_node *dp;
+ const char *od, *mode, *s;
+ char mode_prop[] = "ttyX-mode";
+ int baud, bits, stop, cflag;
+ char parity;
- /* XXX: this is unused below. */
+ dp = of_find_node_by_path("/options");
+ od = of_get_property(dp, "output-device", NULL);
+ if (!strcmp(od, "rsc")) {
+ mode = of_get_property(of_console_device,
+ "ssp-console-modes", NULL);
+ if (!mode)
+ mode = "115200,8,n,1,-";
+ } else {
+ char c;
+
+ c = 'a';
+ if (of_console_options)
+ c = *of_console_options;
+
+ mode_prop[3] = c;
+
+ mode = of_get_property(dp, mode_prop, NULL);
+ if (!mode)
+ mode = "9600,8,n,1,-";
}
-no_options:
cflag = CREAD | HUPCL | CLOCAL;
s = mode;
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h
index 513916a8ce37..829d7d65d6db 100644
--- a/drivers/serial/suncore.h
+++ b/drivers/serial/suncore.h
@@ -24,6 +24,8 @@ extern int suncore_mouse_baud_detection(unsigned char, int);
extern int sunserial_current_minor;
+extern int sunserial_console_match(struct console *, struct device_node *,
+ struct uart_driver *, int);
extern void sunserial_console_termios(struct console *);
#endif /* !(_SERIAL_SUN_H) */
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 17bcca53d6a1..8ff900b09811 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -258,17 +258,7 @@ static void sunhv_stop_tx(struct uart_port *port)
/* port->lock held by caller. */
static void sunhv_start_tx(struct uart_port *port)
{
- struct circ_buf *xmit = &port->info->xmit;
-
- while (!uart_circ_empty(xmit)) {
- long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
-
- if (status != HV_EOK)
- break;
-
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- port->icount.tx++;
- }
+ transmit_chars(port);
}
/* port->lock is not held. */
@@ -530,16 +520,6 @@ static struct console sunhv_console = {
.data = &sunhv_reg,
};
-static inline struct console *SUNHV_CONSOLE(void)
-{
- if (con_is_present())
- return NULL;
-
- sunhv_console.index = 0;
-
- return &sunhv_console;
-}
-
static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match)
{
struct uart_port *port;
@@ -592,7 +572,8 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64;
sunserial_current_minor += 1;
- sunhv_reg.cons = SUNHV_CONSOLE();
+ sunserial_console_match(&sunhv_console, op->node,
+ &sunhv_reg, port->line);
err = uart_add_one_port(&sunhv_reg, port);
if (err)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 8a0f9e4408d4..ff610c23314b 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -38,7 +38,7 @@
#include <asm/prom.h>
#include <asm/of_device.h>
-#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#if defined(CONFIG_SERIAL_SUNSAB_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif
@@ -58,6 +58,7 @@ struct uart_sunsab_port {
unsigned char interrupt_mask1;/* ISR1 masking */
unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */
unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */
+ unsigned int gis_shift;
int type; /* SAB82532 version */
/* Setting configuration bits while the transmitter is active
@@ -305,13 +306,15 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
struct tty_struct *tty;
union sab82532_irq_status status;
unsigned long flags;
+ unsigned char gis;
spin_lock_irqsave(&up->port.lock, flags);
status.stat = 0;
- if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA0)
+ gis = readb(&up->regs->r.gis) >> up->gis_shift;
+ if (gis & 1)
status.sreg.isr0 = readb(&up->regs->r.isr0);
- if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA1)
+ if (gis & 2)
status.sreg.isr1 = readb(&up->regs->r.isr1);
tty = NULL;
@@ -327,35 +330,6 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
transmit_chars(up, &status);
}
- spin_unlock(&up->port.lock);
-
- if (tty)
- tty_flip_buffer_push(tty);
-
- up++;
-
- spin_lock(&up->port.lock);
-
- status.stat = 0;
- if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB0)
- status.sreg.isr0 = readb(&up->regs->r.isr0);
- if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB1)
- status.sreg.isr1 = readb(&up->regs->r.isr1);
-
- tty = NULL;
- if (status.stat) {
- if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
- SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) ||
- (status.sreg.isr1 & SAB82532_ISR1_BRK))
-
- tty = receive_chars(up, &status);
- if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
- (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC)))
- check_status(up, &status);
- if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
- transmit_chars(up, &status);
- }
-
spin_unlock_irqrestore(&up->port.lock, flags);
if (tty)
@@ -539,6 +513,10 @@ static int sunsab_startup(struct uart_port *port)
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
unsigned long flags;
unsigned char tmp;
+ int err = request_irq(up->port.irq, sunsab_interrupt,
+ IRQF_SHARED, "sab", up);
+ if (err)
+ return err;
spin_lock_irqsave(&up->port.lock, flags);
@@ -641,6 +619,7 @@ static void sunsab_shutdown(struct uart_port *port)
#endif
spin_unlock_irqrestore(&up->port.lock, flags);
+ free_irq(up->port.irq, up);
}
/*
@@ -968,22 +947,6 @@ static struct console sunsab_console = {
static inline struct console *SUNSAB_CONSOLE(void)
{
- int i;
-
- if (con_is_present())
- return NULL;
-
- for (i = 0; i < num_channels; i++) {
- int this_minor = sunsab_reg.minor + i;
-
- if ((this_minor - 64) == (serial_console - 1))
- break;
- }
- if (i == num_channels)
- return NULL;
-
- sunsab_console.index = i;
-
return &sunsab_console;
}
#else
@@ -1024,9 +987,11 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
if ((up->port.line & 0x1) == 0) {
up->pvr_dsr_bit = (1 << 0);
up->pvr_dtr_bit = (1 << 1);
+ up->gis_shift = 2;
} else {
up->pvr_dsr_bit = (1 << 3);
up->pvr_dtr_bit = (1 << 2);
+ up->gis_shift = 0;
}
up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4);
writeb(up->cached_pvr, &up->regs->w.pvr);
@@ -1039,19 +1004,6 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
- if (!(up->port.line & 0x01)) {
- int err;
-
- err = request_irq(up->port.irq, sunsab_interrupt,
- IRQF_SHARED, "sab", up);
- if (err) {
- of_iounmap(&op->resource[0],
- up->port.membase,
- sizeof(union sab82532_async_regs));
- return err;
- }
- }
-
return 0;
}
@@ -1067,47 +1019,60 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
0,
(inst * 2) + 0);
if (err)
- return err;
+ goto out;
err = sunsab_init_one(&up[1], op,
sizeof(union sab82532_async_regs),
(inst * 2) + 1);
- if (err) {
- of_iounmap(&op->resource[0],
- up[0].port.membase,
- sizeof(union sab82532_async_regs));
- free_irq(up[0].port.irq, &up[0]);
- return err;
- }
+ if (err)
+ goto out1;
+
+ sunserial_console_match(SUNSAB_CONSOLE(), op->node,
+ &sunsab_reg, up[0].port.line);
- uart_add_one_port(&sunsab_reg, &up[0].port);
- uart_add_one_port(&sunsab_reg, &up[1].port);
+ sunserial_console_match(SUNSAB_CONSOLE(), op->node,
+ &sunsab_reg, up[1].port.line);
+
+ err = uart_add_one_port(&sunsab_reg, &up[0].port);
+ if (err)
+ goto out2;
+
+ err = uart_add_one_port(&sunsab_reg, &up[1].port);
+ if (err)
+ goto out3;
dev_set_drvdata(&op->dev, &up[0]);
inst++;
return 0;
-}
-static void __devexit sab_remove_one(struct uart_sunsab_port *up)
-{
- struct of_device *op = to_of_device(up->port.dev);
-
- uart_remove_one_port(&sunsab_reg, &up->port);
- if (!(up->port.line & 1))
- free_irq(up->port.irq, up);
+out3:
+ uart_remove_one_port(&sunsab_reg, &up[0].port);
+out2:
+ of_iounmap(&op->resource[0],
+ up[1].port.membase,
+ sizeof(union sab82532_async_regs));
+out1:
of_iounmap(&op->resource[0],
- up->port.membase,
+ up[0].port.membase,
sizeof(union sab82532_async_regs));
+out:
+ return err;
}
static int __devexit sab_remove(struct of_device *op)
{
struct uart_sunsab_port *up = dev_get_drvdata(&op->dev);
- sab_remove_one(&up[0]);
- sab_remove_one(&up[1]);
+ uart_remove_one_port(&sunsab_reg, &up[1].port);
+ uart_remove_one_port(&sunsab_reg, &up[0].port);
+ of_iounmap(&op->resource[0],
+ up[1].port.membase,
+ sizeof(union sab82532_async_regs));
+ of_iounmap(&op->resource[0],
+ up[0].port.membase,
+ sizeof(union sab82532_async_regs));
dev_set_drvdata(&op->dev, NULL);
@@ -1154,6 +1119,7 @@ static int __init sunsab_init(void)
sunsab_reg.minor = sunserial_current_minor;
sunsab_reg.nr = num_channels;
+ sunsab_reg.cons = SUNSAB_CONSOLE();
err = uart_register_driver(&sunsab_reg);
if (err) {
@@ -1164,7 +1130,6 @@ static int __init sunsab_init(void)
}
sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
- sunsab_reg.cons = SUNSAB_CONSOLE();
sunserial_current_minor += num_channels;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 26d720baf88c..e074943feff5 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1198,10 +1198,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
if (up->port.type == PORT_UNKNOWN)
return -ENODEV;
- printk("%s: %s port at %lx, irq %u\n",
+ printk("%s: %s port at %llx, irq %u\n",
to_of_device(up->port.dev)->node->full_name,
(up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
- up->port.mapbase, up->port.irq);
+ (unsigned long long) up->port.mapbase,
+ up->port.irq);
#ifdef CONFIG_SERIO
serio = &up->serio;
@@ -1371,28 +1372,12 @@ static struct console sunsu_console = {
* Register console.
*/
-static inline struct console *SUNSU_CONSOLE(int num_uart)
+static inline struct console *SUNSU_CONSOLE(void)
{
- int i;
-
- if (con_is_present())
- return NULL;
-
- for (i = 0; i < num_uart; i++) {
- int this_minor = sunsu_reg.minor + i;
-
- if ((this_minor - 64) == (serial_console - 1))
- break;
- }
- if (i == num_uart)
- return NULL;
-
- sunsu_console.index = i;
-
return &sunsu_console;
}
#else
-#define SUNSU_CONSOLE(num_uart) (NULL)
+#define SUNSU_CONSOLE() (NULL)
#define sunsu_serial_console_init() do { } while (0)
#endif
@@ -1482,6 +1467,8 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
up->port.ops = &sunsu_pops;
+ sunserial_console_match(SUNSU_CONSOLE(), dp,
+ &sunsu_reg, up->port.line);
err = uart_add_one_port(&sunsu_reg, &up->port);
if (err)
goto out_unmap;
@@ -1572,7 +1559,6 @@ static int __init sunsu_init(void)
return err;
sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
sunserial_current_minor += num_uart;
- sunsu_reg.cons = SUNSU_CONSOLE(num_uart);
}
err = of_register_driver(&su_driver, &of_bus_type);
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 0a3e10a4a35d..283bef0d24cb 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1226,23 +1226,6 @@ static struct console sunzilog_console_ops = {
static inline struct console *SUNZILOG_CONSOLE(void)
{
- int i;
-
- if (con_is_present())
- return NULL;
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- int this_minor = sunzilog_reg.minor + i;
-
- if ((this_minor - 64) == (serial_console - 1))
- break;
- }
- if (i == NUM_CHANNELS)
- return NULL;
-
- sunzilog_console_ops.index = i;
- sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
-
return &sunzilog_console_ops;
}
@@ -1428,12 +1411,18 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
sunzilog_init_hw(&up[1]);
if (!keyboard_mouse) {
+ if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
+ &sunzilog_reg, up[0].port.line))
+ up->flags |= SUNZILOG_FLAG_IS_CONS;
err = uart_add_one_port(&sunzilog_reg, &up[0].port);
if (err) {
of_iounmap(&op->resource[0],
rp, sizeof(struct zilog_layout));
return err;
}
+ if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
+ &sunzilog_reg, up[1].port.line))
+ up->flags |= SUNZILOG_FLAG_IS_CONS;
err = uart_add_one_port(&sunzilog_reg, &up[1].port);
if (err) {
uart_remove_one_port(&sunzilog_reg, &up[0].port);
@@ -1442,14 +1431,16 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
return err;
}
} else {
- printk(KERN_INFO "%s: Keyboard at MMIO 0x%lx (irq = %d) "
+ printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id, up[0].port.mapbase, op->irqs[0],
- sunzilog_type (&up[0].port));
- printk(KERN_INFO "%s: Mouse at MMIO 0x%lx (irq = %d) "
+ op->dev.bus_id,
+ (unsigned long long) up[0].port.mapbase,
+ op->irqs[0], sunzilog_type(&up[0].port));
+ printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id, up[1].port.mapbase, op->irqs[0],
- sunzilog_type (&up[1].port));
+ op->dev.bus_id,
+ (unsigned long long) up[1].port.mapbase,
+ op->irqs[0], sunzilog_type(&up[1].port));
}
dev_set_drvdata(&op->dev, &up[0]);
@@ -1531,7 +1522,6 @@ static int __init sunzilog_init(void)
goto out_free_tables;
sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
- sunzilog_reg.cons = SUNZILOG_CONSOLE();
sunserial_current_minor += uart_count;
}
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index cf0e663b42ed..6fd51b0022ca 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -1,7 +1,7 @@
/*
* Driver for NEC VR4100 series Serial Interface Unit.
*
- * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ * Copyright (C) 2004-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
*
* Based on drivers/serial/8250.c, by Russell King.
*
@@ -25,12 +25,12 @@
#endif
#include <linux/console.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/ioport.h>
+#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/ioport.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
@@ -38,11 +38,9 @@
#include <linux/tty_flip.h>
#include <asm/io.h>
-#include <asm/vr41xx/irq.h>
#include <asm/vr41xx/siu.h>
#include <asm/vr41xx/vr41xx.h>
-#define SIU_PORTS_MAX 2
#define SIU_BAUD_BASE 1152000
#define SIU_MAJOR 204
#define SIU_MINOR_BASE 82
@@ -60,33 +58,16 @@
#define IRUSESEL 0x02
#define SIRSEL 0x01
-struct siu_port {
- unsigned int type;
- unsigned int irq;
- unsigned long start;
-};
-
-static const struct siu_port siu_type1_ports[] = {
- { .type = PORT_VR41XX_SIU,
- .irq = SIU_IRQ,
- .start = 0x0c000000UL, },
-};
-
-#define SIU_TYPE1_NR_PORTS (sizeof(siu_type1_ports) / sizeof(struct siu_port))
-
-static const struct siu_port siu_type2_ports[] = {
- { .type = PORT_VR41XX_SIU,
- .irq = SIU_IRQ,
- .start = 0x0f000800UL, },
- { .type = PORT_VR41XX_DSIU,
- .irq = DSIU_IRQ,
- .start = 0x0f000820UL, },
+static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
+ [0 ... SIU_PORTS_MAX-1] = {
+ .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
+ .irq = -1,
+ },
};
-#define SIU_TYPE2_NR_PORTS (sizeof(siu_type2_ports) / sizeof(struct siu_port))
-
-static struct uart_port siu_uart_ports[SIU_PORTS_MAX];
+#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
static uint8_t lsr_break_flag[SIU_PORTS_MAX];
+#endif
#define siu_read(port, offset) readb((port)->membase + (offset))
#define siu_write(port, offset, value) writeb((value), (port)->membase + (offset))
@@ -110,7 +91,6 @@ void vr41xx_select_siu_interface(siu_interface_t interface)
spin_unlock_irqrestore(&port->lock, flags);
}
-
EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface);
void vr41xx_use_irda(irda_use_t use)
@@ -132,7 +112,6 @@ void vr41xx_use_irda(irda_use_t use)
spin_unlock_irqrestore(&port->lock, flags);
}
-
EXPORT_SYMBOL_GPL(vr41xx_use_irda);
void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
@@ -166,7 +145,6 @@ void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
spin_unlock_irqrestore(&port->lock, flags);
}
-
EXPORT_SYMBOL_GPL(vr41xx_select_irda_module);
static inline void siu_clear_fifo(struct uart_port *port)
@@ -177,21 +155,6 @@ static inline void siu_clear_fifo(struct uart_port *port)
siu_write(port, UART_FCR, 0);
}
-static inline int siu_probe_ports(void)
-{
- switch (current_cpu_data.cputype) {
- case CPU_VR4111:
- case CPU_VR4121:
- return SIU_TYPE1_NR_PORTS;
- case CPU_VR4122:
- case CPU_VR4131:
- case CPU_VR4133:
- return SIU_TYPE2_NR_PORTS;
- }
-
- return 0;
-}
-
static inline unsigned long siu_port_size(struct uart_port *port)
{
switch (port->type) {
@@ -206,21 +169,10 @@ static inline unsigned long siu_port_size(struct uart_port *port)
static inline unsigned int siu_check_type(struct uart_port *port)
{
- switch (current_cpu_data.cputype) {
- case CPU_VR4111:
- case CPU_VR4121:
- if (port->line == 0)
- return PORT_VR41XX_SIU;
- break;
- case CPU_VR4122:
- case CPU_VR4131:
- case CPU_VR4133:
- if (port->line == 0)
- return PORT_VR41XX_SIU;
- else if (port->line == 1)
- return PORT_VR41XX_DSIU;
- break;
- }
+ if (port->line == 0)
+ return PORT_VR41XX_SIU;
+ if (port->line == 1 && port->irq != -1)
+ return PORT_VR41XX_DSIU;
return PORT_UNKNOWN;
}
@@ -751,44 +703,34 @@ static struct uart_ops siu_uart_ops = {
.verify_port = siu_verify_port,
};
-static int siu_init_ports(void)
+static int siu_init_ports(struct platform_device *pdev)
{
- const struct siu_port *siu;
struct uart_port *port;
- int i, num;
+ struct resource *res;
+ int *type = pdev->dev.platform_data;
+ int i;
- switch (current_cpu_data.cputype) {
- case CPU_VR4111:
- case CPU_VR4121:
- siu = siu_type1_ports;
- break;
- case CPU_VR4122:
- case CPU_VR4131:
- case CPU_VR4133:
- siu = siu_type2_ports;
- break;
- default:
+ if (!type)
return 0;
- }
port = siu_uart_ports;
- num = siu_probe_ports();
- for (i = 0; i < num; i++) {
- spin_lock_init(&port->lock);
- port->irq = siu->irq;
+ for (i = 0; i < SIU_PORTS_MAX; i++) {
+ port->type = type[i];
+ if (port->type == PORT_UNKNOWN)
+ continue;
+ port->irq = platform_get_irq(pdev, i);
port->uartclk = SIU_BAUD_BASE * 16;
port->fifosize = 16;
port->regshift = 0;
port->iotype = UPIO_MEM;
port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
- port->type = siu->type;
port->line = i;
- port->mapbase = siu->start;
- siu++;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ port->mapbase = res->start;
port++;
}
- return num;
+ return i;
}
#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
@@ -842,7 +784,7 @@ static void siu_console_write(struct console *con, const char *s, unsigned count
siu_write(port, UART_IER, ier);
}
-static int siu_console_setup(struct console *con, char *options)
+static int __init siu_console_setup(struct console *con, char *options)
{
struct uart_port *port;
int baud = 9600;
@@ -860,7 +802,8 @@ static int siu_console_setup(struct console *con, char *options)
port->membase = ioremap(port->mapbase, siu_port_size(port));
}
- vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
+ if (port->type == PORT_VR41XX_SIU)
+ vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
if (options != NULL)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -883,13 +826,9 @@ static struct console siu_console = {
static int __devinit siu_console_init(void)
{
struct uart_port *port;
- int num, i;
-
- num = siu_init_ports();
- if (num <= 0)
- return -ENODEV;
+ int i;
- for (i = 0; i < num; i++) {
+ for (i = 0; i < SIU_PORTS_MAX; i++) {
port = &siu_uart_ports[i];
port->ops = &siu_uart_ops;
}
@@ -920,7 +859,7 @@ static int __devinit siu_probe(struct platform_device *dev)
struct uart_port *port;
int num, i, retval;
- num = siu_init_ports();
+ num = siu_init_ports(dev);
if (num <= 0)
return -ENODEV;
@@ -998,8 +937,6 @@ static int siu_resume(struct platform_device *dev)
return 0;
}
-static struct platform_device *siu_platform_device;
-
static struct platform_driver siu_device_driver = {
.probe = siu_probe,
.remove = __devexit_p(siu_remove),
@@ -1013,29 +950,12 @@ static struct platform_driver siu_device_driver = {
static int __init vr41xx_siu_init(void)
{
- int retval;
-
- siu_platform_device = platform_device_alloc("SIU", -1);
- if (!siu_platform_device)
- return -ENOMEM;
-
- retval = platform_device_add(siu_platform_device);
- if (retval < 0) {
- platform_device_put(siu_platform_device);
- return retval;
- }
-
- retval = platform_driver_register(&siu_device_driver);
- if (retval < 0)
- platform_device_unregister(siu_platform_device);
-
- return retval;
+ return platform_driver_register(&siu_device_driver);
}
static void __exit vr41xx_siu_exit(void)
{
platform_driver_unregister(&siu_device_driver);
- platform_device_unregister(siu_platform_device);
}
module_init(vr41xx_siu_init);