summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/68328serial.c7
-rw-r--r--drivers/serial/8250.c122
-rw-r--r--drivers/serial/8250.h1
-rw-r--r--drivers/serial/8250_au1x00.c102
-rw-r--r--drivers/serial/8250_early.c2
-rw-r--r--drivers/serial/8250_gsc.c6
-rw-r--r--drivers/serial/8250_pci.c28
-rw-r--r--drivers/serial/8250_pnp.c6
-rw-r--r--drivers/serial/Kconfig10
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/amba-pl010.c1
-rw-r--r--drivers/serial/amba-pl011.c46
-rw-r--r--drivers/serial/clps711x.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c2
-rw-r--r--drivers/serial/crisv10.c9
-rw-r--r--drivers/serial/dz.c48
-rw-r--r--drivers/serial/imx.c88
-rw-r--r--drivers/serial/ioc4_serial.c92
-rw-r--r--drivers/serial/mcfserial.c37
-rw-r--r--drivers/serial/mpc52xx_uart.c42
-rw-r--r--drivers/serial/mpsc.c69
-rw-r--r--drivers/serial/mux.c30
-rw-r--r--drivers/serial/pxa.c62
-rw-r--r--drivers/serial/s3c2410.c75
-rw-r--r--drivers/serial/sa1100.c43
-rw-r--r--drivers/serial/serial_core.c94
-rw-r--r--drivers/serial/serial_cs.c7
-rw-r--r--drivers/serial/sh-sci.c2
-rw-r--r--drivers/serial/sunsab.c1
-rw-r--r--drivers/serial/sunsu.c6
-rw-r--r--drivers/serial/sunzilog.c5
-rw-r--r--drivers/serial/vr41xx_siu.c35
34 files changed, 689 insertions, 396 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 2efb317153ce..67e9afa000c1 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -34,6 +34,7 @@
#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>
@@ -1343,7 +1344,7 @@ static void show_serial_version(void)
printk("MC68328 serial driver version 1.00\n");
}
-#ifdef CONFIG_PM
+#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
@@ -1393,7 +1394,7 @@ void startup_console(void)
struct m68k_serial *info = &m68k_soft[0];
startup(info);
}
-#endif
+#endif /* CONFIG_PM_LEGACY */
static struct tty_operations rs_ops = {
@@ -1486,7 +1487,7 @@ rs68328_init(void)
IRQ_FLG_STD,
"M68328_UART", NULL))
panic("Unable to attach 68328 serial interrupt\n");
-#ifdef CONFIG_PM
+#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;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d75cdfa0a0a..d2bcd1f87cd6 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -33,13 +33,14 @@
#include <linux/sysrq.h>
#include <linux/mca.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_reg.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
+#include <linux/nmi.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -101,7 +102,7 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
#define SERIAL_PORT_DFNS
#endif
-static struct old_serial_port old_serial_port[] = {
+static const struct old_serial_port old_serial_port[] = {
SERIAL_PORT_DFNS /* defined in asm/serial.h */
};
@@ -251,9 +252,53 @@ static const struct serial8250_config uart_config[] = {
},
};
+#ifdef CONFIG_SERIAL_8250_AU1X00
+
+/* Au1x00 UART hardware has a weird register layout */
+static const u8 au_io_in_map[] = {
+ [UART_RX] = 0,
+ [UART_IER] = 2,
+ [UART_IIR] = 3,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+ [UART_LSR] = 7,
+ [UART_MSR] = 8,
+};
+
+static const u8 au_io_out_map[] = {
+ [UART_TX] = 1,
+ [UART_IER] = 2,
+ [UART_FCR] = 4,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+};
+
+/* sane hardware needs no mapping */
+static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
+{
+ if (up->port.iotype != UPIO_AU)
+ return offset;
+ return au_io_in_map[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
+{
+ if (up->port.iotype != UPIO_AU)
+ return offset;
+ return au_io_out_map[offset];
+}
+
+#else
+
+/* sane hardware needs no mapping */
+#define map_8250_in_reg(up, offset) (offset)
+#define map_8250_out_reg(up, offset) (offset)
+
+#endif
+
static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
{
- offset <<= up->port.regshift;
+ offset = map_8250_in_reg(up, offset) << up->port.regshift;
switch (up->port.iotype) {
case UPIO_HUB6:
@@ -266,6 +311,11 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
case UPIO_MEM32:
return readl(up->port.membase + offset);
+#ifdef CONFIG_SERIAL_8250_AU1X00
+ case UPIO_AU:
+ return __raw_readl(up->port.membase + offset);
+#endif
+
default:
return inb(up->port.iobase + offset);
}
@@ -274,7 +324,7 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
static _INLINE_ void
serial_out(struct uart_8250_port *up, int offset, int value)
{
- offset <<= up->port.regshift;
+ offset = map_8250_out_reg(up, offset) << up->port.regshift;
switch (up->port.iotype) {
case UPIO_HUB6:
@@ -290,6 +340,12 @@ serial_out(struct uart_8250_port *up, int offset, int value)
writel(value, up->port.membase + offset);
break;
+#ifdef CONFIG_SERIAL_8250_AU1X00
+ case UPIO_AU:
+ __raw_writel(value, up->port.membase + offset);
+ break;
+#endif
+
default:
outb(value, up->port.iobase + offset);
}
@@ -910,6 +966,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
}
}
#endif
+
+#ifdef CONFIG_SERIAL_8250_AU1X00
+ /* if access method is AU, it is a 16550 with a quirk */
+ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
+ up->bugs |= UART_BUG_NOMSR;
+#endif
+
serial_outp(up, UART_LCR, save_lcr);
if (up->capabilities != uart_config[up->port.type].flags) {
@@ -936,7 +999,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
serial_outp(up, UART_MCR, save_mcr);
serial8250_clear_fifos(up);
(void)serial_in(up, UART_RX);
- serial_outp(up, UART_IER, 0);
+ if (up->capabilities & UART_CAP_UUE)
+ serial_outp(up, UART_IER, UART_IER_UUE);
+ else
+ serial_outp(up, UART_IER, 0);
out:
spin_unlock_irqrestore(&up->port.lock, flags);
@@ -1057,6 +1123,10 @@ static void serial8250_enable_ms(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
+ /* no MSR capabilities */
+ if (up->bugs & UART_BUG_NOMSR)
+ return;
+
up->ier |= UART_IER_MSI;
serial_out(up, UART_IER, up->ier);
}
@@ -1774,7 +1844,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
* CTS flow control flag and modem status interrupts
*/
up->ier &= ~UART_IER_MSI;
- if (UART_ENABLE_MS(&up->port, termios->c_cflag))
+ if (!(up->bugs & UART_BUG_NOMSR) &&
+ UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;
if (up->capabilities & UART_CAP_UUE)
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
@@ -2141,6 +2212,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
unsigned int ier;
int i;
+ touch_nmi_watchdog();
+
/*
* First save the UER then disable the interrupts
*/
@@ -2311,9 +2384,9 @@ void serial8250_resume_port(int line)
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
*/
-static int __devinit serial8250_probe(struct device *dev)
+static int __devinit serial8250_probe(struct platform_device *dev)
{
- struct plat_serial8250_port *p = dev->platform_data;
+ struct plat_serial8250_port *p = dev->dev.platform_data;
struct uart_port port;
int ret, i;
@@ -2329,12 +2402,12 @@ static int __devinit serial8250_probe(struct device *dev)
port.flags = p->flags;
port.mapbase = p->mapbase;
port.hub6 = p->hub6;
- port.dev = dev;
+ port.dev = &dev->dev;
if (share_irqs)
port.flags |= UPF_SHARE_IRQ;
ret = serial8250_register_port(&port);
if (ret < 0) {
- dev_err(dev, "unable to register port at index %d "
+ 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);
}
@@ -2345,60 +2418,55 @@ static int __devinit serial8250_probe(struct device *dev)
/*
* Remove serial ports registered against a platform device.
*/
-static int __devexit serial8250_remove(struct device *dev)
+static int __devexit serial8250_remove(struct platform_device *dev)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
- if (up->port.dev == dev)
+ if (up->port.dev == &dev->dev)
serial8250_unregister_port(i);
}
return 0;
}
-static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
+static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
{
int i;
- if (level != SUSPEND_DISABLE)
- return 0;
-
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
- if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
uart_suspend_port(&serial8250_reg, &up->port);
}
return 0;
}
-static int serial8250_resume(struct device *dev, u32 level)
+static int serial8250_resume(struct platform_device *dev)
{
int i;
- if (level != RESUME_ENABLE)
- return 0;
-
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
- if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
uart_resume_port(&serial8250_reg, &up->port);
}
return 0;
}
-static struct device_driver serial8250_isa_driver = {
- .name = "serial8250",
- .bus = &platform_bus_type,
+static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe,
.remove = __devexit_p(serial8250_remove),
.suspend = serial8250_suspend,
.resume = serial8250_resume,
+ .driver = {
+ .name = "serial8250",
+ },
};
/*
@@ -2544,7 +2612,7 @@ static int __init serial8250_init(void)
serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
- ret = driver_register(&serial8250_isa_driver);
+ ret = platform_driver_register(&serial8250_isa_driver);
if (ret == 0)
goto out;
@@ -2566,7 +2634,7 @@ static void __exit serial8250_exit(void)
*/
serial8250_isa_devs = NULL;
- driver_unregister(&serial8250_isa_driver);
+ platform_driver_unregister(&serial8250_isa_driver);
platform_device_unregister(isa_dev);
uart_unregister_driver(&serial8250_reg);
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index b1b459efda52..a607b98016db 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -49,6 +49,7 @@ struct serial8250_config {
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
+#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
#define _INLINE_ inline
diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c
new file mode 100644
index 000000000000..06ae8fbcc947
--- /dev/null
+++ b/drivers/serial/8250_au1x00.c
@@ -0,0 +1,102 @@
+/*
+ * Serial Device Initialisation for Au1x00
+ *
+ * (C) Copyright Embedded Alley Solutions, Inc 2005
+ * Author: Pantelis Antoniou <pantelis@embeddedalley.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/serial_core.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/serial_8250.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+#include "8250.h"
+
+#define PORT(_base, _irq) \
+ { \
+ .iobase = _base, \
+ .membase = (void __iomem *)_base,\
+ .mapbase = _base, \
+ .irq = _irq, \
+ .uartclk = 0, /* filled */ \
+ .regshift = 2, \
+ .iotype = UPIO_AU, \
+ .flags = UPF_SKIP_TEST | \
+ UPF_IOREMAP, \
+ }
+
+static struct plat_serial8250_port au1x00_data[] = {
+#if defined(CONFIG_SOC_AU1000)
+ PORT(UART0_ADDR, AU1000_UART0_INT),
+ PORT(UART1_ADDR, AU1000_UART1_INT),
+ PORT(UART2_ADDR, AU1000_UART2_INT),
+ PORT(UART3_ADDR, AU1000_UART3_INT),
+#elif defined(CONFIG_SOC_AU1500)
+ PORT(UART0_ADDR, AU1500_UART0_INT),
+ PORT(UART3_ADDR, AU1500_UART3_INT),
+#elif defined(CONFIG_SOC_AU1100)
+ PORT(UART0_ADDR, AU1100_UART0_INT),
+ PORT(UART1_ADDR, AU1100_UART1_INT),
+ PORT(UART2_ADDR, AU1100_UART2_INT),
+ PORT(UART3_ADDR, AU1100_UART3_INT),
+#elif defined(CONFIG_SOC_AU1550)
+ PORT(UART0_ADDR, AU1550_UART0_INT),
+ PORT(UART1_ADDR, AU1550_UART1_INT),
+ PORT(UART2_ADDR, AU1550_UART2_INT),
+ PORT(UART3_ADDR, AU1550_UART3_INT),
+#elif defined(CONFIG_SOC_AU1200)
+ PORT(UART0_ADDR, AU1200_UART0_INT),
+ PORT(UART1_ADDR, AU1200_UART1_INT),
+#endif
+ { },
+};
+
+static struct platform_device au1x00_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_AU1X00,
+ .dev = {
+ .platform_data = au1x00_data,
+ },
+};
+
+static int __init au1x00_init(void)
+{
+ int i;
+ unsigned int uartclk;
+
+ /* get uart clock */
+ uartclk = get_au1x00_uart_baud_base() * 16;
+
+ /* fill up uartclk */
+ for (i = 0; au1x00_data[i].flags ; i++)
+ au1x00_data[i].uartclk = uartclk;
+
+ return platform_device_register(&au1x00_device);
+}
+
+/* XXX: Yes, I know this doesn't yet work. */
+static void __exit au1x00_exit(void)
+{
+ platform_device_unregister(&au1x00_device);
+}
+
+module_init(au1x00_init);
+module_exit(au1x00_exit);
+
+MODULE_AUTHOR("Pantelis Antoniou <pantelis@embeddedalley.com>");
+MODULE_DESCRIPTION("8250 serial probe module for Au1x000 cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index b7a5dd710228..59ba5d993b4b 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -164,7 +164,7 @@ static int __init parse_options(struct early_uart_device *device, char *options)
if ((options = strchr(options, ','))) {
options++;
- device->baud = simple_strtoul(options, 0, 0);
+ device->baud = simple_strtoul(options, NULL, 0);
length = min(strcspn(options, " "), sizeof(device->options));
strncpy(device->options, options, length);
} else {
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 431aa5761a7a..8b4947933d9b 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -29,7 +29,6 @@
static int __init
serial_init_chip(struct parisc_device *dev)
{
- static int serial_line_nr;
struct uart_port port;
unsigned long address;
int err;
@@ -42,12 +41,13 @@ serial_init_chip(struct parisc_device *dev)
*/
if (parisc_parent(dev)->id.hw_type != HPHW_IOA) {
printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
- "Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
+ "Enable support for Wax, Lasi, Asp or Dino.\n",
+ dev->hpa.start);
}
return -ENODEV;
}
- address = dev->hpa;
+ address = dev->hpa.start;
if (dev->id.sversion != 0x8d) {
address += 0x800;
}
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 0e21f583690e..8d92adfbb8bd 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -152,6 +152,7 @@ static int __devinit pci_hp_diva_init(struct pci_dev *dev)
rc = 4;
break;
case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
+ case PCI_DEVICE_ID_HP_DIVA_HURRICANE:
rc = 1;
break;
}
@@ -226,8 +227,10 @@ static int __devinit pci_plx9050_init(struct pci_dev *dev)
}
irq_config = 0x41;
- if (dev->vendor == PCI_VENDOR_ID_PANACOM)
+ if (dev->vendor == PCI_VENDOR_ID_PANACOM ||
+ dev->subsystem_vendor == PCI_SUBVENDOR_ID_EXSYS) {
irq_config = 0x43;
+ }
if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
(dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
/*
@@ -465,7 +468,7 @@ static unsigned short timedia_eight_port[] = {
0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
};
-static struct timedia_struct {
+static const struct timedia_struct {
int num;
unsigned short *ids;
} timedia_data[] = {
@@ -664,6 +667,15 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
{
.vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9050,
+ .subvendor = PCI_SUBVENDOR_ID_EXSYS,
+ .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_plx9050_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9050,
.subvendor = PCI_SUBVENDOR_ID_KEYSPAN,
.subdevice = PCI_SUBDEVICE_ID_KEYSPAN_SX2,
.init = pci_plx9050_init,
@@ -927,6 +939,7 @@ enum pci_board_num_t {
pbn_panacom,
pbn_panacom2,
pbn_panacom4,
+ pbn_exsys_4055,
pbn_plx_romulus,
pbn_oxsemi,
pbn_intel_i960,
@@ -1292,6 +1305,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.reg_shift = 7,
},
+ [pbn_exsys_4055] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
/* I think this entry is broken - the first_offset looks wrong --rmk */
[pbn_plx_romulus] = {
.flags = FL_BASE2,
@@ -1853,6 +1873,10 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_SUBVENDOR_ID_CHASE_PCIRAS,
PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
pbn_b2_8_460800 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_EXSYS,
+ PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
+ pbn_exsys_4055 },
/*
* Megawolf Romulus PCI Serial Card, from Mike Hudson
* (Exoray@isys.ca)
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 6b321e82cafb..b79ed0665d51 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -272,8 +272,12 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "SUP1421", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1590", 0 },
+ /* SupraExpress 336i Sp ASVD */
+ { "SUP1620", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1760", 0 },
+ /* SupraExpress 56i Sp Intl */
+ { "SUP2171", 0 },
/* Phoebe Micro */
/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
{ "TEX0011", 0 },
@@ -319,6 +323,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "USR9180", 0 },
/* U.S. Robotics 56K Voice INT PnP*/
{ "USR9190", 0 },
+ /* HP Compaq Tablet PC tc1100 Wacom tablet */
+ { "WACF005", 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
{ "WCI0003", 0 },
/* Unkown PnP modems */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b745a1b9e835..ad47c1b84c3f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -207,6 +207,14 @@ config SERIAL_8250_ACORN
system, say Y to this option. The driver can handle 1, 2, or 3 port
cards. If unsure, say N.
+config SERIAL_8250_AU1X00
+ bool "AU1X00 serial port support"
+ depends on SERIAL_8250 != n && SOC_AU1X00
+ help
+ If you have an Au1x00 board and want to use the serial port, say Y
+ to this option. The driver can handle 1 or 2 serial ports.
+ If unsure, say N.
+
comment "Non-8250 serial port support"
config SERIAL_AMBA_PL010
@@ -499,7 +507,7 @@ config SERIAL_SUNSU_CONSOLE
config SERIAL_MUX
tristate "Serial MUX support"
- depends on PARISC
+ depends on GSC
select SERIAL_CORE
default y
---help---
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 11c7dc483f93..d7c7c7180e33 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 679e678c7e6a..ddd0307fece2 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -50,6 +50,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/hardware.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_serial.h>
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 1ff629c74750..89d7bd3eaee3 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -49,7 +49,7 @@
#include <linux/serial.h>
#include <asm/io.h>
-#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
#include <asm/hardware/amba_serial.h>
@@ -62,7 +62,8 @@
#define AMBA_ISR_PASS_LIMIT 256
-#define UART_DUMMY_RSR_RX 256
+#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
+#define UART_DUMMY_DR_RX (1 << 16)
/*
* We wrap our port structure around the generic uart_port.
@@ -115,7 +116,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
#endif
{
struct tty_struct *tty = uap->port.info->tty;
- unsigned int status, ch, flag, rsr, max_count = 256;
+ unsigned int status, ch, flag, max_count = 256;
status = readw(uap->port.membase + UART01x_FR);
while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
@@ -128,7 +129,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
*/
}
- ch = readw(uap->port.membase + UART01x_DR);
+ ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
flag = TTY_NORMAL;
uap->port.icount.rx++;
@@ -136,34 +137,33 @@ pl011_rx_chars(struct uart_amba_port *uap)
* Note that the error handling code is
* out of the main execution path
*/
- rsr = readw(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
- if (unlikely(rsr & UART01x_RSR_ANY)) {
- if (rsr & UART01x_RSR_BE) {
- rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
+ if (unlikely(ch & UART_DR_ERROR)) {
+ if (ch & UART011_DR_BE) {
+ ch &= ~(UART011_DR_FE | UART011_DR_PE);
uap->port.icount.brk++;
if (uart_handle_break(&uap->port))
goto ignore_char;
- } else if (rsr & UART01x_RSR_PE)
+ } else if (ch & UART011_DR_PE)
uap->port.icount.parity++;
- else if (rsr & UART01x_RSR_FE)
+ else if (ch & UART011_DR_FE)
uap->port.icount.frame++;
- if (rsr & UART01x_RSR_OE)
+ if (ch & UART011_DR_OE)
uap->port.icount.overrun++;
- rsr &= uap->port.read_status_mask;
+ ch &= uap->port.read_status_mask;
- if (rsr & UART01x_RSR_BE)
+ if (ch & UART011_DR_BE)
flag = TTY_BREAK;
- else if (rsr & UART01x_RSR_PE)
+ else if (ch & UART011_DR_PE)
flag = TTY_PARITY;
- else if (rsr & UART01x_RSR_FE)
+ else if (ch & UART011_DR_FE)
flag = TTY_FRAME;
}
if (uart_handle_sysrq_char(&uap->port, ch, regs))
goto ignore_char;
- uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
+ uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
ignore_char:
status = readw(uap->port.membase + UART01x_FR);
@@ -475,33 +475,33 @@ pl011_set_termios(struct uart_port *port, struct termios *termios,
*/
uart_update_timeout(port, termios->c_cflag, baud);
- port->read_status_mask = UART01x_RSR_OE;
+ port->read_status_mask = UART011_DR_OE | 255;
if (termios->c_iflag & INPCK)
- port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+ port->read_status_mask |= UART011_DR_FE | UART011_DR_PE;
if (termios->c_iflag & (BRKINT | PARMRK))
- port->read_status_mask |= UART01x_RSR_BE;
+ port->read_status_mask |= UART011_DR_BE;
/*
* Characters to ignore
*/
port->ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+ port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE;
if (termios->c_iflag & IGNBRK) {
- port->ignore_status_mask |= UART01x_RSR_BE;
+ port->ignore_status_mask |= UART011_DR_BE;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UART01x_RSR_OE;
+ port->ignore_status_mask |= UART011_DR_OE;
}
/*
* Ignore all characters if CREAD is not set.
*/
if ((termios->c_cflag & CREAD) == 0)
- port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+ port->ignore_status_mask |= UART_DUMMY_DR_RX;
if (UART_ENABLE_MS(port, termios->c_cflag))
pl011_enable_ms(port);
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 78c1f36ad9b7..87ef368384fb 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -98,7 +98,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
{
struct uart_port *port = dev_id;
struct tty_struct *tty = port->info->tty;
- unsigned int status, ch, flg, ignored = 0;
+ unsigned int status, ch, flg;
status = clps_readl(SYSFLG(port));
while (!(status & SYSFLG_URXFE)) {
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 25825f2aba22..987d22b53c22 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -7,7 +7,7 @@
* Based on ppc8xx.c by Thomas Gleixner
* Based on drivers/serial/amba.c by Russell King
*
- * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 4b0786e7eb7f..d789ee55cbb7 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -3,7 +3,7 @@
*
* Driver for CPM (SCC/SMC) serial ports; CPM1 definitions
*
- * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 15ad58d94889..fd9e53ed3feb 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -3,7 +3,7 @@
*
* Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
*
- * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 40d3e7139cfe..08c42c000188 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4416,10 +4416,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
info->event = 0;
info->tty = 0;
if (info->blocked_open) {
- if (info->close_delay) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(info->close_delay);
- }
+ if (info->close_delay)
+ schedule_timeout_interruptible(info->close_delay);
wake_up_interruptible(&info->open_wait);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -4469,8 +4467,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
while (info->xmit.head != info->xmit.tail || /* More in send queue */
(*info->ostatusadr & 0x007f) || /* more in FIFO */
(elapsed_usec < 2*info->char_time_usec)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, orig_jiffies + timeout))
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index e63b9dffc8d7..4d8516d1bb71 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -1,9 +1,9 @@
/*
- * dz.c: Serial port driver for DECStations equiped
+ * dz.c: Serial port driver for DECStations equiped
* with the DZ chipset.
*
- * Copyright (C) 1998 Olivier A. D. Lebaillif
- *
+ * Copyright (C) 1998 Olivier A. D. Lebaillif
+ *
* Email: olivier.lebaillif@ifrsys.com
*
* [31-AUG-98] triemer
@@ -11,14 +11,14 @@
* removed base_addr code - moving address assignment to setup.c
* Changed name of dz_init to rs_init to be consistent with tc code
* [13-NOV-98] triemer fixed code to receive characters
- * after patches by harald to irq code.
+ * after patches by harald to irq code.
* [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
* field from "current" - somewhere between 2.1.121 and 2.1.131
Qua Jun 27 15:02:26 BRT 2001
* [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
- *
- * Parts (C) 1999 David Airlie, airlied@linux.ie
- * [07-SEP-99] Bugfixes
+ *
+ * Parts (C) 1999 David Airlie, airlied@linux.ie
+ * [07-SEP-99] Bugfixes
*
* [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
* Converted to new serial core
@@ -64,7 +64,7 @@ static struct dz_port dz_ports[DZ_NB_PORT];
#ifdef DEBUG_DZ
/*
- * debugging code to send out chars via prom
+ * debugging code to send out chars via prom
*/
static void debug_console(const char *s, int count)
{
@@ -82,7 +82,7 @@ static void debug_console(const char *s, int count)
* ------------------------------------------------------------
* dz_in () and dz_out ()
*
- * These routines are used to access the registers of the DZ
+ * These routines are used to access the registers of the DZ
* chip, hiding relocation differences between implementation.
* ------------------------------------------------------------
*/
@@ -106,8 +106,8 @@ static inline void dz_out(struct dz_port *dport, unsigned offset,
* ------------------------------------------------------------
* rs_stop () and rs_start ()
*
- * These routines are called before setting or resetting
- * tty->stopped. They enable or disable transmitter interrupts,
+ * These routines are called before setting or resetting
+ * tty->stopped. They enable or disable transmitter interrupts,
* as necessary.
* ------------------------------------------------------------
*/
@@ -156,17 +156,17 @@ static void dz_enable_ms(struct uart_port *port)
/*
* ------------------------------------------------------------
- * Here starts the interrupt handling routines. All of the
- * following subroutines are declared as inline and are folded
- * into dz_interrupt. They were separated out for readability's
- * sake.
+ * Here starts the interrupt handling routines. All of the
+ * following subroutines are declared as inline and are folded
+ * into dz_interrupt. They were separated out for readability's
+ * sake.
*
* Note: rs_interrupt() is a "fast" interrupt, which means that it
* runs with interrupts turned off. People who may want to modify
* rs_interrupt() should try to keep the interrupt handler as fast as
* possible. After you are done making modifications, it is not a bad
* idea to do:
- *
+ *
* make drivers/serial/dz.s
*
* and look at the resulting assemble code in dz.s.
@@ -403,7 +403,7 @@ static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
* startup ()
*
* various initialization tasks
- * -------------------------------------------------------------------
+ * -------------------------------------------------------------------
*/
static int dz_startup(struct uart_port *uport)
{
@@ -430,13 +430,13 @@ static int dz_startup(struct uart_port *uport)
return 0;
}
-/*
+/*
* -------------------------------------------------------------------
* shutdown ()
*
* This routine will shutdown a serial port; interrupts are disabled, and
* DTR is dropped if the hangup on close termio flag is on.
- * -------------------------------------------------------------------
+ * -------------------------------------------------------------------
*/
static void dz_shutdown(struct uart_port *uport)
{
@@ -451,7 +451,7 @@ static void dz_shutdown(struct uart_port *uport)
* release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality
- * allows an RS485 driver to be written in user space.
+ * allows an RS485 driver to be written in user space.
*/
static unsigned int dz_tx_empty(struct uart_port *uport)
{
@@ -645,9 +645,9 @@ static void __init dz_init_ports(void)
if (mips_machtype == MACH_DS23100 ||
mips_machtype == MACH_DS5100)
- base = (unsigned long) KN01_DZ11_BASE;
+ base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
else
- base = (unsigned long) KN02_DZ11_BASE;
+ base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11);
for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
spin_lock_init(&dport->port.lock);
@@ -695,13 +695,13 @@ static void dz_console_put_char(struct dz_port *dport, unsigned char ch)
spin_unlock_irqrestore(&dport->port.lock, flags);
}
-/*
+/*
* -------------------------------------------------------------------
* dz_console_print ()
*
* dz_console_print is registered for printk.
* The console must be locked when we get here.
- * -------------------------------------------------------------------
+ * -------------------------------------------------------------------
*/
static void dz_console_print(struct console *cons,
const char *str,
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 4c985e6b3784..83c4c1216587 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -36,7 +36,7 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -73,7 +73,7 @@ struct imx_port {
struct uart_port port;
struct timer_list timer;
unsigned int old_status;
- int txirq,rxirq;
+ int txirq,rxirq,rtsirq;
};
/*
@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)
imx_transmit_buffer(sport);
}
+static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct imx_port *sport = (struct imx_port *)dev_id;
+ unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ USR1((u32)sport->port.membase) = USR1_RTSD;
+ uart_handle_cts_change(&sport->port, !!val);
+ wake_up_interruptible(&sport->port.info->delta_msr_wait);
+
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ return IRQ_HANDLED;
+}
+
static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
{
struct imx_port *sport = (struct imx_port *)dev_id;
@@ -383,18 +399,24 @@ static int imx_startup(struct uart_port *port)
*/
retval = request_irq(sport->rxirq, imx_rxint, 0,
DRIVER_NAME, sport);
- if (retval) goto error_out2;
+ if (retval) goto error_out1;
retval = request_irq(sport->txirq, imx_txint, 0,
- "imx-uart", sport);
- if (retval) goto error_out1;
+ DRIVER_NAME, sport);
+ if (retval) goto error_out2;
+
+ retval = request_irq(sport->rtsirq, imx_rtsint, 0,
+ DRIVER_NAME, sport);
+ if (retval) goto error_out3;
+ set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
/*
* Finally, clear and enable interrupts
*/
+ USR1((u32)sport->port.membase) = USR1_RTSD;
UCR1((u32)sport->port.membase) |=
- (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+ (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
/*
@@ -406,10 +428,11 @@ static int imx_startup(struct uart_port *port)
return 0;
-error_out1:
- free_irq(sport->rxirq, sport);
-error_out2:
+error_out3:
free_irq(sport->txirq, sport);
+error_out2:
+ free_irq(sport->rxirq, sport);
+error_out1:
return retval;
}
@@ -425,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
/*
* Free the interrupts
*/
+ free_irq(sport->rtsirq, sport);
free_irq(sport->txirq, sport);
free_irq(sport->rxirq, sport);
@@ -433,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
*/
UCR1((u32)sport->port.membase) &=
- ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+ ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
}
static void
@@ -523,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
* disable interrupts and drain transmitter
*/
old_ucr1 = UCR1((u32)sport->port.membase);
- UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+ UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
barrier();
@@ -644,6 +668,7 @@ static struct imx_port imx_ports[] = {
{
.txirq = UART1_MINT_TX,
.rxirq = UART1_MINT_RX,
+ .rtsirq = UART1_MINT_RTS,
.port = {
.type = PORT_IMX,
.iotype = SERIAL_IO_MEM,
@@ -659,6 +684,7 @@ static struct imx_port imx_ports[] = {
}, {
.txirq = UART2_MINT_TX,
.rxirq = UART2_MINT_RX,
+ .rtsirq = UART2_MINT_RTS,
.port = {
.type = PORT_IMX,
.iotype = SERIAL_IO_MEM,
@@ -738,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
UCR1((u32)sport->port.membase) =
(old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
- & ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+ & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
/*
@@ -860,7 +886,7 @@ imx_console_setup(struct console *co, char *options)
return uart_set_options(&sport->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver imx_reg;
+static struct uart_driver imx_reg;
static struct console imx_console = {
.name = "ttySMX",
.write = imx_console_write,
@@ -895,41 +921,39 @@ static struct uart_driver imx_reg = {
.cons = IMX_CONSOLE,
};
-static int serial_imx_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
{
- struct imx_port *sport = dev_get_drvdata(_dev);
+ struct imx_port *sport = platform_get_drvdata(dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&imx_reg, &sport->port);
return 0;
}
-static int serial_imx_resume(struct device *_dev, u32 level)
+static int serial_imx_resume(struct platform_device *dev)
{
- struct imx_port *sport = dev_get_drvdata(_dev);
+ struct imx_port *sport = platform_get_drvdata(dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&imx_reg, &sport->port);
return 0;
}
-static int serial_imx_probe(struct device *_dev)
+static int serial_imx_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
-
- imx_ports[dev->id].port.dev = _dev;
+ imx_ports[dev->id].port.dev = &dev->dev;
uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
- dev_set_drvdata(_dev, &imx_ports[dev->id]);
+ platform_set_drvdata(dev, &imx_ports[dev->id]);
return 0;
}
-static int serial_imx_remove(struct device *_dev)
+static int serial_imx_remove(struct platform_device *dev)
{
- struct imx_port *sport = dev_get_drvdata(_dev);
+ struct imx_port *sport = platform_get_drvdata(dev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (sport)
uart_remove_one_port(&imx_reg, &sport->port);
@@ -937,14 +961,15 @@ static int serial_imx_remove(struct device *_dev)
return 0;
}
-static struct device_driver serial_imx_driver = {
- .name = "imx-uart",
- .bus = &platform_bus_type,
+static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
.suspend = serial_imx_suspend,
.resume = serial_imx_resume,
+ .driver = {
+ .name = "imx-uart",
+ },
};
static int __init imx_serial_init(void)
@@ -959,7 +984,7 @@ static int __init imx_serial_init(void)
if (ret)
return ret;
- ret = driver_register(&serial_imx_driver);
+ ret = platform_driver_register(&serial_imx_driver);
if (ret != 0)
uart_unregister_driver(&imx_reg);
@@ -969,6 +994,7 @@ 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);
}
module_init(imx_serial_init);
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 0c5c96a582b3..771676abee60 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -308,6 +308,8 @@ struct ioc4_serial {
typedef void ioc4_intr_func_f(void *, uint32_t);
typedef ioc4_intr_func_f *ioc4_intr_func_t;
+static unsigned int Num_of_ioc4_cards;
+
/* defining this will get you LOTS of great debug info */
//#define DEBUG_INTERRUPTS
#define DPRINT_CONFIG(_x...) ;
@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
#define WAKEUP_CHARS 256
/* number of characters we want to transmit to the lower level at a time */
-#define IOC4_MAX_CHARS 128
+#define IOC4_MAX_CHARS 256
+#define IOC4_FIFO_CHARS 255
/* Device name we're using */
#define DEVICE_NAME "ttyIOC"
@@ -973,18 +976,6 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs)
this_ir &= ~this_mir;
}
}
- if (this_ir) {
- printk(KERN_ERR
- "unknown IOC4 %s interrupt 0x%x, sio_ir = 0x%x,"
- " sio_ies = 0x%x, other_ir = 0x%x :"
- "other_ies = 0x%x\n",
- (intr_type == IOC4_SIO_INTR_TYPE) ? "sio" :
- "other", this_ir,
- readl(&soft->is_ioc4_misc_addr->sio_ir.raw),
- readl(&soft->is_ioc4_misc_addr->sio_ies.raw),
- readl(&soft->is_ioc4_misc_addr->other_ir.raw),
- readl(&soft->is_ioc4_misc_addr->other_ies.raw));
- }
}
#ifdef DEBUG_INTERRUPTS
{
@@ -1050,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
return -ENOMEM;
}
memset(port, 0, sizeof(struct ioc4_port));
+ spin_lock_init(&port->ip_lock);
/* we need to remember the previous ones, to point back to
* them farther down - setting up the ring buffers.
@@ -1703,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
baud = 9600;
if (!the_port->fifosize)
- the_port->fifosize = IOC4_MAX_CHARS;
+ the_port->fifosize = IOC4_FIFO_CHARS;
the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
the_port->timeout += HZ / 50; /* Add .02 seconds of slop */
the_port->ignore_status_mask = N_ALL_INPUT;
+ info->tty->low_latency = 1;
+
if (I_IGNPAR(info->tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
@@ -1754,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
*/
static inline int ic4_startup_local(struct uart_port *the_port)
{
- int retval = 0;
struct ioc4_port *port;
struct uart_info *info;
@@ -1766,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
return -1;
info = the_port->info;
- if (info->flags & UIF_INITIALIZED) {
- return retval;
- }
if (info->tty) {
set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1787,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
/* set the speed of the serial port */
ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
- info->flags |= UIF_INITIALIZED;
return 0;
}
@@ -1797,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
*/
static void ioc4_cb_output_lowat(struct ioc4_port *port)
{
+ unsigned long pflags;
+
/* ip_lock is set on the call here */
if (port->ip_port) {
+ spin_lock_irqsave(&port->ip_port->lock, pflags);
transmit_chars(port->ip_port);
+ spin_unlock_irqrestore(&port->ip_port->lock, pflags);
}
}
@@ -2076,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
* available data as long as it returns some.
*/
/* Re-arm the timer */
- writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
- &port->ip_serial_regs->srcir);
+ writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
cons_ptr = port->ip_rx_cons;
@@ -2311,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
}
return total;
}
+
/**
* receive_chars - upper level read. Called with ip_lock.
* @the_port: port to read from
@@ -2319,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
{
struct tty_struct *tty;
unsigned char ch[IOC4_MAX_CHARS];
- int read_count, request_count;
+ int read_count, request_count = IOC4_MAX_CHARS;
struct uart_icount *icount;
struct uart_info *info = the_port->info;
+ int flip = 0;
+ unsigned long pflags;
/* Make sure all the pointers are "good" ones */
if (!info)
@@ -2329,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
if (!info->tty)
return;
+ spin_lock_irqsave(&the_port->lock, pflags);
tty = info->tty;
- request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
+ if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
+ request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
if (request_count > 0) {
- if (request_count > IOC4_MAX_CHARS - 2)
- request_count = IOC4_MAX_CHARS - 2;
icount = &the_port->icount;
read_count = do_read(the_port, ch, request_count);
if (read_count > 0) {
+ flip = 1;
memcpy(tty->flip.char_buf_ptr, ch, read_count);
memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
tty->flip.char_buf_ptr += read_count;
@@ -2347,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
icount->rx += read_count;
}
}
- tty_flip_buffer_push(tty);
+
+ spin_unlock_irqrestore(&the_port->lock, pflags);
+
+ if (flip)
+ tty_flip_buffer_push(tty);
}
/**
@@ -2405,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
info = the_port->info;
- if (!(info->flags & UIF_INITIALIZED))
- return;
-
wake_up_interruptible(&info->delta_msr_wait);
if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
set_notification(port, N_ALL, 0);
- info->flags &= ~UIF_INITIALIZED;
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
}
/**
@@ -2475,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
static void ic4_start_tx(struct uart_port *the_port)
{
struct ioc4_port *port = get_ioc4_port(the_port);
- unsigned long flags;
if (port) {
- spin_lock_irqsave(&port->ip_lock, flags);
- transmit_chars(the_port);
- spin_unlock_irqrestore(&port->ip_lock, flags);
+ set_notification(port, N_OUTPUT_LOWAT, 1);
+ enable_intrs(port, port->ip_hooks->intr_tx_mt);
}
}
@@ -2522,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
}
/* Start up the serial port */
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
retval = ic4_startup_local(the_port);
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
return retval;
}
@@ -2539,12 +2533,11 @@ static void
ic4_set_termios(struct uart_port *the_port,
struct termios *termios, struct termios *old_termios)
{
- struct ioc4_port *port = get_ioc4_port(the_port);
unsigned long port_flags;
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
ioc4_change_speed(the_port, termios, old_termios);
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
}
/**
@@ -2619,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
__FUNCTION__, (void *)the_port,
(void *)port));
- spin_lock_init(&the_port->lock);
/* membase, iobase and mapbase just need to be non-0 */
the_port->membase = (unsigned char __iomem *)1;
- the_port->line = the_port->iobase = ii;
+ the_port->iobase = (pdev->bus->number << 16) | ii;
+ the_port->line = (Num_of_ioc4_cards << 2) | ii;
the_port->mapbase = 1;
the_port->type = PORT_16550A;
- the_port->fifosize = IOC4_MAX_CHARS;
+ the_port->fifosize = IOC4_FIFO_CHARS;
the_port->ops = &ioc4_ops;
the_port->irq = control->ic_irq;
the_port->dev = &pdev->dev;
+ spin_lock_init(&the_port->lock);
if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
printk(KERN_WARNING
- "%s: unable to add port %d\n",
- __FUNCTION__, the_port->line);
+ "%s: unable to add port %d bus %d\n",
+ __FUNCTION__, the_port->line, pdev->bus->number);
} else {
DPRINT_CONFIG(
- ("IOC4 serial driver port %d irq = %d\n",
- the_port->line, the_port->irq));
+ ("IOC4 serial port %d irq = %d, bus %d\n",
+ the_port->line, the_port->irq, pdev->bus->number));
}
/* all ports are rs232 for now */
ioc4_set_proto(port, PROTO_RS232);
@@ -2746,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
goto out4;
+ Num_of_ioc4_cards++;
+
return ret;
/* error exits that give back resources */
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index e2ebdcad553c..47f7404cb045 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -57,7 +57,8 @@ struct timer_list mcfrs_timer_struct;
* keep going. Perhaps one day the cflag settings for the
* console can be used instead.
*/
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+ defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
#define CONSOLE_BAUD_RATE 19200
#define DEFAULT_CBAUD B19200
#endif
@@ -67,7 +68,7 @@ struct timer_list mcfrs_timer_struct;
#define DEFAULT_CBAUD B38400
#endif
-#if defined(CONFIG_MOD5272)
+#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
#define CONSOLE_BAUD_RATE 115200
#define DEFAULT_CBAUD B115200
#endif
@@ -95,7 +96,8 @@ static struct tty_driver *mcfrs_serial_driver;
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M520x)
#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
#else
#define IRQBASE 73
@@ -1528,6 +1530,35 @@ static void mcfrs_irqinit(struct mcf_serial *info)
imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
MCFINTC_IMRL);
*imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#elif defined(CONFIG_M520x)
+ volatile unsigned char *icrp, *uartp;
+ volatile unsigned long *imrp;
+
+ uartp = info->addr;
+
+ icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
+ MCFINTC_ICR0 + MCFINT_UART0 + info->line);
+ *icrp = 0x03;
+
+ imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
+ MCFINTC_IMRL);
+ *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+ if (info->line < 2) {
+ unsigned short *uart_par;
+ uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+ if (info->line == 0)
+ *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0
+ | MCF_GPIO_PAR_UART_PAR_URXD0;
+ else if (info->line == 1)
+ *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1
+ | MCF_GPIO_PAR_UART_PAR_URXD1;
+ } else if (info->line == 2) {
+ unsigned char *feci2c_par;
+ feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+ *feci2c_par &= ~0x0F;
+ *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
+ | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
+ }
#else
volatile unsigned char *icrp, *uartp;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 0585ab27ffde..b8727d9bf690 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -45,7 +45,7 @@
*/
#include <linux/config.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/serial.h>
@@ -717,16 +717,15 @@ static struct uart_driver mpc52xx_uart_driver = {
/* ======================================================================== */
static int __devinit
-mpc52xx_uart_probe(struct device *dev)
+mpc52xx_uart_probe(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct resource *res = pdev->resource;
+ struct resource *res = dev->resource;
struct uart_port *port = NULL;
int i, idx, ret;
/* Check validity & presence */
- idx = pdev->id;
+ idx = dev->id;
if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
return -EINVAL;
@@ -749,7 +748,7 @@ mpc52xx_uart_probe(struct device *dev)
port->ops = &mpc52xx_uart_ops;
/* Search for IRQ and mapbase */
- for (i=0 ; i<pdev->num_resources ; i++, res++) {
+ for (i=0 ; i<dev->num_resources ; i++, res++) {
if (res->flags & IORESOURCE_MEM)
port->mapbase = res->start;
else if (res->flags & IORESOURCE_IRQ)
@@ -761,17 +760,17 @@ mpc52xx_uart_probe(struct device *dev)
/* Add the port to the uart sub-system */
ret = uart_add_one_port(&mpc52xx_uart_driver, port);
if (!ret)
- dev_set_drvdata(dev, (void*)port);
+ platform_set_drvdata(dev, (void*)port);
return ret;
}
static int
-mpc52xx_uart_remove(struct device *dev)
+mpc52xx_uart_remove(struct platform_device *dev)
{
- struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (port)
uart_remove_one_port(&mpc52xx_uart_driver, port);
@@ -781,37 +780,38 @@ mpc52xx_uart_remove(struct device *dev)
#ifdef CONFIG_PM
static int
-mpc52xx_uart_suspend(struct device *dev, pm_message_t state, u32 level)
+mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
{
- struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&mpc52xx_uart_driver, port);
return 0;
}
static int
-mpc52xx_uart_resume(struct device *dev, u32 level)
+mpc52xx_uart_resume(struct platform_device *dev)
{
- struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
+ struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
- if (port && level == RESUME_ENABLE)
+ if (port)
uart_resume_port(&mpc52xx_uart_driver, port);
return 0;
}
#endif
-static struct device_driver mpc52xx_uart_platform_driver = {
- .name = "mpc52xx-psc",
- .bus = &platform_bus_type,
+static struct platform_driver mpc52xx_uart_platform_driver = {
.probe = mpc52xx_uart_probe,
.remove = mpc52xx_uart_remove,
#ifdef CONFIG_PM
.suspend = mpc52xx_uart_suspend,
.resume = mpc52xx_uart_resume,
#endif
+ .driver = {
+ .name = "mpc52xx-psc",
+ },
};
@@ -828,7 +828,7 @@ mpc52xx_uart_init(void)
ret = uart_register_driver(&mpc52xx_uart_driver);
if (ret == 0) {
- ret = driver_register(&mpc52xx_uart_platform_driver);
+ ret = platform_driver_register(&mpc52xx_uart_platform_driver);
if (ret)
uart_unregister_driver(&mpc52xx_uart_driver);
}
@@ -839,7 +839,7 @@ mpc52xx_uart_init(void)
static void __exit
mpc52xx_uart_exit(void)
{
- driver_unregister(&mpc52xx_uart_platform_driver);
+ platform_driver_unregister(&mpc52xx_uart_platform_driver);
uart_unregister_driver(&mpc52xx_uart_driver);
}
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index efe79b1fd431..8f83e4007ecd 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -52,6 +52,8 @@
* 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
*/
+#include <linux/platform_device.h>
+
#include "mpsc.h"
/*
@@ -1100,6 +1102,8 @@ 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);
@@ -1547,15 +1551,14 @@ mpsc_shared_unmap_regs(void)
}
static int
-mpsc_shared_drv_probe(struct device *dev)
+mpsc_shared_drv_probe(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
struct mpsc_shared_pdata *pdata;
int rc = -ENODEV;
- if (pd->id == 0) {
- if (!(rc = mpsc_shared_map_regs(pd))) {
- pdata = (struct mpsc_shared_pdata *)dev->platform_data;
+ if (dev->id == 0) {
+ 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;
@@ -1573,12 +1576,11 @@ mpsc_shared_drv_probe(struct device *dev)
}
static int
-mpsc_shared_drv_remove(struct device *dev)
+mpsc_shared_drv_remove(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
int rc = -ENODEV;
- if (pd->id == 0) {
+ if (dev->id == 0) {
mpsc_shared_unmap_regs();
mpsc_shared_regs.MPSC_MRR_m = 0;
mpsc_shared_regs.MPSC_RCRR_m = 0;
@@ -1591,11 +1593,12 @@ mpsc_shared_drv_remove(struct device *dev)
return rc;
}
-static struct device_driver mpsc_shared_driver = {
- .name = MPSC_SHARED_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mpsc_shared_driver = {
.probe = mpsc_shared_drv_probe,
.remove = mpsc_shared_drv_remove,
+ .driver = {
+ .name = MPSC_SHARED_NAME,
+ },
};
/*
@@ -1728,19 +1731,18 @@ mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
}
static int
-mpsc_drv_probe(struct device *dev)
+mpsc_drv_probe(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
struct mpsc_port_info *pi;
int rc = -ENODEV;
- pr_debug("mpsc_drv_probe: Adding MPSC %d\n", pd->id);
+ pr_debug("mpsc_drv_probe: Adding MPSC %d\n", dev->id);
- if (pd->id < MPSC_NUM_CTLRS) {
- pi = &mpsc_ports[pd->id];
+ if (dev->id < MPSC_NUM_CTLRS) {
+ pi = &mpsc_ports[dev->id];
- if (!(rc = mpsc_drv_map_regs(pi, pd))) {
- mpsc_drv_get_platform_data(pi, pd, pd->id);
+ if (!(rc = mpsc_drv_map_regs(pi, dev))) {
+ mpsc_drv_get_platform_data(pi, dev, dev->id);
if (!(rc = mpsc_make_ready(pi)))
if (!(rc = uart_add_one_port(&mpsc_reg,
@@ -1760,27 +1762,26 @@ mpsc_drv_probe(struct device *dev)
}
static int
-mpsc_drv_remove(struct device *dev)
+mpsc_drv_remove(struct platform_device *dev)
{
- struct platform_device *pd = to_platform_device(dev);
-
- pr_debug("mpsc_drv_exit: Removing MPSC %d\n", pd->id);
+ pr_debug("mpsc_drv_exit: Removing MPSC %d\n", dev->id);
- if (pd->id < MPSC_NUM_CTLRS) {
- uart_remove_one_port(&mpsc_reg, &mpsc_ports[pd->id].port);
- mpsc_release_port((struct uart_port *)&mpsc_ports[pd->id].port);
- mpsc_drv_unmap_regs(&mpsc_ports[pd->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_drv_unmap_regs(&mpsc_ports[dev->id]);
return 0;
}
else
return -ENODEV;
}
-static struct device_driver mpsc_driver = {
- .name = MPSC_CTLR_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver mpsc_driver = {
.probe = mpsc_drv_probe,
.remove = mpsc_drv_remove,
+ .driver = {
+ .name = MPSC_CTLR_NAME,
+ },
};
static int __init
@@ -1794,9 +1795,9 @@ mpsc_drv_init(void)
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
if (!(rc = uart_register_driver(&mpsc_reg))) {
- if (!(rc = driver_register(&mpsc_shared_driver))) {
- if ((rc = driver_register(&mpsc_driver))) {
- driver_unregister(&mpsc_shared_driver);
+ if (!(rc = platform_driver_register(&mpsc_shared_driver))) {
+ if ((rc = platform_driver_register(&mpsc_driver))) {
+ platform_driver_unregister(&mpsc_shared_driver);
uart_unregister_driver(&mpsc_reg);
}
}
@@ -1811,8 +1812,8 @@ mpsc_drv_init(void)
static void __exit
mpsc_drv_exit(void)
{
- driver_unregister(&mpsc_driver);
- driver_unregister(&mpsc_shared_driver);
+ 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));
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 189064607709..7633132a10aa 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -27,6 +27,7 @@
#include <linux/delay.h> /* for udelay */
#include <linux/device.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/parisc-device.h>
#ifdef CONFIG_MAGIC_SYSRQ
@@ -64,8 +65,8 @@ static struct uart_driver mux_driver = {
static struct timer_list mux_timer;
-#define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET)
-#define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET)
+#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
+#define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)
#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8
/**
@@ -78,10 +79,7 @@ static struct timer_list mux_timer;
*/
static unsigned int mux_tx_empty(struct uart_port *port)
{
- unsigned int cnt = __raw_readl((unsigned long)port->membase
- + IO_DCOUNT_REG_OFFSET);
-
- return cnt ? 0 : TIOCSER_TEMT;
+ return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
}
/**
@@ -217,8 +215,7 @@ static void mux_read(struct uart_port *port)
__u32 start_count = port->icount.rx;
while(1) {
- data = __raw_readl((unsigned long)port->membase
- + IO_DATA_REG_OFFSET);
+ data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);
if (MUX_STATUS(data))
continue;
@@ -444,7 +441,7 @@ static int __init mux_probe(struct parisc_device *dev)
unsigned long bytecnt;
struct uart_port *port;
- status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32);
+ status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
if(status != PDC_OK) {
printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
return 1;
@@ -469,16 +466,25 @@ static int __init mux_probe(struct parisc_device *dev)
for(i = 0; i < ports; ++i, ++port_cnt) {
port = &mux_ports[port_cnt];
port->iobase = 0;
- port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
+ port->mapbase = dev->hpa.start + MUX_OFFSET +
+ (i * MUX_LINE_OFFSET);
port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
port->iotype = SERIAL_IO_MEM;
port->type = PORT_MUX;
- port->irq = SERIAL_IRQ_NONE;
+ port->irq = NO_IRQ;
port->uartclk = 0;
port->fifosize = MUX_FIFO_SIZE;
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = port_cnt;
+
+ /* The port->timeout needs to match what is present in
+ * uart_wait_until_sent in serial_core.c. Otherwise
+ * the time spent in msleep_interruptable will be very
+ * long, causing the appearance of a console hang.
+ */
+ port->timeout = HZ / 50;
+ spin_lock_init(&port->lock);
status = uart_add_one_port(&mux_driver, port);
BUG_ON(status);
}
@@ -497,7 +503,7 @@ static struct parisc_device_id mux_tbl[] = {
MODULE_DEVICE_TABLE(parisc, mux_tbl);
static struct parisc_driver serial_mux_driver = {
- .name = "Serial MUX",
+ .name = "serial_mux",
.id_table = mux_tbl,
.probe = mux_probe,
};
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 672b359b07ce..ff5e6309d682 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -39,7 +39,7 @@
#include <linux/circ_buf.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -358,6 +358,9 @@ static int serial_pxa_startup(struct uart_port *port)
unsigned long flags;
int retval;
+ if (port->line == 3) /* HWUART */
+ up->mcr |= UART_MCR_AFE;
+ else
up->mcr = 0;
/*
@@ -481,8 +484,10 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
if ((up->port.uartclk / quot) < (2400 * 16))
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1;
- else
+ else if ((up->port.uartclk / quot) < (230400 * 16))
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8;
+ else
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32;
/*
* Ok, we're now changing the port state. Do it with
@@ -499,7 +504,7 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
- uart_update_timeout(port, termios->c_cflag, quot);
+ uart_update_timeout(port, termios->c_cflag, baud);
up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
if (termios->c_iflag & INPCK)
@@ -772,6 +777,20 @@ static struct uart_pxa_port serial_pxa_ports[] = {
.ops = &serial_pxa_pops,
.line = 2,
},
+ }, { /* HWUART */
+ .name = "HWUART",
+ .cken = CKEN4_HWUART,
+ .port = {
+ .type = PORT_PXA,
+ .iotype = UPIO_MEM,
+ .membase = (void *)&HWUART,
+ .mapbase = __PREG(HWUART),
+ .irq = IRQ_HWUART,
+ .uartclk = 921600 * 16,
+ .fifosize = 64,
+ .ops = &serial_pxa_pops,
+ .line = 3,
+ },
}
};
@@ -786,41 +805,39 @@ static struct uart_driver serial_pxa_reg = {
.cons = PXA_CONSOLE,
};
-static int serial_pxa_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state)
{
- struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ struct uart_pxa_port *sport = platform_get_drvdata(dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&serial_pxa_reg, &sport->port);
return 0;
}
-static int serial_pxa_resume(struct device *_dev, u32 level)
+static int serial_pxa_resume(struct platform_device *dev)
{
- struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ struct uart_pxa_port *sport = platform_get_drvdata(dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&serial_pxa_reg, &sport->port);
return 0;
}
-static int serial_pxa_probe(struct device *_dev)
+static int serial_pxa_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
-
- serial_pxa_ports[dev->id].port.dev = _dev;
+ serial_pxa_ports[dev->id].port.dev = &dev->dev;
uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port);
- dev_set_drvdata(_dev, &serial_pxa_ports[dev->id]);
+ platform_set_drvdata(dev, &serial_pxa_ports[dev->id]);
return 0;
}
-static int serial_pxa_remove(struct device *_dev)
+static int serial_pxa_remove(struct platform_device *dev)
{
- struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+ struct uart_pxa_port *sport = platform_get_drvdata(dev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (sport)
uart_remove_one_port(&serial_pxa_reg, &sport->port);
@@ -828,14 +845,15 @@ static int serial_pxa_remove(struct device *_dev)
return 0;
}
-static struct device_driver serial_pxa_driver = {
- .name = "pxa2xx-uart",
- .bus = &platform_bus_type,
+static struct platform_driver serial_pxa_driver = {
.probe = serial_pxa_probe,
.remove = serial_pxa_remove,
.suspend = serial_pxa_suspend,
.resume = serial_pxa_resume,
+ .driver = {
+ .name = "pxa2xx-uart",
+ },
};
int __init serial_pxa_init(void)
@@ -846,7 +864,7 @@ int __init serial_pxa_init(void)
if (ret != 0)
return ret;
- ret = driver_register(&serial_pxa_driver);
+ ret = platform_driver_register(&serial_pxa_driver);
if (ret != 0)
uart_unregister_driver(&serial_pxa_reg);
@@ -855,7 +873,7 @@ int __init serial_pxa_init(void)
void __exit serial_pxa_exit(void)
{
- driver_unregister(&serial_pxa_driver);
+ platform_driver_unregister(&serial_pxa_driver);
uart_unregister_driver(&serial_pxa_reg);
}
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index c361c6fb0809..47681c4654e4 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -63,7 +63,7 @@
#include <linux/module.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/sysrq.h>
#include <linux/console.h>
@@ -82,8 +82,6 @@
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
-#include <asm/mach-types.h>
-
/* structures */
struct s3c24xx_uart_info {
@@ -753,8 +751,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
{
struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- struct s3c24xx_uart_clksrc *clksrc;
- struct clk *clk;
+ struct s3c24xx_uart_clksrc *clksrc = NULL;
+ struct clk *clk = NULL;
unsigned long flags;
unsigned int baud, quot;
unsigned int ulcon;
@@ -1094,14 +1092,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
static int probe_index = 0;
-int s3c24xx_serial_probe(struct device *_dev,
- struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_probe(struct platform_device *dev,
+ struct s3c24xx_uart_info *info)
{
struct s3c24xx_uart_port *ourport;
- struct platform_device *dev = to_platform_device(_dev);
int ret;
- dbg("s3c24xx_serial_probe(%p, %p) %d\n", _dev, info, probe_index);
+ dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
ourport = &s3c24xx_serial_ports[probe_index];
probe_index++;
@@ -1114,7 +1111,7 @@ int s3c24xx_serial_probe(struct device *_dev,
dbg("%s: adding port\n", __FUNCTION__);
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
- dev_set_drvdata(_dev, &ourport->port);
+ platform_set_drvdata(dev, &ourport->port);
return 0;
@@ -1122,9 +1119,9 @@ int s3c24xx_serial_probe(struct device *_dev,
return ret;
}
-int s3c24xx_serial_remove(struct device *_dev)
+static int s3c24xx_serial_remove(struct platform_device *dev)
{
- struct uart_port *port = s3c24xx_dev_to_port(_dev);
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
if (port)
uart_remove_one_port(&s3c24xx_uart_drv, port);
@@ -1136,22 +1133,22 @@ int s3c24xx_serial_remove(struct device *_dev)
#ifdef CONFIG_PM
-int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t state)
{
- struct uart_port *port = s3c24xx_dev_to_port(dev);
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
- if (port && level == SUSPEND_DISABLE)
+ if (port)
uart_suspend_port(&s3c24xx_uart_drv, port);
return 0;
}
-int s3c24xx_serial_resume(struct device *dev, u32 level)
+static int s3c24xx_serial_resume(struct platform_device *dev)
{
- struct uart_port *port = s3c24xx_dev_to_port(dev);
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- if (port && level == RESUME_ENABLE) {
+ if (port) {
clk_enable(ourport->clk);
s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
clk_disable(ourport->clk);
@@ -1167,11 +1164,11 @@ int s3c24xx_serial_resume(struct device *dev, u32 level)
#define s3c24xx_serial_resume NULL
#endif
-int s3c24xx_serial_init(struct device_driver *drv,
- struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_init(struct platform_driver *drv,
+ struct s3c24xx_uart_info *info)
{
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
- return driver_register(drv);
+ return platform_driver_register(drv);
}
@@ -1230,18 +1227,20 @@ static struct s3c24xx_uart_info s3c2400_uart_inf = {
.reset_port = s3c2400_serial_resetport,
};
-static int s3c2400_serial_probe(struct device *dev)
+static int s3c2400_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2400_uart_inf);
}
-static struct device_driver s3c2400_serial_drv = {
- .name = "s3c2400-uart",
- .bus = &platform_bus_type,
+static struct platform_driver s3c2400_serial_drv = {
.probe = s3c2400_serial_probe,
.remove = s3c24xx_serial_remove,
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .driver = {
+ .name = "s3c2400-uart",
+ .owner = THIS_MODULE,
+ },
};
static inline int s3c2400_serial_init(void)
@@ -1251,7 +1250,7 @@ static inline int s3c2400_serial_init(void)
static inline void s3c2400_serial_exit(void)
{
- driver_unregister(&s3c2400_serial_drv);
+ platform_driver_unregister(&s3c2400_serial_drv);
}
#define s3c2400_uart_inf_at &s3c2400_uart_inf
@@ -1333,18 +1332,20 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = {
/* device management */
-static int s3c2410_serial_probe(struct device *dev)
+static int s3c2410_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
}
-static struct device_driver s3c2410_serial_drv = {
- .name = "s3c2410-uart",
- .bus = &platform_bus_type,
+static struct platform_driver s3c2410_serial_drv = {
.probe = s3c2410_serial_probe,
.remove = s3c24xx_serial_remove,
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .driver = {
+ .name = "s3c2410-uart",
+ .owner = THIS_MODULE,
+ },
};
static inline int s3c2410_serial_init(void)
@@ -1354,7 +1355,7 @@ static inline int s3c2410_serial_init(void)
static inline void s3c2410_serial_exit(void)
{
- driver_unregister(&s3c2410_serial_drv);
+ platform_driver_unregister(&s3c2410_serial_drv);
}
#define s3c2410_uart_inf_at &s3c2410_uart_inf
@@ -1493,19 +1494,21 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = {
/* device management */
-static int s3c2440_serial_probe(struct device *dev)
+static int s3c2440_serial_probe(struct platform_device *dev)
{
dbg("s3c2440_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
}
-static struct device_driver s3c2440_serial_drv = {
- .name = "s3c2440-uart",
- .bus = &platform_bus_type,
+static struct platform_driver s3c2440_serial_drv = {
.probe = s3c2440_serial_probe,
.remove = s3c24xx_serial_remove,
.suspend = s3c24xx_serial_suspend,
.resume = s3c24xx_serial_resume,
+ .driver = {
+ .name = "s3c2440-uart",
+ .owner = THIS_MODULE,
+ },
};
@@ -1516,7 +1519,7 @@ static inline int s3c2440_serial_init(void)
static inline void s3c2440_serial_exit(void)
{
- driver_unregister(&s3c2440_serial_drv);
+ platform_driver_unregister(&s3c2440_serial_drv);
}
#define s3c2440_uart_inf_at &s3c2440_uart_inf
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index dd8aed242357..25a086458ab9 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -35,7 +35,7 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -156,19 +156,16 @@ static void sa1100_stop_tx(struct uart_port *port)
}
/*
- * interrupts may not be disabled on entry
+ * port locked and interrupts disabled
*/
static void sa1100_start_tx(struct uart_port *port)
{
struct sa1100_port *sport = (struct sa1100_port *)port;
- unsigned long flags;
u32 utcr3;
- spin_lock_irqsave(&sport->port.lock, flags);
utcr3 = UART_GET_UTCR3(sport);
sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
- spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
@@ -834,29 +831,28 @@ static struct uart_driver sa1100_reg = {
.cons = SA1100_CONSOLE,
};
-static int sa1100_serial_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int sa1100_serial_suspend(struct platform_device *dev, pm_message_t state)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&sa1100_reg, &sport->port);
return 0;
}
-static int sa1100_serial_resume(struct device *_dev, u32 level)
+static int sa1100_serial_resume(struct platform_device *dev)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&sa1100_reg, &sport->port);
return 0;
}
-static int sa1100_serial_probe(struct device *_dev)
+static int sa1100_serial_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct resource *res = dev->resource;
int i;
@@ -869,9 +865,9 @@ static int sa1100_serial_probe(struct device *_dev)
if (sa1100_ports[i].port.mapbase != res->start)
continue;
- sa1100_ports[i].port.dev = _dev;
+ sa1100_ports[i].port.dev = &dev->dev;
uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
- dev_set_drvdata(_dev, &sa1100_ports[i]);
+ platform_set_drvdata(dev, &sa1100_ports[i]);
break;
}
}
@@ -879,11 +875,11 @@ static int sa1100_serial_probe(struct device *_dev)
return 0;
}
-static int sa1100_serial_remove(struct device *_dev)
+static int sa1100_serial_remove(struct platform_device *pdev)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(pdev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (sport)
uart_remove_one_port(&sa1100_reg, &sport->port);
@@ -891,13 +887,14 @@ static int sa1100_serial_remove(struct device *_dev)
return 0;
}
-static struct device_driver sa11x0_serial_driver = {
- .name = "sa11x0-uart",
- .bus = &platform_bus_type,
+static struct platform_driver sa11x0_serial_driver = {
.probe = sa1100_serial_probe,
.remove = sa1100_serial_remove,
.suspend = sa1100_serial_suspend,
.resume = sa1100_serial_resume,
+ .driver = {
+ .name = "sa11x0-uart",
+ },
};
static int __init sa1100_serial_init(void)
@@ -910,7 +907,7 @@ static int __init sa1100_serial_init(void)
ret = uart_register_driver(&sa1100_reg);
if (ret == 0) {
- ret = driver_register(&sa11x0_serial_driver);
+ ret = platform_driver_register(&sa11x0_serial_driver);
if (ret)
uart_unregister_driver(&sa1100_reg);
}
@@ -919,7 +916,7 @@ static int __init sa1100_serial_init(void)
static void __exit sa1100_serial_exit(void)
{
- driver_unregister(&sa11x0_serial_driver);
+ platform_driver_unregister(&sa11x0_serial_driver);
uart_unregister_driver(&sa1100_reg);
}
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 2d8622eef701..c17d680e3f04 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -147,8 +147,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* once we have successfully opened the port. Also set
* up the tty->alt_speed kludge
*/
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
if (port->type == PORT_UNKNOWN)
return 0;
@@ -210,33 +209,45 @@ static void uart_shutdown(struct uart_state *state)
struct uart_info *info = state->info;
struct uart_port *port = state->port;
- if (!(info->flags & UIF_INITIALIZED))
- return;
-
/*
- * Turn off DTR and RTS early.
+ * Set the TTY IO error marker
*/
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
- uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ if (info->tty)
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
- /*
- * clear delta_msr_wait queue to avoid mem leaks: we may free
- * the irq here so the queue might never be woken up. Note
- * that we won't end up waiting on delta_msr_wait again since
- * any outstanding file descriptors should be pointing at
- * hung_up_tty_fops now.
- */
- wake_up_interruptible(&info->delta_msr_wait);
+ if (info->flags & UIF_INITIALIZED) {
+ info->flags &= ~UIF_INITIALIZED;
- /*
- * Free the IRQ and disable the port.
- */
- port->ops->shutdown(port);
+ /*
+ * Turn off DTR and RTS early.
+ */
+ if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+ /*
+ * clear delta_msr_wait queue to avoid mem leaks: we may free
+ * the irq here so the queue might never be woken up. Note
+ * that we won't end up waiting on delta_msr_wait again since
+ * any outstanding file descriptors should be pointing at
+ * hung_up_tty_fops now.
+ */
+ wake_up_interruptible(&info->delta_msr_wait);
+
+ /*
+ * Free the IRQ and disable the port.
+ */
+ port->ops->shutdown(port);
+
+ /*
+ * Ensure that the IRQ handler isn't running on another CPU.
+ */
+ synchronize_irq(port->irq);
+ }
/*
- * Ensure that the IRQ handler isn't running on another CPU.
+ * kill off our tasklet
*/
- synchronize_irq(port->irq);
+ tasklet_kill(&info->tlet);
/*
* Free the transmit buffer page.
@@ -245,15 +256,6 @@ static void uart_shutdown(struct uart_state *state)
free_page((unsigned long)info->xmit.buf);
info->xmit.buf = NULL;
}
-
- /*
- * kill off our tasklet
- */
- tasklet_kill(&info->tlet);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
-
- info->flags &= ~UIF_INITIALIZED;
}
/**
@@ -1777,7 +1779,7 @@ struct baud_rates {
unsigned int cflag;
};
-static struct baud_rates baud_rates[] = {
+static const struct baud_rates baud_rates[] = {
{ 921600, B921600 },
{ 460800, B460800 },
{ 230400, B230400 },
@@ -1929,14 +1931,25 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
if (state->info && state->info->flags & UIF_INITIALIZED) {
struct uart_ops *ops = port->ops;
+ int ret;
ops->set_mctrl(port, 0);
- ops->startup(port);
- uart_change_speed(state, NULL);
- spin_lock_irq(&port->lock);
- ops->set_mctrl(port, port->mctrl);
- ops->start_tx(port);
- spin_unlock_irq(&port->lock);
+ ret = ops->startup(port);
+ if (ret == 0) {
+ uart_change_speed(state, NULL);
+ spin_lock_irq(&port->lock);
+ ops->set_mctrl(port, port->mctrl);
+ ops->start_tx(port);
+ spin_unlock_irq(&port->lock);
+ } else {
+ /*
+ * Failed to resume - maybe hardware went away?
+ * Clear the "initialized" flag so we won't try
+ * to call the low level drivers shutdown method.
+ */
+ state->info->flags &= ~UIF_INITIALIZED;
+ uart_shutdown(state);
+ }
}
up(&state->sem);
@@ -1960,6 +1973,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
break;
case UPIO_MEM:
case UPIO_MEM32:
+ case UPIO_AU:
snprintf(address, sizeof(address),
"MMIO 0x%lx", port->mapbase);
break;
@@ -1968,7 +1982,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
break;
}
- printk(KERN_INFO "%s%d at %s (irq = %d) is a %s\n",
+ printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
+ port->dev ? port->dev->bus_id : "",
+ port->dev ? ": " : "",
drv->dev_name, port->line, address, port->irq, uart_type(port));
}
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 1ae0b381c162..7ce0c7e66d37 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -85,7 +85,7 @@ struct multi_id {
int multi; /* 1 = multifunction, > 1 = # ports */
};
-static struct multi_id multi_id[] = {
+static const struct multi_id multi_id[] = {
{ MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
@@ -354,8 +354,8 @@ next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
static int simple_config(dev_link_t *link)
{
- static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
- static int size_table[2] = { 8, 16 };
+ static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+ static const int size_table[2] = { 8, 16 };
client_handle_t handle = link->handle;
struct serial_info *info = link->priv;
struct serial_cfg_mem *cfg_mem;
@@ -859,6 +859,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
+ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 512266307866..430754ebac8a 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -967,7 +967,7 @@ static int sci_startup(struct uart_port *port)
#endif
sci_request_irq(s);
- sci_start_tx(port, 1);
+ sci_start_tx(port);
sci_start_rx(port, 1);
return 0;
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index e971156daa60..ba9381fd3f2d 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -274,7 +274,6 @@ static void transmit_chars(struct uart_sunsab_port *up,
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
up->interrupt_mask1 |= SAB82532_IMR1_XPR;
writeb(up->interrupt_mask1, &up->regs->w.imr1);
- uart_write_wakeup(&up->port);
return;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 5959e6755a81..f0738533f39a 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -518,11 +518,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
quot = up->port.uartclk / (16 * new_baud);
- spin_unlock(&up->port.lock);
-
sunsu_change_speed(&up->port, up->cflag, 0, quot);
-
- spin_lock(&up->port.lock);
}
static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)
@@ -1445,7 +1441,7 @@ static void sunsu_console_write(struct console *co, const char *s,
* - initialize the serial port
* Return non-zero if we didn't find a serial port.
*/
-static int __init sunsu_console_setup(struct console *co, char *options)
+static int sunsu_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int baud = 9600;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index d75445738c88..7653d6cf05af 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -517,10 +517,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
if (up->port.info == NULL)
goto ack_tx_int;
xmit = &up->port.info->xmit;
- if (uart_circ_empty(xmit)) {
- uart_write_wakeup(&up->port);
+ if (uart_circ_empty(xmit))
goto ack_tx_int;
- }
+
if (uart_tx_stopped(&up->port))
goto ack_tx_int;
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 0c5d65a08f6e..865d4dea65df 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -26,7 +26,7 @@
#endif
#include <linux/console.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/ioport.h>
#include <linux/init.h>
@@ -924,7 +924,7 @@ static struct uart_driver siu_uart_driver = {
.cons = SERIAL_VR41XX_CONSOLE,
};
-static int siu_probe(struct device *dev)
+static int siu_probe(struct platform_device *dev)
{
struct uart_port *port;
int num, i, retval;
@@ -941,7 +941,7 @@ static int siu_probe(struct device *dev)
for (i = 0; i < num; i++) {
port = &siu_uart_ports[i];
port->ops = &siu_uart_ops;
- port->dev = dev;
+ port->dev = &dev->dev;
retval = uart_add_one_port(&siu_uart_driver, port);
if (retval < 0) {
@@ -958,14 +958,14 @@ static int siu_probe(struct device *dev)
return 0;
}
-static int siu_remove(struct device *dev)
+static int siu_remove(struct platform_device *dev)
{
struct uart_port *port;
int i;
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
- if (port->dev == dev) {
+ if (port->dev == &dev->dev) {
uart_remove_one_port(&siu_uart_driver, port);
port->dev = NULL;
}
@@ -976,18 +976,15 @@ static int siu_remove(struct device *dev)
return 0;
}
-static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
+static int siu_suspend(struct platform_device *dev, pm_message_t state)
{
struct uart_port *port;
int i;
- if (level != SUSPEND_DISABLE)
- return 0;
-
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
if ((port->type == PORT_VR41XX_SIU ||
- port->type == PORT_VR41XX_DSIU) && port->dev == dev)
+ port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
uart_suspend_port(&siu_uart_driver, port);
}
@@ -995,18 +992,15 @@ static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int siu_resume(struct device *dev, u32 level)
+static int siu_resume(struct platform_device *dev)
{
struct uart_port *port;
int i;
- if (level != RESUME_ENABLE)
- return 0;
-
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
if ((port->type == PORT_VR41XX_SIU ||
- port->type == PORT_VR41XX_DSIU) && port->dev == dev)
+ port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
uart_resume_port(&siu_uart_driver, port);
}
@@ -1015,13 +1009,14 @@ static int siu_resume(struct device *dev, u32 level)
static struct platform_device *siu_platform_device;
-static struct device_driver siu_device_driver = {
- .name = "SIU",
- .bus = &platform_bus_type,
+static struct platform_driver siu_device_driver = {
.probe = siu_probe,
.remove = siu_remove,
.suspend = siu_suspend,
.resume = siu_resume,
+ .driver = {
+ .name = "SIU",
+ },
};
static int __devinit vr41xx_siu_init(void)
@@ -1032,7 +1027,7 @@ static int __devinit vr41xx_siu_init(void)
if (IS_ERR(siu_platform_device))
return PTR_ERR(siu_platform_device);
- retval = driver_register(&siu_device_driver);
+ retval = platform_driver_register(&siu_device_driver);
if (retval < 0)
platform_device_unregister(siu_platform_device);
@@ -1041,7 +1036,7 @@ static int __devinit vr41xx_siu_init(void)
static void __devexit vr41xx_siu_exit(void)
{
- driver_unregister(&siu_device_driver);
+ platform_driver_unregister(&siu_device_driver);
platform_device_unregister(siu_platform_device);
}