aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/serial/68328serial.c2
-rw-r--r--drivers/serial/68360serial.c2
-rw-r--r--drivers/serial/8250.c39
-rw-r--r--drivers/serial/8250_gsc.c4
-rw-r--r--drivers/serial/8250_pci.c4
-rw-r--r--drivers/serial/8250_pnp.c13
-rw-r--r--drivers/serial/Kconfig15
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c24
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.h2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c143
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.h4
-rw-r--r--drivers/serial/crisv10.c2
-rw-r--r--drivers/serial/m32r_sio.c5
-rw-r--r--drivers/serial/mcfserial.c2
-rw-r--r--drivers/serial/serial_core.c20
-rw-r--r--drivers/serial/serial_cs.c292
-rw-r--r--drivers/serial/serial_txx9.c2
18 files changed, 395 insertions, 182 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 57438326b07f94..76d83ade9857ea 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/char/21285.c
+ * linux/drivers/serial/21285.c
*
* Driver for the serial port on the 21285 StrongArm-110 core logic chip.
*
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 993a702422ec6e..bac853c5abb565 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -1378,7 +1378,7 @@ void startup_console(void)
#endif /* CONFIG_PM_LEGACY */
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index e80e70e9b12620..1b299e8c57cdf7 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -2424,7 +2424,7 @@ long console_360_init(long kmem_start, long kmem_end)
*/
static int baud_idx;
-static struct tty_operations rs_360_ops = {
+static const struct tty_operations rs_360_ops = {
.owner = THIS_MODULE,
.open = rs_360_open,
.close = rs_360_close,
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0ae9ced00ed4db..cc2a205d42300a 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -320,8 +320,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
case UPIO_TSI:
if (offset == UART_IIR) {
- tmp = readl((u32 *)(up->port.membase + UART_RX));
- return (cpu_to_le32(tmp) >> 8) & 0xff;
+ tmp = readl(up->port.membase + (UART_IIR & ~3));
+ return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
} else
return readb(up->port.membase + offset);
@@ -1896,6 +1896,17 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
serial_outp(up, UART_EFR, efr);
}
+#ifdef CONFIG_ARCH_OMAP15XX
+ /* Workaround to enable 115200 baud on OMAP1510 internal ports */
+ if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+ if (baud == 115200) {
+ quot = 1;
+ serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
+ } else
+ serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
+ }
+#endif
+
if (up->capabilities & UART_NATSEMI) {
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
serial_outp(up, UART_LCR, 0xe0);
@@ -1949,6 +1960,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
case UPIO_AU:
size = 0x100000;
/* fall thru */
+ case UPIO_TSI:
+ case UPIO_MEM32:
case UPIO_MEM:
if (!up->port.mapbase)
break;
@@ -1984,6 +1997,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
case UPIO_AU:
size = 0x100000;
/* fall thru */
+ case UPIO_TSI:
+ case UPIO_MEM32:
case UPIO_MEM:
if (!up->port.mapbase)
break;
@@ -2007,17 +2022,15 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up)
{
unsigned long start = UART_RSA_BASE << up->port.regshift;
unsigned int size = 8 << up->port.regshift;
- int ret = 0;
+ int ret = -EINVAL;
switch (up->port.iotype) {
- case UPIO_MEM:
- ret = -EINVAL;
- break;
-
case UPIO_HUB6:
case UPIO_PORT:
start += up->port.iobase;
- if (!request_region(start, size, "serial-rsa"))
+ if (request_region(start, size, "serial-rsa"))
+ ret = 0;
+ else
ret = -EBUSY;
break;
}
@@ -2031,9 +2044,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
unsigned int size = 8 << up->port.regshift;
switch (up->port.iotype) {
- case UPIO_MEM:
- break;
-
case UPIO_HUB6:
case UPIO_PORT:
release_region(up->port.iobase + offset, size);
@@ -2222,9 +2232,10 @@ 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 (--tmout &&
- ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+ while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
udelay(1);
+ touch_nmi_watchdog();
+ }
}
}
@@ -2397,7 +2408,6 @@ int __init early_serial_setup(struct uart_port *port)
/**
* serial8250_suspend_port - suspend one serial port
* @line: serial line number
- * @level: the level of port suspension, as per uart_suspend_port
*
* Suspend one serial port.
*/
@@ -2409,7 +2419,6 @@ void serial8250_suspend_port(int line)
/**
* serial8250_resume_port - resume one serial port
* @line: serial line number
- * @level: the level of port resumption, as per uart_resume_port
*
* Resume one serial port.
*/
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 1ebe6b585d2d57..c5d0addfda4f94 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -22,7 +22,6 @@
#include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/io.h>
-#include <asm/serial.h> /* for LASI_BASE_BAUD */
#include "8250.h"
@@ -54,7 +53,8 @@ serial_init_chip(struct parisc_device *dev)
memset(&port, 0, sizeof(port));
port.iotype = UPIO_MEM;
- port.uartclk = LASI_BASE_BAUD * 16;
+ /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */
+ port.uartclk = 7272727;
port.mapbase = address;
port.membase = ioremap_nocache(address, 16);
port.irq = dev->irq;
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 851e4839d6d97c..4d0ff8f4a01b14 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1789,6 +1789,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
pci_disable_device(dev);
}
+#ifdef CONFIG_PM
static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
{
struct serial_private *priv = pci_get_drvdata(dev);
@@ -1818,6 +1819,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
}
return 0;
}
+#endif
static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
@@ -2375,8 +2377,10 @@ static struct pci_driver serial_pci_driver = {
.name = "serial",
.probe = pciserial_init_one,
.remove = __devexit_p(pciserial_remove_one),
+#ifdef CONFIG_PM
.suspend = pciserial_suspend_one,
.resume = pciserial_resume_one,
+#endif
.id_table = serial_pci_tbl,
};
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 632f62d6ec7e77..71d907c8288b15 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,19 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "WACF004", 0 },
{ "WACF005", 0 },
{ "WACF006", 0 },
+ /* Compaq touchscreen */
+ { "FPI2002", 0 },
+ /* Fujitsu Stylistic touchscreens */
+ { "FUJ02B2", 0 },
+ { "FUJ02B3", 0 },
+ /* Fujitsu Stylistic LT touchscreens */
+ { "FUJ02B4", 0 },
+ /* Passive Fujitsu Stylistic touchscreens */
+ { "FUJ02B6", 0 },
+ { "FUJ02B7", 0 },
+ { "FUJ02B8", 0 },
+ { "FUJ02B9", 0 },
+ { "FUJ02BC", 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
{ "WCI0003", 0 },
/* Unkown PnP modems */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d926272a40db59..8edee745888a73 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -121,7 +121,7 @@ config SERIAL_8250_RUNTIME_UARTS
default "4"
help
Set this to the maximum number of serial ports you want
- the kernel to register at boot time. This can be overriden
+ the kernel to register at boot time. This can be overridden
with the module parameter "nr_uarts", or boot-time parameter
8250.nr_uarts
@@ -205,7 +205,7 @@ config SERIAL_8250_BOCA
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
help
Say Y here if you have a Boca serial board. Please read the Boca
- mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto>
+ mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
To compile this driver as a module, choose M here: the module
will be called 8250_boca.
@@ -556,10 +556,11 @@ config SERIAL_MUX
default y
---help---
Saying Y here will enable the hardware MUX serial driver for
- the Nova and K class systems. The hardware MUX is not 8250/16550
- compatible therefore the /dev/ttyB0 device is shared between the
- Serial MUX and the PDC software console. The following steps
- need to be completed to use the Serial MUX:
+ the Nova, K class systems and D class with a 'remote control card'.
+ The hardware MUX is not 8250/16550 compatible therefore the
+ /dev/ttyB0 device is shared between the Serial MUX and the PDC
+ software console. The following steps need to be completed to use
+ the Serial MUX:
1. create the device entry (mknod /dev/ttyB0 c 11 0)
2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
@@ -667,7 +668,7 @@ config SERIAL_68328
depends on M68328 || M68EZ328 || M68VZ328
help
This driver supports the built-in serial port of the Motorola 68328
- (standard, EZ and VZ varities).
+ (standard, EZ and VZ varieties).
config SERIAL_68328_RTS_CTS
bool "Support RTS/CTS on 68328 serial port"
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 90ff96e3339bce..a0d6136deb9b0d 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -46,6 +46,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
+#include <asm/fs_pd.h>
#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -1022,15 +1023,17 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
{
struct resource *r;
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
- int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
+ int idx; /* It is UART_SMCx or UART_SCCx index */
struct uart_cpm_port *pinfo;
int line;
u32 mem, pram;
+ idx = pdata->fs_no = fs_uart_get_id(pdata);
+
line = cpm_uart_id2nr(idx);
if(line < 0) {
printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
- return -1;
+ return -EINVAL;
}
pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
@@ -1044,11 +1047,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
return -EINVAL;
- mem = r->start;
+ mem = (u32)ioremap(r->start, r->end - r->start + 1);
if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
return -EINVAL;
- pram = r->start;
+ pram = (u32)ioremap(r->start, r->end - r->start + 1);
if(idx > fsid_smc2_uart) {
pinfo->sccp = (scc_t *)mem;
@@ -1179,7 +1182,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
pdata = pdev->dev.platform_data;
if (pdata)
if (pdata->init_ioports)
- pdata->init_ioports();
+ pdata->init_ioports(pdata);
cpm_uart_drv_get_platform_data(pdev, 1);
}
@@ -1189,11 +1192,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
if (options) {
uart_parse_options(options, &baud, &parity, &bits, &flow);
} else {
- bd_t *bd = (bd_t *) __res;
-
- if (bd->bi_baudrate)
- baud = bd->bi_baudrate;
- else
+ if ((baud = uart_baudrate()) == -1)
baud = 9600;
}
@@ -1266,13 +1265,14 @@ static int cpm_uart_drv_probe(struct device *dev)
}
pdata = pdev->dev.platform_data;
- pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
return ret;
+ pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
+
if (pdata->init_ioports)
- pdata->init_ioports();
+ pdata->init_ioports(pdata);
ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
index 5d867ab581b71f..5eb49ea63bfe4b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/serial/cpm_uart_cpm1.h
+ * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
*
* Driver for CPM (SCC/SMC) serial ports
*
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index ef3bb476c4326a..b691d3e14754fa 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -40,6 +40,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/fs_pd.h>
#include <linux/serial_core.h>
#include <linux/kernel.h>
@@ -50,8 +51,9 @@
void cpm_line_cr_cmd(int line, int cmd)
{
- volatile cpm_cpm2_t *cp = cpmp;
ulong val;
+ volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
+
switch (line) {
case UART_SMC1:
@@ -84,11 +86,14 @@ void cpm_line_cr_cmd(int line, int cmd)
}
cp->cp_cpcr = val;
while (cp->cp_cpcr & CPM_CR_FLG) ;
+
+ cpm2_unmap(cp);
}
void smc1_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
/* SMC1 is only on port D */
io->iop_ppard |= 0x00c00000;
@@ -97,13 +102,17 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
io->iop_psord &= ~0x00c00000;
/* Wire BRG1 to SMC1 */
- cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+ cpmux->cmx_smr &= 0x0f;
pinfo->brg = 1;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void smc2_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
/* SMC2 is only on port A */
io->iop_ppara |= 0x00c00000;
@@ -112,13 +121,17 @@ void smc2_lineif(struct uart_cpm_port *pinfo)
io->iop_psora &= ~0x00c00000;
/* Wire BRG2 to SMC2 */
- cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+ cpmux->cmx_smr &= 0xf0;
pinfo->brg = 2;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc1_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
/* Use Port D for SCC1 instead of other functions. */
io->iop_ppard |= 0x00000003;
@@ -128,9 +141,12 @@ void scc1_lineif(struct uart_cpm_port *pinfo)
io->iop_pdird |= 0x00000002; /* Tx */
/* Wire BRG1 to SCC1 */
- cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
- cpm2_immr->im_cpmux.cmx_scr |= 0x00000000;
+ cpmux->cmx_scr &= 0x00ffffff;
+ cpmux->cmx_scr |= 0x00000000;
pinfo->brg = 1;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc2_lineif(struct uart_cpm_port *pinfo)
@@ -143,43 +159,57 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
* be supported in a sane fashion.
*/
#ifndef CONFIG_STX_GP3
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
#endif
- cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
- cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
+ cpmux->cmx_scr &= 0xff00ffff;
+ cpmux->cmx_scr |= 0x00090000;
pinfo->brg = 2;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc3_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
- cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
- cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
+ cpmux->cmx_scr &= 0xffff00ff;
+ cpmux->cmx_scr |= 0x00001200;
pinfo->brg = 3;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
void scc4_lineif(struct uart_cpm_port *pinfo)
{
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
io->iop_ppard |= 0x00000600;
io->iop_psord &= ~0x00000600; /* Tx/Rx */
io->iop_pdird &= ~0x00000200; /* Rx */
io->iop_pdird |= 0x00000400; /* Tx */
- cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
- cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
+ cpmux->cmx_scr &= 0xffffff00;
+ cpmux->cmx_scr |= 0x0000001b;
pinfo->brg = 4;
+
+ cpm2_unmap(cpmux);
+ cpm2_unmap(io);
}
/*
@@ -254,88 +284,103 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
/* Setup any dynamic params in the uart desc */
int cpm_uart_init_portdesc(void)
{
+#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
+ u32 addr;
+#endif
pr_debug("CPM uart[-]:init portdesc\n");
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
- cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
- cpm_uart_ports[UART_SMC1].smcup =
- (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1];
- *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+ cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
cpm_uart_ports[UART_SMC1].port.mapbase =
- (unsigned long)&cpm2_immr->im_smc[0];
+ (unsigned long)cpm_uart_ports[UART_SMC1].smcp;
+
+ cpm_uart_ports[UART_SMC1].smcup =
+ (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
+ addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
+ *addr = PROFF_SMC1;
+ cpm2_unmap(addr);
+
cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
- cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
#endif
#ifdef CONFIG_SERIAL_CPM_SMC2
- cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1];
- cpm_uart_ports[UART_SMC2].smcup =
- (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2];
- *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+ cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
cpm_uart_ports[UART_SMC2].port.mapbase =
- (unsigned long)&cpm2_immr->im_smc[1];
+ (unsigned long)cpm_uart_ports[UART_SMC2].smcp;
+
+ cpm_uart_ports[UART_SMC2].smcup =
+ (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
+ addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
+ *addr = PROFF_SMC2;
+ cpm2_unmap(addr);
+
cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
- cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC1
- cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0];
- cpm_uart_ports[UART_SCC1].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1];
+ cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
cpm_uart_ports[UART_SCC1].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[0];
+ (unsigned long)cpm_uart_ports[UART_SCC1].sccp;
+ cpm_uart_ports[UART_SCC1].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC2
- cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1];
- cpm_uart_ports[UART_SCC2].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2];
+ cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
cpm_uart_ports[UART_SCC2].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[1];
+ (unsigned long)cpm_uart_ports[UART_SCC2].sccp;
+ cpm_uart_ports[UART_SCC2].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC3
- cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2];
- cpm_uart_ports[UART_SCC3].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3];
+ cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
cpm_uart_ports[UART_SCC3].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[2];
+ (unsigned long)cpm_uart_ports[UART_SCC3].sccp;
+ cpm_uart_ports[UART_SCC3].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC4
- cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3];
- cpm_uart_ports[UART_SCC4].sccup =
- (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4];
+ cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
cpm_uart_ports[UART_SCC4].port.mapbase =
- (unsigned long)&cpm2_immr->im_scc[3];
+ (unsigned long)cpm_uart_ports[UART_SCC4].sccp;
+ cpm_uart_ports[UART_SCC4].sccup =
+ (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);
+
cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
~(UART_SCCM_TX | UART_SCCM_RX);
cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+ cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
#endif
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
index 4793fecf8ecef8..4b779111eaf9cc 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/serial/cpm_uart_cpm2.h
+ * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
*
* Driver for CPM (SCC/SMC) serial ports
*
@@ -40,6 +40,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB;
}
-#define DPRAM_BASE ((unsigned char *)&cpm2_immr->im_dprambase[0])
+#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0))
#endif
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index cabd048c863606..9851d9eff022a6 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4825,7 +4825,7 @@ show_serial_version(void)
/* rs_init inits the driver at boot (using the module_init chain) */
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index e7fe4bb46ecaf2..28c9ce6f0bdc52 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -76,7 +76,7 @@
*/
#define is_real_interrupt(irq) ((irq) != 0)
-#include <asm/serial.h>
+#define BASE_BAUD 115200
/* Standard COM flags */
#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
@@ -86,7 +86,6 @@
* standard enumeration mechanism. Platforms that can find all
* serial ports via mechanisms like ACPI or PCI need not supply it.
*/
-#undef SERIAL_PORT_DFNS
#if defined(CONFIG_PLAT_USRV)
#define SERIAL_PORT_DFNS \
@@ -109,7 +108,7 @@
#endif /* !CONFIG_PLAT_USRV */
static struct old_serial_port old_serial_port[] = {
- SERIAL_PORT_DFNS /* defined in asm/serial.h */
+ SERIAL_PORT_DFNS
};
#define UART_NR ARRAY_SIZE(old_serial_port)
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 832abd3c4706dd..00d7859c167ec7 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -1666,7 +1666,7 @@ static void show_serial_version(void)
printk(mcfrs_drivername);
}
-static struct tty_operations mcfrs_ops = {
+static const struct tty_operations mcfrs_ops = {
.open = mcfrs_open,
.close = mcfrs_close,
.write = mcfrs_write,
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 5f7ba1adb309c2..c67b05e9a45144 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -792,6 +792,7 @@ static int uart_set_info(struct uart_state *state,
* We failed anyway.
*/
retval = -EBUSY;
+ goto exit; // Added to return the correct error -Ram Gupta
}
}
@@ -1662,16 +1663,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
struct uart_port *port = state->port;
char stat_buf[32];
unsigned int status;
- int ret;
+ int mmio, ret;
if (!port)
return 0;
+ mmio = port->iotype >= UPIO_MEM;
ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
port->line, uart_type(port),
- port->iotype == UPIO_MEM ? "mmio:0x" : "port:",
- port->iotype == UPIO_MEM ? port->mapbase :
- (unsigned long) port->iobase,
+ mmio ? "mmio:0x" : "port:",
+ mmio ? port->mapbase : (unsigned long) port->iobase,
port->irq);
if (port->type == PORT_UNKNOWN) {
@@ -1939,6 +1940,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
if (state->info && state->info->flags & UIF_INITIALIZED) {
const struct uart_ops *ops = port->ops;
+ state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+ | UIF_SUSPENDED;
+
spin_lock_irq(&port->lock);
ops->stop_tx(port);
ops->set_mctrl(port, 0);
@@ -2005,7 +2009,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
console_start(port->cons);
}
- if (state->info && state->info->flags & UIF_INITIALIZED) {
+ if (state->info && state->info->flags & UIF_SUSPENDED) {
const struct uart_ops *ops = port->ops;
int ret;
@@ -2017,15 +2021,17 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
ops->set_mctrl(port, port->mctrl);
ops->start_tx(port);
spin_unlock_irq(&port->lock);
+ state->info->flags |= UIF_INITIALIZED;
} 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);
}
+
+ state->info->flags &= ~UIF_SUSPENDED;
}
mutex_unlock(&state->mutex);
@@ -2111,7 +2117,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
}
}
-static struct tty_operations uart_ops = {
+static const struct tty_operations uart_ops = {
.open = uart_open,
.close = uart_close,
.write = uart_write,
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index cbf260bc225dc6..00f9ffd6948969 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -80,23 +80,16 @@ module_param(buggy_uart, int, 0444);
/* Table of multi-port card ID's */
-struct multi_id {
- u_short manfid;
- u_short prodid;
+struct serial_quirk {
+ unsigned int manfid;
+ unsigned int prodid;
int multi; /* 1 = multifunction, > 1 = # ports */
+ void (*config)(struct pcmcia_device *);
+ void (*setup)(struct pcmcia_device *, struct uart_port *);
+ void (*wakeup)(struct pcmcia_device *);
+ int (*post)(struct pcmcia_device *);
};
-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 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
- { MANFID_SOCKET, PRODID_SOCKET_DUAL_RS232, 2 },
- { MANFID_INTEL, PRODID_INTEL_DUAL_RS232, 2 },
- { MANFID_NATINST, PRODID_NATINST_QUAD_RS232, 4 }
-};
-#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
-
struct serial_info {
struct pcmcia_device *p_dev;
int ndev;
@@ -107,6 +100,7 @@ struct serial_info {
int c950ctrl;
dev_node_t node[4];
int line[4];
+ const struct serial_quirk *quirk;
};
struct serial_cfg_mem {
@@ -115,37 +109,165 @@ struct serial_cfg_mem {
u_char buf[256];
};
+/*
+ * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
+ * manfid 0x0160, 0x0104
+ * This card appears to have a 14.7456MHz clock.
+ */
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+{
+ port->uartclk = 14745600;
+}
-static int serial_config(struct pcmcia_device * link);
+static int quirk_post_ibm(struct pcmcia_device *link)
+{
+ conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+ int last_ret, last_fn;
+ last_ret = pcmcia_access_configuration_register(link, &reg);
+ if (last_ret) {
+ last_fn = AccessConfigurationRegister;
+ goto cs_failed;
+ }
+ reg.Action = CS_WRITE;
+ reg.Value = reg.Value | 1;
+ last_ret = pcmcia_access_configuration_register(link, &reg);
+ if (last_ret) {
+ last_fn = AccessConfigurationRegister;
+ goto cs_failed;
+ }
+ return 0;
-static void wakeup_card(struct serial_info *info)
+ cs_failed:
+ cs_error(link, last_fn, last_ret);
+ return -ENODEV;
+}
+
+/*
+ * Nokia cards are not really multiport cards. Shouldn't this
+ * be handled by setting the quirk entry .multi = 0 | 1 ?
+ */
+static void quirk_config_nokia(struct pcmcia_device *link)
{
- int ctrl = info->c950ctrl;
-
- if (info->manfid == MANFID_OXSEMI) {
- outb(12, ctrl + 1);
- } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
- /* request_region? oxsemi branch does no request_region too... */
- /* This sequence is needed to properly initialize MC45 attached to OXCF950.
- * I tried decreasing these msleep()s, but it worked properly (survived
- * 1000 stop/start operations) with these timeouts (or bigger). */
- outb(0xA, ctrl + 1);
- msleep(100);
- outb(0xE, ctrl + 1);
- msleep(300);
- outb(0xC, ctrl + 1);
- msleep(100);
- outb(0xE, ctrl + 1);
- msleep(200);
- outb(0xF, ctrl + 1);
- msleep(100);
- outb(0xE, ctrl + 1);
- msleep(100);
- outb(0xC, ctrl + 1);
+ struct serial_info *info = link->priv;
+
+ if (info->multi > 1)
+ info->multi = 1;
+}
+
+static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
+{
+ struct serial_info *info = link->priv;
+
+ outb(12, info->c950ctrl + 1);
+}
+
+/* request_region? oxsemi branch does no request_region too... */
+/*
+ * This sequence is needed to properly initialize MC45 attached to OXCF950.
+ * I tried decreasing these msleep()s, but it worked properly (survived
+ * 1000 stop/start operations) with these timeouts (or bigger).
+ */
+static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
+{
+ struct serial_info *info = link->priv;
+ unsigned int ctrl = info->c950ctrl;
+
+ outb(0xA, ctrl + 1);
+ msleep(100);
+ outb(0xE, ctrl + 1);
+ msleep(300);
+ outb(0xC, ctrl + 1);
+ msleep(100);
+ outb(0xE, ctrl + 1);
+ msleep(200);
+ outb(0xF, ctrl + 1);
+ msleep(100);
+ outb(0xE, ctrl + 1);
+ msleep(100);
+ outb(0xC, ctrl + 1);
+}
+
+/*
+ * Socket Dual IO: this enables irq's for second port
+ */
+static void quirk_config_socket(struct pcmcia_device *link)
+{
+ struct serial_info *info = link->priv;
+
+ if (info->multi) {
+ link->conf.Present |= PRESENT_EXT_STATUS;
+ link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
}
}
+static const struct serial_quirk quirks[] = {
+ {
+ .manfid = 0x0160,
+ .prodid = 0x0104,
+ .multi = -1,
+ .setup = quirk_setup_brainboxes_0104,
+ }, {
+ .manfid = MANFID_IBM,
+ .prodid = ~0,
+ .multi = -1,
+ .post = quirk_post_ibm,
+ }, {
+ .manfid = MANFID_INTEL,
+ .prodid = PRODID_INTEL_DUAL_RS232,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_NATINST,
+ .prodid = PRODID_NATINST_QUAD_RS232,
+ .multi = 4,
+ }, {
+ .manfid = MANFID_NOKIA,
+ .prodid = ~0,
+ .multi = -1,
+ .config = quirk_config_nokia,
+ }, {
+ .manfid = MANFID_OMEGA,
+ .prodid = PRODID_OMEGA_QSP_100,
+ .multi = 4,
+ }, {
+ .manfid = MANFID_OXSEMI,
+ .prodid = ~0,
+ .multi = -1,
+ .wakeup = quirk_wakeup_oxsemi,
+ }, {
+ .manfid = MANFID_POSSIO,
+ .prodid = PRODID_POSSIO_GCC,
+ .multi = -1,
+ .wakeup = quirk_wakeup_possio_gcc,
+ }, {
+ .manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_DUAL_RS232,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_DUAL_RS232_D1,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_QUAD_RS232,
+ .multi = 4,
+ }, {
+ .manfid = MANFID_SOCKET,
+ .prodid = PRODID_SOCKET_DUAL_RS232,
+ .multi = 2,
+ .config = quirk_config_socket,
+ }, {
+ .manfid = MANFID_SOCKET,
+ .prodid = ~0,
+ .multi = -1,
+ .config = quirk_config_socket,
+ }
+};
+
+
+static int serial_config(struct pcmcia_device * link);
+
+
/*======================================================================
After a card is removed, serial_remove() will unregister
@@ -185,14 +307,14 @@ static int serial_suspend(struct pcmcia_device *link)
static int serial_resume(struct pcmcia_device *link)
{
- if (pcmcia_dev_present(link)) {
- struct serial_info *info = link->priv;
- int i;
+ struct serial_info *info = link->priv;
+ int i;
- for (i = 0; i < info->ndev; i++)
- serial8250_resume_port(info->line[i]);
- wakeup_card(info);
- }
+ for (i = 0; i < info->ndev; i++)
+ serial8250_resume_port(info->line[i]);
+
+ if (info->quirk && info->quirk->wakeup)
+ info->quirk->wakeup(link);
return 0;
}
@@ -278,6 +400,10 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
port.dev = &handle_to_dev(handle);
if (buggy_uart)
port.flags |= UPF_BUGGY_UART;
+
+ if (info->quirk && info->quirk->setup)
+ info->quirk->setup(handle, &port);
+
line = serial8250_register_port(&port);
if (line < 0) {
printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
@@ -433,6 +559,13 @@ next_entry:
}
if (info->multi && (info->manfid == MANFID_3COM))
link->conf.ConfigIndex &= ~(0x08);
+
+ /*
+ * Apply any configuration quirks.
+ */
+ if (info->quirk && info->quirk->config)
+ info->quirk->config(link);
+
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link, RequestConfiguration, i);
@@ -521,11 +654,13 @@ static int multi_config(struct pcmcia_device * link)
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
- /* Socket Dual IO: this enables irq's for second port */
- if (info->multi && (info->manfid == MANFID_SOCKET)) {
- link->conf.Present |= PRESENT_EXT_STATUS;
- link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
- }
+
+ /*
+ * Apply any configuration quirks.
+ */
+ if (info->quirk && info->quirk->config)
+ info->quirk->config(link);
+
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link, RequestConfiguration, i);
@@ -550,17 +685,19 @@ static int multi_config(struct pcmcia_device * link)
link->irq.AssignedIRQ);
}
info->c950ctrl = base2;
- wakeup_card(info);
+
+ /*
+ * FIXME: We really should wake up the port prior to
+ * handing it over to the serial layer.
+ */
+ if (info->quirk && info->quirk->wakeup)
+ info->quirk->wakeup(link);
+
rc = 0;
goto free_cfg_mem;
}
setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
- /* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA) {
- rc = 0;
- goto free_cfg_mem;
- }
for (i = 0; i < info->multi - 1; i++)
setup_serial(link, info, base2 + (8 * i),
link->irq.AssignedIRQ);
@@ -622,13 +759,16 @@ static int serial_config(struct pcmcia_device * link)
tuple->DesiredTuple = CISTPL_MANFID;
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
info->manfid = parse->manfid.manf;
- info->prodid = le16_to_cpu(buf[1]);
- for (i = 0; i < MULTI_COUNT; i++)
- if ((info->manfid == multi_id[i].manfid) &&
- (parse->manfid.card == multi_id[i].prodid))
+ info->prodid = parse->manfid.card;
+
+ for (i = 0; i < ARRAY_SIZE(quirks); i++)
+ if ((quirks[i].manfid == ~0 ||
+ quirks[i].manfid == info->manfid) &&
+ (quirks[i].prodid == ~0 ||
+ quirks[i].prodid == info->prodid)) {
+ info->quirk = &quirks[i];
break;
- if (i < MULTI_COUNT)
- info->multi = multi_id[i].multi;
+ }
}
/* Another check for dual-serial cards: look for either serial or
@@ -648,6 +788,12 @@ static int serial_config(struct pcmcia_device * link)
}
}
+ /*
+ * Apply any multi-port quirk.
+ */
+ if (info->quirk && info->quirk->multi != -1)
+ info->multi = info->quirk->multi;
+
if (info->multi > 1)
multi_config(link);
else
@@ -656,21 +802,13 @@ static int serial_config(struct pcmcia_device * link)
if (info->ndev == 0)
goto failed;
- if (info->manfid == MANFID_IBM) {
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- last_ret = pcmcia_access_configuration_register(link, &reg);
- if (last_ret) {
- last_fn = AccessConfigurationRegister;
- goto cs_failed;
- }
- reg.Action = CS_WRITE;
- reg.Value = reg.Value | 1;
- last_ret = pcmcia_access_configuration_register(link, &reg);
- if (last_ret) {
- last_fn = AccessConfigurationRegister;
- goto cs_failed;
- }
- }
+ /*
+ * Apply any post-init quirk. FIXME: This should really happen
+ * before we register the port, since it might already be in use.
+ */
+ if (info->quirk && info->quirk->post)
+ if (info->quirk->post(link))
+ goto failed;
link->dev_node = &info->node[0];
kfree(cfg_mem);
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index b361669f85a17b..ebd8d2bb17fd24 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -990,7 +990,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
/**
* serial_txx9_suspend_port - suspend one serial port
* @line: serial line number
- * @level: the level of port suspension, as per uart_suspend_port
*
* Suspend one serial port.
*/
@@ -1002,7 +1001,6 @@ static void serial_txx9_suspend_port(int line)
/**
* serial_txx9_resume_port - resume one serial port
* @line: serial line number
- * @level: the level of port resumption, as per uart_resume_port
*
* Resume one serial port.
*/