summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-21 09:33:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-21 09:33:10 -0700
commit41d5e08ea86af3359239d5a6f7021cdc61beaa49 (patch)
tree58ad584b29d097dfa3b5d7bc5e61370d676610a9 /drivers/tty
parent8d582b94291b40dbb5961f99172ee8ebfafd4c9c (diff)
parent5dbc32a88f1e73f244e6134fc119dd4d60a398c0 (diff)
Merge tag 'tty-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH: "Here's the big tty/serial driver update for 4.1-rc1. It was delayed for a bit due to some questions surrounding some of the console command line parsing changes that are in here. There's still one tiny regression for people who were previously putting multiple console command lines and expecting them all to be ignored for some odd reason, but Peter is working on fixing that. If not, I'll send a revert for the offending patch, but I have faith that Peter can address it. Other than the console work here, there's the usual serial driver updates and changes, and a buch of 8250 reworks to try to make that driver easier to maintain over time, and have it support more devices in the future. All of these have been in linux-next for a while" * tag 'tty-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (119 commits) n_gsm: Drop unneeded cast on netdev_priv sc16is7xx: expose RTS inversion in RS-485 mode serial: 8250_pci: port failed after wakeup from S3 earlycon: 8250: Document kernel command line options earlycon: 8250: Fix command line regression earlycon: Fix __earlycon_table stride tty: clean up the tty time logic a bit serial: 8250_dw: only get the clock rate in one place serial: 8250_dw: remove useless ACPI ID check dmaengine: hsu: move memory allocation to GFP_NOWAIT dmaengine: hsu: remove redundant pieces of code serial: 8250_pci: add Intel Tangier support dmaengine: hsu: add Intel Tangier PCI ID serial: 8250_pci: replace switch-case by formula for Intel MID serial: 8250_pci: replace switch-case by formula tty: cpm_uart: replace CONFIG_8xx by CONFIG_CPM1 serial: jsm: some off by one bugs serial: xuartps: Fix check in console_setup(). serial: xuartps: Get rid of register access macros. serial: xuartps: Fix iobase use. ...
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/hvc/hvc_opal.c2
-rw-r--r--drivers/tty/n_gsm.c12
-rw-r--r--drivers/tty/serial/8250/8250.h23
-rw-r--r--drivers/tty/serial/8250/8250_core.c493
-rw-r--r--drivers/tty/serial/8250/8250_dw.c58
-rw-r--r--drivers/tty/serial/8250/8250_early.c69
-rw-r--r--drivers/tty/serial/8250/8250_em.c1
-rw-r--r--drivers/tty/serial/8250/8250_hp300.c1
-rw-r--r--drivers/tty/serial/8250/8250_omap.c1
-rw-r--r--drivers/tty/serial/8250/8250_pci.c414
-rw-r--r--drivers/tty/serial/8250/Kconfig1
-rw-r--r--drivers/tty/serial/Kconfig32
-rw-r--r--drivers/tty/serial/Makefile2
-rw-r--r--drivers/tty/serial/amba-pl011.c234
-rw-r--r--drivers/tty/serial/apbuart.c2
-rw-r--r--drivers/tty/serial/ar933x_uart.c2
-rw-r--r--drivers/tty/serial/atmel_serial.c29
-rw-r--r--drivers/tty/serial/bcm63xx_uart.c4
-rw-r--r--drivers/tty/serial/bfin_uart.c2
-rw-r--r--drivers/tty/serial/clps711x.c2
-rw-r--r--drivers/tty/serial/cpm_uart/Makefile2
-rw-r--r--drivers/tty/serial/cpm_uart/cpm_uart.h2
-rw-r--r--drivers/tty/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/tty/serial/earlycon.c140
-rw-r--r--drivers/tty/serial/fsl_lpuart.c2
-rw-r--r--drivers/tty/serial/imx.c317
-rw-r--r--drivers/tty/serial/jsm/jsm_cls.c2
-rw-r--r--drivers/tty/serial/jsm/jsm_neo.c6
-rw-r--r--drivers/tty/serial/max3100.c2
-rw-r--r--drivers/tty/serial/mfd.c1505
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c2
-rw-r--r--drivers/tty/serial/msm_serial.h9
-rw-r--r--drivers/tty/serial/msm_serial_hs.c1874
-rw-r--r--drivers/tty/serial/mxs-auart.c18
-rw-r--r--drivers/tty/serial/of_serial.c5
-rw-r--r--drivers/tty/serial/omap-serial.c10
-rw-r--r--drivers/tty/serial/pmac_zilog.c2
-rw-r--r--drivers/tty/serial/pxa.c2
-rw-r--r--drivers/tty/serial/sc16is7xx.c46
-rw-r--r--drivers/tty/serial/serial-tegra.c2
-rw-r--r--drivers/tty/serial/serial_core.c52
-rw-r--r--drivers/tty/serial/serial_mctrl_gpio.c50
-rw-r--r--drivers/tty/serial/sh-sci.c88
-rw-r--r--drivers/tty/serial/sirfsoc_uart.c2
-rw-r--r--drivers/tty/serial/sprd_serial.c6
-rw-r--r--drivers/tty/serial/st-asc.c2
-rw-r--r--drivers/tty/serial/uartlite.c2
-rw-r--r--drivers/tty/serial/ucc_uart.c2
-rw-r--r--drivers/tty/serial/xilinx_uartps.c242
-rw-r--r--drivers/tty/tty_io.c24
-rw-r--r--drivers/tty/vt/vt.c74
-rw-r--r--drivers/tty/vt/vt_ioctl.c2
52 files changed, 1442 insertions, 4438 deletions
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 071551bf3e9a..543b234e70fc 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -41,7 +41,7 @@
static const char hvc_opal_name[] = "hvc_opal";
-static struct of_device_id hvc_opal_match[] = {
+static const struct of_device_id hvc_opal_match[] = {
{ .name = "serial", .compatible = "ibm,opal-console-raw" },
{ .name = "serial", .compatible = "ibm,opal-console-hvsi" },
{ },
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index c4343764cc5b..91abc00aa833 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2669,7 +2669,7 @@ static inline void muxnet_put(struct gsm_mux_net *mux_net)
static int gsm_mux_net_start_xmit(struct sk_buff *skb,
struct net_device *net)
{
- struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
+ struct gsm_mux_net *mux_net = netdev_priv(net);
struct gsm_dlci *dlci = mux_net->dlci;
muxnet_get(mux_net);
@@ -2698,7 +2698,7 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
{
struct net_device *net = dlci->net;
struct sk_buff *skb;
- struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
+ struct gsm_mux_net *mux_net = netdev_priv(net);
muxnet_get(mux_net);
/* Allocate an sk_buff */
@@ -2727,7 +2727,7 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
static int gsm_change_mtu(struct net_device *net, int new_mtu)
{
- struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
+ struct gsm_mux_net *mux_net = netdev_priv(net);
if ((new_mtu < 8) || (new_mtu > mux_net->dlci->gsm->mtu))
return -EINVAL;
net->mtu = new_mtu;
@@ -2763,7 +2763,7 @@ static void gsm_destroy_network(struct gsm_dlci *dlci)
pr_debug("destroy network interface");
if (!dlci->net)
return;
- mux_net = (struct gsm_mux_net *)netdev_priv(dlci->net);
+ mux_net = netdev_priv(dlci->net);
muxnet_put(mux_net);
}
@@ -2801,7 +2801,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
return -ENOMEM;
}
net->mtu = dlci->gsm->mtu;
- mux_net = (struct gsm_mux_net *)netdev_priv(net);
+ mux_net = netdev_priv(net);
mux_net->dlci = dlci;
kref_init(&mux_net->ref);
strncpy(nc->if_name, net->name, IFNAMSIZ); /* return net name */
@@ -2824,7 +2824,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
}
/* Line discipline for real tty */
-struct tty_ldisc_ops tty_ldisc_packet = {
+static struct tty_ldisc_ops tty_ldisc_packet = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "n_gsm",
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index b00836851061..c43f74c53cd9 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -21,7 +21,6 @@ struct uart_8250_dma {
/* Filter function */
dma_filter_fn fn;
-
/* Parameter to the filter function */
void *rx_param;
void *tx_param;
@@ -53,7 +52,7 @@ struct old_serial_port {
unsigned int baud_base;
unsigned int port;
unsigned int irq;
- unsigned int flags;
+ upf_t flags;
unsigned char hub6;
unsigned char io_type;
unsigned char __iomem *iomem_base;
@@ -85,9 +84,6 @@ struct serial8250_config {
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
-#define PROBE_RSA (1 << 0)
-#define PROBE_ANY (~0)
-
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
@@ -198,3 +194,20 @@ static inline int serial8250_request_dma(struct uart_8250_port *p)
}
static inline void serial8250_release_dma(struct uart_8250_port *p) { }
#endif
+
+static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
+{
+ unsigned char status;
+
+ status = serial_in(up, 0x04); /* EXCR2 */
+#define PRESL(x) ((x) & 0x30)
+ if (PRESL(status) == 0x10) {
+ /* already in high speed mode */
+ return 0;
+ } else {
+ status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+ status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
+ serial_out(up, 0x04, status);
+ }
+ return 1;
+}
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index deae122c9c4b..422ebea96a64 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -31,7 +31,6 @@
#include <linux/tty.h>
#include <linux/ratelimit.h>
#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/nmi.h>
@@ -61,7 +60,7 @@ static struct uart_driver serial8250_reg;
static int serial_index(struct uart_port *port)
{
- return (serial8250_reg.minor - 64) + port->line;
+ return port->minor - 64;
}
static unsigned int skip_txen_test; /* force skip of txen test at init time */
@@ -358,34 +357,46 @@ static void default_serial_dl_write(struct uart_8250_port *up, int value)
#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
/* Au1x00/RT288x 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 s8 au_io_in_map[8] = {
+ 0, /* UART_RX */
+ 2, /* UART_IER */
+ 3, /* UART_IIR */
+ 5, /* UART_LCR */
+ 6, /* UART_MCR */
+ 7, /* UART_LSR */
+ 8, /* UART_MSR */
+ -1, /* UART_SCR (unmapped) */
};
-static const u8 au_io_out_map[] = {
- [UART_TX] = 1,
- [UART_IER] = 2,
- [UART_FCR] = 4,
- [UART_LCR] = 5,
- [UART_MCR] = 6,
+static const s8 au_io_out_map[8] = {
+ 1, /* UART_TX */
+ 2, /* UART_IER */
+ 4, /* UART_FCR */
+ 5, /* UART_LCR */
+ 6, /* UART_MCR */
+ -1, /* UART_LSR (unmapped) */
+ -1, /* UART_MSR (unmapped) */
+ -1, /* UART_SCR (unmapped) */
};
static unsigned int au_serial_in(struct uart_port *p, int offset)
{
- offset = au_io_in_map[offset] << p->regshift;
- return __raw_readl(p->membase + offset);
+ if (offset >= ARRAY_SIZE(au_io_in_map))
+ return UINT_MAX;
+ offset = au_io_in_map[offset];
+ if (offset < 0)
+ return UINT_MAX;
+ return __raw_readl(p->membase + (offset << p->regshift));
}
static void au_serial_out(struct uart_port *p, int offset, int value)
{
- offset = au_io_out_map[offset] << p->regshift;
- __raw_writel(value, p->membase + offset);
+ if (offset >= ARRAY_SIZE(au_io_out_map))
+ return;
+ offset = au_io_out_map[offset];
+ if (offset < 0)
+ return;
+ __raw_writel(value, p->membase + (offset << p->regshift));
}
/* Au1x00 haven't got a standard divisor latch */
@@ -895,7 +906,7 @@ static int broken_efr(struct uart_8250_port *up)
/*
* Exar ST16C2550 "A2" devices incorrectly detect as
* having an EFR, and report an ID of 0x0201. See
- * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html
+ * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html
*/
if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
return 1;
@@ -903,23 +914,6 @@ static int broken_efr(struct uart_8250_port *up)
return 0;
}
-static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
-{
- unsigned char status;
-
- status = serial_in(up, 0x04); /* EXCR2 */
-#define PRESL(x) ((x) & 0x30)
- if (PRESL(status) == 0x10) {
- /* already in high speed mode */
- return 0;
- } else {
- status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
- status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
- serial_out(up, 0x04, status);
- }
- return 1;
-}
-
/*
* We know that the chip has FIFOs. Does it have an EFR? The
* EFR is located in the same register position as the IIR and
@@ -1122,7 +1116,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
* whether or not this UART is a 16550A or not, since this will
* determine whether or not we can use its FIFO features or not.
*/
-static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
+static void autoconfig(struct uart_8250_port *up)
{
unsigned char status1, scratch, scratch2, scratch3;
unsigned char save_lcr, save_mcr;
@@ -1245,22 +1239,15 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
/*
* Only probe for RSA ports if we got the region.
*/
- if (port->type == PORT_16550A && probeflags & PROBE_RSA) {
- int i;
-
- for (i = 0 ; i < probe_rsa_count; ++i) {
- if (probe_rsa[i] == port->iobase && __enable_rsa(up)) {
- port->type = PORT_RSA;
- break;
- }
- }
- }
+ if (port->type == PORT_16550A && up->probe & UART_PROBE_RSA &&
+ __enable_rsa(up))
+ port->type = PORT_RSA;
#endif
serial_out(up, UART_LCR, save_lcr);
port->fifosize = uart_config[up->port.type].fifo_size;
- old_capabilities = up->capabilities;
+ old_capabilities = up->capabilities;
up->capabilities = uart_config[port->type].flags;
up->tx_loadsz = uart_config[port->type].tx_loadsz;
@@ -1907,6 +1894,48 @@ static void serial8250_backup_timeout(unsigned long data)
jiffies + uart_poll_timeout(&up->port) + HZ / 5);
}
+static int univ8250_setup_irq(struct uart_8250_port *up)
+{
+ struct uart_port *port = &up->port;
+ int retval = 0;
+
+ /*
+ * The above check will only give an accurate result the first time
+ * the port is opened so this value needs to be preserved.
+ */
+ if (up->bugs & UART_BUG_THRE) {
+ pr_debug("ttyS%d - using backup timer\n", serial_index(port));
+
+ up->timer.function = serial8250_backup_timeout;
+ up->timer.data = (unsigned long)up;
+ mod_timer(&up->timer, jiffies +
+ uart_poll_timeout(port) + HZ / 5);
+ }
+
+ /*
+ * If the "interrupt" for this port doesn't correspond with any
+ * hardware interrupt, we use a timer-based system. The original
+ * driver used to do this with IRQ0.
+ */
+ if (!port->irq) {
+ up->timer.data = (unsigned long)up;
+ mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
+ } else
+ retval = serial_link_irq_chain(up);
+
+ return retval;
+}
+
+static void univ8250_release_irq(struct uart_8250_port *up)
+{
+ struct uart_port *port = &up->port;
+
+ del_timer_sync(&up->timer);
+ up->timer.function = serial8250_timeout;
+ if (port->irq)
+ serial_unlink_irq_chain(up);
+}
+
static unsigned int serial8250_tx_empty(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
@@ -2211,35 +2240,12 @@ int serial8250_do_startup(struct uart_port *port)
if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
up->port.flags & UPF_BUG_THRE) {
up->bugs |= UART_BUG_THRE;
- pr_debug("ttyS%d - using backup timer\n",
- serial_index(port));
}
}
- /*
- * The above check will only give an accurate result the first time
- * the port is opened so this value needs to be preserved.
- */
- if (up->bugs & UART_BUG_THRE) {
- up->timer.function = serial8250_backup_timeout;
- up->timer.data = (unsigned long)up;
- mod_timer(&up->timer, jiffies +
- uart_poll_timeout(port) + HZ / 5);
- }
-
- /*
- * If the "interrupt" for this port doesn't correspond with any
- * hardware interrupt, we use a timer-based system. The original
- * driver used to do this with IRQ0.
- */
- if (!port->irq) {
- up->timer.data = (unsigned long)up;
- mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
- } else {
- retval = serial_link_irq_chain(up);
- if (retval)
- goto out;
- }
+ retval = up->ops->setup_irq(up);
+ if (retval)
+ goto out;
/*
* Now, initialize the UART
@@ -2270,7 +2276,7 @@ int serial8250_do_startup(struct uart_port *port)
is variable. So, let's just don't test if we receive
TX irq. This way, we'll never enable UART_BUG_TXEN.
*/
- if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
+ if (up->port.flags & UPF_NO_TXEN_TEST)
goto dont_test_tx_en;
/*
@@ -2397,10 +2403,7 @@ void serial8250_do_shutdown(struct uart_port *port)
serial_port_in(port, UART_RX);
serial8250_rpm_put(up);
- del_timer_sync(&up->timer);
- up->timer.function = serial8250_timeout;
- if (port->irq)
- serial_unlink_irq_chain(up);
+ up->ops->release_irq(up);
}
EXPORT_SYMBOL_GPL(serial8250_do_shutdown);
@@ -2719,6 +2722,8 @@ serial8250_pm(struct uart_port *port, unsigned int state,
static unsigned int serial8250_port_size(struct uart_8250_port *pt)
{
+ if (pt->port.mapsize)
+ return pt->port.mapsize;
if (pt->port.iotype == UPIO_AU) {
if (pt->port.type == PORT_RT2880)
return 0x100;
@@ -2798,6 +2803,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
}
}
+#ifdef CONFIG_SERIAL_8250_RSA
static int serial8250_request_rsa_resource(struct uart_8250_port *up)
{
unsigned long start = UART_RSA_BASE << up->port.regshift;
@@ -2832,14 +2838,13 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
break;
}
}
+#endif
static void serial8250_release_port(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
serial8250_release_std_resource(up);
- if (port->type == PORT_RSA)
- serial8250_release_rsa_resource(up);
}
static int serial8250_request_port(struct uart_port *port)
@@ -2851,11 +2856,6 @@ static int serial8250_request_port(struct uart_port *port)
return -ENODEV;
ret = serial8250_request_std_resource(up);
- if (ret == 0 && port->type == PORT_RSA) {
- ret = serial8250_request_rsa_resource(up);
- if (ret < 0)
- serial8250_release_std_resource(up);
- }
return ret;
}
@@ -3003,7 +3003,6 @@ static void register_dev_spec_attr_grp(struct uart_8250_port *up)
static void serial8250_config_port(struct uart_port *port, int flags)
{
struct uart_8250_port *up = up_to_u8250p(port);
- int probeflags = PROBE_ANY;
int ret;
if (port->type == PORT_8250_CIR)
@@ -3017,15 +3016,11 @@ static void serial8250_config_port(struct uart_port *port, int flags)
if (ret < 0)
return;
- ret = serial8250_request_rsa_resource(up);
- if (ret < 0)
- probeflags &= ~PROBE_RSA;
-
if (port->iotype != up->cur_iotype)
set_io_from_upio(port);
if (flags & UART_CONFIG_TYPE)
- autoconfig(up, probeflags);
+ autoconfig(up);
/* if access method is AU, it is a 16550 with a quirk */
if (port->type == PORT_16550A && port->iotype == UPIO_AU)
@@ -3038,8 +3033,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
autoconfig_irq(up);
- if (port->type != PORT_RSA && probeflags & PROBE_RSA)
- serial8250_release_rsa_resource(up);
if (port->type == PORT_UNKNOWN)
serial8250_release_std_resource(up);
@@ -3073,7 +3066,7 @@ serial8250_type(struct uart_port *port)
return uart_config[type].name;
}
-static struct uart_ops serial8250_pops = {
+static const struct uart_ops serial8250_pops = {
.tx_empty = serial8250_tx_empty,
.set_mctrl = serial8250_set_mctrl,
.get_mctrl = serial8250_get_mctrl,
@@ -3100,6 +3093,14 @@ static struct uart_ops serial8250_pops = {
#endif
};
+static const struct uart_ops *base_ops;
+static struct uart_ops univ8250_port_ops;
+
+static const struct uart_8250_ops univ8250_driver_ops = {
+ .setup_irq = univ8250_setup_irq,
+ .release_irq = univ8250_release_irq,
+};
+
static struct uart_8250_port serial8250_ports[UART_NR];
/**
@@ -3130,6 +3131,105 @@ void serial8250_set_isa_configurator(
}
EXPORT_SYMBOL(serial8250_set_isa_configurator);
+static void serial8250_init_port(struct uart_8250_port *up)
+{
+ struct uart_port *port = &up->port;
+
+ spin_lock_init(&port->lock);
+ port->ops = &serial8250_pops;
+
+ up->cur_iotype = 0xFF;
+}
+
+static void serial8250_set_defaults(struct uart_8250_port *up)
+{
+ struct uart_port *port = &up->port;
+
+ if (up->port.flags & UPF_FIXED_TYPE) {
+ unsigned int type = up->port.type;
+
+ if (!up->port.fifosize)
+ up->port.fifosize = uart_config[type].fifo_size;
+ if (!up->tx_loadsz)
+ up->tx_loadsz = uart_config[type].tx_loadsz;
+ if (!up->capabilities)
+ up->capabilities = uart_config[type].flags;
+ }
+
+ set_io_from_upio(port);
+
+ /* default dma handlers */
+ if (up->dma) {
+ if (!up->dma->tx_dma)
+ up->dma->tx_dma = serial8250_tx_dma;
+ if (!up->dma->rx_dma)
+ up->dma->rx_dma = serial8250_rx_dma;
+ }
+}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+
+static void univ8250_config_port(struct uart_port *port, int flags)
+{
+ struct uart_8250_port *up = up_to_u8250p(port);
+
+ up->probe &= ~UART_PROBE_RSA;
+ if (port->type == PORT_RSA) {
+ if (serial8250_request_rsa_resource(up) == 0)
+ up->probe |= UART_PROBE_RSA;
+ } else if (flags & UART_CONFIG_TYPE) {
+ int i;
+
+ for (i = 0; i < probe_rsa_count; i++) {
+ if (probe_rsa[i] == up->port.iobase) {
+ if (serial8250_request_rsa_resource(up) == 0)
+ up->probe |= UART_PROBE_RSA;
+ break;
+ }
+ }
+ }
+
+ base_ops->config_port(port, flags);
+
+ if (port->type != PORT_RSA && up->probe & UART_PROBE_RSA)
+ serial8250_release_rsa_resource(up);
+}
+
+static int univ8250_request_port(struct uart_port *port)
+{
+ struct uart_8250_port *up = up_to_u8250p(port);
+ int ret;
+
+ ret = base_ops->request_port(port);
+ if (ret == 0 && port->type == PORT_RSA) {
+ ret = serial8250_request_rsa_resource(up);
+ if (ret < 0)
+ base_ops->release_port(port);
+ }
+
+ return ret;
+}
+
+static void univ8250_release_port(struct uart_port *port)
+{
+ struct uart_8250_port *up = up_to_u8250p(port);
+
+ if (port->type == PORT_RSA)
+ serial8250_release_rsa_resource(up);
+ base_ops->release_port(port);
+}
+
+static void univ8250_rsa_support(struct uart_ops *ops)
+{
+ ops->config_port = univ8250_config_port;
+ ops->request_port = univ8250_request_port;
+ ops->release_port = univ8250_release_port;
+}
+
+#else
+#define univ8250_rsa_support(x) do { } while (0)
+#endif /* CONFIG_SERIAL_8250_RSA */
+
static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
@@ -3148,21 +3248,27 @@ static void __init serial8250_isa_init_ports(void)
struct uart_port *port = &up->port;
port->line = i;
- spin_lock_init(&port->lock);
+ serial8250_init_port(up);
+ if (!base_ops)
+ base_ops = port->ops;
+ port->ops = &univ8250_port_ops;
init_timer(&up->timer);
up->timer.function = serial8250_timeout;
- up->cur_iotype = 0xFF;
+
+ up->ops = &univ8250_driver_ops;
/*
* ALPHA_KLUDGE_MCR needs to be killed.
*/
up->mcr_mask = ~ALPHA_KLUDGE_MCR;
up->mcr_force = ALPHA_KLUDGE_MCR;
-
- port->ops = &serial8250_pops;
}
+ /* chain base port ops to support Remote Supervisor Adapter */
+ univ8250_port_ops = *base_ops;
+ univ8250_rsa_support(&univ8250_port_ops);
+
if (share_irqs)
irqflag = IRQF_SHARED;
@@ -3180,26 +3286,14 @@ static void __init serial8250_isa_init_ports(void)
port->membase = old_serial_port[i].iomem_base;
port->iotype = old_serial_port[i].io_type;
port->regshift = old_serial_port[i].iomem_reg_shift;
- set_io_from_upio(port);
+ serial8250_set_defaults(up);
+
port->irqflags |= irqflag;
if (serial8250_isa_config != NULL)
serial8250_isa_config(i, &up->port, &up->capabilities);
-
}
}
-static void
-serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
-{
- up->port.type = type;
- if (!up->port.fifosize)
- up->port.fifosize = uart_config[type].fifo_size;
- if (!up->tx_loadsz)
- up->tx_loadsz = uart_config[type].tx_loadsz;
- if (!up->capabilities)
- up->capabilities = uart_config[type].flags;
-}
-
static void __init
serial8250_register_ports(struct uart_driver *drv, struct device *dev)
{
@@ -3213,8 +3307,8 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
up->port.dev = dev;