summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250.c10
-rw-r--r--drivers/serial/8250_pnp.c3
-rw-r--r--drivers/serial/Kconfig3
-rw-r--r--drivers/serial/atmel_serial.c3
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c2
-rw-r--r--drivers/serial/dz.c7
-rw-r--r--drivers/serial/icom.c9
-rw-r--r--drivers/serial/icom.h1
-rw-r--r--drivers/serial/imx.c14
-rw-r--r--drivers/serial/mcfserial.c44
-rw-r--r--drivers/serial/mpc52xx_uart.c4
-rw-r--r--drivers/serial/mux.c167
-rw-r--r--drivers/serial/pmac_zilog.c4
-rw-r--r--drivers/serial/serial_cs.c5
-rw-r--r--drivers/serial/serial_txx9.c276
-rw-r--r--drivers/serial/sh-sci.c11
-rw-r--r--drivers/serial/sn_console.c52
-rw-r--r--drivers/serial/sunsu.c4
18 files changed, 403 insertions, 216 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 98ec8618532..90621c3312b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1196,7 +1196,7 @@ static void serial8250_enable_ms(struct uart_port *port)
}
static void
-receive_chars(struct uart_8250_port *up, int *status)
+receive_chars(struct uart_8250_port *up, unsigned int *status)
{
struct tty_struct *tty = up->port.info->tty;
unsigned char ch, lsr = *status;
@@ -1310,7 +1310,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
{
unsigned int status = serial_in(up, UART_MSR);
- if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) {
+ if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+ up->port.info != NULL) {
if (status & UART_MSR_TERI)
up->port.icount.rng++;
if (status & UART_MSR_DDSR)
@@ -1333,8 +1334,9 @@ static inline void
serial8250_handle_port(struct uart_8250_port *up)
{
unsigned int status;
+ unsigned long flags;
- spin_lock(&up->port.lock);
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_inp(up, UART_LSR);
@@ -1346,7 +1348,7 @@ serial8250_handle_port(struct uart_8250_port *up)
if (status & UART_LSR_THRE)
transmit_chars(up);
- spin_unlock(&up->port.lock);
+ spin_unlock_irqrestore(&up->port.lock, flags);
}
/*
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index cde5db44abf..301c8c0be9d 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -340,6 +340,9 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "FUJ02B8", 0 },
{ "FUJ02B9", 0 },
{ "FUJ02BC", 0 },
+ /* Fujitsu Wacom Tablet PC devices */
+ { "FUJ02E5", 0 },
+ { "FUJ02E6", 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
{ "WCI0003", 0 },
/* Unkown PnP modems */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e8dd71df916..ad9f321968e 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -262,7 +262,8 @@ config SERIAL_AMBA_PL010
select SERIAL_CORE
help
This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have
- an Integrator/AP or Integrator/PP2 platform, say Y or M here.
+ an Integrator/AP or Integrator/PP2 platform, or if you have a
+ Cirrus Logic EP93xx CPU, say Y or M here.
If unsure, say N.
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index df45a7ac773..935f48fa501 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -33,12 +33,13 @@
#include <linux/sysrq.h>
#include <linux/tty_flip.h>
#include <linux/platform_device.h>
+#include <linux/atmel_pdc.h>
#include <asm/io.h>
#include <asm/mach/serial_at91.h>
#include <asm/arch/board.h>
-#include <asm/arch/at91_pdc.h>
+
#ifdef CONFIG_ARM
#include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 787a8f13467..fa455996ad8 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -285,7 +285,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
int __init cpm_uart_init_portdesc(void)
{
#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
- u32 addr;
+ u16 *addr;
#endif
pr_debug("CPM uart[-]:init portdesc\n");
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 587d87b9eb3..d31721f2744 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -170,8 +170,7 @@ static void dz_enable_ms(struct uart_port *port)
* This routine deals with inputs from any lines.
* ------------------------------------------------------------
*/
-static inline void dz_receive_chars(struct dz_port *dport_in,
- struct pt_regs *regs)
+static inline void dz_receive_chars(struct dz_port *dport_in)
{
struct dz_port *dport;
struct tty_struct *tty = NULL;
@@ -226,7 +225,7 @@ static inline void dz_receive_chars(struct dz_port *dport_in,
break;
}
- if (uart_handle_sysrq_char(&dport->port, ch, regs))
+ if (uart_handle_sysrq_char(&dport->port, ch))
continue;
if ((status & dport->port.ignore_status_mask) == 0) {
@@ -332,7 +331,7 @@ static irqreturn_t dz_interrupt(int irq, void *dev)
status = dz_in(dport, DZ_CSR);
if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
- dz_receive_chars(dport, regs);
+ dz_receive_chars(dport);
if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
dz_transmit_chars(dport);
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 41431d0d551..246c5572667 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -164,7 +164,7 @@ static void free_port_memory(struct icom_port *icom_port)
}
}
-static int __init get_port_memory(struct icom_port *icom_port)
+static int __devinit get_port_memory(struct icom_port *icom_port)
{
int index;
unsigned long stgAddr;
@@ -1380,7 +1380,7 @@ static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *i
0x8024 + 2 - 2 * (icom_port->port - 2);
}
}
-static int __init icom_load_ports(struct icom_adapter *icom_adapter)
+static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
{
struct icom_port *icom_port;
int port_num;
@@ -1473,7 +1473,7 @@ static void icom_remove_adapter(struct icom_adapter *icom_adapter)
}
}
- free_irq(icom_adapter->irq_number, (void *) icom_adapter);
+ free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
iounmap(icom_adapter->base_addr);
icom_free_adapter(icom_adapter);
pci_release_regions(icom_adapter->pci_dev);
@@ -1539,7 +1539,6 @@ static int __devinit icom_probe(struct pci_dev *dev,
}
icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
- icom_adapter->irq_number = dev->irq;
icom_adapter->pci_dev = dev;
icom_adapter->version = ent->driver_data;
icom_adapter->subsystem_id = ent->subdevice;
@@ -1570,7 +1569,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
icom_port = &icom_adapter->port_info[index];
if (icom_port->status == ICOM_PORT_ACTIVE) {
- icom_port->uart_port.irq = icom_port->adapter->irq_number;
+ icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
icom_port->uart_port.type = PORT_ICOM;
icom_port->uart_port.iotype = UPIO_MEM;
icom_port->uart_port.membase =
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h
index 798f1ef2371..e8578d8cd35 100644
--- a/drivers/serial/icom.h
+++ b/drivers/serial/icom.h
@@ -258,7 +258,6 @@ struct icom_port {
struct icom_adapter {
void __iomem * base_addr;
unsigned long base_addr_pci;
- unsigned char irq_number;
struct pci_dev *pci_dev;
struct icom_port port_info[4];
int index;
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index e216dcf2937..04cc88cc528 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -154,7 +154,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
{
struct circ_buf *xmit = &sport->port.info->xmit;
- do {
+ while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) {
/* send xmit->buf[xmit->tail]
* out the port here */
URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail];
@@ -163,7 +163,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
sport->port.icount.tx++;
if (uart_circ_empty(xmit))
break;
- } while (!(UTS((u32)sport->port.membase) & UTS_TXFULL));
+ }
if (uart_circ_empty(xmit))
imx_stop_tx(&sport->port);
@@ -178,8 +178,7 @@ static void imx_start_tx(struct uart_port *port)
UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN;
- if(UTS((u32)sport->port.membase) & UTS_TXEMPTY)
- imx_transmit_buffer(sport);
+ imx_transmit_buffer(sport);
}
static irqreturn_t imx_rtsint(int irq, void *dev_id)
@@ -404,7 +403,8 @@ static int imx_startup(struct uart_port *port)
if (retval) goto error_out2;
retval = request_irq(sport->rtsirq, imx_rtsint,
- IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ (sport->rtsirq < IMX_IRQS) ? 0 :
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
DRIVER_NAME, sport);
if (retval) goto error_out3;
@@ -678,7 +678,7 @@ static struct imx_port imx_ports[] = {
.mapbase = IMX_UART1_BASE, /* FIXME */
.irq = UART1_MINT_RX,
.uartclk = 16000000,
- .fifosize = 8,
+ .fifosize = 32,
.flags = UPF_BOOT_AUTOCONF,
.ops = &imx_pops,
.line = 0,
@@ -694,7 +694,7 @@ static struct imx_port imx_ports[] = {
.mapbase = IMX_UART2_BASE, /* FIXME */
.irq = UART2_MINT_RX,
.uartclk = 16000000,
- .fifosize = 8,
+ .fifosize = 32,
.flags = UPF_BOOT_AUTOCONF,
.ops = &imx_pops,
.line = 1,
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 08430961a89..99af084c7ce 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -425,15 +425,13 @@ irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
* -------------------------------------------------------------------
*/
-static void mcfrs_offintr(void *private)
+static void mcfrs_offintr(struct work_struct *work)
{
- struct mcf_serial *info = (struct mcf_serial *) private;
- struct tty_struct *tty;
+ struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue);
+ struct tty_struct *tty = info->tty;
- tty = info->tty;
- if (!tty)
- return;
- tty_wakeup(tty);
+ if (tty)
+ tty_wakeup(tty);
}
@@ -497,16 +495,13 @@ static void mcfrs_timer(void)
* do_serial_hangup() -> tty->hangup() -> mcfrs_hangup()
*
*/
-static void do_serial_hangup(void *private)
+static void do_serial_hangup(struct work_struct *work)
{
- struct mcf_serial *info = (struct mcf_serial *) private;
- struct tty_struct *tty;
+ struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup);
+ struct tty_struct *tty = info->tty;
- tty = info->tty;
- if (!tty)
- return;
-
- tty_hangup(tty);
+ if (tty)
+ tty_hangup(tty);
}
static int startup(struct mcf_serial * info)
@@ -857,7 +852,7 @@ static void mcfrs_throttle(struct tty_struct * tty)
#ifdef SERIAL_DEBUG_THROTTLE
char buf[64];
- printk("throttle %s: %d....\n", _tty_name(tty, buf),
+ printk("throttle %s: %d....\n", tty_name(tty, buf),
tty->ldisc.chars_in_buffer(tty));
#endif
@@ -876,7 +871,7 @@ static void mcfrs_unthrottle(struct tty_struct * tty)
#ifdef SERIAL_DEBUG_THROTTLE
char buf[64];
- printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+ printk("unthrottle %s: %d....\n", tty_name(tty, buf),
tty->ldisc.chars_in_buffer(tty));
#endif
@@ -1541,8 +1536,8 @@ static void mcfrs_irqinit(struct mcf_serial *info)
* External Pin Mask Setting & Enable External Pin for Interface
* mrcbis@aliceposta.it
*/
- unsigned short *serpin_enable_mask;
- serpin_enable_mask = (MCF_IPSBAR + MCF_GPIO_PAR_UART);
+ u16 *serpin_enable_mask;
+ serpin_enable_mask = (u16 *) (MCF_IPSBAR + MCF_GPIO_PAR_UART);
if (info->line == 0)
*serpin_enable_mask |= UART0_ENABLE_MASK;
else if (info->line == 1)
@@ -1551,6 +1546,13 @@ static void mcfrs_irqinit(struct mcf_serial *info)
*serpin_enable_mask |= UART2_ENABLE_MASK;
}
#endif
+#if defined(CONFIG_M528x)
+ /* make sure PUAPAR is set for UART0 and UART1 */
+ if (info->line < 2) {
+ volatile unsigned char *portp = (volatile unsigned char *) (MCF_MBAR + MCF5282_GPIO_PUAPAR);
+ *portp |= (0x03 << (info->line * 2));
+ }
+#endif
#elif defined(CONFIG_M520x)
volatile unsigned char *icrp, *uartp;
volatile unsigned long *imrp;
@@ -1783,8 +1785,8 @@ mcfrs_init(void)
info->event = 0;
info->count = 0;
info->blocked_open = 0;
- INIT_WORK(&info->tqueue, mcfrs_offintr, info);
- INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
+ INIT_WORK(&info->tqueue, mcfrs_offintr);
+ INIT_WORK(&info->tqueue_hangup, do_serial_hangup);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 955bbd653e2..8d24cd52105 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -995,8 +995,10 @@ mpc52xx_uart_of_remove(struct of_device *op)
struct uart_port *port = dev_get_drvdata(&op->dev);
dev_set_drvdata(&op->dev, NULL);
- if (port)
+ if (port) {
uart_remove_one_port(&mpc52xx_uart_driver, port);
+ irq_dispose_mapping(port->irq);
+ }
return 0;
}
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index ccb8fa1800a..83211013deb 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -51,7 +51,11 @@
#define MUX_NR 256
static unsigned int port_cnt __read_mostly;
-static struct uart_port mux_ports[MUX_NR];
+struct mux_port {
+ struct uart_port port;
+ int enabled;
+};
+static struct mux_port mux_ports[MUX_NR];
static struct uart_driver mux_driver = {
.owner = THIS_MODULE,
@@ -66,7 +70,36 @@ static struct timer_list mux_timer;
#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
+
+/**
+ * get_mux_port_count - Get the number of available ports on the Mux.
+ * @dev: The parisc device.
+ *
+ * This function is used to determine the number of ports the Mux
+ * supports. The IODC data reports the number of ports the Mux
+ * can support, but there are cases where not all the Mux ports
+ * are connected. This function can override the IODC and
+ * return the true port count.
+ */
+static int __init get_mux_port_count(struct parisc_device *dev)
+{
+ int status;
+ u8 iodc_data[32];
+ unsigned long bytecnt;
+
+ /* If this is the built-in Mux for the K-Class (Eole CAP/MUX),
+ * we only need to allocate resources for 1 port since the
+ * other 7 ports are not connected.
+ */
+ if(dev->id.hversion == 0x15)
+ return 1;
+
+ status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
+ BUG_ON(status != PDC_OK);
+
+ /* Return the number of ports specified in the iodc data. */
+ return ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8;
+}
/**
* mux_tx_empty - Check if the transmitter fifo is empty.
@@ -250,7 +283,7 @@ static void mux_read(struct uart_port *port)
*/
static int mux_startup(struct uart_port *port)
{
- mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
+ mux_ports[port->line].enabled = 1;
return 0;
}
@@ -262,6 +295,7 @@ static int mux_startup(struct uart_port *port)
*/
static void mux_shutdown(struct uart_port *port)
{
+ mux_ports[port->line].enabled = 0;
}
/**
@@ -319,7 +353,7 @@ static int mux_request_port(struct uart_port *port)
* @port: Ptr to the uart_port.
* @type: Bitmask of required configurations.
*
- * Perform any autoconfiguration steps for the port. This functino is
+ * Perform any autoconfiguration steps for the port. This function is
* called if the UPF_BOOT_AUTOCONF flag is specified for the port.
* [Note: This is required for now because of a bug in the Serial core.
* rmk has already submitted a patch to linus, should be available for
@@ -357,11 +391,11 @@ static void mux_poll(unsigned long unused)
int i;
for(i = 0; i < port_cnt; ++i) {
- if(!mux_ports[i].info)
+ if(!mux_ports[i].enabled)
continue;
- mux_read(&mux_ports[i]);
- mux_write(&mux_ports[i]);
+ mux_read(&mux_ports[i].port);
+ mux_write(&mux_ports[i].port);
}
mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
@@ -371,8 +405,17 @@ static void mux_poll(unsigned long unused)
#ifdef CONFIG_SERIAL_MUX_CONSOLE
static void mux_console_write(struct console *co, const char *s, unsigned count)
{
- while(count--)
- pdc_iodc_putc(*s++);
+ /* Wait until the FIFO drains. */
+ while(UART_GET_FIFO_CNT(&mux_ports[0].port))
+ udelay(1);
+
+ while(count--) {
+ if(*s == '\n') {
+ UART_PUT_CHAR(&mux_ports[0].port, '\r');
+ }
+ UART_PUT_CHAR(&mux_ports[0].port, *s++);
+ }
+
}
static int mux_console_setup(struct console *co, char *options)
@@ -428,19 +471,14 @@ static struct uart_ops mux_pops = {
*/
static int __init mux_probe(struct parisc_device *dev)
{
- int i, status, ports;
- u8 iodc_data[32];
- unsigned long bytecnt;
- struct uart_port *port;
+ int i, status;
- 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;
- }
+ int port_count = get_mux_port_count(dev);
+ printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.6\n", port_count);
- ports = GET_MUX_PORTS(iodc_data);
- printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.3\n", ports);
+ dev_set_drvdata(&dev->dev, (void *)(long)port_count);
+ request_mem_region(dev->hpa.start + MUX_OFFSET,
+ port_count * MUX_LINE_OFFSET, "Mux");
if(!port_cnt) {
mux_driver.cons = MUX_CONSOLE;
@@ -450,13 +488,10 @@ static int __init mux_probe(struct parisc_device *dev)
printk(KERN_ERR "Serial mux: Unable to register driver.\n");
return 1;
}
-
- init_timer(&mux_timer);
- mux_timer.function = mux_poll;
}
- for(i = 0; i < ports; ++i, ++port_cnt) {
- port = &mux_ports[port_cnt];
+ for(i = 0; i < port_count; ++i, ++port_cnt) {
+ struct uart_port *port = &mux_ports[port_cnt].port;
port->iobase = 0;
port->mapbase = dev->hpa.start + MUX_OFFSET +
(i * MUX_LINE_OFFSET);
@@ -477,27 +512,73 @@ static int __init mux_probe(struct parisc_device *dev)
*/
port->timeout = HZ / 50;
spin_lock_init(&port->lock);
+
status = uart_add_one_port(&mux_driver, port);
BUG_ON(status);
}
-#ifdef CONFIG_SERIAL_MUX_CONSOLE
- register_console(&mux_console);
-#endif
return 0;
}
+static int __devexit mux_remove(struct parisc_device *dev)
+{
+ int i, j;
+ int port_count = (long)dev_get_drvdata(&dev->dev);
+
+ /* Find Port 0 for this card in the mux_ports list. */
+ for(i = 0; i < port_cnt; ++i) {
+ if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET)
+ break;
+ }
+ BUG_ON(i + port_count > port_cnt);
+
+ /* Release the resources associated with each port on the device. */
+ for(j = 0; j < port_count; ++j, ++i) {
+ struct uart_port *port = &mux_ports[i].port;
+
+ uart_remove_one_port(&mux_driver, port);
+ if(port->membase)
+ iounmap(port->membase);
+ }
+
+ release_mem_region(dev->hpa.start + MUX_OFFSET, port_count * MUX_LINE_OFFSET);
+ return 0;
+}
+
+/* Hack. This idea was taken from the 8250_gsc.c on how to properly order
+ * the serial port detection in the proper order. The idea is we always
+ * want the builtin mux to be detected before addin mux cards, so we
+ * specifically probe for the builtin mux cards first.
+ *
+ * This table only contains the parisc_device_id of known builtin mux
+ * devices. All other mux cards will be detected by the generic mux_tbl.
+ */
+static struct parisc_device_id builtin_mux_tbl[] = {
+ { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
+ { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
+ { 0, }
+};
+
static struct parisc_device_id mux_tbl[] = {
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
{ 0, }
};
+MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
MODULE_DEVICE_TABLE(parisc, mux_tbl);
+static struct parisc_driver builtin_serial_mux_driver = {
+ .name = "builtin_serial_mux",
+ .id_table = builtin_mux_tbl,
+ .probe = mux_probe,
+ .remove = __devexit_p(mux_remove),
+};
+
static struct parisc_driver serial_mux_driver = {
.name = "serial_mux",
.id_table = mux_tbl,
.probe = mux_probe,
+ .remove = __devexit_p(mux_remove),
};
/**
@@ -507,7 +588,21 @@ static struct parisc_driver serial_mux_driver = {
*/
static int __init mux_init(void)
{
- return register_parisc_driver(&serial_mux_driver);
+ register_parisc_driver(&builtin_serial_mux_driver);
+ register_parisc_driver(&serial_mux_driver);
+
+ if(port_cnt > 0) {
+ /* Start the Mux timer */
+ init_timer(&mux_timer);
+ mux_timer.function = mux_poll;
+ mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
+
+#ifdef CONFIG_SERIAL_MUX_CONSOLE
+ register_console(&mux_console);
+#endif
+ }
+
+ return 0;
}
/**
@@ -517,14 +612,16 @@ static int __init mux_init(void)
*/
static void __exit mux_exit(void)
{
- int i;
-
- for (i = 0; i < port_cnt; i++) {
- uart_remove_one_port(&mux_driver, &mux_ports[i]);
- if (mux_ports[i].membase)
- iounmap(mux_ports[i].membase);
+ /* Delete the Mux timer. */
+ if(port_cnt > 0) {
+ del_timer(&mux_timer);
+#ifdef CONFIG_SERIAL_MUX_CONSOLE
+ unregister_console(&mux_console);
+#endif
}
+ unregister_parisc_driver(&builtin_serial_mux_driver);
+ unregister_parisc_driver(&serial_mux_driver);
uart_unregister_driver(&mux_driver);
}
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 752ef07516b..be8d75721a8 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1467,7 +1467,8 @@ no_dma:
if (ZS_IS_IRDA(uap))
uap->port_type = PMAC_SCC_IRDA;
if (ZS_IS_INTMODEM(uap)) {
- struct device_node* i2c_modem = find_devices("i2c-modem");
+ struct device_node* i2c_modem =
+ of_find_node_by_name(NULL, "i2c-modem");
if (i2c_modem) {
const char* mid =
get_property(i2c_modem, "modem-id", NULL);
@@ -1482,6 +1483,7 @@ no_dma:
}
printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n",
mid ? (*mid) : 0);
+ of_node_put(i2c_modem);
} else {
printk(KERN_INFO "pmac_zilog: serial modem detected\n");
}
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index c2f1012449d..6b76babc7fb 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -248,6 +248,10 @@ static const struct serial_quirk quirks[] = {
.multi = 2,
}, {
.manfid = MANFID_QUATECH,
+ .prodid = PRODID_QUATECH_DUAL_RS232_G,
+ .multi = 2,
+ }, {
+ .manfid = MANFID_QUATECH,
.prodid = PRODID_QUATECH_QUAD_RS232,
.multi = 4,
}, {
@@ -891,6 +895,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
+ PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index f4440d32931..509ace7e688 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -38,6 +38,8 @@
* Fix some spin_locks.
* Do not call uart_add_one_port for absent ports.
* 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup.
+ * 1.08 Use platform_device.
+ * Fix and cleanup suspend/resume/initialization codes.
*/
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -50,7 +52,7 @@
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -60,7 +62,7 @@
#include <asm/io.h>
-static char *serial_version = "1.07";
+static char *serial_version = "1.08";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -94,12 +96,7 @@ static char *serial_name = "TX39/49 Serial driver";
struct uart_txx9_port {
struct uart_port port;
-
- /*
- * We provide a per-port pm hook.
- */
- void (*pm)(struct uart_port *port,
- unsigned int state, unsigned int old);
+ /* No additional info for now */
};
#define TXX9_REGION_SIZE 0x24
@@ -277,6 +274,31 @@ static void serial_txx9_enable_ms(struct uart_port *port)
/* TXX9-SIO can not control DTR... */
}
+static void serial_txx9_initialize(struct uart_port *port)
+{
+ struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ unsigned int tmout = 10000;
+
+ sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
+ /* TX4925 BUG WORKAROUND. Accessing SIOC register
+ * immediately after soft reset causes bus error. */
+ mmiowb();
+ udelay(1);
+ while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout)
+ udelay(1);
+ /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
+ sio_set(up, TXX9_SIFCR,
+ TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
+ /* initial settings */
+ sio_out(up, TXX9_SILCR,
+ TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+ ((up->port.flags & UPF_TXX9_USE_SCLK) ?
+ TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+ sio_quot_set(up, uart_get_divisor(port, 9600));
+ sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+ sio_out(up, TXX9_SIDICR, 0);
+}
+
static inline void
receive_chars(struct uart_txx9_port *up, unsigned int *status)
{
@@ -657,9 +679,8 @@ static void
serial_txx9_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
- if (up->pm)
- up->pm(port, state, oldstate);
+ if (state == 0)
+ serial_txx9_initialize(port);
}
static int serial_txx9_request_resource(struct uart_txx9_port *up)
@@ -732,7 +753,6 @@ static int serial_txx9_request_port(struct uart_port *port)
static void serial_txx9_config_port(struct uart_port *port, int uflags)
{
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
- unsigned long flags;
int ret;
/*
@@ -749,30 +769,7 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags)
if (up->port.line == up->port.cons->index)
return;
#endif
- spin_lock_irqsave(&up->port.lock, flags);
- /*
- * Reset the UART.
- */
- sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
-#ifdef CONFIG_CPU_TX49XX
- /* TX4925 BUG WORKAROUND. Accessing SIOC register
- * immediately after soft reset causes bus error. */
- iob();
- udelay(1);
-#endif
- while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
- ;
- /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
- sio_set(up, TXX9_SIFCR,
- TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
- /* initial settings */
- sio_out(up, TXX9_SILCR,
- TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
- ((up->port.flags & UPF_TXX9_USE_SCLK) ?
- TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
- sio_quot_set(up, uart_get_divisor(port, 9600));
- sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
- spin_unlock_irqrestore(&up->port.lock, flags);
+ serial_txx9_initialize(port);
}
static int
@@ -818,7 +815,8 @@ static struct uart_ops serial_txx9_pops = {
static struct uart_txx9_port serial_txx9_ports[UART_NR];
-static void __init serial_txx9_register_ports(struct uart_driver *drv)
+static void __init serial_txx9_register_ports(struct uart_driver *drv,
+ struct device *dev)
{
int i;
@@ -827,6 +825,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv)
up->port.line = i;
up->port.ops = &serial_txx9_pops;
+ up->port.dev = dev;
if (up->port.iobase || up->port.mapbase)
uart_add_one_port(drv, &up->port);
}
@@ -898,7 +897,7 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count)
sio_out(up, TXX9_SIDICR, ier);
}
-static int serial_txx9_console_setup(struct console *co, char *options)
+static int __init serial_txx9_console_setup(struct console *co, char *options)
{
struct uart_port *port;
struct uart_txx9_port *up;
@@ -919,17 +918,7 @@ static int serial_txx9_console_setup(struct console *co, char *options)
if (!port->ops)
return -ENODEV;
- /*
- * Disable UART interrupts, set DTR and RTS high
- * and set speed.
- */
- sio_out(up, TXX9_SIDICR, 0);
- /* initial settings */
- sio_out(up, TXX9_SILCR,
- TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
- ((port->flags & UPF_TXX9_USE_SCLK) ?
- TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
- sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+ serial_txx9_initialize(&up->port);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -981,31 +970,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
return 0;
}
-#ifdef ENABLE_SERIAL_TXX9_PCI
-#ifdef CONFIG_PM
-/**
- * serial_txx9_suspend_port - suspend one serial port
- * @line: serial line number
- *
- * Suspend one serial port.
- */
-static void serial_txx9_suspend_port(int line)
-{
- uart_suspend_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-
-/**
- * serial_txx9_resume_port - resume one serial port
- * @line: serial line number
- *
- * Resume one serial port.
- */
-static void serial_txx9_resume_port(int line)
-{
- uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-#endif
-
static DEFINE_MUTEX(serial_txx9_mutex);
/**
@@ -1028,8 +992,18 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
mutex_lock(&serial_txx9_mutex);
for (i = 0; i < UART_NR; i++) {
uart = &serial_txx9_ports[i];
- if (!(uart->port.iobase || uart->port.mapbase))
+ if (uart_match_port(&uart->port, port)) {
+ uart_remove_one_port(&serial_txx9_reg, &uart->port);
break;
+ }
+ }
+ if (i == UART_NR) {
+ /* Find unused port */
+ for (i = 0; i < UART_NR; i++) {
+ uart = &serial_txx9_ports[i];
+ if (!(uart->port.iobase || uart->port.mapbase))
+ break;
+ }
}
if (i < UART_NR) {
uart->port.iobase = port->iobase;
@@ -1072,6 +1046,95 @@ static void __devexit serial_txx9_unregister_port(int line)
}
/*
+ * Register a set of serial devices attached to a platform device.
+ */
+static int __devinit serial_txx9_probe(struct platform_device *dev)
+{
+ struct uart_port *p = dev->dev.platform_data;
+ struct uart_port port;
+ int ret, i;
+
+ memset(&port, 0, sizeof(struct uart_port));
+ for (i = 0; p && p->uartclk != 0; p++, i++) {
+ port.iobase = p->iobase;
+ port.membase = p->membase;
+ port.irq = p->irq;
+ port.uartclk = p->uartclk;
+ port.iotype = p->iotype;
+ port.flags = p->flags;
+ port.mapbase = p->mapbase;
+ port.dev = &dev->dev;
+ ret = serial_txx9_register_port(&port);
+ if (ret < 0) {
+ dev_err(&dev->dev, "unable to register port at index %d "
+ "(IO%x MEM%lx IRQ%d): %d\n", i,
+ p->iobase, p->mapbase, p->irq, ret);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial_txx9_remove(struct platform_device *dev)
+{
+ int i;
+
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+ if (up->port.dev == &dev->dev)
+ serial_txx9_unregister_port(i);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int serial_txx9_suspend(struct platform_device *dev, pm_message_t state)
+{
+ int i;
+
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+ uart_suspend_port(&serial_txx9_reg, &up->port);
+ }
+
+ return 0;
+}
+
+static int serial_txx9_resume(struct platform_device *dev)
+{
+ int i;
+
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+ uart_resume_port(&serial_txx9_reg, &up->port);
+ }
+
+ return 0;
+}
+#endif
+
+static struct platform_driver serial_txx9_plat_driver = {
+ .probe = serial_txx9_probe,
+ .remove = __devexit_p(serial_txx9_remove),
+#ifdef CONFIG_PM
+ .suspend = serial_txx9_suspend,
+ .resume = serial_txx9_resume,
+#endif
+ .driver = {
+ .name = "serial_txx9",
+ .owner = THIS_MODULE,
+ },
+};
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
+/*
* Probe one serial board. Unfortunately, there is no rhyme nor reason
* to the arrangement of serial ports on a PCI card.
*/
@@ -1097,20 +1160,22 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
line = serial_txx9_register_port(&port);
if (line < 0) {
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
+ pci_disable_device(dev);
+ return line;
}
- pci_set_drvdata(dev, (void *)(long)line);
+ pci_set_drvdata(dev, &serial_txx9_ports[line]);
return 0;
}
static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
{
- int line = (int)(long)pci_get_drvdata(dev);
+ struct uart_txx9_port *up = pci_get_drvdata(dev);
pci_set_drvdata(dev, NULL);
- if (line) {
- serial_txx9_unregister_port(line);
+ if (up) {
+ serial_txx9_unregister_port(up->port.line);
pci_disable_device(dev);
}
}
@@ -1118,10 +1183,10 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
#ifdef CONFIG_PM
static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
{
- int line = (int)(long)pci_get_drvdata(dev);
+ struct uart_txx9_port *up = pci_get_drvdata(dev);
- if (line)
- serial_txx9_suspend_port(line);
+ if (up)
+ uart_suspend_port(&serial_txx9_reg, &up->port);
pci_save_state(dev);
pci_set_power_state(dev, pci_choose_state(dev, state));
return 0;
@@ -1129,15 +1194,12 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
static int pciserial_txx9_resume_one(struct pci_dev *dev)
{
- int line = (int)(long)pci_get_drvdata(dev);
+ struct uart_txx9_port *up = pci_get_drvdata(dev);
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
-
- if (line) {
- pci_enable_device(dev);
- serial_txx9_resume_port(line);
- }
+ if (up)
+ uart_resume_port(&serial_txx9_reg, &up->port);
return 0;
}
#endif
@@ -1161,6 +1223,8 @@ static struct pci_driver serial_txx9_pci_driver = {
MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
#endif /* ENABLE_SERIAL_TXX9_PCI */
+static struct platform_device *serial_txx9_plat_devs;
+
static int __init serial_txx9_init(void)
{
int ret;
@@ -1168,13 +1232,39 @@ static int __init serial_txx9_init(void)
printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
ret = uart_register_driver(&serial_txx9_reg);
- if (ret >= 0) {
- serial_txx9_register_ports(&serial_txx9_reg);
+ if (ret)
+ goto out;
+
+ serial_txx9_plat_devs = platform_device_alloc("serial_txx9", -1);
+ if (!serial_txx9_plat_devs) {
+ ret = -ENOMEM;
+ goto unreg_uart_drv;
+ }
+
+ ret = platform_device_add(serial_txx9_plat_devs);
+ if (ret)
+ goto put_dev;
+
+ serial_txx9_register_ports(&serial_txx9_reg,
+ &serial_txx9_plat_devs->dev);
+
+ ret = platform_driver_register(&serial_txx9_plat_driver);
+ if (ret)
+ goto del_dev;
#ifdef ENABLE_SERIAL_TXX9_PCI
- ret = pci_register_driver(&serial_txx9_pci_driver);
+ ret = pci_register_driver(&serial_txx9_pci_driver);
#endif
- }
+ if (ret == 0)
+ goto out;
+
+ del_dev:
+ platform_device_del(serial_txx9_plat_devs);
+ put_dev:
+ platform_device_put(serial_txx9_plat_devs);
+ unreg_uart_drv:
+ uart_unregister_driver(&serial_txx9_reg);
+ out:
return ret;
}
@@ -1185,6 +1275,8 @@ static void __exit serial_txx9_exit(void)
#ifdef ENABLE_SERIAL_TXX9_PCI
pci_unregister_driver(&serial_txx9_pci_driver);
#endif
+ platform_driver_unregister(&serial_txx9_plat_driver);
+ platform_device_unregister(serial_txx9_plat_devs);
for (i = 0; i < UART_NR; i++) {
struct uart_txx9_port *up = &serial_txx9_ports[i];
if (up->port.iobase || up->port.mapbase)
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index c53b69610a5..46c40bbc4bc 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -17,6 +17,9 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
+#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
#undef DEBUG
@@ -49,11 +52,6 @@
#endif
#include <asm/sci.h>
-
-#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
#include "sh-sci.h"
struct sci_port {
@@ -645,6 +643,9 @@ static inline int sci_handle_breaks(struct uart_port *port)
struct tty_struct *tty = port->info->tty;
struct sci_port *s = &sci_ports[port->line];
+ if (uart_handle_break(port))
+ return 0;
+
if (!s->break_flag && status & SCxSR_BRK(port)) {
#if defined(CONFIG_CPU_SH3)
/* Debounce break */
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 253ceb895ca..a27e9e92cb5 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -636,25 +636,6 @@ static irqreturn_t sn_sal_interrupt(int irq, void *dev_id)
}
/**
- * sn_sal_connect_interrupt - Request interrupt, handled by sn_sal_interrupt
- * @port: Our sn_cons_port (which contains the uart port)
- *
- * returns the console irq if interrupt is successfully registered, else 0
- *
- */
-static int sn_sal_connect_interrupt(struct sn_cons_port *port)
-{
- if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
- IRQF_DISABLED | IRQF_SHARED,
- "SAL console driver", port) >= 0) {
- return SGI_UART_VECTOR;
- }
-
- printk(KERN_INFO "sn_console: console proceeding in polled mode\n");
- return 0;
-}
-
-/**
* sn_sal_timer_poll - this function handles polled console mode
* @data: A pointer to our sn_cons_port (which contains the uart port)
*
@@ -746,30 +727,31 @@ static void __init sn_sal_switch_to_asynch(struct sn_cons_port *port)
* mode. We were previously in asynch/polling mode (using init_timer).
*
* We attempt to switch to interrupt mode here by calling
- * sn_sal_connect_interrupt. If that works out, we enable receive interrupts.
+ * request_irq. If that works out, we enable receive interrupts.
*/
static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
{
- int irq;
unsigned long flags;
- if (!port)
- return;
-
- DPRINTF("sn_console: switching to interrupt driven console\n");
-
- spin_lock_irqsave(&port->sc_port.lock, flags);
+ if (port) {
+ DPRINTF("sn_console: switching to interrupt driven console\n");
- irq = sn_sal_connect_interrupt(port);
+ if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
+ IRQF_DISABLED | IRQF_SHARED,
+ "SAL console driver", port) >= 0) {
+ spin_lock_irqsave(&port->sc_port.lock, flags);
+ port->sc_port.irq = SGI_UART_VECTOR;
+ port->sc_ops = &intr_ops;
- if (irq) {
- port->sc_port.irq = irq;
- port->sc_ops = &intr_ops;
-
- /* turn on receive interrupts */
- ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
+ /* turn on receive interrupts */
+ ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
+ spin_unlock_irqrestore(&port->sc_port.lock, flags);
+ }
+ else {
+ printk(KERN_INFO
+ "sn_console: console proceeding in polled mode\n");
+ }
}
- spin_unlock_irqrestore(&port->sc_port.lock, flags);
}
/*
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 96a852aa190..bfd44177a21 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1387,8 +1387,8 @@ static enum su_type __devinit su_get_type(struct device_node *dp)
struct device_node *ap = of_find_node_by_path("/aliases");
if (ap) {
- char *keyb = of_get_property(ap, "keyboard", NULL);
- char *ms = of_get_property(ap, "mouse", NULL);
+ const char *keyb = of_get_property(ap, "keyboard", NULL);
+ const char *ms = of_get_property(ap, "mouse", NULL);
if (keyb) {
if (dp == of_find_node_by_path(keyb))