summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-07-24 09:49:13 -0600
committerGrant Likely <grant.likely@secretlab.ca>2010-07-24 09:49:13 -0600
commit4e4f62bf7396fca48efe61513640ee399a6046e3 (patch)
tree42a503af02d9806bcc05e5fcc2cd53f9bd45b0c2 /drivers/serial
parent9e3288dc9a94fab5ea87db42177d3a9e0345a614 (diff)
parentb37fa16e78d6f9790462b3181602a26b5af36260 (diff)
Merge commit 'v2.6.35-rc6' into devicetree/next
Conflicts: arch/sparc/kernel/prom_64.c
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c143
-rw-r--r--drivers/serial/serial_cs.c1
-rw-r--r--drivers/serial/suncore.c4
-rw-r--r--drivers/serial/sunsu.c13
4 files changed, 92 insertions, 69 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 9eb62a256e9..cd6cf575902 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
}
}
+#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE)
+/*
+ * Write a string to the serial port
+ * Note that this is called with interrupts already disabled
+ */
+static void cpm_uart_early_write(struct uart_cpm_port *pinfo,
+ const char *string, u_int count)
+{
+ unsigned int i;
+ cbd_t __iomem *bdp, *bdbase;
+ unsigned char *cpm_outp_addr;
+
+ /* Get the address of the host memory buffer.
+ */
+ bdp = pinfo->tx_cur;
+ bdbase = pinfo->tx_bd_base;
+
+ /*
+ * Now, do each character. This is not as bad as it looks
+ * since this is a holding FIFO and not a transmitting FIFO.
+ * We could add the complexity of filling the entire transmit
+ * buffer, but we would just wait longer between accesses......
+ */
+ for (i = 0; i < count; i++, string++) {
+ /* Wait for transmitter fifo to empty.
+ * Ready indicates output is ready, and xmt is doing
+ * that, not that it is ready for us to send.
+ */
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
+ ;
+
+ /* Send the character out.
+ * If the buffer address is in the CPM DPRAM, don't
+ * convert it.
+ */
+ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr),
+ pinfo);
+ *cpm_outp_addr = *string;
+
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
+
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
+ bdp = bdbase;
+ else
+ bdp++;
+
+ /* if a LF, also do CR... */
+ if (*string == 10) {
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
+ ;
+
+ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr),
+ pinfo);
+ *cpm_outp_addr = 13;
+
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
+
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
+ bdp = bdbase;
+ else
+ bdp++;
+ }
+ }
+
+ /*
+ * Finally, Wait for transmitter & holding register to empty
+ * and restore the IER
+ */
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
+ ;
+
+ pinfo->tx_cur = bdp;
+}
+#endif
+
#ifdef CONFIG_CONSOLE_POLL
/* Serial polling routines for writing and reading from the uart while
* in an interrupt or debug context.
@@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port,
static char ch[2];
ch[0] = (char)c;
- cpm_uart_early_write(pinfo->port.line, ch, 1);
+ cpm_uart_early_write(pinfo, ch, 1);
}
#endif /* CONFIG_CONSOLE_POLL */
@@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s,
u_int count)
{
struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
- unsigned int i;
- cbd_t __iomem *bdp, *bdbase;
- unsigned char *cp;
unsigned long flags;
int nolock = oops_in_progress;
@@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
spin_lock_irqsave(&pinfo->port.lock, flags);
}
- /* Get the address of the host memory buffer.
- */
- bdp = pinfo->tx_cur;
- bdbase = pinfo->tx_bd_base;
-
- /*
- * Now, do each character. This is not as bad as it looks
- * since this is a holding FIFO and not a transmitting FIFO.
- * We could add the complexity of filling the entire transmit
- * buffer, but we would just wait longer between accesses......
- */
- for (i = 0; i < count; i++, s++) {
- /* Wait for transmitter fifo to empty.
- * Ready indicates output is ready, and xmt is doing
- * that, not that it is ready for us to send.
- */
- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
- ;
-
- /* Send the character out.
- * If the buffer address is in the CPM DPRAM, don't
- * convert it.
- */
- cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
- *cp = *s;
-
- out_be16(&bdp->cbd_datlen, 1);
- setbits16(&bdp->cbd_sc, BD_SC_READY);
-
- if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
- bdp = bdbase;
- else
- bdp++;
-
- /* if a LF, also do CR... */
- if (*s == 10) {
- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
- ;
-
- cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
- *cp = 13;
-
- out_be16(&bdp->cbd_datlen, 1);
- setbits16(&bdp->cbd_sc, BD_SC_READY);
-
- if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
- bdp = bdbase;
- else
- bdp++;
- }
- }
-
- /*
- * Finally, Wait for transmitter & holding register to empty
- * and restore the IER
- */
- while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
- ;
-
- pinfo->tx_cur = bdp;
+ cpm_uart_early_write(pinfo, s, count);
if (unlikely(nolock)) {
local_irq_restore(flags);
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 526307368f8..ab17c08ddc0 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -821,6 +821,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index ed7d958b0a0..544f2e25d0e 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -71,7 +71,9 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
con->index = line;
drv->cons = con;
- add_preferred_console(con->name, line, NULL);
+
+ if (!console_set_on_cmdline)
+ add_preferred_console(con->name, line, NULL);
return 1;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 56d891acf29..5deafc8180b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1500,20 +1500,25 @@ out_unmap:
static int __devexit su_remove(struct of_device *op)
{
struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
+ bool kbdms = false;
if (up->su_type == SU_PORT_MS ||
- up->su_type == SU_PORT_KBD) {
+ up->su_type == SU_PORT_KBD)
+ kbdms = true;
+
+ if (kbdms) {
#ifdef CONFIG_SERIO
serio_unregister_port(&up->serio);
#endif
- kfree(up);
- } else if (up->port.type != PORT_UNKNOWN) {
+ } else if (up->port.type != PORT_UNKNOWN)
uart_remove_one_port(&sunsu_reg, &up->port);
- }
if (up->port.membase)
of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
+ if (kbdms)
+ kfree(up);
+
dev_set_drvdata(&op->dev, NULL);
return 0;