diff options
Diffstat (limited to 'drivers/tty')
45 files changed, 4257 insertions, 3621 deletions
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index a9d837f83ce8..10beb1589d83 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -200,7 +200,7 @@ static int xen_hvm_console_init(void)  {  	int r;  	uint64_t v = 0; -	unsigned long mfn; +	unsigned long gfn;  	struct xencons_info *info;  	if (!xen_hvm_domain()) @@ -217,7 +217,7 @@ static int xen_hvm_console_init(void)  	}  	/*  	 * If the toolstack (or the hypervisor) hasn't set these values, the -	 * default value is 0. Even though mfn = 0 and evtchn = 0 are +	 * default value is 0. Even though gfn = 0 and evtchn = 0 are  	 * theoretically correct values, in practice they never are and they  	 * mean that a legacy toolstack hasn't initialized the pv console correctly.  	 */ @@ -229,8 +229,8 @@ static int xen_hvm_console_init(void)  	r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);  	if (r < 0 || v == 0)  		goto err; -	mfn = v; -	info->intf = xen_remap(mfn << PAGE_SHIFT, PAGE_SIZE); +	gfn = v; +	info->intf = xen_remap(gfn << PAGE_SHIFT, PAGE_SIZE);  	if (info->intf == NULL)  		goto err;  	info->vtermno = HVC_COOKIE; @@ -265,7 +265,8 @@ static int xen_pv_console_init(void)  		return 0;  	}  	info->evtchn = xen_start_info->console.domU.evtchn; -	info->intf = mfn_to_virt(xen_start_info->console.domU.mfn); +	/* GFN == MFN for PV guest */ +	info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);  	info->vtermno = HVC_COOKIE;  	spin_lock(&xencons_lock); @@ -374,7 +375,6 @@ static int xencons_connect_backend(struct xenbus_device *dev,  	int ret, evtchn, devid, ref, irq;  	struct xenbus_transaction xbt;  	grant_ref_t gref_head; -	unsigned long mfn;  	ret = xenbus_alloc_evtchn(dev, &evtchn);  	if (ret) @@ -389,10 +389,6 @@ static int xencons_connect_backend(struct xenbus_device *dev,  			irq, &domU_hvc_ops, 256);  	if (IS_ERR(info->hvc))  		return PTR_ERR(info->hvc); -	if (xen_pv_domain()) -		mfn = virt_to_mfn(info->intf); -	else -		mfn = __pa(info->intf) >> PAGE_SHIFT;  	ret = gnttab_alloc_grant_references(1, &gref_head);  	if (ret < 0)  		return ret; @@ -401,7 +397,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,  	if (ref < 0)  		return ref;  	gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id, -			mfn, 0); +					virt_to_gfn(info->intf), 0);   again:  	ret = xenbus_transaction_start(&xbt); diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 41901997c0d6..a75146f600cb 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -240,9 +240,9 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,  {  	struct hvsi_control *header = (struct hvsi_control *)packet; -	switch (header->verb) { +	switch (be16_to_cpu(header->verb)) {  		case VSV_MODEM_CTL_UPDATE: -			if ((header->word & HVSI_TSCD) == 0) { +			if ((be32_to_cpu(header->word) & HVSI_TSCD) == 0) {  				/* CD went away; no more connection */  				pr_debug("hvsi%i: CD dropped\n", hp->index);  				hp->mctrl &= TIOCM_CD; @@ -267,6 +267,7 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,  static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet)  {  	struct hvsi_query_response *resp = (struct hvsi_query_response *)packet; +	uint32_t mctrl_word;  	switch (hp->state) {  		case HVSI_WAIT_FOR_VER_RESPONSE: @@ -274,9 +275,10 @@ static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet)  			break;  		case HVSI_WAIT_FOR_MCTRL_RESPONSE:  			hp->mctrl = 0; -			if (resp->u.mctrl_word & HVSI_TSDTR) +			mctrl_word = be32_to_cpu(resp->u.mctrl_word); +			if (mctrl_word & HVSI_TSDTR)  				hp->mctrl |= TIOCM_DTR; -			if (resp->u.mctrl_word & HVSI_TSCD) +			if (mctrl_word & HVSI_TSCD)  				hp->mctrl |= TIOCM_CD;  			__set_state(hp, HVSI_OPEN);  			break; @@ -295,10 +297,10 @@ static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno)  	packet.hdr.type = VS_QUERY_RESPONSE_PACKET_HEADER;  	packet.hdr.len = sizeof(struct hvsi_query_response); -	packet.hdr.seqno = atomic_inc_return(&hp->seqno); -	packet.verb = VSV_SEND_VERSION_NUMBER; +	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); +	packet.verb = cpu_to_be16(VSV_SEND_VERSION_NUMBER);  	packet.u.version = HVSI_VERSION; -	packet.query_seqno = query_seqno+1; +	packet.query_seqno = cpu_to_be16(query_seqno+1);  	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);  	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len); @@ -319,7 +321,7 @@ static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet)  	switch (hp->state) {  		case HVSI_WAIT_FOR_VER_QUERY: -			hvsi_version_respond(hp, query->hdr.seqno); +			hvsi_version_respond(hp, be16_to_cpu(query->hdr.seqno));  			__set_state(hp, HVSI_OPEN);  			break;  		default: @@ -555,8 +557,8 @@ static int hvsi_query(struct hvsi_struct *hp, uint16_t verb)  	packet.hdr.type = VS_QUERY_PACKET_HEADER;  	packet.hdr.len = sizeof(struct hvsi_query); -	packet.hdr.seqno = atomic_inc_return(&hp->seqno); -	packet.verb = verb; +	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); +	packet.verb = cpu_to_be16(verb);  	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);  	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len); @@ -596,14 +598,14 @@ static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl)  	struct hvsi_control packet __ALIGNED__;  	int wrote; -	packet.hdr.type = VS_CONTROL_PACKET_HEADER, -	packet.hdr.seqno = atomic_inc_return(&hp->seqno); +	packet.hdr.type = VS_CONTROL_PACKET_HEADER; +	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));  	packet.hdr.len = sizeof(struct hvsi_control); -	packet.verb = VSV_SET_MODEM_CTL; -	packet.mask = HVSI_TSDTR; +	packet.verb = cpu_to_be16(VSV_SET_MODEM_CTL); +	packet.mask = cpu_to_be32(HVSI_TSDTR);  	if (mctrl & TIOCM_DTR) -		packet.word = HVSI_TSDTR; +		packet.word = cpu_to_be32(HVSI_TSDTR);  	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);  	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len); @@ -680,7 +682,7 @@ static int hvsi_put_chars(struct hvsi_struct *hp, const char *buf, int count)  	BUG_ON(count > HVSI_MAX_OUTGOING_DATA);  	packet.hdr.type = VS_DATA_PACKET_HEADER; -	packet.hdr.seqno = atomic_inc_return(&hp->seqno); +	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));  	packet.hdr.len = count + sizeof(struct hvsi_header);  	memcpy(&packet.data, buf, count); @@ -697,9 +699,9 @@ static void hvsi_close_protocol(struct hvsi_struct *hp)  	struct hvsi_control packet __ALIGNED__;  	packet.hdr.type = VS_CONTROL_PACKET_HEADER; -	packet.hdr.seqno = atomic_inc_return(&hp->seqno); +	packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno));  	packet.hdr.len = 6; -	packet.verb = VSV_CLOSE_PROTOCOL; +	packet.verb = cpu_to_be16(VSV_CLOSE_PROTOCOL);  	pr_debug("%s: sending %i bytes\n", __func__, packet.hdr.len);  	dbg_dump_hex((uint8_t*)&packet, packet.hdr.len); @@ -1180,7 +1182,7 @@ static int __init hvsi_console_init(void)  	/* search device tree for vty nodes */  	for_each_compatible_node(vty, "serial", "hvterm-protocol") {  		struct hvsi_struct *hp; -		const uint32_t *vtermno, *irq; +		const __be32 *vtermno, *irq;  		vtermno = of_get_property(vty, "reg", NULL);  		irq = of_get_property(vty, "interrupts", NULL); @@ -1202,11 +1204,11 @@ static int __init hvsi_console_init(void)  		hp->index = hvsi_count;  		hp->inbuf_end = hp->inbuf;  		hp->state = HVSI_CLOSED; -		hp->vtermno = *vtermno; -		hp->virq = irq_create_mapping(NULL, irq[0]); +		hp->vtermno = be32_to_cpup(vtermno); +		hp->virq = irq_create_mapping(NULL, be32_to_cpup(irq));  		if (hp->virq == 0) {  			printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", -				__func__, irq[0]); +			       __func__, be32_to_cpup(irq));  			tty_port_destroy(&hp->port);  			continue;  		} diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index 358323c83b4f..a8c8cfd52a23 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -879,6 +879,11 @@ static const struct tty_operations mips_ejtag_fdc_tty_ops = {  	.chars_in_buffer	= mips_ejtag_fdc_tty_chars_in_buffer,  }; +int __weak get_c0_fdc_int(void) +{ +	return -1; +} +  static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev)  {  	int ret, nport; @@ -967,9 +972,7 @@ static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev)  	wake_up_process(priv->thread);  	/* Look for an FDC IRQ */ -	priv->irq = -1; -	if (get_c0_fdc_int) -		priv->irq = get_c0_fdc_int(); +	priv->irq = get_c0_fdc_int();  	/* Try requesting the IRQ */  	if (priv->irq >= 0) { diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 382d3fcba6cc..c3fe026d3168 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2712,7 +2712,7 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,  	memcpy(skb_put(skb, size), in_buf, size);  	skb->dev = net; -	skb->protocol = __constant_htons(ETH_P_IP); +	skb->protocol = htons(ETH_P_IP);  	/* Ship it off to the kernel */  	netif_rx(skb); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c9c27f69e101..20932cc9c8f7 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1108,19 +1108,29 @@ static void eraser(unsigned char c, struct tty_struct *tty)   *	Locking: ctrl_lock   */ -static void isig(int sig, struct tty_struct *tty) +static void __isig(int sig, struct tty_struct *tty)  { -	struct n_tty_data *ldata = tty->disc_data;  	struct pid *tty_pgrp = tty_get_pgrp(tty);  	if (tty_pgrp) {  		kill_pgrp(tty_pgrp, sig, 1);  		put_pid(tty_pgrp);  	} +} + +static void isig(int sig, struct tty_struct *tty) +{ +	struct n_tty_data *ldata = tty->disc_data; + +	if (L_NOFLSH(tty)) { +		/* signal only */ +		__isig(sig, tty); -	if (!L_NOFLSH(tty)) { +	} else { /* signal and flush */  		up_read(&tty->termios_rwsem);  		down_write(&tty->termios_rwsem); +		__isig(sig, tty); +  		/* clear echo buffer */  		mutex_lock(&ldata->output_lock);  		ldata->echo_head = ldata->echo_tail = 0; @@ -2137,6 +2147,8 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *,  static int job_control(struct tty_struct *tty, struct file *file)  { +	struct pid *pgrp; +  	/* Job control check -- must be done at start and after  	   every sleep (POSIX.1 7.1.1.4). */  	/* NOTE: not yet done after every sleep pending a thorough @@ -2146,18 +2158,25 @@ static int job_control(struct tty_struct *tty, struct file *file)  	    current->signal->tty != tty)  		return 0; +	rcu_read_lock(); +	pgrp = task_pgrp(current); +  	spin_lock_irq(&tty->ctrl_lock);  	if (!tty->pgrp)  		printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); -	else if (task_pgrp(current) != tty->pgrp) { +	else if (pgrp != tty->pgrp) {  		spin_unlock_irq(&tty->ctrl_lock); -		if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) +		if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) { +			rcu_read_unlock();  			return -EIO; -		kill_pgrp(task_pgrp(current), SIGTTIN, 1); +		} +		kill_pgrp(pgrp, SIGTTIN, 1); +		rcu_read_unlock();  		set_thread_flag(TIF_SIGPENDING);  		return -ERESTARTSYS;  	}  	spin_unlock_irq(&tty->ctrl_lock); +	rcu_read_unlock();  	return 0;  } diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 4d5e8409769c..4d5937c185c1 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -26,6 +26,12 @@  #include <linux/mutex.h>  #include <linux/poll.h> +#undef TTY_DEBUG_HANGUP +#ifdef TTY_DEBUG_HANGUP +# define tty_debug_hangup(tty, f, args...)	tty_debug(tty, f, ##args) +#else +# define tty_debug_hangup(tty, f, args...)	do {} while (0) +#endif  #ifdef CONFIG_UNIX98_PTYS  static struct tty_driver *ptm_driver; @@ -779,6 +785,8 @@ static int ptmx_open(struct inode *inode, struct file *filp)  	if (retval)  		goto err_release; +	tty_debug_hangup(tty, "(tty count=%d)\n", tty->count); +  	tty_unlock(tty);  	return 0;  err_release: diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index c43f74c53cd9..d54dcd87c67e 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -42,9 +42,9 @@ struct uart_8250_dma {  	size_t			rx_size;  	size_t			tx_size; -	unsigned char		tx_running:1; -	unsigned char		tx_err: 1; -	unsigned char		rx_running:1; +	unsigned char		tx_running; +	unsigned char		tx_err; +	unsigned char		rx_running;  };  struct old_serial_port { @@ -211,3 +211,14 @@ static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)  	}  	return 1;  } + +static inline int serial_index(struct uart_port *port) +{ +	return port->minor - 64; +} + +#if 0 +#define DEBUG_INTR(fmt...)	printk(fmt) +#else +#define DEBUG_INTR(fmt...)	do { } while (0) +#endif diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 37fff12dd4d0..271d12137649 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1,25 +1,23 @@  /* - *  Driver for 8250/16550-type serial ports + *  Universal/legacy driver for 8250/16550-type serial ports   *   *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.   *   *  Copyright (C) 2001 Russell King.   * + *  Supports: ISA-compatible 8250/16550 ports + *	      PNP 8250/16550 ports + *	      early_serial_setup() ports + *	      userspace-configurable "phantom" ports + *	      "serial8250" platform devices + *	      serial8250_register_8250_port() ports + *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by   * the Free Software Foundation; either version 2 of the License, or   * (at your option) any later version. - * - * A note about mapbase / membase - * - *  mapbase is the physical address of the IO port. - *  membase is an 'ioremapped' cookie.   */ -#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif -  #include <linux/module.h>  #include <linux/moduleparam.h>  #include <linux/ioport.h> @@ -38,11 +36,11 @@  #include <linux/slab.h>  #include <linux/uaccess.h>  #include <linux/pm_runtime.h> +#include <linux/io.h>  #ifdef CONFIG_SPARC  #include <linux/sunserialcore.h>  #endif -#include <asm/io.h>  #include <asm/irq.h>  #include "8250.h" @@ -58,33 +56,10 @@ static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;  static struct uart_driver serial8250_reg; -static int serial_index(struct uart_port *port) -{ -	return port->minor - 64; -} -  static unsigned int skip_txen_test; /* force skip of txen test at init time */ -/* - * Debugging. - */ -#if 0 -#define DEBUG_AUTOCONF(fmt...)	printk(fmt) -#else -#define DEBUG_AUTOCONF(fmt...)	do { } while (0) -#endif - -#if 0 -#define DEBUG_INTR(fmt...)	printk(fmt) -#else -#define DEBUG_INTR(fmt...)	do { } while (0) -#endif -  #define PASS_LIMIT	512 -#define BOTH_EMPTY 	(UART_LSR_TEMT | UART_LSR_THRE) - -  #include <asm/serial.h>  /*   * SERIAL_PORT_DFNS tells us about built-in ports that have no @@ -120,1563 +95,6 @@ static struct hlist_head irq_lists[NR_IRQ_HASH];  static DEFINE_MUTEX(hash_mutex);	/* Used to walk the hash */  /* - * Here we define the default xmit fifo size used for each type of UART. - */ -static const struct serial8250_config uart_config[] = { -	[PORT_UNKNOWN] = { -		.name		= "unknown", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -	}, -	[PORT_8250] = { -		.name		= "8250", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -	}, -	[PORT_16450] = { -		.name		= "16450", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -	}, -	[PORT_16550] = { -		.name		= "16550", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -	}, -	[PORT_16550A] = { -		.name		= "16550A", -		.fifo_size	= 16, -		.tx_loadsz	= 16, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.rxtrig_bytes	= {1, 4, 8, 14}, -		.flags		= UART_CAP_FIFO, -	}, -	[PORT_CIRRUS] = { -		.name		= "Cirrus", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -	}, -	[PORT_16650] = { -		.name		= "ST16650", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, -	}, -	[PORT_16650V2] = { -		.name		= "ST16650V2", -		.fifo_size	= 32, -		.tx_loadsz	= 16, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | -				  UART_FCR_T_TRIG_00, -		.rxtrig_bytes	= {8, 16, 24, 28}, -		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, -	}, -	[PORT_16750] = { -		.name		= "TI16750", -		.fifo_size	= 64, -		.tx_loadsz	= 64, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | -				  UART_FCR7_64BYTE, -		.rxtrig_bytes	= {1, 16, 32, 56}, -		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, -	}, -	[PORT_STARTECH] = { -		.name		= "Startech", -		.fifo_size	= 1, -		.tx_loadsz	= 1, -	}, -	[PORT_16C950] = { -		.name		= "16C950/954", -		.fifo_size	= 128, -		.tx_loadsz	= 128, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		/* UART_CAP_EFR breaks billionon CF bluetooth card. */ -		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP, -	}, -	[PORT_16654] = { -		.name		= "ST16654", -		.fifo_size	= 64, -		.tx_loadsz	= 32, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | -				  UART_FCR_T_TRIG_10, -		.rxtrig_bytes	= {8, 16, 56, 60}, -		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, -	}, -	[PORT_16850] = { -		.name		= "XR16850", -		.fifo_size	= 128, -		.tx_loadsz	= 128, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, -	}, -	[PORT_RSA] = { -		.name		= "RSA", -		.fifo_size	= 2048, -		.tx_loadsz	= 2048, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, -		.flags		= UART_CAP_FIFO, -	}, -	[PORT_NS16550A] = { -		.name		= "NS16550A", -		.fifo_size	= 16, -		.tx_loadsz	= 16, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_NATSEMI, -	}, -	[PORT_XSCALE] = { -		.name		= "XScale", -		.fifo_size	= 32, -		.tx_loadsz	= 32, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, -	}, -	[PORT_OCTEON] = { -		.name		= "OCTEON", -		.fifo_size	= 64, -		.tx_loadsz	= 64, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO, -	}, -	[PORT_AR7] = { -		.name		= "AR7", -		.fifo_size	= 16, -		.tx_loadsz	= 16, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE, -	}, -	[PORT_U6_16550A] = { -		.name		= "U6_16550A", -		.fifo_size	= 64, -		.tx_loadsz	= 64, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE, -	}, -	[PORT_TEGRA] = { -		.name		= "Tegra", -		.fifo_size	= 32, -		.tx_loadsz	= 8, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | -				  UART_FCR_T_TRIG_01, -		.rxtrig_bytes	= {1, 4, 8, 14}, -		.flags		= UART_CAP_FIFO | UART_CAP_RTOIE, -	}, -	[PORT_XR17D15X] = { -		.name		= "XR17D15X", -		.fifo_size	= 64, -		.tx_loadsz	= 64, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | -				  UART_CAP_SLEEP, -	}, -	[PORT_XR17V35X] = { -		.name		= "XR17V35X", -		.fifo_size	= 256, -		.tx_loadsz	= 256, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | -				  UART_FCR_T_TRIG_11, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | -				  UART_CAP_SLEEP, -	}, -	[PORT_LPC3220] = { -		.name		= "LPC3220", -		.fifo_size	= 64, -		.tx_loadsz	= 32, -		.fcr		= UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | -				  UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, -		.flags		= UART_CAP_FIFO, -	}, -	[PORT_BRCM_TRUMANAGE] = { -		.name		= "TruManage", -		.fifo_size	= 1, -		.tx_loadsz	= 1024, -		.flags		= UART_CAP_HFIFO, -	}, -	[PORT_8250_CIR] = { -		.name		= "CIR port" -	}, -	[PORT_ALTR_16550_F32] = { -		.name		= "Altera 16550 FIFO32", -		.fifo_size	= 32, -		.tx_loadsz	= 32, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE, -	}, -	[PORT_ALTR_16550_F64] = { -		.name		= "Altera 16550 FIFO64", -		.fifo_size	= 64, -		.tx_loadsz	= 64, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE, -	}, -	[PORT_ALTR_16550_F128] = { -		.name		= "Altera 16550 FIFO128", -		.fifo_size	= 128, -		.tx_loadsz	= 128, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_AFE, -	}, -/* tx_loadsz is set to 63-bytes instead of 64-bytes to implement -workaround of errata A-008006 which states that tx_loadsz should  be -configured less than Maximum supported fifo bytes */ -	[PORT_16550A_FSL64] = { -		.name		= "16550A_FSL64", -		.fifo_size	= 64, -		.tx_loadsz	= 63, -		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | -				  UART_FCR7_64BYTE, -		.flags		= UART_CAP_FIFO, -	}, -}; - -/* Uart divisor latch read */ -static int default_serial_dl_read(struct uart_8250_port *up) -{ -	return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; -} - -/* Uart divisor latch write */ -static void default_serial_dl_write(struct uart_8250_port *up, int value) -{ -	serial_out(up, UART_DLL, value & 0xff); -	serial_out(up, UART_DLM, value >> 8 & 0xff); -} - -#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) - -/* Au1x00/RT288x UART hardware has a weird register layout */ -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 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) -{ -	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) -{ -	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 */ -static int au_serial_dl_read(struct uart_8250_port *up) -{ -	return __raw_readl(up->port.membase + 0x28); -} - -static void au_serial_dl_write(struct uart_8250_port *up, int value) -{ -	__raw_writel(value, up->port.membase + 0x28); -} - -#endif - -static unsigned int hub6_serial_in(struct uart_port *p, int offset) -{ -	offset = offset << p->regshift; -	outb(p->hub6 - 1 + offset, p->iobase); -	return inb(p->iobase + 1); -} - -static void hub6_serial_out(struct uart_port *p, int offset, int value) -{ -	offset = offset << p->regshift; -	outb(p->hub6 - 1 + offset, p->iobase); -	outb(value, p->iobase + 1); -} - -static unsigned int mem_serial_in(struct uart_port *p, int offset) -{ -	offset = offset << p->regshift; -	return readb(p->membase + offset); -} - -static void mem_serial_out(struct uart_port *p, int offset, int value) -{ -	offset = offset << p->regshift; -	writeb(value, p->membase + offset); -} - -static void mem32_serial_out(struct uart_port *p, int offset, int value) -{ -	offset = offset << p->regshift; -	writel(value, p->membase + offset); -} - -static unsigned int mem32_serial_in(struct uart_port *p, int offset) -{ -	offset = offset << p->regshift; -	return readl(p->membase + offset); -} - -static void mem32be_serial_out(struct uart_port *p, int offset, int value) -{ -	offset = offset << p->regshift; -	iowrite32be(value, p->membase + offset); -} - -static unsigned int mem32be_serial_in(struct uart_port *p, int offset) -{ -	offset = offset << p->regshift; -	return ioread32be(p->membase + offset); -} - -static unsigned int io_serial_in(struct uart_port *p, int offset) -{ -	offset = offset << p->regshift; -	return inb(p->iobase + offset); -} - -static void io_serial_out(struct uart_port *p, int offset, int value) -{ -	offset = offset << p->regshift; -	outb(value, p->iobase + offset); -} - -static int serial8250_default_handle_irq(struct uart_port *port); -static int exar_handle_irq(struct uart_port *port); - -static void set_io_from_upio(struct uart_port *p) -{ -	struct uart_8250_port *up = up_to_u8250p(p); - -	up->dl_read = default_serial_dl_read; -	up->dl_write = default_serial_dl_write; - -	switch (p->iotype) { -	case UPIO_HUB6: -		p->serial_in = hub6_serial_in; -		p->serial_out = hub6_serial_out; -		break; - -	case UPIO_MEM: -		p->serial_in = mem_serial_in; -		p->serial_out = mem_serial_out; -		break; - -	case UPIO_MEM32: -		p->serial_in = mem32_serial_in; -		p->serial_out = mem32_serial_out; -		break; - -	case UPIO_MEM32BE: -		p->serial_in = mem32be_serial_in; -		p->serial_out = mem32be_serial_out; -		break; - -#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) -	case UPIO_AU: -		p->serial_in = au_serial_in; -		p->serial_out = au_serial_out; -		up->dl_read = au_serial_dl_read; -		up->dl_write = au_serial_dl_write; -		break; -#endif - -	default: -		p->serial_in = io_serial_in; -		p->serial_out = io_serial_out; -		break; -	} -	/* Remember loaded iotype */ -	up->cur_iotype = p->iotype; -	p->handle_irq = serial8250_default_handle_irq; -} - -static void -serial_port_out_sync(struct uart_port *p, int offset, int value) -{ -	switch (p->iotype) { -	case UPIO_MEM: -	case UPIO_MEM32: -	case UPIO_MEM32BE: -	case UPIO_AU: -		p->serial_out(p, offset, value); -		p->serial_in(p, UART_LCR);	/* safe, no side-effects */ -		break; -	default: -		p->serial_out(p, offset, value); -	} -} - -/* - * For the 16C950 - */ -static void serial_icr_write(struct uart_8250_port *up, int offset, int value) -{ -	serial_out(up, UART_SCR, offset); -	serial_out(up, UART_ICR, value); -} - -static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) -{ -	unsigned int value; - -	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD); -	serial_out(up, UART_SCR, offset); -	value = serial_in(up, UART_ICR); -	serial_icr_write(up, UART_ACR, up->acr); - -	return value; -} - -/* - * FIFO support. - */ -static void serial8250_clear_fifos(struct uart_8250_port *p) -{ -	if (p->capabilities & UART_CAP_FIFO) { -		serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); -		serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | -			       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); -		serial_out(p, UART_FCR, 0); -	} -} - -void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) -{ -	serial8250_clear_fifos(p); -	serial_out(p, UART_FCR, p->fcr); -} -EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); - -void serial8250_rpm_get(struct uart_8250_port *p) -{ -	if (!(p->capabilities & UART_CAP_RPM)) -		return; -	pm_runtime_get_sync(p->port.dev); -} -EXPORT_SYMBOL_GPL(serial8250_rpm_get); - -void serial8250_rpm_put(struct uart_8250_port *p) -{ -	if (!(p->capabilities & UART_CAP_RPM)) -		return; -	pm_runtime_mark_last_busy(p->port.dev); -	pm_runtime_put_autosuspend(p->port.dev); -} -EXPORT_SYMBOL_GPL(serial8250_rpm_put); - -/* - * These two wrappers ensure that enable_runtime_pm_tx() can be called more than - * once and disable_runtime_pm_tx() will still disable RPM because the fifo is - * empty and the HW can idle again. - */ -static void serial8250_rpm_get_tx(struct uart_8250_port *p) -{ -	unsigned char rpm_active; - -	if (!(p->capabilities & UART_CAP_RPM)) -		return; - -	rpm_active = xchg(&p->rpm_tx_active, 1); -	if (rpm_active) -		return; -	pm_runtime_get_sync(p->port.dev); -} - -static void serial8250_rpm_put_tx(struct uart_8250_port *p) -{ -	unsigned char rpm_active; - -	if (!(p->capabilities & UART_CAP_RPM)) -		return; - -	rpm_active = xchg(&p->rpm_tx_active, 0); -	if (!rpm_active) -		return; -	pm_runtime_mark_last_busy(p->port.dev); -	pm_runtime_put_autosuspend(p->port.dev); -} - -/* - * IER sleep support.  UARTs which have EFRs need the "extended - * capability" bit enabled.  Note that on XR16C850s, we need to - * reset LCR to write to IER. - */ -static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) -{ -	unsigned char lcr = 0, efr = 0; -	/* -	 * Exar UARTs have a SLEEP register that enables or disables -	 * each UART to enter sleep mode separately.  On the XR17V35x the -	 * register is accessible to each UART at the UART_EXAR_SLEEP -	 * offset but the UART channel may only write to the corresponding -	 * bit. -	 */ -	serial8250_rpm_get(p); -	if ((p->port.type == PORT_XR17V35X) || -	   (p->port.type == PORT_XR17D15X)) { -		serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); -		goto out; -	} - -	if (p->capabilities & UART_CAP_SLEEP) { -		if (p->capabilities & UART_CAP_EFR) { -			lcr = serial_in(p, UART_LCR); -			efr = serial_in(p, UART_EFR); -			serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); -			serial_out(p, UART_EFR, UART_EFR_ECB); -			serial_out(p, UART_LCR, 0); -		} -		serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); -		if (p->capabilities & UART_CAP_EFR) { -			serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); -			serial_out(p, UART_EFR, efr); -			serial_out(p, UART_LCR, lcr); -		} -	} -out: -	serial8250_rpm_put(p); -} - -#ifdef CONFIG_SERIAL_8250_RSA -/* - * Attempts to turn on the RSA FIFO.  Returns zero on failure. - * We set the port uart clock rate if we succeed. - */ -static int __enable_rsa(struct uart_8250_port *up) -{ -	unsigned char mode; -	int result; - -	mode = serial_in(up, UART_RSA_MSR); -	result = mode & UART_RSA_MSR_FIFO; - -	if (!result) { -		serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); -		mode = serial_in(up, UART_RSA_MSR); -		result = mode & UART_RSA_MSR_FIFO; -	} - -	if (result) -		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; - -	return result; -} - -static void enable_rsa(struct uart_8250_port *up) -{ -	if (up->port.type == PORT_RSA) { -		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { -			spin_lock_irq(&up->port.lock); -			__enable_rsa(up); -			spin_unlock_irq(&up->port.lock); -		} -		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) -			serial_out(up, UART_RSA_FRR, 0); -	} -} - -/* - * Attempts to turn off the RSA FIFO.  Returns zero on failure. - * It is unknown why interrupts were disabled in here.  However, - * the caller is expected to preserve this behaviour by grabbing - * the spinlock before calling this function. - */ -static void disable_rsa(struct uart_8250_port *up) -{ -	unsigned char mode; -	int result; - -	if (up->port.type == PORT_RSA && -	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { -		spin_lock_irq(&up->port.lock); - -		mode = serial_in(up, UART_RSA_MSR); -		result = !(mode & UART_RSA_MSR_FIFO); - -		if (!result) { -			serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); -			mode = serial_in(up, UART_RSA_MSR); -			result = !(mode & UART_RSA_MSR_FIFO); -		} - -		if (result) -			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; -		spin_unlock_irq(&up->port.lock); -	} -} -#endif /* CONFIG_SERIAL_8250_RSA */ - -/* - * This is a quickie test to see how big the FIFO is. - * It doesn't work at all the time, more's the pity. - */ -static int size_fifo(struct uart_8250_port *up) -{ -	unsigned char old_fcr, old_mcr, old_lcr; -	unsigned short old_dl; -	int count; - -	old_lcr = serial_in(up, UART_LCR); -	serial_out(up, UART_LCR, 0); -	old_fcr = serial_in(up, UART_FCR); -	old_mcr = serial_in(up, UART_MCR); -	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | -		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); -	serial_out(up, UART_MCR, UART_MCR_LOOP); -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); -	old_dl = serial_dl_read(up); -	serial_dl_write(up, 0x0001); -	serial_out(up, UART_LCR, 0x03); -	for (count = 0; count < 256; count++) -		serial_out(up, UART_TX, count); -	mdelay(20);/* FIXME - schedule_timeout */ -	for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && -	     (count < 256); count++) -		serial_in(up, UART_RX); -	serial_out(up, UART_FCR, old_fcr); -	serial_out(up, UART_MCR, old_mcr); -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); -	serial_dl_write(up, old_dl); -	serial_out(up, UART_LCR, old_lcr); - -	return count; -} - -/* - * Read UART ID using the divisor method - set DLL and DLM to zero - * and the revision will be in DLL and device type in DLM.  We - * preserve the device state across this. - */ -static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) -{ -	unsigned char old_dll, old_dlm, old_lcr; -	unsigned int id; - -	old_lcr = serial_in(p, UART_LCR); -	serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); - -	old_dll = serial_in(p, UART_DLL); -	old_dlm = serial_in(p, UART_DLM); - -	serial_out(p, UART_DLL, 0); -	serial_out(p, UART_DLM, 0); - -	id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; - -	serial_out(p, UART_DLL, old_dll); -	serial_out(p, UART_DLM, old_dlm); -	serial_out(p, UART_LCR, old_lcr); - -	return id; -} - -/* - * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. - * When this function is called we know it is at least a StarTech - * 16650 V2, but it might be one of several StarTech UARTs, or one of - * its clones.  (We treat the broken original StarTech 16650 V1 as a - * 16550, and why not?  Startech doesn't seem to even acknowledge its - * existence.) - * - * What evil have men's minds wrought... - */ -static void autoconfig_has_efr(struct uart_8250_port *up) -{ -	unsigned int id1, id2, id3, rev; - -	/* -	 * Everything with an EFR has SLEEP -	 */ -	up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; - -	/* -	 * First we check to see if it's an Oxford Semiconductor UART. -	 * -	 * If we have to do this here because some non-National -	 * Semiconductor clone chips lock up if you try writing to the -	 * LSR register (which serial_icr_read does) -	 */ - -	/* -	 * Check for Oxford Semiconductor 16C950. -	 * -	 * EFR [4] must be set else this test fails. -	 * -	 * This shouldn't be necessary, but Mike Hudson ([email protected]) -	 * claims that it's needed for 952 dual UART's (which are not -	 * recommended for new designs). -	 */ -	up->acr = 0; -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); -	serial_out(up, UART_EFR, UART_EFR_ECB); -	serial_out(up, UART_LCR, 0x00); -	id1 = serial_icr_read(up, UART_ID1); -	id2 = serial_icr_read(up, UART_ID2); -	id3 = serial_icr_read(up, UART_ID3); -	rev = serial_icr_read(up, UART_REV); - -	DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev); - -	if (id1 == 0x16 && id2 == 0xC9 && -	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { -		up->port.type = PORT_16C950; - -		/* -		 * Enable work around for the Oxford Semiconductor 952 rev B -		 * chip which causes it to seriously miscalculate baud rates -		 * when DLL is 0. -		 */ -		if (id3 == 0x52 && rev == 0x01) -			up->bugs |= UART_BUG_QUOT; -		return; -	} - -	/* -	 * We check for a XR16C850 by setting DLL and DLM to 0, and then -	 * reading back DLL and DLM.  The chip type depends on the DLM -	 * value read back: -	 *  0x10 - XR16C850 and the DLL contains the chip revision. -	 *  0x12 - XR16C2850. -	 *  0x14 - XR16C854. -	 */ -	id1 = autoconfig_read_divisor_id(up); -	DEBUG_AUTOCONF("850id=%04x ", id1); - -	id2 = id1 >> 8; -	if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { -		up->port.type = PORT_16850; -		return; -	} - -	/* -	 * It wasn't an XR16C850. -	 * -	 * We distinguish between the '654 and the '650 by counting -	 * how many bytes are in the FIFO.  I'm using this for now, -	 * since that's the technique that was sent to me in the -	 * serial driver update, but I'm not convinced this works. -	 * I've had problems doing this in the past.  -TYT -	 */ -	if (size_fifo(up) == 64) -		up->port.type = PORT_16654; -	else -		up->port.type = PORT_16650V2; -} - -/* - * We detected a chip without a FIFO.  Only two fall into - * this category - the original 8250 and the 16450.  The - * 16450 has a scratch register (accessible with LCR=0) - */ -static void autoconfig_8250(struct uart_8250_port *up) -{ -	unsigned char scratch, status1, status2; - -	up->port.type = PORT_8250; - -	scratch = serial_in(up, UART_SCR); -	serial_out(up, UART_SCR, 0xa5); -	status1 = serial_in(up, UART_SCR); -	serial_out(up, UART_SCR, 0x5a); -	status2 = serial_in(up, UART_SCR); -	serial_out(up, UART_SCR, scratch); - -	if (status1 == 0xa5 && status2 == 0x5a) -		up->port.type = PORT_16450; -} - -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 -	 */ -	if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) -		return 1; - -	return 0; -} - -/* - * 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 - * we know the top two bits of the IIR are currently set.  The - * EFR should contain zero.  Try to read the EFR. - */ -static void autoconfig_16550a(struct uart_8250_port *up) -{ -	unsigned char status1, status2; -	unsigned int iersave; - -	up->port.type = PORT_16550A; -	up->capabilities |= UART_CAP_FIFO; - -	/* -	 * XR17V35x UARTs have an extra divisor register, DLD -	 * that gets enabled with when DLAB is set which will -	 * cause the device to incorrectly match and assign -	 * port type to PORT_16650.  The EFR for this UART is -	 * found at offset 0x09. Instead check the Deice ID (DVID) -	 * register for a 2, 4 or 8 port UART. -	 */ -	if (up->port.flags & UPF_EXAR_EFR) { -		status1 = serial_in(up, UART_EXAR_DVID); -		if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) { -			DEBUG_AUTOCONF("Exar XR17V35x "); -			up->port.type = PORT_XR17V35X; -			up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | -						UART_CAP_SLEEP; - -			return; -		} - -	} - -	/* -	 * Check for presence of the EFR when DLAB is set. -	 * Only ST16C650V1 UARTs pass this test. -	 */ -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); -	if (serial_in(up, UART_EFR) == 0) { -		serial_out(up, UART_EFR, 0xA8); -		if (serial_in(up, UART_EFR) != 0) { -			DEBUG_AUTOCONF("EFRv1 "); -			up->port.type = PORT_16650; -			up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; -		} else { -			serial_out(up, UART_LCR, 0); -			serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | -				   UART_FCR7_64BYTE); -			status1 = serial_in(up, UART_IIR) >> 5; -			serial_out(up, UART_FCR, 0); -			serial_out(up, UART_LCR, 0); - -			if (status1 == 7) -				up->port.type = PORT_16550A_FSL64; -			else -				DEBUG_AUTOCONF("Motorola 8xxx DUART "); -		} -		serial_out(up, UART_EFR, 0); -		return; -	} - -	/* -	 * Maybe it requires 0xbf to be written to the LCR. -	 * (other ST16C650V2 UARTs, TI16C752A, etc) -	 */ -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); -	if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { -		DEBUG_AUTOCONF("EFRv2 "); -		autoconfig_has_efr(up); -		return; -	} - -	/* -	 * Check for a National Semiconductor SuperIO chip. -	 * Attempt to switch to bank 2, read the value of the LOOP bit -	 * from EXCR1. Switch back to bank 0, change it in MCR. Then -	 * switch back to bank 2, read it from EXCR1 again and check -	 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 -	 */ -	serial_out(up, UART_LCR, 0); -	status1 = serial_in(up, UART_MCR); -	serial_out(up, UART_LCR, 0xE0); -	status2 = serial_in(up, 0x02); /* EXCR1 */ - -	if (!((status2 ^ status1) & UART_MCR_LOOP)) { -		serial_out(up, UART_LCR, 0); -		serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); -		serial_out(up, UART_LCR, 0xE0); -		status2 = serial_in(up, 0x02); /* EXCR1 */ -		serial_out(up, UART_LCR, 0); -		serial_out(up, UART_MCR, status1); - -		if ((status2 ^ status1) & UART_MCR_LOOP) { -			unsigned short quot; - -			serial_out(up, UART_LCR, 0xE0); - -			quot = serial_dl_read(up); -			quot <<= 3; - -			if (ns16550a_goto_highspeed(up)) -				serial_dl_write(up, quot); - -			serial_out(up, UART_LCR, 0); - -			up->port.uartclk = 921600*16; -			up->port.type = PORT_NS16550A; -			up->capabilities |= UART_NATSEMI; -			return; -		} -	} - -	/* -	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of -	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set. -	 * Try setting it with and without DLAB set.  Cheap clones -	 * set bit 5 without DLAB set. -	 */ -	serial_out(up, UART_LCR, 0); -	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); -	status1 = serial_in(up, UART_IIR) >> 5; -	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); -	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); -	status2 = serial_in(up, UART_IIR) >> 5; -	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); -	serial_out(up, UART_LCR, 0); - -	DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); - -	if (status1 == 6 && status2 == 7) { -		up->port.type = PORT_16750; -		up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; -		return; -	} - -	/* -	 * Try writing and reading the UART_IER_UUE bit (b6). -	 * If it works, this is probably one of the Xscale platform's -	 * internal UARTs. -	 * We're going to explicitly set the UUE bit to 0 before -	 * trying to write and read a 1 just to make sure it's not -	 * already a 1 and maybe locked there before we even start start. -	 */ -	iersave = serial_in(up, UART_IER); -	serial_out(up, UART_IER, iersave & ~UART_IER_UUE); -	if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { -		/* -		 * OK it's in a known zero state, try writing and reading -		 * without disturbing the current state of the other bits. -		 */ -		serial_out(up, UART_IER, iersave | UART_IER_UUE); -		if (serial_in(up, UART_IER) & UART_IER_UUE) { -			/* -			 * It's an Xscale. -			 * We'll leave the UART_IER_UUE bit set to 1 (enabled). -			 */ -			DEBUG_AUTOCONF("Xscale "); -			up->port.type = PORT_XSCALE; -			up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; -			return; -		} -	} else { -		/* -		 * If we got here we couldn't force the IER_UUE bit to 0. -		 * Log it and continue. -		 */ -		DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); -	} -	serial_out(up, UART_IER, iersave); - -	/* -	 * Exar uarts have EFR in a weird location -	 */ -	if (up->port.flags & UPF_EXAR_EFR) { -		DEBUG_AUTOCONF("Exar XR17D15x "); -		up->port.type = PORT_XR17D15X; -		up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | -				    UART_CAP_SLEEP; - -		return; -	} - -	/* -	 * We distinguish between 16550A and U6 16550A by counting -	 * how many bytes are in the FIFO. -	 */ -	if (up->port.type == PORT_16550A && size_fifo(up) == 64) { -		up->port.type = PORT_U6_16550A; -		up->capabilities |= UART_CAP_AFE; -	} -} - -/* - * This routine is called by rs_init() to initialize a specific serial - * port.  It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A.  The important question is - * 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 char status1, scratch, scratch2, scratch3; -	unsigned char save_lcr, save_mcr; -	struct uart_port *port = &up->port; -	unsigned long flags; -	unsigned int old_capabilities; - -	if (!port->iobase && !port->mapbase && !port->membase) -		return; - -	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", -		       serial_index(port), port->iobase, port->membase); - -	/* -	 * We really do need global IRQs disabled here - we're going to -	 * be frobbing the chips IRQ enable register to see if it exists. -	 */ -	spin_lock_irqsave(&port->lock, flags); - -	up->capabilities = 0; -	up->bugs = 0; - -	if (!(port->flags & UPF_BUGGY_UART)) { -		/* -		 * Do a simple existence test first; if we fail this, -		 * there's no point trying anything else. -		 * -		 * 0x80 is used as a nonsense port to prevent against -		 * false positives due to ISA bus float.  The -		 * assumption is that 0x80 is a non-existent port; -		 * which should be safe since include/asm/io.h also -		 * makes this assumption. -		 * -		 * Note: this is safe as long as MCR bit 4 is clear -		 * and the device is in "PC" mode. -		 */ -		scratch = serial_in(up, UART_IER); -		serial_out(up, UART_IER, 0); -#ifdef __i386__ -		outb(0xff, 0x080); -#endif -		/* -		 * Mask out IER[7:4] bits for test as some UARTs (e.g. TL -		 * 16C754B) allow only to modify them if an EFR bit is set. -		 */ -		scratch2 = serial_in(up, UART_IER) & 0x0f; -		serial_out(up, UART_IER, 0x0F); -#ifdef __i386__ -		outb(0, 0x080); -#endif -		scratch3 = serial_in(up, UART_IER) & 0x0f; -		serial_out(up, UART_IER, scratch); -		if (scratch2 != 0 || scratch3 != 0x0F) { -			/* -			 * We failed; there's nothing here -			 */ -			spin_unlock_irqrestore(&port->lock, flags); -			DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", -				       scratch2, scratch3); -			goto out; -		} -	} - -	save_mcr = serial_in(up, UART_MCR); -	save_lcr = serial_in(up, UART_LCR); - -	/* -	 * Check to see if a UART is really there.  Certain broken -	 * internal modems based on the Rockwell chipset fail this -	 * test, because they apparently don't implement the loopback -	 * test mode.  So this test is skipped on the COM 1 through -	 * COM 4 ports.  This *should* be safe, since no board -	 * manufacturer would be stupid enough to design a board -	 * that conflicts with COM 1-4 --- we hope! -	 */ -	if (!(port->flags & UPF_SKIP_TEST)) { -		serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); -		status1 = serial_in(up, UART_MSR) & 0xF0; -		serial_out(up, UART_MCR, save_mcr); -		if (status1 != 0x90) { -			spin_unlock_irqrestore(&port->lock, flags); -			DEBUG_AUTOCONF("LOOP test failed (%02x) ", -				       status1); -			goto out; -		} -	} - -	/* -	 * We're pretty sure there's a port here.  Lets find out what -	 * type of port it is.  The IIR top two bits allows us to find -	 * out if it's 8250 or 16450, 16550, 16550A or later.  This -	 * determines what we test for next. -	 * -	 * We also initialise the EFR (if any) to zero for later.  The -	 * EFR occupies the same register location as the FCR and IIR. -	 */ -	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); -	serial_out(up, UART_EFR, 0); -	serial_out(up, UART_LCR, 0); - -	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); -	scratch = serial_in(up, UART_IIR) >> 6; - -	switch (scratch) { -	case 0: -		autoconfig_8250(up); -		break; -	case 1: -		port->type = PORT_UNKNOWN; -		break; -	case 2: -		port->type = PORT_16550; -		break; -	case 3: -		autoconfig_16550a(up); -		break; -	} - -#ifdef CONFIG_SERIAL_8250_RSA -	/* -	 * Only probe for RSA ports if we got the region. -	 */ -	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; -	up->capabilities = uart_config[port->type].flags; -	up->tx_loadsz = uart_config[port->type].tx_loadsz; - -	if (port->type == PORT_UNKNOWN) -		goto out_lock; - -	/* -	 * Reset the UART. -	 */ -#ifdef CONFIG_SERIAL_8250_RSA -	if (port->type == PORT_RSA) -		serial_out(up, UART_RSA_FRR, 0); -#endif -	serial_out(up, UART_MCR, save_mcr); -	serial8250_clear_fifos(up); -	serial_in(up, UART_RX); -	if (up->capabilities & UART_CAP_UUE) -		serial_out(up, UART_IER, UART_IER_UUE); -	else -		serial_out(up, UART_IER, 0); - -out_lock: -	spin_unlock_irqrestore(&port->lock, flags); -	if (up->capabilities != old_capabilities) { -		printk(KERN_WARNING -		       "ttyS%d: detected caps %08x should be %08x\n", -		       serial_index(port), old_capabilities, -		       up->capabilities); -	} -out: -	DEBUG_AUTOCONF("iir=%d ", scratch); -	DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); -} - -static void autoconfig_irq(struct uart_8250_port *up) -{ -	struct uart_port *port = &up->port; -	unsigned char save_mcr, save_ier; -	unsigned char save_ICP = 0; -	unsigned int ICP = 0; -	unsigned long irqs; -	int irq; - -	if (port->flags & UPF_FOURPORT) { -		ICP = (port->iobase & 0xfe0) | 0x1f; -		save_ICP = inb_p(ICP); -		outb_p(0x80, ICP); -		inb_p(ICP); -	} - -	/* forget possible initially masked and pending IRQ */ -	probe_irq_off(probe_irq_on()); -	save_mcr = serial_in(up, UART_MCR); -	save_ier = serial_in(up, UART_IER); -	serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); - -	irqs = probe_irq_on(); -	serial_out(up, UART_MCR, 0); -	udelay(10); -	if (port->flags & UPF_FOURPORT) { -		serial_out(up, UART_MCR, -			    UART_MCR_DTR | UART_MCR_RTS); -	} else { -		serial_out(up, UART_MCR, -			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); -	} -	serial_out(up, UART_IER, 0x0f);	/* enable all intrs */ -	serial_in(up, UART_LSR); -	serial_in(up, UART_RX); -	serial_in(up, UART_IIR); -	serial_in(up, UART_MSR); -	serial_out(up, UART_TX, 0xFF); -	udelay(20); -	irq = probe_irq_off(irqs); - -	serial_out(up, UART_MCR, save_mcr); -	serial_out(up, UART_IER, save_ier); - -	if (port->flags & UPF_FOURPORT) -		outb_p(save_ICP, ICP); - -	port->irq = (irq > 0) ? irq : 0; -} - -static inline void __stop_tx(struct uart_8250_port *p) -{ -	if (p->ier & UART_IER_THRI) { -		p->ier &= ~UART_IER_THRI; -		serial_out(p, UART_IER, p->ier); -		serial8250_rpm_put_tx(p); -	} -} - -static void serial8250_stop_tx(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	serial8250_rpm_get(up); -	__stop_tx(up); - -	/* -	 * We really want to stop the transmitter from sending. -	 */ -	if (port->type == PORT_16C950) { -		up->acr |= UART_ACR_TXDIS; -		serial_icr_write(up, UART_ACR, up->acr); -	} -	serial8250_rpm_put(up); -} - -static void serial8250_start_tx(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	serial8250_rpm_get_tx(up); - -	if (up->dma && !up->dma->tx_dma(up)) -		return; - -	if (!(up->ier & UART_IER_THRI)) { -		up->ier |= UART_IER_THRI; -		serial_port_out(port, UART_IER, up->ier); - -		if (up->bugs & UART_BUG_TXEN) { -			unsigned char lsr; -			lsr = serial_in(up, UART_LSR); -			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; -			if (lsr & UART_LSR_THRE) -				serial8250_tx_chars(up); -		} -	} - -	/* -	 * Re-enable the transmitter if we disabled it. -	 */ -	if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { -		up->acr &= ~UART_ACR_TXDIS; -		serial_icr_write(up, UART_ACR, up->acr); -	} -} - -static void serial8250_throttle(struct uart_port *port) -{ -	port->throttle(port); -} - -static void serial8250_unthrottle(struct uart_port *port) -{ -	port->unthrottle(port); -} - -static void serial8250_stop_rx(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	serial8250_rpm_get(up); - -	up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); -	up->port.read_status_mask &= ~UART_LSR_DR; -	serial_port_out(port, UART_IER, up->ier); - -	serial8250_rpm_put(up); -} - -static void serial8250_disable_ms(struct uart_port *port) -{ -	struct uart_8250_port *up = -		container_of(port, struct uart_8250_port, port); - -	/* no MSR capabilities */ -	if (up->bugs & UART_BUG_NOMSR) -		return; - -	up->ier &= ~UART_IER_MSI; -	serial_port_out(port, UART_IER, up->ier); -} - -static void serial8250_enable_ms(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	/* no MSR capabilities */ -	if (up->bugs & UART_BUG_NOMSR) -		return; - -	up->ier |= UART_IER_MSI; - -	serial8250_rpm_get(up); -	serial_port_out(port, UART_IER, up->ier); -	serial8250_rpm_put(up); -} - -/* - * serial8250_rx_chars: processes according to the passed in LSR - * value, and returns the remaining LSR bits not handled - * by this Rx routine. - */ -unsigned char -serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) -{ -	struct uart_port *port = &up->port; -	unsigned char ch; -	int max_count = 256; -	char flag; - -	do { -		if (likely(lsr & UART_LSR_DR)) -			ch = serial_in(up, UART_RX); -		else -			/* -			 * Intel 82571 has a Serial Over Lan device that will -			 * set UART_LSR_BI without setting UART_LSR_DR when -			 * it receives a break. To avoid reading from the -			 * receive buffer without UART_LSR_DR bit set, we -			 * just force the read character to be 0 -			 */ -			ch = 0; - -		flag = TTY_NORMAL; -		port->icount.rx++; - -		lsr |= up->lsr_saved_flags; -		up->lsr_saved_flags = 0; - -		if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { -			if (lsr & UART_LSR_BI) { -				lsr &= ~(UART_LSR_FE | UART_LSR_PE); -				port->icount.brk++; -				/* -				 * We do the SysRQ and SAK checking -				 * here because otherwise the break -				 * may get masked by ignore_status_mask -				 * or read_status_mask. -				 */ -				if (uart_handle_break(port)) -					goto ignore_char; -			} else if (lsr & UART_LSR_PE) -				port->icount.parity++; -			else if (lsr & UART_LSR_FE) -				port->icount.frame++; -			if (lsr & UART_LSR_OE) -				port->icount.overrun++; - -			/* -			 * Mask off conditions which should be ignored. -			 */ -			lsr &= port->read_status_mask; - -			if (lsr & UART_LSR_BI) { -				DEBUG_INTR("handling break...."); -				flag = TTY_BREAK; -			} else if (lsr & UART_LSR_PE) -				flag = TTY_PARITY; -			else if (lsr & UART_LSR_FE) -				flag = TTY_FRAME; -		} -		if (uart_handle_sysrq_char(port, ch)) -			goto ignore_char; - -		uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); - -ignore_char: -		lsr = serial_in(up, UART_LSR); -	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); -	spin_unlock(&port->lock); -	tty_flip_buffer_push(&port->state->port); -	spin_lock(&port->lock); -	return lsr; -} -EXPORT_SYMBOL_GPL(serial8250_rx_chars); - -void serial8250_tx_chars(struct uart_8250_port *up) -{ -	struct uart_port *port = &up->port; -	struct circ_buf *xmit = &port->state->xmit; -	int count; - -	if (port->x_char) { -		serial_out(up, UART_TX, port->x_char); -		port->icount.tx++; -		port->x_char = 0; -		return; -	} -	if (uart_tx_stopped(port)) { -		serial8250_stop_tx(port); -		return; -	} -	if (uart_circ_empty(xmit)) { -		__stop_tx(up); -		return; -	} - -	count = up->tx_loadsz; -	do { -		serial_out(up, UART_TX, xmit->buf[xmit->tail]); -		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -		port->icount.tx++; -		if (uart_circ_empty(xmit)) -			break; -		if (up->capabilities & UART_CAP_HFIFO) { -			if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) != -			    BOTH_EMPTY) -				break; -		} -	} while (--count > 0); - -	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -		uart_write_wakeup(port); - -	DEBUG_INTR("THRE..."); - -	/* -	 * With RPM enabled, we have to wait until the FIFO is empty before the -	 * HW can go idle. So we get here once again with empty FIFO and disable -	 * the interrupt and RPM in __stop_tx() -	 */ -	if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM)) -		__stop_tx(up); -} -EXPORT_SYMBOL_GPL(serial8250_tx_chars); - -/* Caller holds uart port lock */ -unsigned int serial8250_modem_status(struct uart_8250_port *up) -{ -	struct uart_port *port = &up->port; -	unsigned int status = serial_in(up, UART_MSR); - -	status |= up->msr_saved_flags; -	up->msr_saved_flags = 0; -	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && -	    port->state != NULL) { -		if (status & UART_MSR_TERI) -			port->icount.rng++; -		if (status & UART_MSR_DDSR) -			port->icount.dsr++; -		if (status & UART_MSR_DDCD) -			uart_handle_dcd_change(port, status & UART_MSR_DCD); -		if (status & UART_MSR_DCTS) -			uart_handle_cts_change(port, status & UART_MSR_CTS); - -		wake_up_interruptible(&port->state->port.delta_msr_wait); -	} - -	return status; -} -EXPORT_SYMBOL_GPL(serial8250_modem_status); - -/* - * This handles the interrupt from one port. - */ -int serial8250_handle_irq(struct uart_port *port, unsigned int iir) -{ -	unsigned char status; -	unsigned long flags; -	struct uart_8250_port *up = up_to_u8250p(port); -	int dma_err = 0; - -	if (iir & UART_IIR_NO_INT) -		return 0; - -	spin_lock_irqsave(&port->lock, flags); - -	status = serial_port_in(port, UART_LSR); - -	DEBUG_INTR("status = %x...", status); - -	if (status & (UART_LSR_DR | UART_LSR_BI)) { -		if (up->dma) -			dma_err = up->dma->rx_dma(up, iir); - -		if (!up->dma || dma_err) -			status = serial8250_rx_chars(up, status); -	} -	serial8250_modem_status(up); -	if ((!up->dma || (up->dma && up->dma->tx_err)) && -	    (status & UART_LSR_THRE)) -		serial8250_tx_chars(up); - -	spin_unlock_irqrestore(&port->lock, flags); -	return 1; -} -EXPORT_SYMBOL_GPL(serial8250_handle_irq); - -static int serial8250_default_handle_irq(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned int iir; -	int ret; - -	serial8250_rpm_get(up); - -	iir = serial_port_in(port, UART_IIR); -	ret = serial8250_handle_irq(port, iir); - -	serial8250_rpm_put(up); -	return ret; -} - -/* - * These Exar UARTs have an extra interrupt indicator that could - * fire for a few unimplemented interrupts.  One of which is a - * wakeup event when coming out of sleep.  Put this here just - * to be on the safe side that these interrupts don't go unhandled. - */ -static int exar_handle_irq(struct uart_port *port) -{ -	unsigned char int0, int1, int2, int3; -	unsigned int iir = serial_port_in(port, UART_IIR); -	int ret; - -	ret = serial8250_handle_irq(port, iir); - -	if ((port->type == PORT_XR17V35X) || -	   (port->type == PORT_XR17D15X)) { -		int0 = serial_port_in(port, 0x80); -		int1 = serial_port_in(port, 0x81); -		int2 = serial_port_in(port, 0x82); -		int3 = serial_port_in(port, 0x83); -	} - -	return ret; -} - -/*   * This is the serial driver's interrupt routine.   *   * Arjan thinks the old way was overly complex, so it got simplified. @@ -1941,876 +359,6 @@ static void univ8250_release_irq(struct uart_8250_port *up)  		serial_unlink_irq_chain(up);  } -static unsigned int serial8250_tx_empty(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned long flags; -	unsigned int lsr; - -	serial8250_rpm_get(up); - -	spin_lock_irqsave(&port->lock, flags); -	lsr = serial_port_in(port, UART_LSR); -	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; -	spin_unlock_irqrestore(&port->lock, flags); - -	serial8250_rpm_put(up); - -	return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; -} - -static unsigned int serial8250_get_mctrl(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned int status; -	unsigned int ret; - -	serial8250_rpm_get(up); -	status = serial8250_modem_status(up); -	serial8250_rpm_put(up); - -	ret = 0; -	if (status & UART_MSR_DCD) -		ret |= TIOCM_CAR; -	if (status & UART_MSR_RI) -		ret |= TIOCM_RNG; -	if (status & UART_MSR_DSR) -		ret |= TIOCM_DSR; -	if (status & UART_MSR_CTS) -		ret |= TIOCM_CTS; -	return ret; -} - -void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned char mcr = 0; - -	if (mctrl & TIOCM_RTS) -		mcr |= UART_MCR_RTS; -	if (mctrl & TIOCM_DTR) -		mcr |= UART_MCR_DTR; -	if (mctrl & TIOCM_OUT1) -		mcr |= UART_MCR_OUT1; -	if (mctrl & TIOCM_OUT2) -		mcr |= UART_MCR_OUT2; -	if (mctrl & TIOCM_LOOP) -		mcr |= UART_MCR_LOOP; - -	mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; - -	serial_port_out(port, UART_MCR, mcr); -} -EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); - -static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -	if (port->set_mctrl) -		port->set_mctrl(port, mctrl); -	else -		serial8250_do_set_mctrl(port, mctrl); -} - -static void serial8250_break_ctl(struct uart_port *port, int break_state) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned long flags; - -	serial8250_rpm_get(up); -	spin_lock_irqsave(&port->lock, flags); -	if (break_state == -1) -		up->lcr |= UART_LCR_SBC; -	else -		up->lcr &= ~UART_LCR_SBC; -	serial_port_out(port, UART_LCR, up->lcr); -	spin_unlock_irqrestore(&port->lock, flags); -	serial8250_rpm_put(up); -} - -/* - *	Wait for transmitter & holding register to empty - */ -static void wait_for_xmitr(struct uart_8250_port *up, int bits) -{ -	unsigned int status, tmout = 10000; - -	/* Wait up to 10ms for the character(s) to be sent. */ -	for (;;) { -		status = serial_in(up, UART_LSR); - -		up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; - -		if ((status & bits) == bits) -			break; -		if (--tmout == 0) -			break; -		udelay(1); -	} - -	/* Wait up to 1s for flow control if necessary */ -	if (up->port.flags & UPF_CONS_FLOW) { -		unsigned int tmout; -		for (tmout = 1000000; tmout; tmout--) { -			unsigned int msr = serial_in(up, UART_MSR); -			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; -			if (msr & UART_MSR_CTS) -				break; -			udelay(1); -			touch_nmi_watchdog(); -		} -	} -} - -#ifdef CONFIG_CONSOLE_POLL -/* - * Console polling routines for writing and reading from the uart while - * in an interrupt or debug context. - */ - -static int serial8250_get_poll_char(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned char lsr; -	int status; - -	serial8250_rpm_get(up); - -	lsr = serial_port_in(port, UART_LSR); - -	if (!(lsr & UART_LSR_DR)) { -		status = NO_POLL_CHAR; -		goto out; -	} - -	status = serial_port_in(port, UART_RX); -out: -	serial8250_rpm_put(up); -	return status; -} - - -static void serial8250_put_poll_char(struct uart_port *port, -			 unsigned char c) -{ -	unsigned int ier; -	struct uart_8250_port *up = up_to_u8250p(port); - -	serial8250_rpm_get(up); -	/* -	 *	First save the IER then disable the interrupts -	 */ -	ier = serial_port_in(port, UART_IER); -	if (up->capabilities & UART_CAP_UUE) -		serial_port_out(port, UART_IER, UART_IER_UUE); -	else -		serial_port_out(port, UART_IER, 0); - -	wait_for_xmitr(up, BOTH_EMPTY); -	/* -	 *	Send the character out. -	 */ -	serial_port_out(port, UART_TX, c); - -	/* -	 *	Finally, wait for transmitter to become empty -	 *	and restore the IER -	 */ -	wait_for_xmitr(up, BOTH_EMPTY); -	serial_port_out(port, UART_IER, ier); -	serial8250_rpm_put(up); -} - -#endif /* CONFIG_CONSOLE_POLL */ - -int serial8250_do_startup(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned long flags; -	unsigned char lsr, iir; -	int retval; - -	if (port->type == PORT_8250_CIR) -		return -ENODEV; - -	if (!port->fifosize) -		port->fifosize = uart_config[port->type].fifo_size; -	if (!up->tx_loadsz) -		up->tx_loadsz = uart_config[port->type].tx_loadsz; -	if (!up->capabilities) -		up->capabilities = uart_config[port->type].flags; -	up->mcr = 0; - -	if (port->iotype != up->cur_iotype) -		set_io_from_upio(port); - -	serial8250_rpm_get(up); -	if (port->type == PORT_16C950) { -		/* Wake up and initialize UART */ -		up->acr = 0; -		serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); -		serial_port_out(port, UART_EFR, UART_EFR_ECB); -		serial_port_out(port, UART_IER, 0); -		serial_port_out(port, UART_LCR, 0); -		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ -		serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); -		serial_port_out(port, UART_EFR, UART_EFR_ECB); -		serial_port_out(port, UART_LCR, 0); -	} - -#ifdef CONFIG_SERIAL_8250_RSA -	/* -	 * If this is an RSA port, see if we can kick it up to the -	 * higher speed clock. -	 */ -	enable_rsa(up); -#endif -	/* -	 * Clear the FIFO buffers and disable them. -	 * (they will be reenabled in set_termios()) -	 */ -	serial8250_clear_fifos(up); - -	/* -	 * Clear the interrupt registers. -	 */ -	serial_port_in(port, UART_LSR); -	serial_port_in(port, UART_RX); -	serial_port_in(port, UART_IIR); -	serial_port_in(port, UART_MSR); - -	/* -	 * At this point, there's no way the LSR could still be 0xff; -	 * if it is, then bail out, because there's likely no UART -	 * here. -	 */ -	if (!(port->flags & UPF_BUGGY_UART) && -	    (serial_port_in(port, UART_LSR) == 0xff)) { -		printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", -				   serial_index(port)); -		retval = -ENODEV; -		goto out; -	} - -	/* -	 * For a XR16C850, we need to set the trigger levels -	 */ -	if (port->type == PORT_16850) { -		unsigned char fctr; - -		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - -		fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); -		serial_port_out(port, UART_FCTR, -				fctr | UART_FCTR_TRGD | UART_FCTR_RX); -		serial_port_out(port, UART_TRG, UART_TRG_96); -		serial_port_out(port, UART_FCTR, -				fctr | UART_FCTR_TRGD | UART_FCTR_TX); -		serial_port_out(port, UART_TRG, UART_TRG_96); - -		serial_port_out(port, UART_LCR, 0); -	} - -	if (port->irq) { -		unsigned char iir1; -		/* -		 * Test for UARTs that do not reassert THRE when the -		 * transmitter is idle and the interrupt has already -		 * been cleared.  Real 16550s should always reassert -		 * this interrupt whenever the transmitter is idle and -		 * the interrupt is enabled.  Delays are necessary to -		 * allow register changes to become visible. -		 */ -		spin_lock_irqsave(&port->lock, flags); -		if (up->port.irqflags & IRQF_SHARED) -			disable_irq_nosync(port->irq); - -		wait_for_xmitr(up, UART_LSR_THRE); -		serial_port_out_sync(port, UART_IER, UART_IER_THRI); -		udelay(1); /* allow THRE to set */ -		iir1 = serial_port_in(port, UART_IIR); -		serial_port_out(port, UART_IER, 0); -		serial_port_out_sync(port, UART_IER, UART_IER_THRI); -		udelay(1); /* allow a working UART time to re-assert THRE */ -		iir = serial_port_in(port, UART_IIR); -		serial_port_out(port, UART_IER, 0); - -		if (port->irqflags & IRQF_SHARED) -			enable_irq(port->irq); -		spin_unlock_irqrestore(&port->lock, flags); - -		/* -		 * If the interrupt is not reasserted, or we otherwise -		 * don't trust the iir, setup a timer to kick the UART -		 * on a regular basis. -		 */ -		if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || -		    up->port.flags & UPF_BUG_THRE) { -			up->bugs |= UART_BUG_THRE; -		} -	} - -	retval = up->ops->setup_irq(up); -	if (retval) -		goto out; - -	/* -	 * Now, initialize the UART -	 */ -	serial_port_out(port, UART_LCR, UART_LCR_WLEN8); - -	spin_lock_irqsave(&port->lock, flags); -	if (up->port.flags & UPF_FOURPORT) { -		if (!up->port.irq) -			up->port.mctrl |= TIOCM_OUT1; -	} else -		/* -		 * Most PC uarts need OUT2 raised to enable interrupts. -		 */ -		if (port->irq) -			up->port.mctrl |= TIOCM_OUT2; - -	serial8250_set_mctrl(port, port->mctrl); - -	/* Serial over Lan (SoL) hack: -	   Intel 8257x Gigabit ethernet chips have a -	   16550 emulation, to be used for Serial Over Lan. -	   Those chips take a longer time than a normal -	   serial device to signalize that a transmission -	   data was queued. Due to that, the above test generally -	   fails. One solution would be to delay the reading of -	   iir. However, this is not reliable, since the timeout -	   is variable. So, let's just don't test if we receive -	   TX irq. This way, we'll never enable UART_BUG_TXEN. -	 */ -	if (up->port.flags & UPF_NO_TXEN_TEST) -		goto dont_test_tx_en; - -	/* -	 * Do a quick test to see if we receive an -	 * interrupt when we enable the TX irq. -	 */ -	serial_port_out(port, UART_IER, UART_IER_THRI); -	lsr = serial_port_in(port, UART_LSR); -	iir = serial_port_in(port, UART_IIR); -	serial_port_out(port, UART_IER, 0); - -	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { -		if (!(up->bugs & UART_BUG_TXEN)) { -			up->bugs |= UART_BUG_TXEN; -			pr_debug("ttyS%d - enabling bad tx status workarounds\n", -				 serial_index(port)); -		} -	} else { -		up->bugs &= ~UART_BUG_TXEN; -	} - -dont_test_tx_en: -	spin_unlock_irqrestore(&port->lock, flags); - -	/* -	 * Clear the interrupt registers again for luck, and clear the -	 * saved flags to avoid getting false values from polling -	 * routines or the previous session. -	 */ -	serial_port_in(port, UART_LSR); -	serial_port_in(port, UART_RX); -	serial_port_in(port, UART_IIR); -	serial_port_in(port, UART_MSR); -	up->lsr_saved_flags = 0; -	up->msr_saved_flags = 0; - -	/* -	 * Request DMA channels for both RX and TX. -	 */ -	if (up->dma) { -		retval = serial8250_request_dma(up); -		if (retval) { -			pr_warn_ratelimited("ttyS%d - failed to request DMA\n", -					    serial_index(port)); -			up->dma = NULL; -		} -	} - -	/* -	 * Finally, enable interrupts.  Note: Modem status interrupts -	 * are set via set_termios(), which will be occurring imminently -	 * anyway, so we don't enable them here. -	 */ -	up->ier = UART_IER_RLSI | UART_IER_RDI; -	serial_port_out(port, UART_IER, up->ier); - -	if (port->flags & UPF_FOURPORT) { -		unsigned int icp; -		/* -		 * Enable interrupts on the AST Fourport board -		 */ -		icp = (port->iobase & 0xfe0) | 0x01f; -		outb_p(0x80, icp); -		inb_p(icp); -	} -	retval = 0; -out: -	serial8250_rpm_put(up); -	return retval; -} -EXPORT_SYMBOL_GPL(serial8250_do_startup); - -static int serial8250_startup(struct uart_port *port) -{ -	if (port->startup) -		return port->startup(port); -	return serial8250_do_startup(port); -} - -void serial8250_do_shutdown(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned long flags; - -	serial8250_rpm_get(up); -	/* -	 * Disable interrupts from this port -	 */ -	up->ier = 0; -	serial_port_out(port, UART_IER, 0); - -	if (up->dma) -		serial8250_release_dma(up); - -	spin_lock_irqsave(&port->lock, flags); -	if (port->flags & UPF_FOURPORT) { -		/* reset interrupts on the AST Fourport board */ -		inb((port->iobase & 0xfe0) | 0x1f); -		port->mctrl |= TIOCM_OUT1; -	} else -		port->mctrl &= ~TIOCM_OUT2; - -	serial8250_set_mctrl(port, port->mctrl); -	spin_unlock_irqrestore(&port->lock, flags); - -	/* -	 * Disable break condition and FIFOs -	 */ -	serial_port_out(port, UART_LCR, -			serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); -	serial8250_clear_fifos(up); - -#ifdef CONFIG_SERIAL_8250_RSA -	/* -	 * Reset the RSA board back to 115kbps compat mode. -	 */ -	disable_rsa(up); -#endif - -	/* -	 * Read data port to reset things, and then unlink from -	 * the IRQ chain. -	 */ -	serial_port_in(port, UART_RX); -	serial8250_rpm_put(up); - -	up->ops->release_irq(up); -} -EXPORT_SYMBOL_GPL(serial8250_do_shutdown); - -static void serial8250_shutdown(struct uart_port *port) -{ -	if (port->shutdown) -		port->shutdown(port); -	else -		serial8250_do_shutdown(port); -} - -/* - * XR17V35x UARTs have an extra fractional divisor register (DLD) - * Calculate divisor with extra 4-bit fractional portion - */ -static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up, -					 unsigned int baud, -					 unsigned int *frac) -{ -	struct uart_port *port = &up->port; -	unsigned int quot_16; - -	quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud); -	*frac = quot_16 & 0x0f; - -	return quot_16 >> 4; -} - -static unsigned int serial8250_get_divisor(struct uart_8250_port *up, -					   unsigned int baud, -					   unsigned int *frac) -{ -	struct uart_port *port = &up->port; -	unsigned int quot; - -	/* -	 * Handle magic divisors for baud rates above baud_base on -	 * SMSC SuperIO chips. -	 * -	 */ -	if ((port->flags & UPF_MAGIC_MULTIPLIER) && -	    baud == (port->uartclk/4)) -		quot = 0x8001; -	else if ((port->flags & UPF_MAGIC_MULTIPLIER) && -		 baud == (port->uartclk/8)) -		quot = 0x8002; -	else if (up->port.type == PORT_XR17V35X) -		quot = xr17v35x_get_divisor(up, baud, frac); -	else -		quot = uart_get_divisor(port, baud); - -	/* -	 * Oxford Semi 952 rev B workaround -	 */ -	if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) -		quot++; - -	return quot; -} - -static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, -					    tcflag_t c_cflag) -{ -	unsigned char cval; - -	switch (c_cflag & CSIZE) { -	case CS5: -		cval = UART_LCR_WLEN5; -		break; -	case CS6: -		cval = UART_LCR_WLEN6; -		break; -	case CS7: -		cval = UART_LCR_WLEN7; -		break; -	default: -	case CS8: -		cval = UART_LCR_WLEN8; -		break; -	} - -	if (c_cflag & CSTOPB) -		cval |= UART_LCR_STOP; -	if (c_cflag & PARENB) { -		cval |= UART_LCR_PARITY; -		if (up->bugs & UART_BUG_PARITY) -			up->fifo_bug = true; -	} -	if (!(c_cflag & PARODD)) -		cval |= UART_LCR_EPAR; -#ifdef CMSPAR -	if (c_cflag & CMSPAR) -		cval |= UART_LCR_SPAR; -#endif - -	return cval; -} - -static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, -			    unsigned int quot, unsigned int quot_frac) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	/* Workaround to enable 115200 baud on OMAP1510 internal ports */ -	if (is_omap1510_8250(up)) { -		if (baud == 115200) { -			quot = 1; -			serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); -		} else -			serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); -	} - -	/* -	 * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, -	 * otherwise just set DLAB -	 */ -	if (up->capabilities & UART_NATSEMI) -		serial_port_out(port, UART_LCR, 0xe0); -	else -		serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); - -	serial_dl_write(up, quot); - -	/* XR17V35x UARTs have an extra fractional divisor register (DLD) */ -	if (up->port.type == PORT_XR17V35X) -		serial_port_out(port, 0x2, quot_frac); -} - -void -serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, -		          struct ktermios *old) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	unsigned char cval; -	unsigned long flags; -	unsigned int baud, quot, frac = 0; - -	cval = serial8250_compute_lcr(up, termios->c_cflag); - -	/* -	 * Ask the core to calculate the divisor for us. -	 */ -	baud = uart_get_baud_rate(port, termios, old, -				  port->uartclk / 16 / 0xffff, -				  port->uartclk / 16); -	quot = serial8250_get_divisor(up, baud, &frac); - -	/* -	 * Ok, we're now changing the port state.  Do it with -	 * interrupts disabled. -	 */ -	serial8250_rpm_get(up); -	spin_lock_irqsave(&port->lock, flags); - -	up->lcr = cval;					/* Save computed LCR */ - -	if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { -		/* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ -		if ((baud < 2400 && !up->dma) || up->fifo_bug) { -			up->fcr &= ~UART_FCR_TRIGGER_MASK; -			up->fcr |= UART_FCR_TRIGGER_1; -		} -	} - -	/* -	 * MCR-based auto flow control.  When AFE is enabled, RTS will be -	 * deasserted when the receive FIFO contains more characters than -	 * the trigger, or the MCR RTS bit is cleared.  In the case where -	 * the remote UART is not using CTS auto flow control, we must -	 * have sufficient FIFO entries for the latency of the remote -	 * UART to respond.  IOW, at least 32 bytes of FIFO. -	 */ -	if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { -		up->mcr &= ~UART_MCR_AFE; -		if (termios->c_cflag & CRTSCTS) -			up->mcr |= UART_MCR_AFE; -	} - -	/* -	 * Update the per-port timeout. -	 */ -	uart_update_timeout(port, termios->c_cflag, baud); - -	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; -	if (termios->c_iflag & INPCK) -		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; -	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) -		port->read_status_mask |= UART_LSR_BI; - -	/* -	 * Characteres to ignore -	 */ -	port->ignore_status_mask = 0; -	if (termios->c_iflag & IGNPAR) -		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; -	if (termios->c_iflag & IGNBRK) { -		port->ignore_status_mask |= UART_LSR_BI; -		/* -		 * If we're ignoring parity and break indicators, -		 * ignore overruns too (for real raw support). -		 */ -		if (termios->c_iflag & IGNPAR) -			port->ignore_status_mask |= UART_LSR_OE; -	} - -	/* -	 * ignore all characters if CREAD is not set -	 */ -	if ((termios->c_cflag & CREAD) == 0) -		port->ignore_status_mask |= UART_LSR_DR; - -	/* -	 * CTS flow control flag and modem status interrupts -	 */ -	up->ier &= ~UART_IER_MSI; -	if (!(up->bugs & UART_BUG_NOMSR) && -			UART_ENABLE_MS(&up->port, termios->c_cflag)) -		up->ier |= UART_IER_MSI; -	if (up->capabilities & UART_CAP_UUE) -		up->ier |= UART_IER_UUE; -	if (up->capabilities & UART_CAP_RTOIE) -		up->ier |= UART_IER_RTOIE; - -	serial_port_out(port, UART_IER, up->ier); - -	if (up->capabilities & UART_CAP_EFR) { -		unsigned char efr = 0; -		/* -		 * TI16C752/Startech hardware flow control.  FIXME: -		 * - TI16C752 requires control thresholds to be set. -		 * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. -		 */ -		if (termios->c_cflag & CRTSCTS) -			efr |= UART_EFR_CTS; - -		serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); -		if (port->flags & UPF_EXAR_EFR) -			serial_port_out(port, UART_XR_EFR, efr); -		else -			serial_port_out(port, UART_EFR, efr); -	} - -	serial8250_set_divisor(port, baud, quot, frac); - -	/* -	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR -	 * is written without DLAB set, this mode will be disabled. -	 */ -	if (port->type == PORT_16750) -		serial_port_out(port, UART_FCR, up->fcr); - -	serial_port_out(port, UART_LCR, up->lcr);	/* reset DLAB */ -	if (port->type != PORT_16750) { -		/* emulated UARTs (Lucent Venus 167x) need two steps */ -		if (up->fcr & UART_FCR_ENABLE_FIFO) -			serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); -		serial_port_out(port, UART_FCR, up->fcr);	/* set fcr */ -	} -	serial8250_set_mctrl(port, port->mctrl); -	spin_unlock_irqrestore(&port->lock, flags); -	serial8250_rpm_put(up); - -	/* Don't rewrite B0 */ -	if (tty_termios_baud_rate(termios)) -		tty_termios_encode_baud_rate(termios, baud, baud); -} -EXPORT_SYMBOL(serial8250_do_set_termios); - -static void -serial8250_set_termios(struct uart_port *port, struct ktermios *termios, -		       struct ktermios *old) -{ -	if (port->set_termios) -		port->set_termios(port, termios, old); -	else -		serial8250_do_set_termios(port, termios, old); -} - -static void -serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) -{ -	if (termios->c_line == N_PPS) { -		port->flags |= UPF_HARDPPS_CD; -		spin_lock_irq(&port->lock); -		serial8250_enable_ms(port); -		spin_unlock_irq(&port->lock); -	} else { -		port->flags &= ~UPF_HARDPPS_CD; -		if (!UART_ENABLE_MS(port, termios->c_cflag)) { -			spin_lock_irq(&port->lock); -			serial8250_disable_ms(port); -			spin_unlock_irq(&port->lock); -		} -	} -} - - -void serial8250_do_pm(struct uart_port *port, unsigned int state, -		      unsigned int oldstate) -{ -	struct uart_8250_port *p = up_to_u8250p(port); - -	serial8250_set_sleep(p, state != 0); -} -EXPORT_SYMBOL(serial8250_do_pm); - -static void -serial8250_pm(struct uart_port *port, unsigned int state, -	      unsigned int oldstate) -{ -	if (port->pm) -		port->pm(port, state, oldstate); -	else -		serial8250_do_pm(port, state, oldstate); -} - -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; -		return 0x1000; -	} -	if (is_omap1_8250(pt)) -		return 0x16 << pt->port.regshift; - -	return 8 << pt->port.regshift; -} - -/* - * Resource handling. - */ -static int serial8250_request_std_resource(struct uart_8250_port *up) -{ -	unsigned int size = serial8250_port_size(up); -	struct uart_port *port = &up->port; -	int ret = 0; - -	switch (port->iotype) { -	case UPIO_AU: -	case UPIO_TSI: -	case UPIO_MEM32: -	case UPIO_MEM32BE: -	case UPIO_MEM: -		if (!port->mapbase) -			break; - -		if (!request_mem_region(port->mapbase, size, "serial")) { -			ret = -EBUSY; -			break; -		} - -		if (port->flags & UPF_IOREMAP) { -			port->membase = ioremap_nocache(port->mapbase, size); -			if (!port->membase) { -				release_mem_region(port->mapbase, size); -				ret = -ENOMEM; -			} -		} -		break; - -	case UPIO_HUB6: -	case UPIO_PORT: -		if (!request_region(port->iobase, size, "serial")) -			ret = -EBUSY; -		break; -	} -	return ret; -} - -static void serial8250_release_std_resource(struct uart_8250_port *up) -{ -	unsigned int size = serial8250_port_size(up); -	struct uart_port *port = &up->port; - -	switch (port->iotype) { -	case UPIO_AU: -	case UPIO_TSI: -	case UPIO_MEM32: -	case UPIO_MEM32BE: -	case UPIO_MEM: -		if (!port->mapbase) -			break; - -		if (port->flags & UPF_IOREMAP) { -			iounmap(port->membase); -			port->membase = NULL; -		} - -		release_mem_region(port->mapbase, size); -		break; - -	case UPIO_HUB6: -	case UPIO_PORT: -		release_region(port->iobase, size); -		break; -	} -} -  #ifdef CONFIG_SERIAL_8250_RSA  static int serial8250_request_rsa_resource(struct uart_8250_port *up)  { @@ -2848,259 +396,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)  }  #endif -static void serial8250_release_port(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	serial8250_release_std_resource(up); -} - -static int serial8250_request_port(struct uart_port *port) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	int ret; - -	if (port->type == PORT_8250_CIR) -		return -ENODEV; - -	ret = serial8250_request_std_resource(up); - -	return ret; -} - -static int fcr_get_rxtrig_bytes(struct uart_8250_port *up) -{ -	const struct serial8250_config *conf_type = &uart_config[up->port.type]; -	unsigned char bytes; - -	bytes = conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)]; - -	return bytes ? bytes : -EOPNOTSUPP; -} - -static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes) -{ -	const struct serial8250_config *conf_type = &uart_config[up->port.type]; -	int i; - -	if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)]) -		return -EOPNOTSUPP; - -	for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) { -		if (bytes < conf_type->rxtrig_bytes[i]) -			/* Use the nearest lower value */ -			return (--i) << UART_FCR_R_TRIG_SHIFT; -	} - -	return UART_FCR_R_TRIG_11; -} - -static int do_get_rxtrig(struct tty_port *port) -{ -	struct uart_state *state = container_of(port, struct uart_state, port); -	struct uart_port *uport = state->uart_port; -	struct uart_8250_port *up = -		container_of(uport, struct uart_8250_port, port); - -	if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) -		return -EINVAL; - -	return fcr_get_rxtrig_bytes(up); -} - -static int do_serial8250_get_rxtrig(struct tty_port *port) -{ -	int rxtrig_bytes; - -	mutex_lock(&port->mutex); -	rxtrig_bytes = do_get_rxtrig(port); -	mutex_unlock(&port->mutex); - -	return rxtrig_bytes; -} - -static ssize_t serial8250_get_attr_rx_trig_bytes(struct device *dev, -	struct device_attribute *attr, char *buf) -{ -	struct tty_port *port = dev_get_drvdata(dev); -	int rxtrig_bytes; - -	rxtrig_bytes = do_serial8250_get_rxtrig(port); -	if (rxtrig_bytes < 0) -		return rxtrig_bytes; - -	return snprintf(buf, PAGE_SIZE, "%d\n", rxtrig_bytes); -} - -static int do_set_rxtrig(struct tty_port *port, unsigned char bytes) -{ -	struct uart_state *state = container_of(port, struct uart_state, port); -	struct uart_port *uport = state->uart_port; -	struct uart_8250_port *up = -		container_of(uport, struct uart_8250_port, port); -	int rxtrig; - -	if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || -	    up->fifo_bug) -		return -EINVAL; - -	rxtrig = bytes_to_fcr_rxtrig(up, bytes); -	if (rxtrig < 0) -		return rxtrig; - -	serial8250_clear_fifos(up); -	up->fcr &= ~UART_FCR_TRIGGER_MASK; -	up->fcr |= (unsigned char)rxtrig; -	serial_out(up, UART_FCR, up->fcr); -	return 0; -} - -static int do_serial8250_set_rxtrig(struct tty_port *port, unsigned char bytes) -{ -	int ret; - -	mutex_lock(&port->mutex); -	ret = do_set_rxtrig(port, bytes); -	mutex_unlock(&port->mutex); - -	return ret; -} - -static ssize_t serial8250_set_attr_rx_trig_bytes(struct device *dev, -	struct device_attribute *attr, const char *buf, size_t count) -{ -	struct tty_port *port = dev_get_drvdata(dev); -	unsigned char bytes; -	int ret; - -	if (!count) -		return -EINVAL; - -	ret = kstrtou8(buf, 10, &bytes); -	if (ret < 0) -		return ret; - -	ret = do_serial8250_set_rxtrig(port, bytes); -	if (ret < 0) -		return ret; - -	return count; -} - -static DEVICE_ATTR(rx_trig_bytes, S_IRUSR | S_IWUSR | S_IRGRP, -		   serial8250_get_attr_rx_trig_bytes, -		   serial8250_set_attr_rx_trig_bytes); - -static struct attribute *serial8250_dev_attrs[] = { -	&dev_attr_rx_trig_bytes.attr, -	NULL, -	}; - -static struct attribute_group serial8250_dev_attr_group = { -	.attrs = serial8250_dev_attrs, -	}; - -static void register_dev_spec_attr_grp(struct uart_8250_port *up) -{ -	const struct serial8250_config *conf_type = &uart_config[up->port.type]; - -	if (conf_type->rxtrig_bytes[0]) -		up->port.attr_group = &serial8250_dev_attr_group; -} - -static void serial8250_config_port(struct uart_port *port, int flags) -{ -	struct uart_8250_port *up = up_to_u8250p(port); -	int ret; - -	if (port->type == PORT_8250_CIR) -		return; - -	/* -	 * Find the region that we can probe for.  This in turn -	 * tells us whether we can probe for the type of port. -	 */ -	ret = serial8250_request_std_resource(up); -	if (ret < 0) -		return; - -	if (port->iotype != up->cur_iotype) -		set_io_from_upio(port); - -	if (flags & UART_CONFIG_TYPE) -		autoconfig(up); - -	/* if access method is AU, it is a 16550 with a quirk */ -	if (port->type == PORT_16550A && port->iotype == UPIO_AU) -		up->bugs |= UART_BUG_NOMSR; - -	/* HW bugs may trigger IRQ while IIR == NO_INT */ -	if (port->type == PORT_TEGRA) -		up->bugs |= UART_BUG_NOMSR; - -	if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) -		autoconfig_irq(up); - -	if (port->type == PORT_UNKNOWN) -		serial8250_release_std_resource(up); - -	/* Fixme: probably not the best place for this */ -	if ((port->type == PORT_XR17V35X) || -	   (port->type == PORT_XR17D15X)) -		port->handle_irq = exar_handle_irq; - -	register_dev_spec_attr_grp(up); -	up->fcr = uart_config[up->port.type].fcr; -} - -static int -serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) -{ -	if (ser->irq >= nr_irqs || ser->irq < 0 || -	    ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || -	    ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || -	    ser->type == PORT_STARTECH) -		return -EINVAL; -	return 0; -} - -static const char * -serial8250_type(struct uart_port *port) -{ -	int type = port->type; - -	if (type >= ARRAY_SIZE(uart_config)) -		type = 0; -	return uart_config[type].name; -} - -static const struct uart_ops serial8250_pops = { -	.tx_empty	= serial8250_tx_empty, -	.set_mctrl	= serial8250_set_mctrl, -	.get_mctrl	= serial8250_get_mctrl, -	.stop_tx	= serial8250_stop_tx, -	.start_tx	= serial8250_start_tx, -	.throttle	= serial8250_throttle, -	.unthrottle	= serial8250_unthrottle, -	.stop_rx	= serial8250_stop_rx, -	.enable_ms	= serial8250_enable_ms, -	.break_ctl	= serial8250_break_ctl, -	.startup	= serial8250_startup, -	.shutdown	= serial8250_shutdown, -	.set_termios	= serial8250_set_termios, -	.set_ldisc	= serial8250_set_ldisc, -	.pm		= serial8250_pm, -	.type		= serial8250_type, -	.release_port	= serial8250_release_port, -	.request_port	= serial8250_request_port, -	.config_port	= serial8250_config_port, -	.verify_port	= serial8250_verify_port, -#ifdef CONFIG_CONSOLE_POLL -	.poll_get_char = serial8250_get_poll_char, -	.poll_put_char = serial8250_put_poll_char, -#endif -}; -  static const struct uart_ops *base_ops;  static struct uart_ops univ8250_port_ops; @@ -3139,42 +434,6 @@ 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) @@ -3324,94 +583,6 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)  #ifdef CONFIG_SERIAL_8250_CONSOLE -static void serial8250_console_putchar(struct uart_port *port, int ch) -{ -	struct uart_8250_port *up = up_to_u8250p(port); - -	wait_for_xmitr(up, UART_LSR_THRE); -	serial_port_out(port, UART_TX, ch); -} - -/* - *	Print a string to the serial port trying not to disturb - *	any possible real use of the port... - * - *	The console_lock must be held when we get here. - */ -static void serial8250_console_write(struct uart_8250_port *up, const char *s, -				     unsigned int count) -{ -	struct uart_port *port = &up->port; -	unsigned long flags; -	unsigned int ier; -	int locked = 1; - -	touch_nmi_watchdog(); - -	serial8250_rpm_get(up); - -	if (port->sysrq) -		locked = 0; -	else if (oops_in_progress) -		locked = spin_trylock_irqsave(&port->lock, flags); -	else -		spin_lock_irqsave(&port->lock, flags); - -	/* -	 *	First save the IER then disable the interrupts -	 */ -	ier = serial_port_in(port, UART_IER); - -	if (up->capabilities & UART_CAP_UUE) -		serial_port_out(port, UART_IER, UART_IER_UUE); -	else -		serial_port_out(port, UART_IER, 0); - -	/* check scratch reg to see if port powered off during system sleep */ -	if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { -		struct ktermios termios; -		unsigned int baud, quot, frac = 0; - -		termios.c_cflag = port->cons->cflag; -		if (port->state->port.tty && termios.c_cflag == 0) -			termios.c_cflag = port->state->port.tty->termios.c_cflag; - -		baud = uart_get_baud_rate(port, &termios, NULL, -					  port->uartclk / 16 / 0xffff, -					  port->uartclk / 16); -		quot = serial8250_get_divisor(up, baud, &frac); - -		serial8250_set_divisor(port, baud, quot, frac); -		serial_port_out(port, UART_LCR, up->lcr); -		serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); - -		up->canary = 0; -	} - -	uart_console_write(port, s, count, serial8250_console_putchar); - -	/* -	 *	Finally, wait for transmitter to become empty -	 *	and restore the IER -	 */ -	wait_for_xmitr(up, BOTH_EMPTY); -	serial_port_out(port, UART_IER, ier); - -	/* -	 *	The receive handling will happen properly because the -	 *	receive ready bit will still be set; it is not cleared -	 *	on read.  However, modem control will not, we must -	 *	call it if we have saved something in the saved flags -	 *	while processing with interrupts off. -	 */ -	if (up->msr_saved_flags) -		serial8250_modem_status(up); - -	if (locked) -		spin_unlock_irqrestore(&port->lock, flags); -	serial8250_rpm_put(up); -} -  static void univ8250_console_write(struct console *co, const char *s,  				   unsigned int count)  { @@ -3420,39 +591,6 @@ static void univ8250_console_write(struct console *co, const char *s,  	serial8250_console_write(up, s, count);  } -static unsigned int probe_baud(struct uart_port *port) -{ -	unsigned char lcr, dll, dlm; -	unsigned int quot; - -	lcr = serial_port_in(port, UART_LCR); -	serial_port_out(port, UART_LCR, lcr | UART_LCR_DLAB); -	dll = serial_port_in(port, UART_DLL); -	dlm = serial_port_in(port, UART_DLM); -	serial_port_out(port, UART_LCR, lcr); - -	quot = (dlm << 8) | dll; -	return (port->uartclk / 16) / quot; -} - -static int serial8250_console_setup(struct uart_port *port, char *options, bool probe) -{ -	int baud = 9600; -	int bits = 8; -	int parity = 'n'; -	int flow = 'n'; - -	if (!port->iobase && !port->membase) -		return -ENODEV; - -	if (options) -		uart_parse_options(options, &baud, &parity, &bits, &flow); -	else if (probe) -		baud = probe_baud(port); - -	return uart_set_options(port, port->cons, baud, parity, bits, flow); -} -  static int univ8250_console_setup(struct console *co, char *options)  {  	struct uart_port *port; diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index d48b50641e9a..06324f17a0cb 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -56,7 +56,6 @@  struct dw8250_data {  	u8			usr_reg; -	int			last_mcr;  	int			line;  	int			msr_mask_on;  	int			msr_mask_off; @@ -76,12 +75,6 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)  {  	struct dw8250_data *d = p->private_data; -	/* If reading MSR, report CTS asserted when auto-CTS/RTS enabled */ -	if (offset == UART_MSR && d->last_mcr & UART_MCR_AFE) { -		value |= UART_MSR_CTS; -		value &= ~UART_MSR_DCTS; -	} -  	/* Override any modem control signals if needed */  	if (offset == UART_MSR) {  		value |= d->msr_mask_on; @@ -101,11 +94,6 @@ static void dw8250_force_idle(struct uart_port *p)  static void dw8250_serial_out(struct uart_port *p, int offset, int value)  { -	struct dw8250_data *d = p->private_data; - -	if (offset == UART_MCR) -		d->last_mcr = value; -  	writeb(value, p->membase + (offset << p->regshift));  	/* Make sure LCR write wasn't ignored */ @@ -144,11 +132,6 @@ static unsigned int dw8250_serial_inq(struct uart_port *p, int offset)  static void dw8250_serial_outq(struct uart_port *p, int offset, int value)  { -	struct dw8250_data *d = p->private_data; - -	if (offset == UART_MCR) -		d->last_mcr = value; -  	value &= 0xff;  	__raw_writeq(value, p->membase + (offset << p->regshift));  	/* Read back to ensure register write ordering. */ @@ -175,11 +158,6 @@ static void dw8250_serial_outq(struct uart_port *p, int offset, int value)  static void dw8250_serial_out32(struct uart_port *p, int offset, int value)  { -	struct dw8250_data *d = p->private_data; - -	if (offset == UART_MCR) -		d->last_mcr = value; -  	writel(value, p->membase + (offset << p->regshift));  	/* Make sure LCR write wasn't ignored */ @@ -257,6 +235,11 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,  	if (!ret)  		p->uartclk = rate; + +	p->status &= ~UPSTAT_AUTOCTS; +	if (termios->c_cflag & CRTSCTS) +		p->status |= UPSTAT_AUTOCTS; +  out:  	serial8250_do_set_termios(p, termios, old);  } diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 771dda29a0f8..faed05f25bc2 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -35,7 +35,7 @@  #include <asm/io.h>  #include <asm/serial.h> -unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset) +static unsigned int __init serial8250_early_in(struct uart_port *port, int offset)  {  	switch (port->iotype) {  	case UPIO_MEM: @@ -51,7 +51,7 @@ unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offse  	}  } -void __weak __init serial8250_early_out(struct uart_port *port, int offset, int value) +static void __init serial8250_early_out(struct uart_port *port, int offset, int value)  {  	switch (port->iotype) {  	case UPIO_MEM: diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index 5815e81b5fc6..89474399ab89 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c @@ -17,18 +17,19 @@  #include <linux/serial_core.h>  #include  "8250.h" -#define ADDR_PORT 0x4E -#define DATA_PORT 0x4F -#define ENTRY_KEY 0x77 +#define ADDR_PORT 0 +#define DATA_PORT 1  #define EXIT_KEY 0xAA  #define CHIP_ID1  0x20 -#define CHIP_ID1_VAL 0x02  #define CHIP_ID2  0x21 -#define CHIP_ID2_VAL 0x16 +#define CHIP_ID_0 0x1602 +#define CHIP_ID_1 0x0501  #define VENDOR_ID1 0x23  #define VENDOR_ID1_VAL 0x19  #define VENDOR_ID2 0x24  #define VENDOR_ID2_VAL 0x34 +#define IO_ADDR1 0x61 +#define IO_ADDR2 0x60  #define LDN 0x7  #define RS485  0xF0 @@ -39,51 +40,49 @@  #define DRIVER_NAME "8250_fintek" -static int fintek_8250_enter_key(void){ +struct fintek_8250 { +	u16 base_port; +	u8 index; +	u8 key; +	long line; +}; + +static int fintek_8250_enter_key(u16 base_port, u8 key) +{ -	if (!request_muxed_region(ADDR_PORT, 2, DRIVER_NAME)) +	if (!request_muxed_region(base_port, 2, DRIVER_NAME))  		return -EBUSY; -	outb(ENTRY_KEY, ADDR_PORT); -	outb(ENTRY_KEY, ADDR_PORT); +	outb(key, base_port + ADDR_PORT); +	outb(key, base_port + ADDR_PORT);  	return 0;  } -static void fintek_8250_exit_key(void){ - -	outb(EXIT_KEY, ADDR_PORT); -	release_region(ADDR_PORT, 2); -} - -static int fintek_8250_get_index(resource_size_t base_addr) +static void fintek_8250_exit_key(u16 base_port)  { -	resource_size_t base[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; -	int i; - -	for (i = 0; i < ARRAY_SIZE(base); i++) -		if (base_addr == base[i]) -			return i; -	return -ENODEV; +	outb(EXIT_KEY, base_port + ADDR_PORT); +	release_region(base_port + ADDR_PORT, 2);  } -static int fintek_8250_check_id(void) +static int fintek_8250_check_id(u16 base_port)  { +	u16 chip; -	outb(CHIP_ID1, ADDR_PORT); -	if (inb(DATA_PORT) != CHIP_ID1_VAL) +	outb(VENDOR_ID1, base_port + ADDR_PORT); +	if (inb(base_port + DATA_PORT) != VENDOR_ID1_VAL)  		return -ENODEV; -	outb(CHIP_ID2, ADDR_PORT); -	if (inb(DATA_PORT) != CHIP_ID2_VAL) +	outb(VENDOR_ID2, base_port + ADDR_PORT); +	if (inb(base_port + DATA_PORT) != VENDOR_ID2_VAL)  		return -ENODEV; -	outb(VENDOR_ID1, ADDR_PORT); -	if (inb(DATA_PORT) != VENDOR_ID1_VAL) -		return -ENODEV; +	outb(CHIP_ID1, base_port + ADDR_PORT); +	chip = inb(base_port + DATA_PORT); +	outb(CHIP_ID2, base_port + ADDR_PORT); +	chip |= inb(base_port + DATA_PORT) << 8; -	outb(VENDOR_ID2, ADDR_PORT); -	if (inb(DATA_PORT) != VENDOR_ID2_VAL) +	if (chip != CHIP_ID_0 && chip != CHIP_ID_1)  		return -ENODEV;  	return 0; @@ -93,9 +92,9 @@ static int fintek_8250_rs485_config(struct uart_port *port,  			      struct serial_rs485 *rs485)  {  	uint8_t config = 0; -	int index = fintek_8250_get_index(port->iobase); +	struct fintek_8250 *pdata = port->private_data; -	if (index < 0) +	if (!pdata)  		return -EINVAL;  	if (rs485->flags & SER_RS485_ENABLED) @@ -125,44 +124,84 @@ static int fintek_8250_rs485_config(struct uart_port *port,  	if (rs485->flags & SER_RS485_RTS_ON_SEND)  		config |= RTS_INVERT; -	if (fintek_8250_enter_key()) +	if (fintek_8250_enter_key(pdata->base_port, pdata->key))  		return -EBUSY; -	outb(LDN, ADDR_PORT); -	outb(index, DATA_PORT); -	outb(RS485, ADDR_PORT); -	outb(config, DATA_PORT); -	fintek_8250_exit_key(); +	outb(LDN, pdata->base_port + ADDR_PORT); +	outb(pdata->index, pdata->base_port + DATA_PORT); +	outb(RS485, pdata->base_port + ADDR_PORT); +	outb(config, pdata->base_port + DATA_PORT); +	fintek_8250_exit_key(pdata->base_port);  	port->rs485 = *rs485;  	return 0;  } +static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index) +{ +	static const u16 addr[] = {0x4e, 0x2e}; +	static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67}; +	int i, j, k; + +	for (i = 0; i < ARRAY_SIZE(addr); i++) { +		for (j = 0; j < ARRAY_SIZE(keys); j++) { + +			if (fintek_8250_enter_key(addr[i], keys[j])) +				continue; +			if (fintek_8250_check_id(addr[i])) { +				fintek_8250_exit_key(addr[i]); +				continue; +			} + +			for (k = 0; k < 4; k++) { +				u16 aux; + +				outb(LDN, addr[i] + ADDR_PORT); +				outb(k, addr[i] + DATA_PORT); + +				outb(IO_ADDR1, addr[i] + ADDR_PORT); +				aux = inb(addr[i] + DATA_PORT); +				outb(IO_ADDR2, addr[i] + ADDR_PORT); +				aux |= inb(addr[i] + DATA_PORT) << 8; +				if (aux != io_address) +					continue; + +				fintek_8250_exit_key(addr[i]); +				*key = keys[j]; +				*index = k; +				return addr[i]; +			} +			fintek_8250_exit_key(addr[i]); +		} +	} + +	return -ENODEV; +} +  static int  fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)  { -	int line;  	struct uart_8250_port uart; -	int ret; +	struct fintek_8250 *pdata; +	int base_port; +	u8 key; +	u8 index;  	if (!pnp_port_valid(dev, 0))  		return -ENODEV; -	if (fintek_8250_get_index(pnp_port_start(dev, 0)) < 0) +	base_port = fintek_8250_base_port(pnp_port_start(dev, 0), &key, &index); +	if (base_port < 0)  		return -ENODEV; -	/* Enable configuration registers*/ -	if (fintek_8250_enter_key()) -		return -EBUSY; +	memset(&uart, 0, sizeof(uart)); -	/*Check ID*/ -	ret = fintek_8250_check_id(); -	fintek_8250_exit_key(); -	if (ret) -		return ret; +	pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); +	if (!pdata) +		return -ENOMEM; +	uart.port.private_data = pdata; -	memset(&uart, 0, sizeof(uart));  	if (!pnp_irq_valid(dev, 0))  		return -ENODEV;  	uart.port.irq = pnp_irq(dev, 0); @@ -176,40 +215,43 @@ fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)  	uart.port.uartclk = 1843200;  	uart.port.dev = &dev->dev; -	line = serial8250_register_8250_port(&uart); -	if (line < 0) +	pdata->key = key; +	pdata->base_port = base_port; +	pdata->index = index; +	pdata->line = serial8250_register_8250_port(&uart); +	if (pdata->line < 0)  		return -ENODEV; -	pnp_set_drvdata(dev, (void *)((long)line + 1)); +	pnp_set_drvdata(dev, pdata);  	return 0;  }  static void fintek_8250_remove(struct pnp_dev *dev)  { -	long line = (long)pnp_get_drvdata(dev); +	struct fintek_8250 *pdata = pnp_get_drvdata(dev); -	if (line) -		serial8250_unregister_port(line - 1); +	if (pdata) +		serial8250_unregister_port(pdata->line);  }  #ifdef CONFIG_PM  static int fintek_8250_suspend(struct pnp_dev *dev, pm_message_t state)  { -	long line = (long)pnp_get_drvdata(dev); +	struct fintek_8250 *pdata = pnp_get_drvdata(dev); -	if (!line) +	if (!pdata)  		return -ENODEV; -	serial8250_suspend_port(line - 1); +	serial8250_suspend_port(pdata->line);  	return 0;  }  static int fintek_8250_resume(struct pnp_dev *dev)  { -	long line = (long)pnp_get_drvdata(dev); +	struct fintek_8250 *pdata = pnp_get_drvdata(dev); -	if (!line) +	if (!pdata)  		return -ENODEV; -	serial8250_resume_port(line - 1); +	serial8250_resume_port(pdata->line);  	return 0;  }  #else diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 21bf81fe794f..7c1e4be48e7b 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -252,7 +252,6 @@ MODULE_DEVICE_TABLE(of, of_match);  static struct platform_driver ingenic_uart_platform_driver = {  	.driver = {  		.name		= "ingenic-uart", -		.owner		= THIS_MODULE,  		.of_match_table	= of_match,  	},  	.probe			= ingenic_uart_probe, diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index d75a66c72750..826c5c4a2103 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -16,6 +16,7 @@  #include <linux/platform_device.h>  #include <linux/slab.h>  #include <linux/of.h> +#include <linux/of_device.h>  #include <linux/of_gpio.h>  #include <linux/of_irq.h>  #include <linux/delay.h> @@ -32,6 +33,11 @@  #define UART_ERRATA_i202_MDR1_ACCESS	(1 << 0)  #define OMAP_UART_WER_HAS_TX_WAKEUP	(1 << 1)  #define OMAP_DMA_TX_KICK		(1 << 2) +/* + * See Advisory 21 in AM437x errata SPRZ408B, updated April 2015. + * The same errata is applicable to AM335x and DRA7x processors too. + */ +#define UART_ERRATA_CLOCK_DISABLE	(1 << 3)  #define OMAP_UART_FCR_RX_TRIG		6  #define OMAP_UART_FCR_TX_TRIG		4 @@ -53,6 +59,12 @@  #define OMAP_UART_MVR_MAJ_SHIFT		8  #define OMAP_UART_MVR_MIN_MASK		0x3f +/* SYSC register bitmasks */ +#define OMAP_UART_SYSC_SOFTRESET	(1 << 1) + +/* SYSS register bitmasks */ +#define OMAP_UART_SYSS_RESETDONE	(1 << 0) +  #define UART_TI752_TLR_TX	0  #define UART_TI752_TLR_RX	4 @@ -100,6 +112,7 @@ struct omap8250_priv {  	struct work_struct qos_work;  	struct uart_8250_dma omap8250_dma;  	spinlock_t rx_dma_lock; +	bool rx_dma_broken;  };  static u32 uart_read(struct uart_8250_port *up, u32 reg) @@ -232,6 +245,15 @@ static void omap8250_update_scr(struct uart_8250_port *up,  	serial_out(up, UART_OMAP_SCR, priv->scr);  } +static void omap8250_update_mdr1(struct uart_8250_port *up, +				 struct omap8250_priv *priv) +{ +	if (priv->habit & UART_ERRATA_i202_MDR1_ACCESS) +		omap_8250_mdr1_errataset(up, priv); +	else +		serial_out(up, UART_OMAP_MDR1, priv->mdr1); +} +  static void omap8250_restore_regs(struct uart_8250_port *up)  {  	struct omap8250_priv *priv = up->port.private_data; @@ -282,11 +304,9 @@ static void omap8250_restore_regs(struct uart_8250_port *up)  	serial_out(up, UART_XOFF1, priv->xoff);  	serial_out(up, UART_LCR, up->lcr); -	/* need mode A for FCR */ -	if (priv->habit & UART_ERRATA_i202_MDR1_ACCESS) -		omap_8250_mdr1_errataset(up, priv); -	else -		serial_out(up, UART_OMAP_MDR1, priv->mdr1); + +	omap8250_update_mdr1(up, priv); +  	up->port.ops->set_mctrl(&up->port, up->port.mctrl);  } @@ -428,12 +448,9 @@ static void omap_8250_set_termios(struct uart_port *port,  		priv->efr |= UART_EFR_CTS;  	} else	if (up->port.flags & UPF_SOFT_FLOW) {  		/* -		 * IXON Flag: -		 * Enable XON/XOFF flow control on input. -		 * Receiver compares XON1, XOFF1. +		 * OMAP rx s/w flow control is borked; the transmitter remains +		 * stuck off even if rx flow control is subsequently disabled  		 */ -		if (termios->c_iflag & IXON) -			priv->efr |= OMAP_UART_SW_RX;  		/*  		 * IXOFF Flag: @@ -444,15 +461,6 @@ static void omap_8250_set_termios(struct uart_port *port,  			up->port.status |= UPSTAT_AUTOXOFF;  			priv->efr |= OMAP_UART_SW_TX;  		} - -		/* -		 * IXANY Flag: -		 * Enable any character to restart output. -		 * Operation resumes after receiving any -		 * character after recognition of the XOFF character -		 */ -		if (termios->c_iflag & IXANY) -			up->mcr |= UART_MCR_XONANY;  	}  	omap8250_restore_regs(up); @@ -530,14 +538,14 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up,  	switch (revision) {  	case OMAP_UART_REV_46: -		priv->habit = UART_ERRATA_i202_MDR1_ACCESS; +		priv->habit |= UART_ERRATA_i202_MDR1_ACCESS;  		break;  	case OMAP_UART_REV_52: -		priv->habit = UART_ERRATA_i202_MDR1_ACCESS | +		priv->habit |= UART_ERRATA_i202_MDR1_ACCESS |  				OMAP_UART_WER_HAS_TX_WAKEUP;  		break;  	case OMAP_UART_REV_63: -		priv->habit = UART_ERRATA_i202_MDR1_ACCESS | +		priv->habit |= UART_ERRATA_i202_MDR1_ACCESS |  			OMAP_UART_WER_HAS_TX_WAKEUP;  		break;  	default: @@ -754,6 +762,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)  	struct omap8250_priv	*priv = p->port.private_data;  	struct uart_8250_dma	*dma = p->dma;  	unsigned long		flags; +	int ret;  	spin_lock_irqsave(&priv->rx_dma_lock, flags); @@ -762,7 +771,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)  		return;  	} -	dmaengine_pause(dma->rxchan); +	ret = dmaengine_pause(dma->rxchan); +	if (WARN_ON_ONCE(ret)) +		priv->rx_dma_broken = true;  	spin_unlock_irqrestore(&priv->rx_dma_lock, flags); @@ -806,6 +817,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)  		break;  	} +	if (priv->rx_dma_broken) +		return -EINVAL; +  	spin_lock_irqsave(&priv->rx_dma_lock, flags);  	if (dma->rx_running) @@ -1054,6 +1068,20 @@ static int omap8250_no_handle_irq(struct uart_port *port)  	return 0;  } +static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE; +static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE; + +static const struct of_device_id omap8250_dt_ids[] = { +	{ .compatible = "ti,omap2-uart" }, +	{ .compatible = "ti,omap3-uart" }, +	{ .compatible = "ti,omap4-uart" }, +	{ .compatible = "ti,am3352-uart", .data = &am3352_habit, }, +	{ .compatible = "ti,am4372-uart", .data = &am4372_habit, }, +	{ .compatible = "ti,dra742-uart", .data = &am4372_habit, }, +	{}, +}; +MODULE_DEVICE_TABLE(of, omap8250_dt_ids); +  static int omap8250_probe(struct platform_device *pdev)  {  	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1118,11 +1146,17 @@ static int omap8250_probe(struct platform_device *pdev)  	up.port.unthrottle = omap_8250_unthrottle;  	if (pdev->dev.of_node) { +		const struct of_device_id *id; +  		ret = of_alias_get_id(pdev->dev.of_node, "serial");  		of_property_read_u32(pdev->dev.of_node, "clock-frequency",  				     &up.port.uartclk);  		priv->wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1); + +		id = of_match_device(of_match_ptr(omap8250_dt_ids), &pdev->dev); +		if (id && id->data) +			priv->habit |= *(u8 *)id->data;  	} else {  		ret = pdev->id;  	} @@ -1180,6 +1214,11 @@ static int omap8250_probe(struct platform_device *pdev)  			if (of_machine_is_compatible("ti,am33xx"))  				priv->habit |= OMAP_DMA_TX_KICK; +			/* +			 * pause is currently not supported atleast on omap-sdma +			 * and edma on most earlier kernels. +			 */ +			priv->rx_dma_broken = true;  		}  	}  #endif @@ -1257,17 +1296,46 @@ static int omap8250_lost_context(struct uart_8250_port *up)  {  	u32 val; -	val = serial_in(up, UART_OMAP_MDR1); +	val = serial_in(up, UART_OMAP_SCR);  	/* -	 * If we lose context, then MDR1 is set to its reset value which is -	 * UART_OMAP_MDR1_DISABLE. After set_termios() we set it either to 13x -	 * or 16x but never to disable again. +	 * If we lose context, then SCR is set to its reset value of zero. +	 * After set_termios() we set bit 3 of SCR (TX_EMPTY_CTL_IT) to 1, +	 * among other bits, to never set the register back to zero again.  	 */ -	if (val == UART_OMAP_MDR1_DISABLE) +	if (!val)  		return 1;  	return 0;  } +/* TODO: in future, this should happen via API in drivers/reset/ */ +static int omap8250_soft_reset(struct device *dev) +{ +	struct omap8250_priv *priv = dev_get_drvdata(dev); +	struct uart_8250_port *up = serial8250_get_port(priv->line); +	int timeout = 100; +	int sysc; +	int syss; + +	sysc = serial_in(up, UART_OMAP_SYSC); + +	/* softreset the UART */ +	sysc |= OMAP_UART_SYSC_SOFTRESET; +	serial_out(up, UART_OMAP_SYSC, sysc); + +	/* By experiments, 1us enough for reset complete on AM335x */ +	do { +		udelay(1); +		syss = serial_in(up, UART_OMAP_SYSS); +	} while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE)); + +	if (!timeout) { +		dev_err(dev, "timed out waiting for reset done\n"); +		return -ETIMEDOUT; +	} + +	return 0; +} +  static int omap8250_runtime_suspend(struct device *dev)  {  	struct omap8250_priv *priv = dev_get_drvdata(dev); @@ -1285,7 +1353,18 @@ static int omap8250_runtime_suspend(struct device *dev)  			return -EBUSY;  	} -	if (up->dma) +	if (priv->habit & UART_ERRATA_CLOCK_DISABLE) { +		int ret; + +		ret = omap8250_soft_reset(dev); +		if (ret) +			return ret; + +		/* Restore to UART mode after reset (for wakeup) */ +		omap8250_update_mdr1(up, priv); +	} + +	if (up->dma && up->dma->rxchan)  		omap_8250_rx_dma(up, UART_IIR_RX_TIMEOUT);  	priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; @@ -1310,7 +1389,7 @@ static int omap8250_runtime_resume(struct device *dev)  	if (loss_cntx)  		omap8250_restore_regs(up); -	if (up->dma) +	if (up->dma && up->dma->rxchan)  		omap_8250_rx_dma(up, 0);  	priv->latency = priv->calc_latency; @@ -1367,14 +1446,6 @@ static const struct dev_pm_ops omap8250_dev_pm_ops = {  	.complete       = omap8250_complete,  }; -static const struct of_device_id omap8250_dt_ids[] = { -	{ .compatible = "ti,omap2-uart" }, -	{ .compatible = "ti,omap3-uart" }, -	{ .compatible = "ti,omap4-uart" }, -	{}, -}; -MODULE_DEVICE_TABLE(of, omap8250_dt_ids); -  static struct platform_driver omap8250_platform_driver = {  	.driver = {  		.name		= "omap8250", diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index e55f18b93fe7..68042dd1c525 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1417,6 +1417,10 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,  	reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;  	writel(reg, p->membase + BYT_PRV_CLK); +	p->status &= ~UPSTAT_AUTOCTS; +	if (termios->c_cflag & CRTSCTS) +		p->status |= UPSTAT_AUTOCTS; +  	serial8250_do_set_termios(p, termios, old);  } @@ -1685,11 +1689,65 @@ pci_brcm_trumanage_setup(struct serial_private *priv,  	return ret;  } +/* RTS will control by MCR if this bit is 0 */ +#define FINTEK_RTS_CONTROL_BY_HW	BIT(4) +/* only worked with FINTEK_RTS_CONTROL_BY_HW on */ +#define FINTEK_RTS_INVERT		BIT(5) + +/* We should do proper H/W transceiver setting before change to RS485 mode */ +static int pci_fintek_rs485_config(struct uart_port *port, +			       struct serial_rs485 *rs485) +{ +	u8 setting; +	u8 *index = (u8 *) port->private_data; +	struct pci_dev *pci_dev = container_of(port->dev, struct pci_dev, +						dev); + +	pci_read_config_byte(pci_dev, 0x40 + 8 * *index + 7, &setting); + +	if (!rs485) +		rs485 = &port->rs485; +	else if (rs485->flags & SER_RS485_ENABLED) +		memset(rs485->padding, 0, sizeof(rs485->padding)); +	else +		memset(rs485, 0, sizeof(*rs485)); + +	/* F81504/508/512 not support RTS delay before or after send */ +	rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND; + +	if (rs485->flags & SER_RS485_ENABLED) { +		/* Enable RTS H/W control mode */ +		setting |= FINTEK_RTS_CONTROL_BY_HW; + +		if (rs485->flags & SER_RS485_RTS_ON_SEND) { +			/* RTS driving high on TX */ +			setting &= ~FINTEK_RTS_INVERT; +		} else { +			/* RTS driving low on TX */ +			setting |= FINTEK_RTS_INVERT; +		} + +		rs485->delay_rts_after_send = 0; +		rs485->delay_rts_before_send = 0; +	} else { +		/* Disable RTS H/W control mode */ +		setting &= ~(FINTEK_RTS_CONTROL_BY_HW | FINTEK_RTS_INVERT); +	} + +	pci_write_config_byte(pci_dev, 0x40 + 8 * *index + 7, setting); + +	if (rs485 != &port->rs485) +		port->rs485 = *rs485; + +	return 0; +} +  static int pci_fintek_setup(struct serial_private *priv,  			    const struct pciserial_board *board,  			    struct uart_8250_port *port, int idx)  {  	struct pci_dev *pdev = priv->dev; +	u8 *data;  	u8 config_base;  	u16 iobase; @@ -1702,6 +1760,15 @@ static int pci_fintek_setup(struct serial_private *priv,  	port->port.iotype = UPIO_PORT;  	port->port.iobase = iobase; +	port->port.rs485_config = pci_fintek_rs485_config; + +	data = devm_kzalloc(&pdev->dev, sizeof(u8), GFP_KERNEL); +	if (!data) +		return -ENOMEM; + +	/* preserve index in PCI configuration space */ +	*data = idx; +	port->port.private_data = data;  	return 0;  } @@ -1712,6 +1779,8 @@ static int pci_fintek_init(struct pci_dev *dev)  	u32 max_port, i;  	u32 bar_data[3];  	u8 config_base; +	struct serial_private *priv = pci_get_drvdata(dev); +	struct uart_8250_port *port;  	switch (dev->device) {  	case 0x1104: /* 4 ports */ @@ -1752,6 +1821,19 @@ static int pci_fintek_init(struct pci_dev *dev)  				(u8)((iobase & 0xff00) >> 8));  		pci_write_config_byte(dev, config_base + 0x06, dev->irq); + +		if (priv) { +			/* re-apply RS232/485 mode when +			 * pciserial_resume_ports() +			 */ +			port = serial8250_get_port(priv->line[i]); +			pci_fintek_rs485_config(&port->port, NULL); +		} else { +			/* First init without port data +			 * force init to RS232 Mode +			 */ +			pci_write_config_byte(dev, config_base + 0x07, 0x01); +		}  	}  	return max_port; @@ -2017,6 +2099,12 @@ pci_wch_ch38x_setup(struct serial_private *priv,  #define PCIE_DEVICE_ID_WCH_CH382_2S1P	0x3250  #define PCIE_DEVICE_ID_WCH_CH384_4S	0x3470 +#define PCI_VENDOR_ID_PERICOM			0x12D8 +#define PCI_DEVICE_ID_PERICOM_PI7C9X7951	0x7951 +#define PCI_DEVICE_ID_PERICOM_PI7C9X7952	0x7952 +#define PCI_DEVICE_ID_PERICOM_PI7C9X7954	0x7954 +#define PCI_DEVICE_ID_PERICOM_PI7C9X7958	0x7958 +  /* Unknown vendors/cards - this should not be in linux/pci_ids.h */  #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584	0x1584  #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588	0x1588 @@ -2331,27 +2419,12 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {  	 * Pericom  	 */  	{ -		.vendor		= 0x12d8, -		.device		= 0x7952, -		.subvendor	= PCI_ANY_ID, -		.subdevice	= PCI_ANY_ID, -		.setup		= pci_pericom_setup, -	}, -	{ -		.vendor		= 0x12d8, -		.device		= 0x7954, -		.subvendor	= PCI_ANY_ID, -		.subdevice	= PCI_ANY_ID, -		.setup		= pci_pericom_setup, -	}, -	{ -		.vendor		= 0x12d8, -		.device		= 0x7958, -		.subvendor	= PCI_ANY_ID, -		.subdevice	= PCI_ANY_ID, -		.setup		= pci_pericom_setup, +		.vendor         = PCI_VENDOR_ID_PERICOM, +		.device         = PCI_ANY_ID, +		.subvendor      = PCI_ANY_ID, +		.subdevice      = PCI_ANY_ID, +		.setup          = pci_pericom_setup,  	}, -  	/*  	 * PLX  	 */ @@ -3056,6 +3129,10 @@ enum pci_board_num_t {  	pbn_fintek_8,  	pbn_fintek_12,  	pbn_wch384_4, +	pbn_pericom_PI7C9X7951, +	pbn_pericom_PI7C9X7952, +	pbn_pericom_PI7C9X7954, +	pbn_pericom_PI7C9X7958,  };  /* @@ -3881,7 +3958,6 @@ static struct pciserial_board pci_boards[] = {  		.base_baud	= 115200,  		.first_offset	= 0x40,  	}, -  	[pbn_wch384_4] = {  		.flags		= FL_BASE0,  		.num_ports	= 4, @@ -3889,6 +3965,33 @@ static struct pciserial_board pci_boards[] = {  		.uart_offset    = 8,  		.first_offset   = 0xC0,  	}, +	/* +	 * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART +	 */ +	[pbn_pericom_PI7C9X7951] = { +		.flags          = FL_BASE0, +		.num_ports      = 1, +		.base_baud      = 921600, +		.uart_offset	= 0x8, +	}, +	[pbn_pericom_PI7C9X7952] = { +		.flags          = FL_BASE0, +		.num_ports      = 2, +		.base_baud      = 921600, +		.uart_offset	= 0x8, +	}, +	[pbn_pericom_PI7C9X7954] = { +		.flags          = FL_BASE0, +		.num_ports      = 4, +		.base_baud      = 921600, +		.uart_offset	= 0x8, +	}, +	[pbn_pericom_PI7C9X7958] = { +		.flags          = FL_BASE0, +		.num_ports      = 8, +		.base_baud      = 921600, +		.uart_offset	= 0x8, +	},  };  static const struct pci_device_id blacklist[] = { @@ -5154,6 +5257,25 @@ static struct pci_device_id serial_pci_tbl[] = {  		0,  		0, pbn_exar_XR17V8358 },  	/* +	 * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART +	 */ +	{   PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7951, +		PCI_ANY_ID, PCI_ANY_ID, +		0, +		0, pbn_pericom_PI7C9X7951 }, +	{   PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7952, +		PCI_ANY_ID, PCI_ANY_ID, +		0, +		0, pbn_pericom_PI7C9X7952 }, +	{   PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7954, +		PCI_ANY_ID, PCI_ANY_ID, +		0, +		0, pbn_pericom_PI7C9X7954 }, +	{   PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7958, +		PCI_ANY_ID, PCI_ANY_ID, +		0, +		0, pbn_pericom_PI7C9X7958 }, +	/*  	 * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)  	 */  	{	PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 50a09cd76d50..658b392d1170 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c @@ -41,6 +41,12 @@ static const struct pnp_device_id pnp_dev_table[] = {  	{	"AEI1240",		0	},  	/* Rockwell 56K ACF II Fax+Data+Voice Modem */  	{	"AKY1021",		0 /*SPCI_FL_NO_SHIRQ*/	}, +	/* +	 * ALi Fast Infrared Controller +	 * Native driver (ali-ircc) is broken so at least +	 * it can be used with irtty-sir. +	 */ +	{	"ALI5123",		0	},  	/* AZT3005 PnP SOUND DEVICE */  	{	"AZT4001",		0	},  	/* Best Data Products Inc. Smart One 336F PnP Modem */ @@ -364,6 +370,11 @@ static const struct pnp_device_id pnp_dev_table[] = {  	/* Winbond CIR port, should not be probed. We should keep track  	   of it to prevent the legacy serial driver from probing it */  	{	"WEC1022",		CIR_PORT	}, +	/* +	 * SMSC IrCC SIR/FIR port, should not be probed by serial driver +	 * as well so its own driver can bind to it. +	 */ +	{	"SMCF010",		CIR_PORT	},  	{	"",			0	}  }; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c new file mode 100644 index 000000000000..54e6c8ddef5d --- /dev/null +++ b/drivers/tty/serial/8250/8250_port.c @@ -0,0 +1,2912 @@ +/* + *  Base port operations for 8250/16550-type serial ports + * + *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + *  Split from 8250_core.c, Copyright (C) 2001 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A note about mapbase / membase + * + *  mapbase is the physical address of the IO port. + *  membase is an 'ioremapped' cookie. + */ + +#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/ioport.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/sysrq.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/tty.h> +#include <linux/ratelimit.h> +#include <linux/tty_flip.h> +#include <linux/serial.h> +#include <linux/serial_8250.h> +#include <linux/nmi.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include <linux/pm_runtime.h> + +#include <asm/io.h> +#include <asm/irq.h> + +#include "8250.h" + +/* + * Debugging. + */ +#if 0 +#define DEBUG_AUTOCONF(fmt...)	printk(fmt) +#else +#define DEBUG_AUTOCONF(fmt...)	do { } while (0) +#endif + +#define BOTH_EMPTY 	(UART_LSR_TEMT | UART_LSR_THRE) + +/* + * Here we define the default xmit fifo size used for each type of UART. + */ +static const struct serial8250_config uart_config[] = { +	[PORT_UNKNOWN] = { +		.name		= "unknown", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +	}, +	[PORT_8250] = { +		.name		= "8250", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +	}, +	[PORT_16450] = { +		.name		= "16450", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +	}, +	[PORT_16550] = { +		.name		= "16550", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +	}, +	[PORT_16550A] = { +		.name		= "16550A", +		.fifo_size	= 16, +		.tx_loadsz	= 16, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.rxtrig_bytes	= {1, 4, 8, 14}, +		.flags		= UART_CAP_FIFO, +	}, +	[PORT_CIRRUS] = { +		.name		= "Cirrus", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +	}, +	[PORT_16650] = { +		.name		= "ST16650", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, +	}, +	[PORT_16650V2] = { +		.name		= "ST16650V2", +		.fifo_size	= 32, +		.tx_loadsz	= 16, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | +				  UART_FCR_T_TRIG_00, +		.rxtrig_bytes	= {8, 16, 24, 28}, +		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, +	}, +	[PORT_16750] = { +		.name		= "TI16750", +		.fifo_size	= 64, +		.tx_loadsz	= 64, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | +				  UART_FCR7_64BYTE, +		.rxtrig_bytes	= {1, 16, 32, 56}, +		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, +	}, +	[PORT_STARTECH] = { +		.name		= "Startech", +		.fifo_size	= 1, +		.tx_loadsz	= 1, +	}, +	[PORT_16C950] = { +		.name		= "16C950/954", +		.fifo_size	= 128, +		.tx_loadsz	= 128, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		/* UART_CAP_EFR breaks billionon CF bluetooth card. */ +		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP, +	}, +	[PORT_16654] = { +		.name		= "ST16654", +		.fifo_size	= 64, +		.tx_loadsz	= 32, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | +				  UART_FCR_T_TRIG_10, +		.rxtrig_bytes	= {8, 16, 56, 60}, +		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, +	}, +	[PORT_16850] = { +		.name		= "XR16850", +		.fifo_size	= 128, +		.tx_loadsz	= 128, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, +	}, +	[PORT_RSA] = { +		.name		= "RSA", +		.fifo_size	= 2048, +		.tx_loadsz	= 2048, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, +		.flags		= UART_CAP_FIFO, +	}, +	[PORT_NS16550A] = { +		.name		= "NS16550A", +		.fifo_size	= 16, +		.tx_loadsz	= 16, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_NATSEMI, +	}, +	[PORT_XSCALE] = { +		.name		= "XScale", +		.fifo_size	= 32, +		.tx_loadsz	= 32, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, +	}, +	[PORT_OCTEON] = { +		.name		= "OCTEON", +		.fifo_size	= 64, +		.tx_loadsz	= 64, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO, +	}, +	[PORT_AR7] = { +		.name		= "AR7", +		.fifo_size	= 16, +		.tx_loadsz	= 16, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +	[PORT_U6_16550A] = { +		.name		= "U6_16550A", +		.fifo_size	= 64, +		.tx_loadsz	= 64, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +	[PORT_TEGRA] = { +		.name		= "Tegra", +		.fifo_size	= 32, +		.tx_loadsz	= 8, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | +				  UART_FCR_T_TRIG_01, +		.rxtrig_bytes	= {1, 4, 8, 14}, +		.flags		= UART_CAP_FIFO | UART_CAP_RTOIE, +	}, +	[PORT_XR17D15X] = { +		.name		= "XR17D15X", +		.fifo_size	= 64, +		.tx_loadsz	= 64, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | +				  UART_CAP_SLEEP, +	}, +	[PORT_XR17V35X] = { +		.name		= "XR17V35X", +		.fifo_size	= 256, +		.tx_loadsz	= 256, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | +				  UART_FCR_T_TRIG_11, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | +				  UART_CAP_SLEEP, +	}, +	[PORT_LPC3220] = { +		.name		= "LPC3220", +		.fifo_size	= 64, +		.tx_loadsz	= 32, +		.fcr		= UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | +				  UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, +		.flags		= UART_CAP_FIFO, +	}, +	[PORT_BRCM_TRUMANAGE] = { +		.name		= "TruManage", +		.fifo_size	= 1, +		.tx_loadsz	= 1024, +		.flags		= UART_CAP_HFIFO, +	}, +	[PORT_8250_CIR] = { +		.name		= "CIR port" +	}, +	[PORT_ALTR_16550_F32] = { +		.name		= "Altera 16550 FIFO32", +		.fifo_size	= 32, +		.tx_loadsz	= 32, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +	[PORT_ALTR_16550_F64] = { +		.name		= "Altera 16550 FIFO64", +		.fifo_size	= 64, +		.tx_loadsz	= 64, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +	[PORT_ALTR_16550_F128] = { +		.name		= "Altera 16550 FIFO128", +		.fifo_size	= 128, +		.tx_loadsz	= 128, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +/* tx_loadsz is set to 63-bytes instead of 64-bytes to implement +workaround of errata A-008006 which states that tx_loadsz should  be +configured less than Maximum supported fifo bytes */ +	[PORT_16550A_FSL64] = { +		.name		= "16550A_FSL64", +		.fifo_size	= 64, +		.tx_loadsz	= 63, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | +				  UART_FCR7_64BYTE, +		.flags		= UART_CAP_FIFO, +	}, +}; + +/* Uart divisor latch read */ +static int default_serial_dl_read(struct uart_8250_port *up) +{ +	return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; +} + +/* Uart divisor latch write */ +static void default_serial_dl_write(struct uart_8250_port *up, int value) +{ +	serial_out(up, UART_DLL, value & 0xff); +	serial_out(up, UART_DLM, value >> 8 & 0xff); +} + +#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) + +/* Au1x00/RT288x UART hardware has a weird register layout */ +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 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) +{ +	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) +{ +	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 */ +static int au_serial_dl_read(struct uart_8250_port *up) +{ +	return __raw_readl(up->port.membase + 0x28); +} + +static void au_serial_dl_write(struct uart_8250_port *up, int value) +{ +	__raw_writel(value, up->port.membase + 0x28); +} + +#endif + +static unsigned int hub6_serial_in(struct uart_port *p, int offset) +{ +	offset = offset << p->regshift; +	outb(p->hub6 - 1 + offset, p->iobase); +	return inb(p->iobase + 1); +} + +static void hub6_serial_out(struct uart_port *p, int offset, int value) +{ +	offset = offset << p->regshift; +	outb(p->hub6 - 1 + offset, p->iobase); +	outb(value, p->iobase + 1); +} + +static unsigned int mem_serial_in(struct uart_port *p, int offset) +{ +	offset = offset << p->regshift; +	return readb(p->membase + offset); +} + +static void mem_serial_out(struct uart_port *p, int offset, int value) +{ +	offset = offset << p->regshift; +	writeb(value, p->membase + offset); +} + +static void mem32_serial_out(struct uart_port *p, int offset, int value) +{ +	offset = offset << p->regshift; +	writel(value, p->membase + offset); +} + +static unsigned int mem32_serial_in(struct uart_port *p, int offset) +{ +	offset = offset << p->regshift; +	return readl(p->membase + offset); +} + +static void mem32be_serial_out(struct uart_port *p, int offset, int value) +{ +	offset = offset << p->regshift; +	iowrite32be(value, p->membase + offset); +} + +static unsigned int mem32be_serial_in(struct uart_port *p, int offset) +{ +	offset = offset << p->regshift; +	return ioread32be(p->membase + offset); +} + +static unsigned int io_serial_in(struct uart_port *p, int offset) +{ +	offset = offset << p->regshift; +	return inb(p->iobase + offset); +} + +static void io_serial_out(struct uart_port *p, int offset, int value) +{ +	offset = offset << p->regshift; +	outb(value, p->iobase + offset); +} + +static int serial8250_default_handle_irq(struct uart_port *port); +static int exar_handle_irq(struct uart_port *port); + +static void set_io_from_upio(struct uart_port *p) +{ +	struct uart_8250_port *up = up_to_u8250p(p); + +	up->dl_read = default_serial_dl_read; +	up->dl_write = default_serial_dl_write; + +	switch (p->iotype) { +	case UPIO_HUB6: +		p->serial_in = hub6_serial_in; +		p->serial_out = hub6_serial_out; +		break; + +	case UPIO_MEM: +		p->serial_in = mem_serial_in; +		p->serial_out = mem_serial_out; +		break; + +	case UPIO_MEM32: +		p->serial_in = mem32_serial_in; +		p->serial_out = mem32_serial_out; +		break; + +	case UPIO_MEM32BE: +		p->serial_in = mem32be_serial_in; +		p->serial_out = mem32be_serial_out; +		break; + +#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) +	case UPIO_AU: +		p->serial_in = au_serial_in; +		p->serial_out = au_serial_out; +		up->dl_read = au_serial_dl_read; +		up->dl_write = au_serial_dl_write; +		break; +#endif + +	default: +		p->serial_in = io_serial_in; +		p->serial_out = io_serial_out; +		break; +	} +	/* Remember loaded iotype */ +	up->cur_iotype = p->iotype; +	p->handle_irq = serial8250_default_handle_irq; +} + +static void +serial_port_out_sync(struct uart_port *p, int offset, int value) +{ +	switch (p->iotype) { +	case UPIO_MEM: +	case UPIO_MEM32: +	case UPIO_MEM32BE: +	case UPIO_AU: +		p->serial_out(p, offset, value); +		p->serial_in(p, UART_LCR);	/* safe, no side-effects */ +		break; +	default: +		p->serial_out(p, offset, value); +	} +} + +/* + * For the 16C950 + */ +static void serial_icr_write(struct uart_8250_port *up, int offset, int value) +{ +	serial_out(up, UART_SCR, offset); +	serial_out(up, UART_ICR, value); +} + +static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) +{ +	unsigned int value; + +	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD); +	serial_out(up, UART_SCR, offset); +	value = serial_in(up, UART_ICR); +	serial_icr_write(up, UART_ACR, up->acr); + +	return value; +} + +/* + * FIFO support. + */ +static void serial8250_clear_fifos(struct uart_8250_port *p) +{ +	if (p->capabilities & UART_CAP_FIFO) { +		serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); +		serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | +			       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); +		serial_out(p, UART_FCR, 0); +	} +} + +void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) +{ +	serial8250_clear_fifos(p); +	serial_out(p, UART_FCR, p->fcr); +} +EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); + +void serial8250_rpm_get(struct uart_8250_port *p) +{ +	if (!(p->capabilities & UART_CAP_RPM)) +		return; +	pm_runtime_get_sync(p->port.dev); +} +EXPORT_SYMBOL_GPL(serial8250_rpm_get); + +void serial8250_rpm_put(struct uart_8250_port *p) +{ +	if (!(p->capabilities & UART_CAP_RPM)) +		return; +	pm_runtime_mark_last_busy(p->port.dev); +	pm_runtime_put_autosuspend(p->port.dev); +} +EXPORT_SYMBOL_GPL(serial8250_rpm_put); + +/* + * These two wrappers ensure that enable_runtime_pm_tx() can be called more than + * once and disable_runtime_pm_tx() will still disable RPM because the fifo is + * empty and the HW can idle again. + */ +static void serial8250_rpm_get_tx(struct uart_8250_port *p) +{ +	unsigned char rpm_active; + +	if (!(p->capabilities & UART_CAP_RPM)) +		return; + +	rpm_active = xchg(&p->rpm_tx_active, 1); +	if (rpm_active) +		return; +	pm_runtime_get_sync(p->port.dev); +} + +static void serial8250_rpm_put_tx(struct uart_8250_port *p) +{ +	unsigned char rpm_active; + +	if (!(p->capabilities & UART_CAP_RPM)) +		return; + +	rpm_active = xchg(&p->rpm_tx_active, 0); +	if (!rpm_active) +		return; +	pm_runtime_mark_last_busy(p->port.dev); +	pm_runtime_put_autosuspend(p->port.dev); +} + +/* + * IER sleep support.  UARTs which have EFRs need the "extended + * capability" bit enabled.  Note that on XR16C850s, we need to + * reset LCR to write to IER. + */ +static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) +{ +	unsigned char lcr = 0, efr = 0; +	/* +	 * Exar UARTs have a SLEEP register that enables or disables +	 * each UART to enter sleep mode separately.  On the XR17V35x the +	 * register is accessible to each UART at the UART_EXAR_SLEEP +	 * offset but the UART channel may only write to the corresponding +	 * bit. +	 */ +	serial8250_rpm_get(p); +	if ((p->port.type == PORT_XR17V35X) || +	   (p->port.type == PORT_XR17D15X)) { +		serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); +		goto out; +	} + +	if (p->capabilities & UART_CAP_SLEEP) { +		if (p->capabilities & UART_CAP_EFR) { +			lcr = serial_in(p, UART_LCR); +			efr = serial_in(p, UART_EFR); +			serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); +			serial_out(p, UART_EFR, UART_EFR_ECB); +			serial_out(p, UART_LCR, 0); +		} +		serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); +		if (p->capabilities & UART_CAP_EFR) { +			serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); +			serial_out(p, UART_EFR, efr); +			serial_out(p, UART_LCR, lcr); +		} +	} +out: +	serial8250_rpm_put(p); +} + +#ifdef CONFIG_SERIAL_8250_RSA +/* + * Attempts to turn on the RSA FIFO.  Returns zero on failure. + * We set the port uart clock rate if we succeed. + */ +static int __enable_rsa(struct uart_8250_port *up) +{ +	unsigned char mode; +	int result; + +	mode = serial_in(up, UART_RSA_MSR); +	result = mode & UART_RSA_MSR_FIFO; + +	if (!result) { +		serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); +		mode = serial_in(up, UART_RSA_MSR); +		result = mode & UART_RSA_MSR_FIFO; +	} + +	if (result) +		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; + +	return result; +} + +static void enable_rsa(struct uart_8250_port *up) +{ +	if (up->port.type == PORT_RSA) { +		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { +			spin_lock_irq(&up->port.lock); +			__enable_rsa(up); +			spin_unlock_irq(&up->port.lock); +		} +		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) +			serial_out(up, UART_RSA_FRR, 0); +	} +} + +/* + * Attempts to turn off the RSA FIFO.  Returns zero on failure. + * It is unknown why interrupts were disabled in here.  However, + * the caller is expected to preserve this behaviour by grabbing + * the spinlock before calling this function. + */ +static void disable_rsa(struct uart_8250_port *up) +{ +	unsigned char mode; +	int result; + +	if (up->port.type == PORT_RSA && +	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { +		spin_lock_irq(&up->port.lock); + +		mode = serial_in(up, UART_RSA_MSR); +		result = !(mode & UART_RSA_MSR_FIFO); + +		if (!result) { +			serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); +			mode = serial_in(up, UART_RSA_MSR); +			result = !(mode & UART_RSA_MSR_FIFO); +		} + +		if (result) +			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; +		spin_unlock_irq(&up->port.lock); +	} +} +#endif /* CONFIG_SERIAL_8250_RSA */ + +/* + * This is a quickie test to see how big the FIFO is. + * It doesn't work at all the time, more's the pity. + */ +static int size_fifo(struct uart_8250_port *up) +{ +	unsigned char old_fcr, old_mcr, old_lcr; +	unsigned short old_dl; +	int count; + +	old_lcr = serial_in(up, UART_LCR); +	serial_out(up, UART_LCR, 0); +	old_fcr = serial_in(up, UART_FCR); +	old_mcr = serial_in(up, UART_MCR); +	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | +		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); +	serial_out(up, UART_MCR, UART_MCR_LOOP); +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); +	old_dl = serial_dl_read(up); +	serial_dl_write(up, 0x0001); +	serial_out(up, UART_LCR, 0x03); +	for (count = 0; count < 256; count++) +		serial_out(up, UART_TX, count); +	mdelay(20);/* FIXME - schedule_timeout */ +	for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && +	     (count < 256); count++) +		serial_in(up, UART_RX); +	serial_out(up, UART_FCR, old_fcr); +	serial_out(up, UART_MCR, old_mcr); +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); +	serial_dl_write(up, old_dl); +	serial_out(up, UART_LCR, old_lcr); + +	return count; +} + +/* + * Read UART ID using the divisor method - set DLL and DLM to zero + * and the revision will be in DLL and device type in DLM.  We + * preserve the device state across this. + */ +static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) +{ +	unsigned char old_dll, old_dlm, old_lcr; +	unsigned int id; + +	old_lcr = serial_in(p, UART_LCR); +	serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); + +	old_dll = serial_in(p, UART_DLL); +	old_dlm = serial_in(p, UART_DLM); + +	serial_out(p, UART_DLL, 0); +	serial_out(p, UART_DLM, 0); + +	id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; + +	serial_out(p, UART_DLL, old_dll); +	serial_out(p, UART_DLM, old_dlm); +	serial_out(p, UART_LCR, old_lcr); + +	return id; +} + +/* + * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. + * When this function is called we know it is at least a StarTech + * 16650 V2, but it might be one of several StarTech UARTs, or one of + * its clones.  (We treat the broken original StarTech 16650 V1 as a + * 16550, and why not?  Startech doesn't seem to even acknowledge its + * existence.) + * + * What evil have men's minds wrought... + */ +static void autoconfig_has_efr(struct uart_8250_port *up) +{ +	unsigned int id1, id2, id3, rev; + +	/* +	 * Everything with an EFR has SLEEP +	 */ +	up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; + +	/* +	 * First we check to see if it's an Oxford Semiconductor UART. +	 * +	 * If we have to do this here because some non-National +	 * Semiconductor clone chips lock up if you try writing to the +	 * LSR register (which serial_icr_read does) +	 */ + +	/* +	 * Check for Oxford Semiconductor 16C950. +	 * +	 * EFR [4] must be set else this test fails. +	 * +	 * This shouldn't be necessary, but Mike Hudson ([email protected]) +	 * claims that it's needed for 952 dual UART's (which are not +	 * recommended for new designs). +	 */ +	up->acr = 0; +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +	serial_out(up, UART_EFR, UART_EFR_ECB); +	serial_out(up, UART_LCR, 0x00); +	id1 = serial_icr_read(up, UART_ID1); +	id2 = serial_icr_read(up, UART_ID2); +	id3 = serial_icr_read(up, UART_ID3); +	rev = serial_icr_read(up, UART_REV); + +	DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev); + +	if (id1 == 0x16 && id2 == 0xC9 && +	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { +		up->port.type = PORT_16C950; + +		/* +		 * Enable work around for the Oxford Semiconductor 952 rev B +		 * chip which causes it to seriously miscalculate baud rates +		 * when DLL is 0. +		 */ +		if (id3 == 0x52 && rev == 0x01) +			up->bugs |= UART_BUG_QUOT; +		return; +	} + +	/* +	 * We check for a XR16C850 by setting DLL and DLM to 0, and then +	 * reading back DLL and DLM.  The chip type depends on the DLM +	 * value read back: +	 *  0x10 - XR16C850 and the DLL contains the chip revision. +	 *  0x12 - XR16C2850. +	 *  0x14 - XR16C854. +	 */ +	id1 = autoconfig_read_divisor_id(up); +	DEBUG_AUTOCONF("850id=%04x ", id1); + +	id2 = id1 >> 8; +	if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { +		up->port.type = PORT_16850; +		return; +	} + +	/* +	 * It wasn't an XR16C850. +	 * +	 * We distinguish between the '654 and the '650 by counting +	 * how many bytes are in the FIFO.  I'm using this for now, +	 * since that's the technique that was sent to me in the +	 * serial driver update, but I'm not convinced this works. +	 * I've had problems doing this in the past.  -TYT +	 */ +	if (size_fifo(up) == 64) +		up->port.type = PORT_16654; +	else +		up->port.type = PORT_16650V2; +} + +/* + * We detected a chip without a FIFO.  Only two fall into + * this category - the original 8250 and the 16450.  The + * 16450 has a scratch register (accessible with LCR=0) + */ +static void autoconfig_8250(struct uart_8250_port *up) +{ +	unsigned char scratch, status1, status2; + +	up->port.type = PORT_8250; + +	scratch = serial_in(up, UART_SCR); +	serial_out(up, UART_SCR, 0xa5); +	status1 = serial_in(up, UART_SCR); +	serial_out(up, UART_SCR, 0x5a); +	status2 = serial_in(up, UART_SCR); +	serial_out(up, UART_SCR, scratch); + +	if (status1 == 0xa5 && status2 == 0x5a) +		up->port.type = PORT_16450; +} + +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 +	 */ +	if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) +		return 1; + +	return 0; +} + +/* + * 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 + * we know the top two bits of the IIR are currently set.  The + * EFR should contain zero.  Try to read the EFR. + */ +static void autoconfig_16550a(struct uart_8250_port *up) +{ +	unsigned char status1, status2; +	unsigned int iersave; + +	up->port.type = PORT_16550A; +	up->capabilities |= UART_CAP_FIFO; + +	/* +	 * XR17V35x UARTs have an extra divisor register, DLD +	 * that gets enabled with when DLAB is set which will +	 * cause the device to incorrectly match and assign +	 * port type to PORT_16650.  The EFR for this UART is +	 * found at offset 0x09. Instead check the Deice ID (DVID) +	 * register for a 2, 4 or 8 port UART. +	 */ +	if (up->port.flags & UPF_EXAR_EFR) { +		status1 = serial_in(up, UART_EXAR_DVID); +		if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) { +			DEBUG_AUTOCONF("Exar XR17V35x "); +			up->port.type = PORT_XR17V35X; +			up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | +						UART_CAP_SLEEP; + +			return; +		} + +	} + +	/* +	 * Check for presence of the EFR when DLAB is set. +	 * Only ST16C650V1 UARTs pass this test. +	 */ +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); +	if (serial_in(up, UART_EFR) == 0) { +		serial_out(up, UART_EFR, 0xA8); +		if (serial_in(up, UART_EFR) != 0) { +			DEBUG_AUTOCONF("EFRv1 "); +			up->port.type = PORT_16650; +			up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; +		} else { +			serial_out(up, UART_LCR, 0); +			serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | +				   UART_FCR7_64BYTE); +			status1 = serial_in(up, UART_IIR) >> 5; +			serial_out(up, UART_FCR, 0); +			serial_out(up, UART_LCR, 0); + +			if (status1 == 7) +				up->port.type = PORT_16550A_FSL64; +			else +				DEBUG_AUTOCONF("Motorola 8xxx DUART "); +		} +		serial_out(up, UART_EFR, 0); +		return; +	} + +	/* +	 * Maybe it requires 0xbf to be written to the LCR. +	 * (other ST16C650V2 UARTs, TI16C752A, etc) +	 */ +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +	if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { +		DEBUG_AUTOCONF("EFRv2 "); +		autoconfig_has_efr(up); +		return; +	} + +	/* +	 * Check for a National Semiconductor SuperIO chip. +	 * Attempt to switch to bank 2, read the value of the LOOP bit +	 * from EXCR1. Switch back to bank 0, change it in MCR. Then +	 * switch back to bank 2, read it from EXCR1 again and check +	 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 +	 */ +	serial_out(up, UART_LCR, 0); +	status1 = serial_in(up, UART_MCR); +	serial_out(up, UART_LCR, 0xE0); +	status2 = serial_in(up, 0x02); /* EXCR1 */ + +	if (!((status2 ^ status1) & UART_MCR_LOOP)) { +		serial_out(up, UART_LCR, 0); +		serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); +		serial_out(up, UART_LCR, 0xE0); +		status2 = serial_in(up, 0x02); /* EXCR1 */ +		serial_out(up, UART_LCR, 0); +		serial_out(up, UART_MCR, status1); + +		if ((status2 ^ status1) & UART_MCR_LOOP) { +			unsigned short quot; + +			serial_out(up, UART_LCR, 0xE0); + +			quot = serial_dl_read(up); +			quot <<= 3; + +			if (ns16550a_goto_highspeed(up)) +				serial_dl_write(up, quot); + +			serial_out(up, UART_LCR, 0); + +			up->port.uartclk = 921600*16; +			up->port.type = PORT_NS16550A; +			up->capabilities |= UART_NATSEMI; +			return; +		} +	} + +	/* +	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of +	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set. +	 * Try setting it with and without DLAB set.  Cheap clones +	 * set bit 5 without DLAB set. +	 */ +	serial_out(up, UART_LCR, 0); +	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); +	status1 = serial_in(up, UART_IIR) >> 5; +	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); +	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); +	status2 = serial_in(up, UART_IIR) >> 5; +	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); +	serial_out(up, UART_LCR, 0); + +	DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); + +	if (status1 == 6 && status2 == 7) { +		up->port.type = PORT_16750; +		up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; +		return; +	} + +	/* +	 * Try writing and reading the UART_IER_UUE bit (b6). +	 * If it works, this is probably one of the Xscale platform's +	 * internal UARTs. +	 * We're going to explicitly set the UUE bit to 0 before +	 * trying to write and read a 1 just to make sure it's not +	 * already a 1 and maybe locked there before we even start start. +	 */ +	iersave = serial_in(up, UART_IER); +	serial_out(up, UART_IER, iersave & ~UART_IER_UUE); +	if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { +		/* +		 * OK it's in a known zero state, try writing and reading +		 * without disturbing the current state of the other bits. +		 */ +		serial_out(up, UART_IER, iersave | UART_IER_UUE); +		if (serial_in(up, UART_IER) & UART_IER_UUE) { +			/* +			 * It's an Xscale. +			 * We'll leave the UART_IER_UUE bit set to 1 (enabled). +			 */ +			DEBUG_AUTOCONF("Xscale "); +			up->port.type = PORT_XSCALE; +			up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; +			return; +		} +	} else { +		/* +		 * If we got here we couldn't force the IER_UUE bit to 0. +		 * Log it and continue. +		 */ +		DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); +	} +	serial_out(up, UART_IER, iersave); + +	/* +	 * Exar uarts have EFR in a weird location +	 */ +	if (up->port.flags & UPF_EXAR_EFR) { +		DEBUG_AUTOCONF("Exar XR17D15x "); +		up->port.type = PORT_XR17D15X; +		up->capabilities |= UART_CAP_AFE | UART_CAP_EFR | +				    UART_CAP_SLEEP; + +		return; +	} + +	/* +	 * We distinguish between 16550A and U6 16550A by counting +	 * how many bytes are in the FIFO. +	 */ +	if (up->port.type == PORT_16550A && size_fifo(up) == 64) { +		up->port.type = PORT_U6_16550A; +		up->capabilities |= UART_CAP_AFE; +	} +} + +/* + * This routine is called by rs_init() to initialize a specific serial + * port.  It determines what type of UART chip this serial port is + * using: 8250, 16450, 16550, 16550A.  The important question is + * 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 char status1, scratch, scratch2, scratch3; +	unsigned char save_lcr, save_mcr; +	struct uart_port *port = &up->port; +	unsigned long flags; +	unsigned int old_capabilities; + +	if (!port->iobase && !port->mapbase && !port->membase) +		return; + +	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", +		       serial_index(port), port->iobase, port->membase); + +	/* +	 * We really do need global IRQs disabled here - we're going to +	 * be frobbing the chips IRQ enable register to see if it exists. +	 */ +	spin_lock_irqsave(&port->lock, flags); + +	up->capabilities = 0; +	up->bugs = 0; + +	if (!(port->flags & UPF_BUGGY_UART)) { +		/* +		 * Do a simple existence test first; if we fail this, +		 * there's no point trying anything else. +		 * +		 * 0x80 is used as a nonsense port to prevent against +		 * false positives due to ISA bus float.  The +		 * assumption is that 0x80 is a non-existent port; +		 * which should be safe since include/asm/io.h also +		 * makes this assumption. +		 * +		 * Note: this is safe as long as MCR bit 4 is clear +		 * and the device is in "PC" mode. +		 */ +		scratch = serial_in(up, UART_IER); +		serial_out(up, UART_IER, 0); +#ifdef __i386__ +		outb(0xff, 0x080); +#endif +		/* +		 * Mask out IER[7:4] bits for test as some UARTs (e.g. TL +		 * 16C754B) allow only to modify them if an EFR bit is set. +		 */ +		scratch2 = serial_in(up, UART_IER) & 0x0f; +		serial_out(up, UART_IER, 0x0F); +#ifdef __i386__ +		outb(0, 0x080); +#endif +		scratch3 = serial_in(up, UART_IER) & 0x0f; +		serial_out(up, UART_IER, scratch); +		if (scratch2 != 0 || scratch3 != 0x0F) { +			/* +			 * We failed; there's nothing here +			 */ +			spin_unlock_irqrestore(&port->lock, flags); +			DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", +				       scratch2, scratch3); +			goto out; +		} +	} + +	save_mcr = serial_in(up, UART_MCR); +	save_lcr = serial_in(up, UART_LCR); + +	/* +	 * Check to see if a UART is really there.  Certain broken +	 * internal modems based on the Rockwell chipset fail this +	 * test, because they apparently don't implement the loopback +	 * test mode.  So this test is skipped on the COM 1 through +	 * COM 4 ports.  This *should* be safe, since no board +	 * manufacturer would be stupid enough to design a board +	 * that conflicts with COM 1-4 --- we hope! +	 */ +	if (!(port->flags & UPF_SKIP_TEST)) { +		serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); +		status1 = serial_in(up, UART_MSR) & 0xF0; +		serial_out(up, UART_MCR, save_mcr); +		if (status1 != 0x90) { +			spin_unlock_irqrestore(&port->lock, flags); +			DEBUG_AUTOCONF("LOOP test failed (%02x) ", +				       status1); +			goto out; +		} +	} + +	/* +	 * We're pretty sure there's a port here.  Lets find out what +	 * type of port it is.  The IIR top two bits allows us to find +	 * out if it's 8250 or 16450, 16550, 16550A or later.  This +	 * determines what we test for next. +	 * +	 * We also initialise the EFR (if any) to zero for later.  The +	 * EFR occupies the same register location as the FCR and IIR. +	 */ +	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); +	serial_out(up, UART_EFR, 0); +	serial_out(up, UART_LCR, 0); + +	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); +	scratch = serial_in(up, UART_IIR) >> 6; + +	switch (scratch) { +	case 0: +		autoconfig_8250(up); +		break; +	case 1: +		port->type = PORT_UNKNOWN; +		break; +	case 2: +		port->type = PORT_16550; +		break; +	case 3: +		autoconfig_16550a(up); +		break; +	} + +#ifdef CONFIG_SERIAL_8250_RSA +	/* +	 * Only probe for RSA ports if we got the region. +	 */ +	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; +	up->capabilities = uart_config[port->type].flags; +	up->tx_loadsz = uart_config[port->type].tx_loadsz; + +	if (port->type == PORT_UNKNOWN) +		goto out_lock; + +	/* +	 * Reset the UART. +	 */ +#ifdef CONFIG_SERIAL_8250_RSA +	if (port->type == PORT_RSA) +		serial_out(up, UART_RSA_FRR, 0); +#endif +	serial_out(up, UART_MCR, save_mcr); +	serial8250_clear_fifos(up); +	serial_in(up, UART_RX); +	if (up->capabilities & UART_CAP_UUE) +		serial_out(up, UART_IER, UART_IER_UUE); +	else +		serial_out(up, UART_IER, 0); + +out_lock: +	spin_unlock_irqrestore(&port->lock, flags); +	if (up->capabilities != old_capabilities) { +		printk(KERN_WARNING +		       "ttyS%d: detected caps %08x should be %08x\n", +		       serial_index(port), old_capabilities, +		       up->capabilities); +	} +out: +	DEBUG_AUTOCONF("iir=%d ", scratch); +	DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); +} + +static void autoconfig_irq(struct uart_8250_port *up) +{ +	struct uart_port *port = &up->port; +	unsigned char save_mcr, save_ier; +	unsigned char save_ICP = 0; +	unsigned int ICP = 0; +	unsigned long irqs; +	int irq; + +	if (port->flags & UPF_FOURPORT) { +		ICP = (port->iobase & 0xfe0) | 0x1f; +		save_ICP = inb_p(ICP); +		outb_p(0x80, ICP); +		inb_p(ICP); +	} + +	/* forget possible initially masked and pending IRQ */ +	probe_irq_off(probe_irq_on()); +	save_mcr = serial_in(up, UART_MCR); +	save_ier = serial_in(up, UART_IER); +	serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); + +	irqs = probe_irq_on(); +	serial_out(up, UART_MCR, 0); +	udelay(10); +	if (port->flags & UPF_FOURPORT) { +		serial_out(up, UART_MCR, +			    UART_MCR_DTR | UART_MCR_RTS); +	} else { +		serial_out(up, UART_MCR, +			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); +	} +	serial_out(up, UART_IER, 0x0f);	/* enable all intrs */ +	serial_in(up, UART_LSR); +	serial_in(up, UART_RX); +	serial_in(up, UART_IIR); +	serial_in(up, UART_MSR); +	serial_out(up, UART_TX, 0xFF); +	udelay(20); +	irq = probe_irq_off(irqs); + +	serial_out(up, UART_MCR, save_mcr); +	serial_out(up, UART_IER, save_ier); + +	if (port->flags & UPF_FOURPORT) +		outb_p(save_ICP, ICP); + +	port->irq = (irq > 0) ? irq : 0; +} + +static inline void __stop_tx(struct uart_8250_port *p) +{ +	if (p->ier & UART_IER_THRI) { +		p->ier &= ~UART_IER_THRI; +		serial_out(p, UART_IER, p->ier); +		serial8250_rpm_put_tx(p); +	} +} + +static void serial8250_stop_tx(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	serial8250_rpm_get(up); +	__stop_tx(up); + +	/* +	 * We really want to stop the transmitter from sending. +	 */ +	if (port->type == PORT_16C950) { +		up->acr |= UART_ACR_TXDIS; +		serial_icr_write(up, UART_ACR, up->acr); +	} +	serial8250_rpm_put(up); +} + +static void serial8250_start_tx(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	serial8250_rpm_get_tx(up); + +	if (up->dma && !up->dma->tx_dma(up)) +		return; + +	if (!(up->ier & UART_IER_THRI)) { +		up->ier |= UART_IER_THRI; +		serial_port_out(port, UART_IER, up->ier); + +		if (up->bugs & UART_BUG_TXEN) { +			unsigned char lsr; +			lsr = serial_in(up, UART_LSR); +			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; +			if (lsr & UART_LSR_THRE) +				serial8250_tx_chars(up); +		} +	} + +	/* +	 * Re-enable the transmitter if we disabled it. +	 */ +	if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { +		up->acr &= ~UART_ACR_TXDIS; +		serial_icr_write(up, UART_ACR, up->acr); +	} +} + +static void serial8250_throttle(struct uart_port *port) +{ +	port->throttle(port); +} + +static void serial8250_unthrottle(struct uart_port *port) +{ +	port->unthrottle(port); +} + +static void serial8250_stop_rx(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	serial8250_rpm_get(up); + +	up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); +	up->port.read_status_mask &= ~UART_LSR_DR; +	serial_port_out(port, UART_IER, up->ier); + +	serial8250_rpm_put(up); +} + +static void serial8250_disable_ms(struct uart_port *port) +{ +	struct uart_8250_port *up = +		container_of(port, struct uart_8250_port, port); + +	/* no MSR capabilities */ +	if (up->bugs & UART_BUG_NOMSR) +		return; + +	up->ier &= ~UART_IER_MSI; +	serial_port_out(port, UART_IER, up->ier); +} + +static void serial8250_enable_ms(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	/* no MSR capabilities */ +	if (up->bugs & UART_BUG_NOMSR) +		return; + +	up->ier |= UART_IER_MSI; + +	serial8250_rpm_get(up); +	serial_port_out(port, UART_IER, up->ier); +	serial8250_rpm_put(up); +} + +/* + * serial8250_rx_chars: processes according to the passed in LSR + * value, and returns the remaining LSR bits not handled + * by this Rx routine. + */ +unsigned char +serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) +{ +	struct uart_port *port = &up->port; +	unsigned char ch; +	int max_count = 256; +	char flag; + +	do { +		if (likely(lsr & UART_LSR_DR)) +			ch = serial_in(up, UART_RX); +		else +			/* +			 * Intel 82571 has a Serial Over Lan device that will +			 * set UART_LSR_BI without setting UART_LSR_DR when +			 * it receives a break. To avoid reading from the +			 * receive buffer without UART_LSR_DR bit set, we +			 * just force the read character to be 0 +			 */ +			ch = 0; + +		flag = TTY_NORMAL; +		port->icount.rx++; + +		lsr |= up->lsr_saved_flags; +		up->lsr_saved_flags = 0; + +		if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { +			if (lsr & UART_LSR_BI) { +				lsr &= ~(UART_LSR_FE | UART_LSR_PE); +				port->icount.brk++; +				/* +				 * We do the SysRQ and SAK checking +				 * here because otherwise the break +				 * may get masked by ignore_status_mask +				 * or read_status_mask. +				 */ +				if (uart_handle_break(port)) +					goto ignore_char; +			} else if (lsr & UART_LSR_PE) +				port->icount.parity++; +			else if (lsr & UART_LSR_FE) +				port->icount.frame++; +			if (lsr & UART_LSR_OE) +				port->icount.overrun++; + +			/* +			 * Mask off conditions which should be ignored. +			 */ +			lsr &= port->read_status_mask; + +			if (lsr & UART_LSR_BI) { +				DEBUG_INTR("handling break...."); +				flag = TTY_BREAK; +			} else if (lsr & UART_LSR_PE) +				flag = TTY_PARITY; +			else if (lsr & UART_LSR_FE) +				flag = TTY_FRAME; +		} +		if (uart_handle_sysrq_char(port, ch)) +			goto ignore_char; + +		uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); + +ignore_char: +		lsr = serial_in(up, UART_LSR); +	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); +	spin_unlock(&port->lock); +	tty_flip_buffer_push(&port->state->port); +	spin_lock(&port->lock); +	return lsr; +} +EXPORT_SYMBOL_GPL(serial8250_rx_chars); + +void serial8250_tx_chars(struct uart_8250_port *up) +{ +	struct uart_port *port = &up->port; +	struct circ_buf *xmit = &port->state->xmit; +	int count; + +	if (port->x_char) { +		serial_out(up, UART_TX, port->x_char); +		port->icount.tx++; +		port->x_char = 0; +		return; +	} +	if (uart_tx_stopped(port)) { +		serial8250_stop_tx(port); +		return; +	} +	if (uart_circ_empty(xmit)) { +		__stop_tx(up); +		return; +	} + +	count = up->tx_loadsz; +	do { +		serial_out(up, UART_TX, xmit->buf[xmit->tail]); +		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); +		port->icount.tx++; +		if (uart_circ_empty(xmit)) +			break; +		if (up->capabilities & UART_CAP_HFIFO) { +			if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) != +			    BOTH_EMPTY) +				break; +		} +	} while (--count > 0); + +	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) +		uart_write_wakeup(port); + +	DEBUG_INTR("THRE..."); + +	/* +	 * With RPM enabled, we have to wait until the FIFO is empty before the +	 * HW can go idle. So we get here once again with empty FIFO and disable +	 * the interrupt and RPM in __stop_tx() +	 */ +	if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM)) +		__stop_tx(up); +} +EXPORT_SYMBOL_GPL(serial8250_tx_chars); + +/* Caller holds uart port lock */ +unsigned int serial8250_modem_status(struct uart_8250_port *up) +{ +	struct uart_port *port = &up->port; +	unsigned int status = serial_in(up, UART_MSR); + +	status |= up->msr_saved_flags; +	up->msr_saved_flags = 0; +	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && +	    port->state != NULL) { +		if (status & UART_MSR_TERI) +			port->icount.rng++; +		if (status & UART_MSR_DDSR) +			port->icount.dsr++; +		if (status & UART_MSR_DDCD) +			uart_handle_dcd_change(port, status & UART_MSR_DCD); +		if (status & UART_MSR_DCTS) +			uart_handle_cts_change(port, status & UART_MSR_CTS); + +		wake_up_interruptible(&port->state->port.delta_msr_wait); +	} + +	return status; +} +EXPORT_SYMBOL_GPL(serial8250_modem_status); + +/* + * This handles the interrupt from one port. + */ +int serial8250_handle_irq(struct uart_port *port, unsigned int iir) +{ +	unsigned char status; +	unsigned long flags; +	struct uart_8250_port *up = up_to_u8250p(port); +	int dma_err = 0; + +	if (iir & UART_IIR_NO_INT) +		return 0; + +	spin_lock_irqsave(&port->lock, flags); + +	status = serial_port_in(port, UART_LSR); + +	DEBUG_INTR("status = %x...", status); + +	if (status & (UART_LSR_DR | UART_LSR_BI)) { +		if (up->dma) +			dma_err = up->dma->rx_dma(up, iir); + +		if (!up->dma || dma_err) +			status = serial8250_rx_chars(up, status); +	} +	serial8250_modem_status(up); +	if ((!up->dma || (up->dma && up->dma->tx_err)) && +	    (status & UART_LSR_THRE)) +		serial8250_tx_chars(up); + +	spin_unlock_irqrestore(&port->lock, flags); +	return 1; +} +EXPORT_SYMBOL_GPL(serial8250_handle_irq); + +static int serial8250_default_handle_irq(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned int iir; +	int ret; + +	serial8250_rpm_get(up); + +	iir = serial_port_in(port, UART_IIR); +	ret = serial8250_handle_irq(port, iir); + +	serial8250_rpm_put(up); +	return ret; +} + +/* + * These Exar UARTs have an extra interrupt indicator that could + * fire for a few unimplemented interrupts.  One of which is a + * wakeup event when coming out of sleep.  Put this here just + * to be on the safe side that these interrupts don't go unhandled. + */ +static int exar_handle_irq(struct uart_port *port) +{ +	unsigned char int0, int1, int2, int3; +	unsigned int iir = serial_port_in(port, UART_IIR); +	int ret; + +	ret = serial8250_handle_irq(port, iir); + +	if ((port->type == PORT_XR17V35X) || +	   (port->type == PORT_XR17D15X)) { +		int0 = serial_port_in(port, 0x80); +		int1 = serial_port_in(port, 0x81); +		int2 = serial_port_in(port, 0x82); +		int3 = serial_port_in(port, 0x83); +	} + +	return ret; +} + +static unsigned int serial8250_tx_empty(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned long flags; +	unsigned int lsr; + +	serial8250_rpm_get(up); + +	spin_lock_irqsave(&port->lock, flags); +	lsr = serial_port_in(port, UART_LSR); +	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; +	spin_unlock_irqrestore(&port->lock, flags); + +	serial8250_rpm_put(up); + +	return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; +} + +static unsigned int serial8250_get_mctrl(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned int status; +	unsigned int ret; + +	serial8250_rpm_get(up); +	status = serial8250_modem_status(up); +	serial8250_rpm_put(up); + +	ret = 0; +	if (status & UART_MSR_DCD) +		ret |= TIOCM_CAR; +	if (status & UART_MSR_RI) +		ret |= TIOCM_RNG; +	if (status & UART_MSR_DSR) +		ret |= TIOCM_DSR; +	if (status & UART_MSR_CTS) +		ret |= TIOCM_CTS; +	return ret; +} + +void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned char mcr = 0; + +	if (mctrl & TIOCM_RTS) +		mcr |= UART_MCR_RTS; +	if (mctrl & TIOCM_DTR) +		mcr |= UART_MCR_DTR; +	if (mctrl & TIOCM_OUT1) +		mcr |= UART_MCR_OUT1; +	if (mctrl & TIOCM_OUT2) +		mcr |= UART_MCR_OUT2; +	if (mctrl & TIOCM_LOOP) +		mcr |= UART_MCR_LOOP; + +	mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; + +	serial_port_out(port, UART_MCR, mcr); +} +EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); + +static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +	if (port->set_mctrl) +		port->set_mctrl(port, mctrl); +	else +		serial8250_do_set_mctrl(port, mctrl); +} + +static void serial8250_break_ctl(struct uart_port *port, int break_state) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned long flags; + +	serial8250_rpm_get(up); +	spin_lock_irqsave(&port->lock, flags); +	if (break_state == -1) +		up->lcr |= UART_LCR_SBC; +	else +		up->lcr &= ~UART_LCR_SBC; +	serial_port_out(port, UART_LCR, up->lcr); +	spin_unlock_irqrestore(&port->lock, flags); +	serial8250_rpm_put(up); +} + +/* + *	Wait for transmitter & holding register to empty + */ +static void wait_for_xmitr(struct uart_8250_port *up, int bits) +{ +	unsigned int status, tmout = 10000; + +	/* Wait up to 10ms for the character(s) to be sent. */ +	for (;;) { +		status = serial_in(up, UART_LSR); + +		up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; + +		if ((status & bits) == bits) +			break; +		if (--tmout == 0) +			break; +		udelay(1); +	} + +	/* Wait up to 1s for flow control if necessary */ +	if (up->port.flags & UPF_CONS_FLOW) { +		unsigned int tmout; +		for (tmout = 1000000; tmout; tmout--) { +			unsigned int msr = serial_in(up, UART_MSR); +			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; +			if (msr & UART_MSR_CTS) +				break; +			udelay(1); +			touch_nmi_watchdog(); +		} +	} +} + +#ifdef CONFIG_CONSOLE_POLL +/* + * Console polling routines for writing and reading from the uart while + * in an interrupt or debug context. + */ + +static int serial8250_get_poll_char(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned char lsr; +	int status; + +	serial8250_rpm_get(up); + +	lsr = serial_port_in(port, UART_LSR); + +	if (!(lsr & UART_LSR_DR)) { +		status = NO_POLL_CHAR; +		goto out; +	} + +	status = serial_port_in(port, UART_RX); +out: +	serial8250_rpm_put(up); +	return status; +} + + +static void serial8250_put_poll_char(struct uart_port *port, +			 unsigned char c) +{ +	unsigned int ier; +	struct uart_8250_port *up = up_to_u8250p(port); + +	serial8250_rpm_get(up); +	/* +	 *	First save the IER then disable the interrupts +	 */ +	ier = serial_port_in(port, UART_IER); +	if (up->capabilities & UART_CAP_UUE) +		serial_port_out(port, UART_IER, UART_IER_UUE); +	else +		serial_port_out(port, UART_IER, 0); + +	wait_for_xmitr(up, BOTH_EMPTY); +	/* +	 *	Send the character out. +	 */ +	serial_port_out(port, UART_TX, c); + +	/* +	 *	Finally, wait for transmitter to become empty +	 *	and restore the IER +	 */ +	wait_for_xmitr(up, BOTH_EMPTY); +	serial_port_out(port, UART_IER, ier); +	serial8250_rpm_put(up); +} + +#endif /* CONFIG_CONSOLE_POLL */ + +int serial8250_do_startup(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned long flags; +	unsigned char lsr, iir; +	int retval; + +	if (port->type == PORT_8250_CIR) +		return -ENODEV; + +	if (!port->fifosize) +		port->fifosize = uart_config[port->type].fifo_size; +	if (!up->tx_loadsz) +		up->tx_loadsz = uart_config[port->type].tx_loadsz; +	if (!up->capabilities) +		up->capabilities = uart_config[port->type].flags; +	up->mcr = 0; + +	if (port->iotype != up->cur_iotype) +		set_io_from_upio(port); + +	serial8250_rpm_get(up); +	if (port->type == PORT_16C950) { +		/* Wake up and initialize UART */ +		up->acr = 0; +		serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); +		serial_port_out(port, UART_EFR, UART_EFR_ECB); +		serial_port_out(port, UART_IER, 0); +		serial_port_out(port, UART_LCR, 0); +		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ +		serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); +		serial_port_out(port, UART_EFR, UART_EFR_ECB); +		serial_port_out(port, UART_LCR, 0); +	} + +#ifdef CONFIG_SERIAL_8250_RSA +	/* +	 * If this is an RSA port, see if we can kick it up to the +	 * higher speed clock. +	 */ +	enable_rsa(up); +#endif + +	if (port->type == PORT_XR17V35X) { +		/* +		 * First enable access to IER [7:5], ISR [5:4], FCR [5:4], +		 * MCR [7:5] and MSR [7:0] +		 */ +		serial_port_out(port, UART_XR_EFR, UART_EFR_ECB); + +		/* +		 * Make sure all interrups are masked until initialization is +		 * complete and the FIFOs are cleared +		 */ +		serial_port_out(port, UART_IER, 0); +	} + +	/* +	 * Clear the FIFO buffers and disable them. +	 * (they will be reenabled in set_termios()) +	 */ +	serial8250_clear_fifos(up); + +	/* +	 * Clear the interrupt registers. +	 */ +	serial_port_in(port, UART_LSR); +	serial_port_in(port, UART_RX); +	serial_port_in(port, UART_IIR); +	serial_port_in(port, UART_MSR); + +	/* +	 * At this point, there's no way the LSR could still be 0xff; +	 * if it is, then bail out, because there's likely no UART +	 * here. +	 */ +	if (!(port->flags & UPF_BUGGY_UART) && +	    (serial_port_in(port, UART_LSR) == 0xff)) { +		printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", +				   serial_index(port)); +		retval = -ENODEV; +		goto out; +	} + +	/* +	 * For a XR16C850, we need to set the trigger levels +	 */ +	if (port->type == PORT_16850) { +		unsigned char fctr; + +		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + +		fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); +		serial_port_out(port, UART_FCTR, +				fctr | UART_FCTR_TRGD | UART_FCTR_RX); +		serial_port_out(port, UART_TRG, UART_TRG_96); +		serial_port_out(port, UART_FCTR, +				fctr | UART_FCTR_TRGD | UART_FCTR_TX); +		serial_port_out(port, UART_TRG, UART_TRG_96); + +		serial_port_out(port, UART_LCR, 0); +	} + +	if (port->irq) { +		unsigned char iir1; +		/* +		 * Test for UARTs that do not reassert THRE when the +		 * transmitter is idle and the interrupt has already +		 * been cleared.  Real 16550s should always reassert +		 * this interrupt whenever the transmitter is idle and +		 * the interrupt is enabled.  Delays are necessary to +		 * allow register changes to become visible. +		 */ +		spin_lock_irqsave(&port->lock, flags); +		if (up->port.irqflags & IRQF_SHARED) +			disable_irq_nosync(port->irq); + +		wait_for_xmitr(up, UART_LSR_THRE); +		serial_port_out_sync(port, UART_IER, UART_IER_THRI); +		udelay(1); /* allow THRE to set */ +		iir1 = serial_port_in(port, UART_IIR); +		serial_port_out(port, UART_IER, 0); +		serial_port_out_sync(port, UART_IER, UART_IER_THRI); +		udelay(1); /* allow a working UART time to re-assert THRE */ +		iir = serial_port_in(port, UART_IIR); +		serial_port_out(port, UART_IER, 0); + +		if (port->irqflags & IRQF_SHARED) +			enable_irq(port->irq); +		spin_unlock_irqrestore(&port->lock, flags); + +		/* +		 * If the interrupt is not reasserted, or we otherwise +		 * don't trust the iir, setup a timer to kick the UART +		 * on a regular basis. +		 */ +		if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || +		    up->port.flags & UPF_BUG_THRE) { +			up->bugs |= UART_BUG_THRE; +		} +	} + +	retval = up->ops->setup_irq(up); +	if (retval) +		goto out; + +	/* +	 * Now, initialize the UART +	 */ +	serial_port_out(port, UART_LCR, UART_LCR_WLEN8); + +	spin_lock_irqsave(&port->lock, flags); +	if (up->port.flags & UPF_FOURPORT) { +		if (!up->port.irq) +			up->port.mctrl |= TIOCM_OUT1; +	} else +		/* +		 * Most PC uarts need OUT2 raised to enable interrupts. +		 */ +		if (port->irq) +			up->port.mctrl |= TIOCM_OUT2; + +	serial8250_set_mctrl(port, port->mctrl); + +	/* Serial over Lan (SoL) hack: +	   Intel 8257x Gigabit ethernet chips have a +	   16550 emulation, to be used for Serial Over Lan. +	   Those chips take a longer time than a normal +	   serial device to signalize that a transmission +	   data was queued. Due to that, the above test generally +	   fails. One solution would be to delay the reading of +	   iir. However, this is not reliable, since the timeout +	   is variable. So, let's just don't test if we receive +	   TX irq. This way, we'll never enable UART_BUG_TXEN. +	 */ +	if (up->port.flags & UPF_NO_TXEN_TEST) +		goto dont_test_tx_en; + +	/* +	 * Do a quick test to see if we receive an +	 * interrupt when we enable the TX irq. +	 */ +	serial_port_out(port, UART_IER, UART_IER_THRI); +	lsr = serial_port_in(port, UART_LSR); +	iir = serial_port_in(port, UART_IIR); +	serial_port_out(port, UART_IER, 0); + +	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { +		if (!(up->bugs & UART_BUG_TXEN)) { +			up->bugs |= UART_BUG_TXEN; +			pr_debug("ttyS%d - enabling bad tx status workarounds\n", +				 serial_index(port)); +		} +	} else { +		up->bugs &= ~UART_BUG_TXEN; +	} + +dont_test_tx_en: +	spin_unlock_irqrestore(&port->lock, flags); + +	/* +	 * Clear the interrupt registers again for luck, and clear the +	 * saved flags to avoid getting false values from polling +	 * routines or the previous session. +	 */ +	serial_port_in(port, UART_LSR); +	serial_port_in(port, UART_RX); +	serial_port_in(port, UART_IIR); +	serial_port_in(port, UART_MSR); +	up->lsr_saved_flags = 0; +	up->msr_saved_flags = 0; + +	/* +	 * Request DMA channels for both RX and TX. +	 */ +	if (up->dma) { +		retval = serial8250_request_dma(up); +		if (retval) { +			pr_warn_ratelimited("ttyS%d - failed to request DMA\n", +					    serial_index(port)); +			up->dma = NULL; +		} +	} + +	/* +	 * Set the IER shadow for rx interrupts but defer actual interrupt +	 * enable until after the FIFOs are enabled; otherwise, an already- +	 * active sender can swamp the interrupt handler with "too much work". +	 */ +	up->ier = UART_IER_RLSI | UART_IER_RDI; + +	if (port->flags & UPF_FOURPORT) { +		unsigned int icp; +		/* +		 * Enable interrupts on the AST Fourport board +		 */ +		icp = (port->iobase & 0xfe0) | 0x01f; +		outb_p(0x80, icp); +		inb_p(icp); +	} +	retval = 0; +out: +	serial8250_rpm_put(up); +	return retval; +} +EXPORT_SYMBOL_GPL(serial8250_do_startup); + +static int serial8250_startup(struct uart_port *port) +{ +	if (port->startup) +		return port->startup(port); +	return serial8250_do_startup(port); +} + +void serial8250_do_shutdown(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned long flags; + +	serial8250_rpm_get(up); +	/* +	 * Disable interrupts from this port +	 */ +	up->ier = 0; +	serial_port_out(port, UART_IER, 0); + +	if (up->dma) +		serial8250_release_dma(up); + +	spin_lock_irqsave(&port->lock, flags); +	if (port->flags & UPF_FOURPORT) { +		/* reset interrupts on the AST Fourport board */ +		inb((port->iobase & 0xfe0) | 0x1f); +		port->mctrl |= TIOCM_OUT1; +	} else +		port->mctrl &= ~TIOCM_OUT2; + +	serial8250_set_mctrl(port, port->mctrl); +	spin_unlock_irqrestore(&port->lock, flags); + +	/* +	 * Disable break condition and FIFOs +	 */ +	serial_port_out(port, UART_LCR, +			serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); +	serial8250_clear_fifos(up); + +#ifdef CONFIG_SERIAL_8250_RSA +	/* +	 * Reset the RSA board back to 115kbps compat mode. +	 */ +	disable_rsa(up); +#endif + +	/* +	 * Read data port to reset things, and then unlink from +	 * the IRQ chain. +	 */ +	serial_port_in(port, UART_RX); +	serial8250_rpm_put(up); + +	up->ops->release_irq(up); +} +EXPORT_SYMBOL_GPL(serial8250_do_shutdown); + +static void serial8250_shutdown(struct uart_port *port) +{ +	if (port->shutdown) +		port->shutdown(port); +	else +		serial8250_do_shutdown(port); +} + +/* + * XR17V35x UARTs have an extra fractional divisor register (DLD) + * Calculate divisor with extra 4-bit fractional portion + */ +static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up, +					 unsigned int baud, +					 unsigned int *frac) +{ +	struct uart_port *port = &up->port; +	unsigned int quot_16; + +	quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud); +	*frac = quot_16 & 0x0f; + +	return quot_16 >> 4; +} + +static unsigned int serial8250_get_divisor(struct uart_8250_port *up, +					   unsigned int baud, +					   unsigned int *frac) +{ +	struct uart_port *port = &up->port; +	unsigned int quot; + +	/* +	 * Handle magic divisors for baud rates above baud_base on +	 * SMSC SuperIO chips. +	 * +	 */ +	if ((port->flags & UPF_MAGIC_MULTIPLIER) && +	    baud == (port->uartclk/4)) +		quot = 0x8001; +	else if ((port->flags & UPF_MAGIC_MULTIPLIER) && +		 baud == (port->uartclk/8)) +		quot = 0x8002; +	else if (up->port.type == PORT_XR17V35X) +		quot = xr17v35x_get_divisor(up, baud, frac); +	else +		quot = uart_get_divisor(port, baud); + +	/* +	 * Oxford Semi 952 rev B workaround +	 */ +	if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) +		quot++; + +	return quot; +} + +static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, +					    tcflag_t c_cflag) +{ +	unsigned char cval; + +	switch (c_cflag & CSIZE) { +	case CS5: +		cval = UART_LCR_WLEN5; +		break; +	case CS6: +		cval = UART_LCR_WLEN6; +		break; +	case CS7: +		cval = UART_LCR_WLEN7; +		break; +	default: +	case CS8: +		cval = UART_LCR_WLEN8; +		break; +	} + +	if (c_cflag & CSTOPB) +		cval |= UART_LCR_STOP; +	if (c_cflag & PARENB) { +		cval |= UART_LCR_PARITY; +		if (up->bugs & UART_BUG_PARITY) +			up->fifo_bug = true; +	} +	if (!(c_cflag & PARODD)) +		cval |= UART_LCR_EPAR; +#ifdef CMSPAR +	if (c_cflag & CMSPAR) +		cval |= UART_LCR_SPAR; +#endif + +	return cval; +} + +static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, +			    unsigned int quot, unsigned int quot_frac) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	/* Workaround to enable 115200 baud on OMAP1510 internal ports */ +	if (is_omap1510_8250(up)) { +		if (baud == 115200) { +			quot = 1; +			serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); +		} else +			serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); +	} + +	/* +	 * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, +	 * otherwise just set DLAB +	 */ +	if (up->capabilities & UART_NATSEMI) +		serial_port_out(port, UART_LCR, 0xe0); +	else +		serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); + +	serial_dl_write(up, quot); + +	/* XR17V35x UARTs have an extra fractional divisor register (DLD) */ +	if (up->port.type == PORT_XR17V35X) +		serial_port_out(port, 0x2, quot_frac); +} + +void +serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, +		          struct ktermios *old) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	unsigned char cval; +	unsigned long flags; +	unsigned int baud, quot, frac = 0; + +	cval = serial8250_compute_lcr(up, termios->c_cflag); + +	/* +	 * Ask the core to calculate the divisor for us. +	 */ +	baud = uart_get_baud_rate(port, termios, old, +				  port->uartclk / 16 / 0xffff, +				  port->uartclk / 16); +	quot = serial8250_get_divisor(up, baud, &frac); + +	/* +	 * Ok, we're now changing the port state.  Do it with +	 * interrupts disabled. +	 */ +	serial8250_rpm_get(up); +	spin_lock_irqsave(&port->lock, flags); + +	up->lcr = cval;					/* Save computed LCR */ + +	if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { +		/* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ +		if ((baud < 2400 && !up->dma) || up->fifo_bug) { +			up->fcr &= ~UART_FCR_TRIGGER_MASK; +			up->fcr |= UART_FCR_TRIGGER_1; +		} +	} + +	/* +	 * MCR-based auto flow control.  When AFE is enabled, RTS will be +	 * deasserted when the receive FIFO contains more characters than +	 * the trigger, or the MCR RTS bit is cleared.  In the case where +	 * the remote UART is not using CTS auto flow control, we must +	 * have sufficient FIFO entries for the latency of the remote +	 * UART to respond.  IOW, at least 32 bytes of FIFO. +	 */ +	if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { +		up->mcr &= ~UART_MCR_AFE; +		if (termios->c_cflag & CRTSCTS) +			up->mcr |= UART_MCR_AFE; +	} + +	/* +	 * Update the per-port timeout. +	 */ +	uart_update_timeout(port, termios->c_cflag, baud); + +	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; +	if (termios->c_iflag & INPCK) +		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; +	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) +		port->read_status_mask |= UART_LSR_BI; + +	/* +	 * Characteres to ignore +	 */ +	port->ignore_status_mask = 0; +	if (termios->c_iflag & IGNPAR) +		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; +	if (termios->c_iflag & IGNBRK) { +		port->ignore_status_mask |= UART_LSR_BI; +		/* +		 * If we're ignoring parity and break indicators, +		 * ignore overruns too (for real raw support). +		 */ +		if (termios->c_iflag & IGNPAR) +			port->ignore_status_mask |= UART_LSR_OE; +	} + +	/* +	 * ignore all characters if CREAD is not set +	 */ +	if ((termios->c_cflag & CREAD) == 0) +		port->ignore_status_mask |= UART_LSR_DR; + +	/* +	 * CTS flow control flag and modem status interrupts +	 */ +	up->ier &= ~UART_IER_MSI; +	if (!(up->bugs & UART_BUG_NOMSR) && +			UART_ENABLE_MS(&up->port, termios->c_cflag)) +		up->ier |= UART_IER_MSI; +	if (up->capabilities & UART_CAP_UUE) +		up->ier |= UART_IER_UUE; +	if (up->capabilities & UART_CAP_RTOIE) +		up->ier |= UART_IER_RTOIE; + +	serial_port_out(port, UART_IER, up->ier); + +	if (up->capabilities & UART_CAP_EFR) { +		unsigned char efr = 0; +		/* +		 * TI16C752/Startech hardware flow control.  FIXME: +		 * - TI16C752 requires control thresholds to be set. +		 * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. +		 */ +		if (termios->c_cflag & CRTSCTS) +			efr |= UART_EFR_CTS; + +		serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); +		if (port->flags & UPF_EXAR_EFR) +			serial_port_out(port, UART_XR_EFR, efr); +		else +			serial_port_out(port, UART_EFR, efr); +	} + +	serial8250_set_divisor(port, baud, quot, frac); + +	/* +	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR +	 * is written without DLAB set, this mode will be disabled. +	 */ +	if (port->type == PORT_16750) +		serial_port_out(port, UART_FCR, up->fcr); + +	serial_port_out(port, UART_LCR, up->lcr);	/* reset DLAB */ +	if (port->type != PORT_16750) { +		/* emulated UARTs (Lucent Venus 167x) need two steps */ +		if (up->fcr & UART_FCR_ENABLE_FIFO) +			serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); +		serial_port_out(port, UART_FCR, up->fcr);	/* set fcr */ +	} +	serial8250_set_mctrl(port, port->mctrl); +	spin_unlock_irqrestore(&port->lock, flags); +	serial8250_rpm_put(up); + +	/* Don't rewrite B0 */ +	if (tty_termios_baud_rate(termios)) +		tty_termios_encode_baud_rate(termios, baud, baud); +} +EXPORT_SYMBOL(serial8250_do_set_termios); + +static void +serial8250_set_termios(struct uart_port *port, struct ktermios *termios, +		       struct ktermios *old) +{ +	if (port->set_termios) +		port->set_termios(port, termios, old); +	else +		serial8250_do_set_termios(port, termios, old); +} + +static void +serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) +{ +	if (termios->c_line == N_PPS) { +		port->flags |= UPF_HARDPPS_CD; +		spin_lock_irq(&port->lock); +		serial8250_enable_ms(port); +		spin_unlock_irq(&port->lock); +	} else { +		port->flags &= ~UPF_HARDPPS_CD; +		if (!UART_ENABLE_MS(port, termios->c_cflag)) { +			spin_lock_irq(&port->lock); +			serial8250_disable_ms(port); +			spin_unlock_irq(&port->lock); +		} +	} +} + + +void serial8250_do_pm(struct uart_port *port, unsigned int state, +		      unsigned int oldstate) +{ +	struct uart_8250_port *p = up_to_u8250p(port); + +	serial8250_set_sleep(p, state != 0); +} +EXPORT_SYMBOL(serial8250_do_pm); + +static void +serial8250_pm(struct uart_port *port, unsigned int state, +	      unsigned int oldstate) +{ +	if (port->pm) +		port->pm(port, state, oldstate); +	else +		serial8250_do_pm(port, state, oldstate); +} + +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; +		return 0x1000; +	} +	if (is_omap1_8250(pt)) +		return 0x16 << pt->port.regshift; + +	return 8 << pt->port.regshift; +} + +/* + * Resource handling. + */ +static int serial8250_request_std_resource(struct uart_8250_port *up) +{ +	unsigned int size = serial8250_port_size(up); +	struct uart_port *port = &up->port; +	int ret = 0; + +	switch (port->iotype) { +	case UPIO_AU: +	case UPIO_TSI: +	case UPIO_MEM32: +	case UPIO_MEM32BE: +	case UPIO_MEM: +		if (!port->mapbase) +			break; + +		if (!request_mem_region(port->mapbase, size, "serial")) { +			ret = -EBUSY; +			break; +		} + +		if (port->flags & UPF_IOREMAP) { +			port->membase = ioremap_nocache(port->mapbase, size); +			if (!port->membase) { +				release_mem_region(port->mapbase, size); +				ret = -ENOMEM; +			} +		} +		break; + +	case UPIO_HUB6: +	case UPIO_PORT: +		if (!request_region(port->iobase, size, "serial")) +			ret = -EBUSY; +		break; +	} +	return ret; +} + +static void serial8250_release_std_resource(struct uart_8250_port *up) +{ +	unsigned int size = serial8250_port_size(up); +	struct uart_port *port = &up->port; + +	switch (port->iotype) { +	case UPIO_AU: +	case UPIO_TSI: +	case UPIO_MEM32: +	case UPIO_MEM32BE: +	case UPIO_MEM: +		if (!port->mapbase) +			break; + +		if (port->flags & UPF_IOREMAP) { +			iounmap(port->membase); +			port->membase = NULL; +		} + +		release_mem_region(port->mapbase, size); +		break; + +	case UPIO_HUB6: +	case UPIO_PORT: +		release_region(port->iobase, size); +		break; +	} +} + +static void serial8250_release_port(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	serial8250_release_std_resource(up); +} + +static int serial8250_request_port(struct uart_port *port) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	int ret; + +	if (port->type == PORT_8250_CIR) +		return -ENODEV; + +	ret = serial8250_request_std_resource(up); + +	return ret; +} + +static int fcr_get_rxtrig_bytes(struct uart_8250_port *up) +{ +	const struct serial8250_config *conf_type = &uart_config[up->port.type]; +	unsigned char bytes; + +	bytes = conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)]; + +	return bytes ? bytes : -EOPNOTSUPP; +} + +static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes) +{ +	const struct serial8250_config *conf_type = &uart_config[up->port.type]; +	int i; + +	if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)]) +		return -EOPNOTSUPP; + +	for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) { +		if (bytes < conf_type->rxtrig_bytes[i]) +			/* Use the nearest lower value */ +			return (--i) << UART_FCR_R_TRIG_SHIFT; +	} + +	return UART_FCR_R_TRIG_11; +} + +static int do_get_rxtrig(struct tty_port *port) +{ +	struct uart_state *state = container_of(port, struct uart_state, port); +	struct uart_port *uport = state->uart_port; +	struct uart_8250_port *up = +		container_of(uport, struct uart_8250_port, port); + +	if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) +		return -EINVAL; + +	return fcr_get_rxtrig_bytes(up); +} + +static int do_serial8250_get_rxtrig(struct tty_port *port) +{ +	int rxtrig_bytes; + +	mutex_lock(&port->mutex); +	rxtrig_bytes = do_get_rxtrig(port); +	mutex_unlock(&port->mutex); + +	return rxtrig_bytes; +} + +static ssize_t serial8250_get_attr_rx_trig_bytes(struct device *dev, +	struct device_attribute *attr, char *buf) +{ +	struct tty_port *port = dev_get_drvdata(dev); +	int rxtrig_bytes; + +	rxtrig_bytes = do_serial8250_get_rxtrig(port); +	if (rxtrig_bytes < 0) +		return rxtrig_bytes; + +	return snprintf(buf, PAGE_SIZE, "%d\n", rxtrig_bytes); +} + +static int do_set_rxtrig(struct tty_port *port, unsigned char bytes) +{ +	struct uart_state *state = container_of(port, struct uart_state, port); +	struct uart_port *uport = state->uart_port; +	struct uart_8250_port *up = +		container_of(uport, struct uart_8250_port, port); +	int rxtrig; + +	if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || +	    up->fifo_bug) +		return -EINVAL; + +	rxtrig = bytes_to_fcr_rxtrig(up, bytes); +	if (rxtrig < 0) +		return rxtrig; + +	serial8250_clear_fifos(up); +	up->fcr &= ~UART_FCR_TRIGGER_MASK; +	up->fcr |= (unsigned char)rxtrig; +	serial_out(up, UART_FCR, up->fcr); +	return 0; +} + +static int do_serial8250_set_rxtrig(struct tty_port *port, unsigned char bytes) +{ +	int ret; + +	mutex_lock(&port->mutex); +	ret = do_set_rxtrig(port, bytes); +	mutex_unlock(&port->mutex); + +	return ret; +} + +static ssize_t serial8250_set_attr_rx_trig_bytes(struct device *dev, +	struct device_attribute *attr, const char *buf, size_t count) +{ +	struct tty_port *port = dev_get_drvdata(dev); +	unsigned char bytes; +	int ret; + +	if (!count) +		return -EINVAL; + +	ret = kstrtou8(buf, 10, &bytes); +	if (ret < 0) +		return ret; + +	ret = do_serial8250_set_rxtrig(port, bytes); +	if (ret < 0) +		return ret; + +	return count; +} + +static DEVICE_ATTR(rx_trig_bytes, S_IRUSR | S_IWUSR | S_IRGRP, +		   serial8250_get_attr_rx_trig_bytes, +		   serial8250_set_attr_rx_trig_bytes); + +static struct attribute *serial8250_dev_attrs[] = { +	&dev_attr_rx_trig_bytes.attr, +	NULL, +	}; + +static struct attribute_group serial8250_dev_attr_group = { +	.attrs = serial8250_dev_attrs, +	}; + +static void register_dev_spec_attr_grp(struct uart_8250_port *up) +{ +	const struct serial8250_config *conf_type = &uart_config[up->port.type]; + +	if (conf_type->rxtrig_bytes[0]) +		up->port.attr_group = &serial8250_dev_attr_group; +} + +static void serial8250_config_port(struct uart_port *port, int flags) +{ +	struct uart_8250_port *up = up_to_u8250p(port); +	int ret; + +	if (port->type == PORT_8250_CIR) +		return; + +	/* +	 * Find the region that we can probe for.  This in turn +	 * tells us whether we can probe for the type of port. +	 */ +	ret = serial8250_request_std_resource(up); +	if (ret < 0) +		return; + +	if (port->iotype != up->cur_iotype) +		set_io_from_upio(port); + +	if (flags & UART_CONFIG_TYPE) +		autoconfig(up); + +	/* if access method is AU, it is a 16550 with a quirk */ +	if (port->type == PORT_16550A && port->iotype == UPIO_AU) +		up->bugs |= UART_BUG_NOMSR; + +	/* HW bugs may trigger IRQ while IIR == NO_INT */ +	if (port->type == PORT_TEGRA) +		up->bugs |= UART_BUG_NOMSR; + +	if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) +		autoconfig_irq(up); + +	if (port->type == PORT_UNKNOWN) +		serial8250_release_std_resource(up); + +	/* Fixme: probably not the best place for this */ +	if ((port->type == PORT_XR17V35X) || +	   (port->type == PORT_XR17D15X)) +		port->handle_irq = exar_handle_irq; + +	register_dev_spec_attr_grp(up); +	up->fcr = uart_config[up->port.type].fcr; +} + +static int +serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) +{ +	if (ser->irq >= nr_irqs || ser->irq < 0 || +	    ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || +	    ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || +	    ser->type == PORT_STARTECH) +		return -EINVAL; +	return 0; +} + +static const char * +serial8250_type(struct uart_port *port) +{ +	int type = port->type; + +	if (type >= ARRAY_SIZE(uart_config)) +		type = 0; +	return uart_config[type].name; +} + +static const struct uart_ops serial8250_pops = { +	.tx_empty	= serial8250_tx_empty, +	.set_mctrl	= serial8250_set_mctrl, +	.get_mctrl	= serial8250_get_mctrl, +	.stop_tx	= serial8250_stop_tx, +	.start_tx	= serial8250_start_tx, +	.throttle	= serial8250_throttle, +	.unthrottle	= serial8250_unthrottle, +	.stop_rx	= serial8250_stop_rx, +	.enable_ms	= serial8250_enable_ms, +	.break_ctl	= serial8250_break_ctl, +	.startup	= serial8250_startup, +	.shutdown	= serial8250_shutdown, +	.set_termios	= serial8250_set_termios, +	.set_ldisc	= serial8250_set_ldisc, +	.pm		= serial8250_pm, +	.type		= serial8250_type, +	.release_port	= serial8250_release_port, +	.request_port	= serial8250_request_port, +	.config_port	= serial8250_config_port, +	.verify_port	= serial8250_verify_port, +#ifdef CONFIG_CONSOLE_POLL +	.poll_get_char = serial8250_get_poll_char, +	.poll_put_char = serial8250_put_poll_char, +#endif +}; + +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; +} +EXPORT_SYMBOL_GPL(serial8250_init_port); + +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; +	} +} +EXPORT_SYMBOL_GPL(serial8250_set_defaults); + +#ifdef CONFIG_SERIAL_8250_CONSOLE + +static void serial8250_console_putchar(struct uart_port *port, int ch) +{ +	struct uart_8250_port *up = up_to_u8250p(port); + +	wait_for_xmitr(up, UART_LSR_THRE); +	serial_port_out(port, UART_TX, ch); +} + +/* + *	Print a string to the serial port trying not to disturb + *	any possible real use of the port... + * + *	The console_lock must be held when we get here. + */ +void serial8250_console_write(struct uart_8250_port *up, const char *s, +			      unsigned int count) +{ +	struct uart_port *port = &up->port; +	unsigned long flags; +	unsigned int ier; +	int locked = 1; + +	touch_nmi_watchdog(); + +	serial8250_rpm_get(up); + +	if (port->sysrq) +		locked = 0; +	else if (oops_in_progress) +		locked = spin_trylock_irqsave(&port->lock, flags); +	else +		spin_lock_irqsave(&port->lock, flags); + +	/* +	 *	First save the IER then disable the interrupts +	 */ +	ier = serial_port_in(port, UART_IER); + +	if (up->capabilities & UART_CAP_UUE) +		serial_port_out(port, UART_IER, UART_IER_UUE); +	else +		serial_port_out(port, UART_IER, 0); + +	/* check scratch reg to see if port powered off during system sleep */ +	if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { +		struct ktermios termios; +		unsigned int baud, quot, frac = 0; + +		termios.c_cflag = port->cons->cflag; +		if (port->state->port.tty && termios.c_cflag == 0) +			termios.c_cflag = port->state->port.tty->termios.c_cflag; + +		baud = uart_get_baud_rate(port, &termios, NULL, +					  port->uartclk / 16 / 0xffff, +					  port->uartclk / 16); +		quot = serial8250_get_divisor(up, baud, &frac); + +		serial8250_set_divisor(port, baud, quot, frac); +		serial_port_out(port, UART_LCR, up->lcr); +		serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); + +		up->canary = 0; +	} + +	uart_console_write(port, s, count, serial8250_console_putchar); + +	/* +	 *	Finally, wait for transmitter to become empty +	 *	and restore the IER +	 */ +	wait_for_xmitr(up, BOTH_EMPTY); +	serial_port_out(port, UART_IER, ier); + +	/* +	 *	The receive handling will happen properly because the +	 *	receive ready bit will still be set; it is not cleared +	 *	on read.  However, modem control will not, we must +	 *	call it if we have saved something in the saved flags +	 *	while processing with interrupts off. +	 */ +	if (up->msr_saved_flags) +		serial8250_modem_status(up); + +	if (locked) +		spin_unlock_irqrestore(&port->lock, flags); +	serial8250_rpm_put(up); +} + +static unsigned int probe_baud(struct uart_port *port) +{ +	unsigned char lcr, dll, dlm; +	unsigned int quot; + +	lcr = serial_port_in(port, UART_LCR); +	serial_port_out(port, UART_LCR, lcr | UART_LCR_DLAB); +	dll = serial_port_in(port, UART_DLL); +	dlm = serial_port_in(port, UART_DLM); +	serial_port_out(port, UART_LCR, lcr); + +	quot = (dlm << 8) | dll; +	return (port->uartclk / 16) / quot; +} + +int serial8250_console_setup(struct uart_port *port, char *options, bool probe) +{ +	int baud = 9600; +	int bits = 8; +	int parity = 'n'; +	int flow = 'n'; + +	if (!port->iobase && !port->membase) +		return -ENODEV; + +	if (options) +		uart_parse_options(options, &baud, &parity, &bits, &flow); +	else if (probe) +		baud = probe_baud(port); + +	return uart_set_options(port, port->cons, baud, parity, bits, flow); +} + +#endif /* CONFIG_SERIAL_8250_CONSOLE */ diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 7d79425c2b09..d11621e2cf1d 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -218,6 +218,7 @@ static int uniphier_uart_probe(struct platform_device *pdev)  	ret = serial8250_register_8250_port(&up);  	if (ret < 0) {  		dev_err(dev, "failed to register 8250 port\n"); +		clk_disable_unprepare(priv->clk);  		return ret;  	} diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 706295913c34..39c6d2277570 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -2,10 +2,11 @@  # Makefile for the 8250 serial device drivers.  # -obj-$(CONFIG_SERIAL_8250)		+= 8250.o +obj-$(CONFIG_SERIAL_8250)		+= 8250.o 8250_base.o  8250-y					:= 8250_core.o  8250-$(CONFIG_SERIAL_8250_PNP)		+= 8250_pnp.o -8250-$(CONFIG_SERIAL_8250_DMA)		+= 8250_dma.o +8250_base-y				:= 8250_port.o +8250_base-$(CONFIG_SERIAL_8250_DMA)	+= 8250_dma.o  obj-$(CONFIG_SERIAL_8250_GSC)		+= 8250_gsc.o  obj-$(CONFIG_SERIAL_8250_PCI)		+= 8250_pci.o  obj-$(CONFIG_SERIAL_8250_HP300)		+= 8250_hp300.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 76e65b714471..687b1ea294b7 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -594,7 +594,7 @@ config SERIAL_IMX_CONSOLE  config SERIAL_UARTLITE  	tristate "Xilinx uartlite serial port support" -	depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE || ARCH_ZYNQ +	depends on HAS_IOMEM  	select SERIAL_CORE  	help  	  Say Y here if you want to use the Xilinx uartlite serial controller. @@ -1067,6 +1067,7 @@ config SERIAL_ETRAXFS  	bool "ETRAX FS serial port support"  	depends on ETRAX_ARCH_V32 && OF  	select SERIAL_CORE +	select SERIAL_MCTRL_GPIO if GPIOLIB  config SERIAL_ETRAXFS_CONSOLE  	bool "ETRAX FS serial console support" @@ -1185,7 +1186,7 @@ config SERIAL_SC16IS7XX_CORE  config SERIAL_SC16IS7XX          tristate "SC16IS7xx serial support"          select SERIAL_CORE -        depends on I2C || SPI_MASTER +        depends on (SPI_MASTER && !I2C) || I2C          help            This selects support for SC16IS7xx serial ports.            Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752, @@ -1376,7 +1377,8 @@ config SERIAL_ALTERA_UART_CONSOLE  config SERIAL_IFX6X60          tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" -	depends on GPIOLIB && SPI && HAS_DMA +	depends on GPIOLIB || COMPILE_TEST +	depends on SPI && HAS_DMA  	help  	  Support for the IFX6x60 modem devices on Intel MID platforms. diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 50cf5b10ceed..fd27e986b1dd 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2310,8 +2310,8 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,  	void __iomem *base;  	base = devm_ioremap_resource(dev, mmiobase); -	if (!base) -		return -ENOMEM; +	if (IS_ERR(base)) +		return PTR_ERR(base);  	index = pl011_probe_dt_alias(index, dev); diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 2a8f528153e7..5ca5cf3e9359 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -56,6 +56,15 @@  /* Revisit: We should calculate this based on the actual port settings */  #define PDC_RX_TIMEOUT		(3 * 10)		/* 3 bytes */ +/* The minium number of data FIFOs should be able to contain */ +#define ATMEL_MIN_FIFO_SIZE	8 +/* + * These two offsets are substracted from the RX FIFO size to define the RTS + * high and low thresholds + */ +#define ATMEL_RTS_HIGH_OFFSET	16 +#define ATMEL_RTS_LOW_OFFSET	20 +  #if defined(CONFIG_SERIAL_ATMEL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)  #define SUPPORT_SYSRQ  #endif @@ -88,37 +97,6 @@ static void atmel_stop_rx(struct uart_port *port);  #define ATMEL_ISR_PASS_LIMIT	256 -/* UART registers. CR is write-only, hence no GET macro */ -#define UART_PUT_CR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_CR) -#define UART_GET_MR(port)	__raw_readl((port)->membase + ATMEL_US_MR) -#define UART_PUT_MR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_MR) -#define UART_PUT_IER(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_IER) -#define UART_PUT_IDR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_IDR) -#define UART_GET_IMR(port)	__raw_readl((port)->membase + ATMEL_US_IMR) -#define UART_GET_CSR(port)	__raw_readl((port)->membase + ATMEL_US_CSR) -#define UART_GET_CHAR(port)	__raw_readl((port)->membase + ATMEL_US_RHR) -#define UART_PUT_CHAR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_THR) -#define UART_GET_BRGR(port)	__raw_readl((port)->membase + ATMEL_US_BRGR) -#define UART_PUT_BRGR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_BRGR) -#define UART_PUT_RTOR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_RTOR) -#define UART_PUT_TTGR(port, v)	__raw_writel(v, (port)->membase + ATMEL_US_TTGR) -#define UART_GET_IP_NAME(port)	__raw_readl((port)->membase + ATMEL_US_NAME) -#define UART_GET_IP_VERSION(port) __raw_readl((port)->membase + ATMEL_US_VERSION) - - /* PDC registers */ -#define UART_PUT_PTCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) -#define UART_GET_PTSR(port)	__raw_readl((port)->membase + ATMEL_PDC_PTSR) - -#define UART_PUT_RPR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_RPR) -#define UART_GET_RPR(port)	__raw_readl((port)->membase + ATMEL_PDC_RPR) -#define UART_PUT_RCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_RCR) -#define UART_PUT_RNPR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_RNPR) -#define UART_PUT_RNCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_RNCR) - -#define UART_PUT_TPR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_TPR) -#define UART_PUT_TCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_TCR) -#define UART_GET_TCR(port)	__raw_readl((port)->membase + ATMEL_PDC_TCR) -  struct atmel_dma_buffer {  	unsigned char	*buf;  	dma_addr_t	dma_addr; @@ -166,12 +144,16 @@ struct atmel_uart_port {  	unsigned int		irq_status;  	unsigned int		irq_status_prev;  	unsigned int		status_change; +	unsigned int		tx_len;  	struct circ_buf		rx_ring;  	struct mctrl_gpios	*gpios;  	int			gpio_irq[UART_GPIO_MAX];  	unsigned int		tx_done_mask; +	u32			fifo_size; +	u32			rts_high; +	u32			rts_low;  	bool			ms_irq_enabled;  	bool			is_usart;	/* usart or uart */  	struct timer_list	uart_timer;	/* uart timer */ @@ -212,6 +194,43 @@ to_atmel_uart_port(struct uart_port *uart)  	return container_of(uart, struct atmel_uart_port, uart);  } +static inline u32 atmel_uart_readl(struct uart_port *port, u32 reg) +{ +	return __raw_readl(port->membase + reg); +} + +static inline void atmel_uart_writel(struct uart_port *port, u32 reg, u32 value) +{ +	__raw_writel(value, port->membase + reg); +} + +#ifdef CONFIG_AVR32 + +/* AVR32 cannot handle 8 or 16bit I/O accesses but only 32bit I/O accesses */ +static inline u8 atmel_uart_read_char(struct uart_port *port) +{ +	return __raw_readl(port->membase + ATMEL_US_RHR); +} + +static inline void atmel_uart_write_char(struct uart_port *port, u8 value) +{ +	__raw_writel(value, port->membase + ATMEL_US_THR); +} + +#else + +static inline u8 atmel_uart_read_char(struct uart_port *port) +{ +	return __raw_readb(port->membase + ATMEL_US_RHR); +} + +static inline void atmel_uart_write_char(struct uart_port *port, u8 value) +{ +	__raw_writeb(value, port->membase + ATMEL_US_THR); +} + +#endif +  #ifdef CONFIG_SERIAL_ATMEL_PDC  static bool atmel_use_pdc_rx(struct uart_port *port)  { @@ -257,7 +276,7 @@ static unsigned int atmel_get_lines_status(struct uart_port *port)  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);  	unsigned int status, ret = 0; -	status = UART_GET_CSR(port); +	status = atmel_uart_readl(port, ATMEL_US_CSR);  	mctrl_gpio_get(atmel_port->gpios, &ret); @@ -304,9 +323,9 @@ static int atmel_config_rs485(struct uart_port *port,  	unsigned int mode;  	/* Disable interrupts */ -	UART_PUT_IDR(port, atmel_port->tx_done_mask); +	atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); -	mode = UART_GET_MR(port); +	mode = atmel_uart_readl(port, ATMEL_US_MR);  	/* Resetting serial mode to RS232 (0x0) */  	mode &= ~ATMEL_US_USMODE; @@ -316,7 +335,8 @@ static int atmel_config_rs485(struct uart_port *port,  	if (rs485conf->flags & SER_RS485_ENABLED) {  		dev_dbg(port->dev, "Setting UART to RS485\n");  		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; -		UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); +		atmel_uart_writel(port, ATMEL_US_TTGR, +				  rs485conf->delay_rts_after_send);  		mode |= ATMEL_US_USMODE_RS485;  	} else {  		dev_dbg(port->dev, "Setting UART to RS232\n"); @@ -326,10 +346,10 @@ static int atmel_config_rs485(struct uart_port *port,  		else  			atmel_port->tx_done_mask = ATMEL_US_TXRDY;  	} -	UART_PUT_MR(port, mode); +	atmel_uart_writel(port, ATMEL_US_MR, mode);  	/* Enable interrupts */ -	UART_PUT_IER(port, atmel_port->tx_done_mask); +	atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);  	return 0;  } @@ -339,7 +359,9 @@ static int atmel_config_rs485(struct uart_port *port,   */  static u_int atmel_tx_empty(struct uart_port *port)  { -	return (UART_GET_CSR(port) & ATMEL_US_TXEMPTY) ? TIOCSER_TEMT : 0; +	return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ? +		TIOCSER_TEMT : +		0;  }  /* @@ -348,13 +370,14 @@ static u_int atmel_tx_empty(struct uart_port *port)  static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)  {  	unsigned int control = 0; -	unsigned int mode = UART_GET_MR(port); +	unsigned int mode = atmel_uart_readl(port, ATMEL_US_MR);  	unsigned int rts_paused, rts_ready;  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);  	/* override mode to RS485 if needed, otherwise keep the current mode */  	if (port->rs485.flags & SER_RS485_ENABLED) { -		UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); +		atmel_uart_writel(port, ATMEL_US_TTGR, +				  port->rs485.delay_rts_after_send);  		mode &= ~ATMEL_US_USMODE;  		mode |= ATMEL_US_USMODE_RS485;  	} @@ -384,7 +407,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)  	else  		control |= ATMEL_US_DTRDIS; -	UART_PUT_CR(port, control); +	atmel_uart_writel(port, ATMEL_US_CR, control);  	mctrl_gpio_set(atmel_port->gpios, mctrl); @@ -395,7 +418,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)  	else  		mode |= ATMEL_US_CHMODE_NORMAL; -	UART_PUT_MR(port, mode); +	atmel_uart_writel(port, ATMEL_US_MR, mode);  }  /* @@ -406,7 +429,7 @@ static u_int atmel_get_mctrl(struct uart_port *port)  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);  	unsigned int ret = 0, status; -	status = UART_GET_CSR(port); +	status = atmel_uart_readl(port, ATMEL_US_CSR);  	/*  	 * The control signals are active low. @@ -432,10 +455,10 @@ static void atmel_stop_tx(struct uart_port *port)  	if (atmel_use_pdc_tx(port)) {  		/* disable PDC transmit */ -		UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);  	}  	/* Disable interrupts */ -	UART_PUT_IDR(port, atmel_port->tx_done_mask); +	atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);  	if ((port->rs485.flags & SER_RS485_ENABLED) &&  	    !(port->rs485.flags & SER_RS485_RX_DURING_TX)) @@ -450,7 +473,7 @@ static void atmel_start_tx(struct uart_port *port)  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);  	if (atmel_use_pdc_tx(port)) { -		if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) +		if (atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN)  			/* The transmitter is already running.  Yes, we  			   really need this.*/  			return; @@ -460,10 +483,10 @@ static void atmel_start_tx(struct uart_port *port)  			atmel_stop_rx(port);  		/* re-enable PDC transmit */ -		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);  	}  	/* Enable interrupts */ -	UART_PUT_IER(port, atmel_port->tx_done_mask); +	atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);  }  /* @@ -471,17 +494,19 @@ static void atmel_start_tx(struct uart_port *port)   */  static void atmel_start_rx(struct uart_port *port)  { -	UART_PUT_CR(port, ATMEL_US_RSTSTA);  /* reset status and receiver */ +	/* reset status and receiver */ +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA); -	UART_PUT_CR(port, ATMEL_US_RXEN); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RXEN);  	if (atmel_use_pdc_rx(port)) {  		/* enable PDC controller */ -		UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | -			port->read_status_mask); -		UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); +		atmel_uart_writel(port, ATMEL_US_IER, +				  ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | +				  port->read_status_mask); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);  	} else { -		UART_PUT_IER(port, ATMEL_US_RXRDY); +		atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_RXRDY);  	}  } @@ -490,15 +515,16 @@ static void atmel_start_rx(struct uart_port *port)   */  static void atmel_stop_rx(struct uart_port *port)  { -	UART_PUT_CR(port, ATMEL_US_RXDIS); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RXDIS);  	if (atmel_use_pdc_rx(port)) {  		/* disable PDC receive */ -		UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); -		UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | -			port->read_status_mask); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS); +		atmel_uart_writel(port, ATMEL_US_IDR, +				  ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | +				  port->read_status_mask);  	} else { -		UART_PUT_IDR(port, ATMEL_US_RXRDY); +		atmel_uart_writel(port, ATMEL_US_IDR, ATMEL_US_RXRDY);  	}  } @@ -538,7 +564,7 @@ static void atmel_enable_ms(struct uart_port *port)  	else  		ier |= ATMEL_US_DCDIC; -	UART_PUT_IER(port, ier); +	atmel_uart_writel(port, ATMEL_US_IER, ier);  }  /* @@ -577,7 +603,7 @@ static void atmel_disable_ms(struct uart_port *port)  	else  		idr |= ATMEL_US_DCDIC; -	UART_PUT_IDR(port, idr); +	atmel_uart_writel(port, ATMEL_US_IDR, idr);  }  /* @@ -586,9 +612,11 @@ static void atmel_disable_ms(struct uart_port *port)  static void atmel_break_ctl(struct uart_port *port, int break_state)  {  	if (break_state != 0) -		UART_PUT_CR(port, ATMEL_US_STTBRK);	/* start break */ +		/* start break */ +		atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTBRK);  	else -		UART_PUT_CR(port, ATMEL_US_STPBRK);	/* stop break */ +		/* stop break */ +		atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STPBRK);  }  /* @@ -622,7 +650,7 @@ atmel_buffer_rx_char(struct uart_port *port, unsigned int status,  static void atmel_pdc_rxerr(struct uart_port *port, unsigned int status)  {  	/* clear error */ -	UART_PUT_CR(port, ATMEL_US_RSTSTA); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);  	if (status & ATMEL_US_RXBRK) {  		/* ignore side-effect */ @@ -645,9 +673,9 @@ static void atmel_rx_chars(struct uart_port *port)  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);  	unsigned int status, ch; -	status = UART_GET_CSR(port); +	status = atmel_uart_readl(port, ATMEL_US_CSR);  	while (status & ATMEL_US_RXRDY) { -		ch = UART_GET_CHAR(port); +		ch = atmel_uart_read_char(port);  		/*  		 * note that the error handling code is @@ -658,12 +686,13 @@ static void atmel_rx_chars(struct uart_port *port)  			     || atmel_port->break_active)) {  			/* clear error */ -			UART_PUT_CR(port, ATMEL_US_RSTSTA); +			atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);  			if (status & ATMEL_US_RXBRK  			    && !atmel_port->break_active) {  				atmel_port->break_active = 1; -				UART_PUT_IER(port, ATMEL_US_RXBRK); +				atmel_uart_writel(port, ATMEL_US_IER, +						  ATMEL_US_RXBRK);  			} else {  				/*  				 * This is either the end-of-break @@ -672,14 +701,15 @@ static void atmel_rx_chars(struct uart_port *port)  				 * being set. In both cases, the next  				 * RXBRK will indicate start-of-break.  				 */ -				UART_PUT_IDR(port, ATMEL_US_RXBRK); +				atmel_uart_writel(port, ATMEL_US_IDR, +						  ATMEL_US_RXBRK);  				status &= ~ATMEL_US_RXBRK;  				atmel_port->break_active = 0;  			}  		}  		atmel_buffer_rx_char(port, status, ch); -		status = UART_GET_CSR(port); +		status = atmel_uart_readl(port, ATMEL_US_CSR);  	}  	tasklet_schedule(&atmel_port->tasklet); @@ -694,16 +724,18 @@ static void atmel_tx_chars(struct uart_port *port)  	struct circ_buf *xmit = &port->state->xmit;  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); -	if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) { -		UART_PUT_CHAR(port, port->x_char); +	if (port->x_char && +	    (atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask)) { +		atmel_uart_write_char(port, port->x_char);  		port->icount.tx++;  		port->x_char = 0;  	}  	if (uart_circ_empty(xmit) || uart_tx_stopped(port))  		return; -	while (UART_GET_CSR(port) & atmel_port->tx_done_mask) { -		UART_PUT_CHAR(port, xmit->buf[xmit->tail]); +	while (atmel_uart_readl(port, ATMEL_US_CSR) & +	       atmel_port->tx_done_mask) { +		atmel_uart_write_char(port, xmit->buf[xmit->tail]);  		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);  		port->icount.tx++;  		if (uart_circ_empty(xmit)) @@ -715,7 +747,8 @@ static void atmel_tx_chars(struct uart_port *port)  	if (!uart_circ_empty(xmit))  		/* Enable interrupts */ -		UART_PUT_IER(port, atmel_port->tx_done_mask); +		atmel_uart_writel(port, ATMEL_US_IER, +				  atmel_port->tx_done_mask);  }  static void atmel_complete_tx_dma(void *arg) @@ -730,10 +763,10 @@ static void atmel_complete_tx_dma(void *arg)  	if (chan)  		dmaengine_terminate_all(chan); -	xmit->tail += sg_dma_len(&atmel_port->sg_tx); +	xmit->tail += atmel_port->tx_len;  	xmit->tail &= UART_XMIT_SIZE - 1; -	port->icount.tx += sg_dma_len(&atmel_port->sg_tx); +	port->icount.tx += atmel_port->tx_len;  	spin_lock_irq(&atmel_port->lock_tx);  	async_tx_ack(atmel_port->desc_tx); @@ -781,7 +814,9 @@ static void atmel_tx_dma(struct uart_port *port)  	struct circ_buf *xmit = &port->state->xmit;  	struct dma_chan *chan = atmel_port->chan_tx;  	struct dma_async_tx_descriptor *desc; -	struct scatterlist *sg = &atmel_port->sg_tx; +	struct scatterlist sgl[2], *sg, *sg_tx = &atmel_port->sg_tx; +	unsigned int tx_len, part1_len, part2_len, sg_len; +	dma_addr_t phys_addr;  	/* Make sure we have an idle channel */  	if (atmel_port->desc_tx != NULL) @@ -797,18 +832,46 @@ static void atmel_tx_dma(struct uart_port *port)  		 * Take the port lock to get a  		 * consistent xmit buffer state.  		 */ -		sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); -		sg_dma_address(sg) = (sg_dma_address(sg) & -					~(UART_XMIT_SIZE - 1)) -					+ sg->offset; -		sg_dma_len(sg) = CIRC_CNT_TO_END(xmit->head, -						xmit->tail, -						UART_XMIT_SIZE); -		BUG_ON(!sg_dma_len(sg)); +		tx_len = CIRC_CNT_TO_END(xmit->head, +					 xmit->tail, +					 UART_XMIT_SIZE); + +		if (atmel_port->fifo_size) { +			/* multi data mode */ +			part1_len = (tx_len & ~0x3); /* DWORD access */ +			part2_len = (tx_len & 0x3); /* BYTE access */ +		} else { +			/* single data (legacy) mode */ +			part1_len = 0; +			part2_len = tx_len; /* BYTE access only */ +		} + +		sg_init_table(sgl, 2); +		sg_len = 0; +		phys_addr = sg_dma_address(sg_tx) + xmit->tail; +		if (part1_len) { +			sg = &sgl[sg_len++]; +			sg_dma_address(sg) = phys_addr; +			sg_dma_len(sg) = part1_len; + +			phys_addr += part1_len; +		} + +		if (part2_len) { +			sg = &sgl[sg_len++]; +			sg_dma_address(sg) = phys_addr; +			sg_dma_len(sg) = part2_len; +		} + +		/* +		 * save tx_len so atmel_complete_tx_dma() will increase +		 * xmit->tail correctly +		 */ +		atmel_port->tx_len = tx_len;  		desc = dmaengine_prep_slave_sg(chan, -					       sg, -					       1, +					       sgl, +					       sg_len,  					       DMA_MEM_TO_DEV,  					       DMA_PREP_INTERRUPT |  					       DMA_CTRL_ACK); @@ -817,7 +880,7 @@ static void atmel_tx_dma(struct uart_port *port)  			return;  		} -		dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); +		dma_sync_sg_for_device(port->dev, sg_tx, 1, DMA_TO_DEVICE);  		atmel_port->desc_tx = desc;  		desc->callback = atmel_complete_tx_dma; @@ -877,7 +940,9 @@ static int atmel_prepare_tx_dma(struct uart_port *port)  	/* Configure the slave DMA */  	memset(&config, 0, sizeof(config));  	config.direction = DMA_MEM_TO_DEV; -	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; +	config.dst_addr_width = (atmel_port->fifo_size) ? +				DMA_SLAVE_BUSWIDTH_4_BYTES : +				DMA_SLAVE_BUSWIDTH_1_BYTE;  	config.dst_addr = port->mapbase + ATMEL_US_THR;  	config.dst_maxburst = 1; @@ -935,14 +1000,14 @@ static void atmel_rx_from_dma(struct uart_port *port)  	/* Reset the UART timeout early so that we don't miss one */ -	UART_PUT_CR(port, ATMEL_US_STTTO); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO);  	dmastat = dmaengine_tx_status(chan,  				atmel_port->cookie_rx,  				&state);  	/* Restart a new tasklet if DMA status is error */  	if (dmastat == DMA_ERROR) {  		dev_dbg(port->dev, "Get residue error, restart tasklet\n"); -		UART_PUT_IER(port, ATMEL_US_TIMEOUT); +		atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT);  		tasklet_schedule(&atmel_port->tasklet);  		return;  	} @@ -1008,7 +1073,7 @@ static void atmel_rx_from_dma(struct uart_port *port)  	tty_flip_buffer_push(tport);  	spin_lock(&port->lock); -	UART_PUT_IER(port, ATMEL_US_TIMEOUT); +	atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT);  }  static int atmel_prepare_rx_dma(struct uart_port *port) @@ -1118,8 +1183,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending)  		 * the moment.  		 */  		if (pending & (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)) { -			UART_PUT_IDR(port, (ATMEL_US_ENDRX -						| ATMEL_US_TIMEOUT)); +			atmel_uart_writel(port, ATMEL_US_IDR, +					  (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT));  			tasklet_schedule(&atmel_port->tasklet);  		} @@ -1130,7 +1195,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending)  	if (atmel_use_dma_rx(port)) {  		if (pending & ATMEL_US_TIMEOUT) { -			UART_PUT_IDR(port, ATMEL_US_TIMEOUT); +			atmel_uart_writel(port, ATMEL_US_IDR, +					  ATMEL_US_TIMEOUT);  			tasklet_schedule(&atmel_port->tasklet);  		}  	} @@ -1143,8 +1209,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending)  		 * End of break detected. If it came along with a  		 * character, atmel_rx_chars will handle it.  		 */ -		UART_PUT_CR(port, ATMEL_US_RSTSTA); -		UART_PUT_IDR(port, ATMEL_US_RXBRK); +		atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA); +		atmel_uart_writel(port, ATMEL_US_IDR, ATMEL_US_RXBRK);  		atmel_port->break_active = 0;  	}  } @@ -1159,7 +1225,8 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)  	if (pending & atmel_port->tx_done_mask) {  		/* Either PDC or interrupt transmission */ -		UART_PUT_IDR(port, atmel_port->tx_done_mask); +		atmel_uart_writel(port, ATMEL_US_IDR, +				  atmel_port->tx_done_mask);  		tasklet_schedule(&atmel_port->tasklet);  	}  } @@ -1197,7 +1264,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)  	do {  		status = atmel_get_lines_status(port); -		mask = UART_GET_IMR(port); +		mask = atmel_uart_readl(port, ATMEL_US_IMR);  		pending = status & mask;  		if (!gpio_handled) {  			/* @@ -1223,7 +1290,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)  		if (atmel_port->suspended) {  			atmel_port->pending |= pending;  			atmel_port->pending_status = status; -			UART_PUT_IDR(port, mask); +			atmel_uart_writel(port, ATMEL_US_IDR, mask);  			pm_system_wakeup();  			break;  		} @@ -1260,7 +1327,7 @@ static void atmel_tx_pdc(struct uart_port *port)  	int count;  	/* nothing left to transmit? */ -	if (UART_GET_TCR(port)) +	if (atmel_uart_readl(port, ATMEL_PDC_TCR))  		return;  	xmit->tail += pdc->ofs; @@ -1272,7 +1339,7 @@ static void atmel_tx_pdc(struct uart_port *port)  	/* more to transmit - setup next transfer */  	/* disable PDC transmit */ -	UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); +	atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);  	if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {  		dma_sync_single_for_device(port->dev, @@ -1283,12 +1350,14 @@ static void atmel_tx_pdc(struct uart_port *port)  		count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);  		pdc->ofs = count; -		UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); -		UART_PUT_TCR(port, count); +		atmel_uart_writel(port, ATMEL_PDC_TPR, +				  pdc->dma_addr + xmit->tail); +		atmel_uart_writel(port, ATMEL_PDC_TCR, count);  		/* re-enable PDC transmit */ -		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);  		/* Enable interrupts */ -		UART_PUT_IER(port, atmel_port->tx_done_mask); +		atmel_uart_writel(port, ATMEL_US_IER, +				  atmel_port->tx_done_mask);  	} else {  		if ((port->rs485.flags & SER_RS485_ENABLED) &&  		    !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { @@ -1414,10 +1483,10 @@ static void atmel_rx_from_pdc(struct uart_port *port)  	do {  		/* Reset the UART timeout early so that we don't miss one */ -		UART_PUT_CR(port, ATMEL_US_STTTO); +		atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO);  		pdc = &atmel_port->pdc_rx[rx_idx]; -		head = UART_GET_RPR(port) - pdc->dma_addr; +		head = atmel_uart_readl(port, ATMEL_PDC_RPR) - pdc->dma_addr;  		tail = pdc->ofs;  		/* If the PDC has switched buffers, RPR won't contain @@ -1460,8 +1529,8 @@ static void atmel_rx_from_pdc(struct uart_port *port)  		 */  		if (head >= pdc->dma_size) {  			pdc->ofs = 0; -			UART_PUT_RNPR(port, pdc->dma_addr); -			UART_PUT_RNCR(port, pdc->dma_size); +			atmel_uart_writel(port, ATMEL_PDC_RNPR, pdc->dma_addr); +			atmel_uart_writel(port, ATMEL_PDC_RNCR, pdc->dma_size);  			rx_idx = !rx_idx;  			atmel_port->pdc_rx_idx = rx_idx; @@ -1476,7 +1545,8 @@ static void atmel_rx_from_pdc(struct uart_port *port)  	tty_flip_buffer_push(tport);  	spin_lock(&port->lock); -	UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); +	atmel_uart_writel(port, ATMEL_US_IER, +			  ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);  }  static int atmel_prepare_rx_pdc(struct uart_port *port) @@ -1509,11 +1579,12 @@ static int atmel_prepare_rx_pdc(struct uart_port *port)  	atmel_port->pdc_rx_idx = 0; -	UART_PUT_RPR(port, atmel_port->pdc_rx[0].dma_addr); -	UART_PUT_RCR(port, PDC_BUFFER_SIZE); +	atmel_uart_writel(port, ATMEL_PDC_RPR, atmel_port->pdc_rx[0].dma_addr); +	atmel_uart_writel(port, ATMEL_PDC_RCR, PDC_BUFFER_SIZE); -	UART_PUT_RNPR(port, atmel_port->pdc_rx[1].dma_addr); -	UART_PUT_RNCR(port, PDC_BUFFER_SIZE); +	atmel_uart_writel(port, ATMEL_PDC_RNPR, +			  atmel_port->pdc_rx[1].dma_addr); +	atmel_uart_writel(port, ATMEL_PDC_RNCR, PDC_BUFFER_SIZE);  	return 0;  } @@ -1667,7 +1738,7 @@ static void atmel_set_ops(struct uart_port *port)  static void atmel_get_ip_name(struct uart_port *port)  {  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); -	int name = UART_GET_IP_NAME(port); +	int name = atmel_uart_readl(port, ATMEL_US_NAME);  	u32 version;  	int usart, uart;  	/* usart and uart ascii */ @@ -1684,7 +1755,7 @@ static void atmel_get_ip_name(struct uart_port *port)  		atmel_port->is_usart = false;  	} else {  		/* fallback for older SoCs: use version field */ -		version = UART_GET_IP_VERSION(port); +		version = atmel_uart_readl(port, ATMEL_US_VERSION);  		switch (version) {  		case 0x302:  		case 0x10213: @@ -1756,7 +1827,7 @@ static int atmel_startup(struct uart_port *port)  	 * request_irq() is called we could get stuck trying to  	 * handle an unexpected interrupt  	 */ -	UART_PUT_IDR(port, -1); +	atmel_uart_writel(port, ATMEL_US_IDR, -1);  	atmel_port->ms_irq_enabled = false;  	/* @@ -1797,6 +1868,32 @@ static int atmel_startup(struct uart_port *port)  			atmel_set_ops(port);  	} +	/* +	 * Enable FIFO when available +	 */ +	if (atmel_port->fifo_size) { +		unsigned int txrdym = ATMEL_US_ONE_DATA; +		unsigned int rxrdym = ATMEL_US_ONE_DATA; +		unsigned int fmr; + +		atmel_uart_writel(port, ATMEL_US_CR, +				  ATMEL_US_FIFOEN | +				  ATMEL_US_RXFCLR | +				  ATMEL_US_TXFLCLR); + +		if (atmel_use_dma_tx(port)) +			txrdym = ATMEL_US_FOUR_DATA; + +		fmr = ATMEL_US_TXRDYM(txrdym) | ATMEL_US_RXRDYM(rxrdym); +		if (atmel_port->rts_high && +		    atmel_port->rts_low) +			fmr |=	ATMEL_US_FRTSC | +				ATMEL_US_RXFTHRES(atmel_port->rts_high) | +				ATMEL_US_RXFTHRES2(atmel_port->rts_low); + +		atmel_uart_writel(port, ATMEL_US_FMR, fmr); +	} +  	/* Save current CSR for comparison in atmel_tasklet_func() */  	atmel_port->irq_status_prev = atmel_get_lines_status(port);  	atmel_port->irq_status = atmel_port->irq_status_prev; @@ -1804,9 +1901,9 @@ static int atmel_startup(struct uart_port *port)  	/*  	 * Finally, enable the serial port  	 */ -	UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);  	/* enable xmit & rcvr */ -	UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);  	setup_timer(&atmel_port->uart_timer,  			atmel_uart_timer_callback, @@ -1819,13 +1916,14 @@ static int atmel_startup(struct uart_port *port)  					jiffies + uart_poll_timeout(port));  		/* set USART timeout */  		} else { -			UART_PUT_RTOR(port, PDC_RX_TIMEOUT); -			UART_PUT_CR(port, ATMEL_US_STTTO); +			atmel_uart_writel(port, ATMEL_US_RTOR, PDC_RX_TIMEOUT); +			atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO); -			UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); +			atmel_uart_writel(port, ATMEL_US_IER, +					  ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);  		}  		/* enable PDC controller */ -		UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);  	} else if (atmel_use_dma_rx(port)) {  		/* set UART timeout */  		if (!atmel_port->is_usart) { @@ -1833,14 +1931,15 @@ static int atmel_startup(struct uart_port *port)  					jiffies + uart_poll_timeout(port));  		/* set USART timeout */  		} else { -			UART_PUT_RTOR(port, PDC_RX_TIMEOUT); -			UART_PUT_CR(port, ATMEL_US_STTTO); +			atmel_uart_writel(port, ATMEL_US_RTOR, PDC_RX_TIMEOUT); +			atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO); -			UART_PUT_IER(port, ATMEL_US_TIMEOUT); +			atmel_uart_writel(port, ATMEL_US_IER, +					  ATMEL_US_TIMEOUT);  		}  	} else {  		/* enable receive only */ -		UART_PUT_IER(port, ATMEL_US_RXRDY); +		atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_RXRDY);  	}  	return 0; @@ -1860,7 +1959,7 @@ static void atmel_flush_buffer(struct uart_port *port)  	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);  	if (atmel_use_pdc_tx(port)) { -		UART_PUT_TCR(port, 0); +		atmel_uart_writel(port, ATMEL_PDC_TCR, 0);  		atmel_port->pdc_tx.ofs = 0;  	}  } @@ -1892,8 +1991,8 @@ static void atmel_shutdown(struct uart_port *port)  	atmel_stop_rx(port);  	atmel_stop_tx(port); -	UART_PUT_CR(port, ATMEL_US_RSTSTA); -	UART_PUT_IDR(port, -1); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA); +	atmel_uart_writel(port, ATMEL_US_IDR, -1);  	/* @@ -1938,12 +2037,12 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,  		clk_prepare_enable(atmel_port->clk);  		/* re-enable interrupts if we disabled some on suspend */ -		UART_PUT_IER(port, atmel_port->backup_imr); +		atmel_uart_writel(port, ATMEL_US_IER, atmel_port->backup_imr);  		break;  	case 3:  		/* Back up the interrupt mask and disable all interrupts */ -		atmel_port->backup_imr = UART_GET_IMR(port); -		UART_PUT_IDR(port, -1); +		atmel_port->backup_imr = atmel_uart_readl(port, ATMEL_US_IMR); +		atmel_uart_writel(port, ATMEL_US_IDR, -1);  		/*  		 * Disable the peripheral clock for this serial port. @@ -1966,7 +2065,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,  	unsigned int old_mode, mode, imr, quot, baud;  	/* save the current mode register */ -	mode = old_mode = UART_GET_MR(port); +	mode = old_mode = atmel_uart_readl(port, ATMEL_US_MR);  	/* reset the mode, clock divisor, parity, stop bits and data size */  	mode &= ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | @@ -2025,7 +2124,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,  	if (atmel_use_pdc_rx(port))  		/* need to enable error interrupts */ -		UART_PUT_IER(port, port->read_status_mask); +		atmel_uart_writel(port, ATMEL_US_IER, port->read_status_mask);  	/*  	 * Characters to ignore @@ -2052,15 +2151,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,  	 * transmitter is empty if requested by the caller, so there's  	 * no need to wait for it here.  	 */ -	imr = UART_GET_IMR(port); -	UART_PUT_IDR(port, -1); +	imr = atmel_uart_readl(port, ATMEL_US_IMR); +	atmel_uart_writel(port, ATMEL_US_IDR, -1);  	/* disable receiver and transmitter */ -	UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS);  	/* mode */  	if (port->rs485.flags & SER_RS485_ENABLED) { -		UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); +		atmel_uart_writel(port, ATMEL_US_TTGR, +				  port->rs485.delay_rts_after_send);  		mode |= ATMEL_US_USMODE_RS485;  	} else if (termios->c_cflag & CRTSCTS) {  		/* RS232 with hardware handshake (RTS/CTS) */ @@ -2071,7 +2171,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,  	}  	/* set the mode, clock divisor, parity, stop bits and data size */ -	UART_PUT_MR(port, mode); +	atmel_uart_writel(port, ATMEL_US_MR, mode);  	/*  	 * when switching the mode, set the RTS line state according to the @@ -2088,16 +2188,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,  			rts_state = ATMEL_US_RTSEN;  		} -		UART_PUT_CR(port, rts_state); +		atmel_uart_writel(port, ATMEL_US_CR, rts_state);  	}  	/* set the baud rate */ -	UART_PUT_BRGR(port, quot); -	UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); -	UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); +	atmel_uart_writel(port, ATMEL_US_BRGR, quot); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);  	/* restore interrupts */ -	UART_PUT_IER(port, imr); +	atmel_uart_writel(port, ATMEL_US_IER, imr);  	/* CTS flow-control and modem-status interrupts */  	if (UART_ENABLE_MS(port, termios->c_cflag)) @@ -2208,18 +2308,18 @@ static int atmel_verify_port(struct uart_port *port, struct serial_struct *ser)  #ifdef CONFIG_CONSOLE_POLL  static int atmel_poll_get_char(struct uart_port *port)  { -	while (!(UART_GET_CSR(port) & ATMEL_US_RXRDY)) +	while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_RXRDY))  		cpu_relax(); -	return UART_GET_CHAR(port); +	return atmel_uart_read_char(port);  }  static void atmel_poll_put_char(struct uart_port *port, unsigned char ch)  { -	while (!(UART_GET_CSR(port) & ATMEL_US_TXRDY)) +	while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY))  		cpu_relax(); -	UART_PUT_CHAR(port, ch); +	atmel_uart_write_char(port, ch);  }  #endif @@ -2324,9 +2424,9 @@ struct platform_device *atmel_default_console_device;	/* the serial console devi  #ifdef CONFIG_SERIAL_ATMEL_CONSOLE  static void atmel_console_putchar(struct uart_port *port, int ch)  { -	while (!(UART_GET_CSR(port) & ATMEL_US_TXRDY)) +	while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY))  		cpu_relax(); -	UART_PUT_CHAR(port, ch); +	atmel_uart_write_char(port, ch);  }  /* @@ -2342,12 +2442,13 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)  	/*  	 * First, save IMR and then disable interrupts  	 */ -	imr = UART_GET_IMR(port); -	UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask); +	imr = atmel_uart_readl(port, ATMEL_US_IMR); +	atmel_uart_writel(port, ATMEL_US_IDR, +			  ATMEL_US_RXRDY | atmel_port->tx_done_mask);  	/* Store PDC transmit status and disable it */ -	pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; -	UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); +	pdc_tx = atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN; +	atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);  	uart_console_write(port, s, count, atmel_console_putchar); @@ -2356,15 +2457,15 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)  	 * and restore IMR  	 */  	do { -		status = UART_GET_CSR(port); +		status = atmel_uart_readl(port, ATMEL_US_CSR);  	} while (!(status & ATMEL_US_TXRDY));  	/* Restore PDC transmit status */  	if (pdc_tx) -		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); +		atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);  	/* set interrupts back the way they were */ -	UART_PUT_IER(port, imr); +	atmel_uart_writel(port, ATMEL_US_IER, imr);  }  /* @@ -2380,17 +2481,17 @@ static void __init atmel_console_get_options(struct uart_port *port, int *baud,  	 * If the baud rate generator isn't running, the port wasn't  	 * initialized by the boot loader.  	 */ -	quot = UART_GET_BRGR(port) & ATMEL_US_CD; +	quot = atmel_uart_readl(port, ATMEL_US_BRGR) & ATMEL_US_CD;  	if (!quot)  		return; -	mr = UART_GET_MR(port) & ATMEL_US_CHRL; +	mr = atmel_uart_readl(port, ATMEL_US_MR) & ATMEL_US_CHRL;  	if (mr == ATMEL_US_CHRL_8)  		*bits = 8;  	else  		*bits = 7; -	mr = UART_GET_MR(port) & ATMEL_US_PAR; +	mr = atmel_uart_readl(port, ATMEL_US_MR) & ATMEL_US_PAR;  	if (mr == ATMEL_US_PAR_EVEN)  		*parity = 'e';  	else if (mr == ATMEL_US_PAR_ODD) @@ -2423,9 +2524,9 @@ static int __init atmel_console_setup(struct console *co, char *options)  	if (ret)  		return ret; -	UART_PUT_IDR(port, -1); -	UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); -	UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); +	atmel_uart_writel(port, ATMEL_US_IDR, -1); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); +	atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);  	if (options)  		uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -2532,7 +2633,8 @@ static int atmel_serial_suspend(struct platform_device *pdev,  	if (atmel_is_console_port(port) && console_suspend_enabled) {  		/* Drain the TX shifter */ -		while (!(UART_GET_CSR(port) & ATMEL_US_TXEMPTY)) +		while (!(atmel_uart_readl(port, ATMEL_US_CSR) & +			 ATMEL_US_TXEMPTY))  			cpu_relax();  	} @@ -2599,6 +2701,48 @@ static int atmel_init_gpios(struct atmel_uart_port *p, struct device *dev)  	return 0;  } +static void atmel_serial_probe_fifos(struct atmel_uart_port *port, +				     struct platform_device *pdev) +{ +	port->fifo_size = 0; +	port->rts_low = 0; +	port->rts_high = 0; + +	if (of_property_read_u32(pdev->dev.of_node, +				 "atmel,fifo-size", +				 &port->fifo_size)) +		return; + +	if (!port->fifo_size) +		return; + +	if (port->fifo_size < ATMEL_MIN_FIFO_SIZE) { +		port->fifo_size = 0; +		dev_err(&pdev->dev, "Invalid FIFO size\n"); +		return; +	} + +	/* +	 * 0 <= rts_low <= rts_high <= fifo_size +	 * Once their CTS line asserted by the remote peer, some x86 UARTs tend +	 * to flush their internal TX FIFO, commonly up to 16 data, before +	 * actually stopping to send new data. So we try to set the RTS High +	 * Threshold to a reasonably high value respecting this 16 data +	 * empirical rule when possible. +	 */ +	port->rts_high = max_t(int, port->fifo_size >> 1, +			       port->fifo_size - ATMEL_RTS_HIGH_OFFSET); +	port->rts_low  = max_t(int, port->fifo_size >> 2, +			       port->fifo_size - ATMEL_RTS_LOW_OFFSET); + +	dev_info(&pdev->dev, "Using FIFO (%u data)\n", +		 port->fifo_size); +	dev_dbg(&pdev->dev, "RTS High Threshold : %2u data\n", +		port->rts_high); +	dev_dbg(&pdev->dev, "RTS Low Threshold  : %2u data\n", +		port->rts_low); +} +  static int atmel_serial_probe(struct platform_device *pdev)  {  	struct atmel_uart_port *port; @@ -2635,6 +2779,7 @@ static int atmel_serial_probe(struct platform_device *pdev)  	port = &atmel_ports[ret];  	port->backup_imr = 0;  	port->uart.line = ret; +	atmel_serial_probe_fifos(port, pdev);  	spin_lock_init(&port->lock_suspended); @@ -2684,8 +2829,9 @@ static int atmel_serial_probe(struct platform_device *pdev)  	clk_prepare_enable(port->clk);  	if (rs485_enabled) { -		UART_PUT_MR(&port->uart, ATMEL_US_USMODE_NORMAL); -		UART_PUT_CR(&port->uart, ATMEL_US_RTSEN); +		atmel_uart_writel(&port->uart, ATMEL_US_MR, +				  ATMEL_US_USMODE_NORMAL); +		atmel_uart_writel(&port->uart, ATMEL_US_CR, ATMEL_US_RTSEN);  	}  	/* diff --git a/drivers/tty/serial/etraxfs-uart.c b/drivers/tty/serial/etraxfs-uart.c index a57301a6fe42..6813e316e9ff 100644 --- a/drivers/tty/serial/etraxfs-uart.c +++ b/drivers/tty/serial/etraxfs-uart.c @@ -10,6 +10,8 @@  #include <linux/of_address.h>  #include <hwregs/ser_defs.h> +#include "serial_mctrl_gpio.h" +  #define DRV_NAME "etraxfs-uart"  #define UART_NR CONFIG_ETRAX_SERIAL_PORTS @@ -28,10 +30,7 @@ struct uart_cris_port {  	void __iomem *regi_ser; -	struct gpio_desc *dtr_pin; -	struct gpio_desc *dsr_pin; -	struct gpio_desc *ri_pin; -	struct gpio_desc *cd_pin; +	struct mctrl_gpios *gpios;  	int write_ongoing;  }; @@ -112,17 +111,10 @@ cris_console_setup(struct console *co, char *options)  	return 0;  } -static struct tty_driver *cris_console_device(struct console *co, int *index) -{ -	struct uart_driver *p = co->data; -	*index = co->index; -	return p->tty_driver; -} -  static struct console cris_console = {  	.name = "ttyS",  	.write = cris_console_write, -	.device = cris_console_device, +	.device = uart_console_device,  	.setup = cris_console_setup,  	.flags = CON_PRINTBUFFER,  	.index = -1, @@ -373,14 +365,6 @@ static void etraxfs_uart_stop_rx(struct uart_port *port)  	REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);  } -static void etraxfs_uart_enable_ms(struct uart_port *port) -{ -} - -static void check_modem_status(struct uart_cris_port *up) -{ -} -  static unsigned int etraxfs_uart_tx_empty(struct uart_port *port)  {  	struct uart_cris_port *up = (struct uart_cris_port *)port; @@ -404,21 +388,9 @@ static unsigned int etraxfs_uart_get_mctrl(struct uart_port *port)  	ret = 0;  	if (crisv32_serial_get_rts(up))  		ret |= TIOCM_RTS; -	/* DTR is active low */ -	if (up->dtr_pin && !gpiod_get_raw_value(up->dtr_pin)) -		ret |= TIOCM_DTR; -	/* CD is active low */ -	if (up->cd_pin && !gpiod_get_raw_value(up->cd_pin)) -		ret |= TIOCM_CD; -	/* RI is active low */ -	if (up->ri_pin && !gpiod_get_raw_value(up->ri_pin)) -		ret |= TIOCM_RI; -	/* DSR is active low */ -	if (up->dsr_pin && !gpiod_get_raw_value(up->dsr_pin)) -		ret |= TIOCM_DSR;  	if (crisv32_serial_get_cts(up))  		ret |= TIOCM_CTS; -	return ret; +	return mctrl_gpio_get(up->gpios, &ret);  }  static void etraxfs_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) @@ -426,15 +398,7 @@ static void etraxfs_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)  	struct uart_cris_port *up = (struct uart_cris_port *)port;  	crisv32_serial_set_rts(up, mctrl & TIOCM_RTS ? 1 : 0, 0); -	/* DTR is active low */ -	if (up->dtr_pin) -		gpiod_set_raw_value(up->dtr_pin, mctrl & TIOCM_DTR ? 0 : 1); -	/* RI is active low */ -	if (up->ri_pin) -		gpiod_set_raw_value(up->ri_pin, mctrl & TIOCM_RNG ? 0 : 1); -	/* CD is active low */ -	if (up->cd_pin) -		gpiod_set_raw_value(up->cd_pin, mctrl & TIOCM_CD ? 0 : 1); +	mctrl_gpio_set(up->gpios, mctrl);  }  static void etraxfs_uart_break_ctl(struct uart_port *port, int break_state) @@ -598,7 +562,6 @@ ser_interrupt(int irq, void *dev_id)  			receive_chars_no_dma(up);  			handled = 1;  		} -		check_modem_status(up);  		if (masked_intr.tr_rdy) {  			transmit_chars_no_dma(up); @@ -862,7 +825,6 @@ static const struct uart_ops etraxfs_uart_pops = {  	.start_tx = etraxfs_uart_start_tx,  	.send_xchar = etraxfs_uart_send_xchar,  	.stop_rx = etraxfs_uart_stop_rx, -	.enable_ms = etraxfs_uart_enable_ms,  	.break_ctl = etraxfs_uart_break_ctl,  	.startup = etraxfs_uart_startup,  	.shutdown = etraxfs_uart_shutdown, @@ -930,11 +892,12 @@ static int etraxfs_uart_probe(struct platform_device *pdev)  	up->irq = irq_of_parse_and_map(np, 0);  	up->regi_ser = of_iomap(np, 0); -	up->dtr_pin = devm_gpiod_get_optional(&pdev->dev, "dtr"); -	up->dsr_pin = devm_gpiod_get_optional(&pdev->dev, "dsr"); -	up->ri_pin = devm_gpiod_get_optional(&pdev->dev, "ri"); -	up->cd_pin = devm_gpiod_get_optional(&pdev->dev, "cd");  	up->port.dev = &pdev->dev; + +	up->gpios = mctrl_gpio_init(&pdev->dev, 0); +	if (IS_ERR(up->gpios)) +		return PTR_ERR(up->gpios); +  	cris_serial_port_init(&up->port, dev_id);  	etraxfs_uart_ports[dev_id] = up; @@ -950,7 +913,7 @@ static int etraxfs_uart_remove(struct platform_device *pdev)  	port = platform_get_drvdata(pdev);  	uart_remove_one_port(&etraxfs_uart_driver, port); -	etraxfs_uart_ports[pdev->id] = NULL; +	etraxfs_uart_ports[port->line] = NULL;  	return 0;  } diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 2c90dc31bfaa..fe3d41cc8416 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -216,6 +216,8 @@ struct imx_port {  	unsigned int		tx_bytes;  	unsigned int		dma_tx_nents;  	wait_queue_head_t	dma_wait; +	unsigned int            saved_reg[10]; +	bool			context_saved;  };  struct imx_port_ucrs { @@ -700,7 +702,8 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)  		if (sport->port.ignore_status_mask & URXD_DUMMY_READ)  			goto out; -		tty_insert_flip_char(port, rx, flg); +		if (tty_insert_flip_char(port, rx, flg) == 0) +			sport->port.icount.buf_overrun++;  	}  out: @@ -766,7 +769,6 @@ static irqreturn_t imx_int(int irq, void *dev_id)  		writel(USR1_AWAKE, sport->port.membase + USR1);  	if (sts2 & USR2_ORE) { -		dev_err(sport->port.dev, "Rx FIFO overrun\n");  		sport->port.icount.overrun++;  		writel(USR2_ORE, sport->port.membase + USR2);  	} @@ -921,8 +923,13 @@ static void dma_rx_callback(void *data)  	dev_dbg(sport->port.dev, "We get %d bytes.\n", count);  	if (count) { -		if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) -			tty_insert_flip_string(port, sport->rx_buf, count); +		if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) { +			int bytes = tty_insert_flip_string(port, sport->rx_buf, +					count); + +			if (bytes != count) +				sport->port.icount.buf_overrun++; +		}  		tty_flip_buffer_push(port);  		start_rx_dma(sport); @@ -1121,11 +1128,6 @@ static int imx_startup(struct uart_port *port)  	writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); -	/* Can we enable the DMA support? */ -	if (is_imx6q_uart(sport) && !uart_console(port) && -	    !sport->dma_is_inited) -		imx_uart_dma_init(sport); -  	spin_lock_irqsave(&sport->port.lock, flags);  	/* Reset fifo's and state machines */  	i = 100; @@ -1143,9 +1145,6 @@ static int imx_startup(struct uart_port *port)  	writel(USR1_RTSD, sport->port.membase + USR1);  	writel(USR2_ORE, sport->port.membase + USR2); -	if (sport->dma_is_inited && !sport->dma_is_enabled) -		imx_enable_dma(sport); -  	temp = readl(sport->port.membase + UCR1);  	temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; @@ -1316,6 +1315,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,  			} else {  				ucr2 |= UCR2_CTSC;  			} + +			/* Can we enable the DMA support? */ +			if (is_imx6q_uart(sport) && !uart_console(port) +				&& !sport->dma_is_inited) +				imx_uart_dma_init(sport);  		} else {  			termios->c_cflag &= ~CRTSCTS;  		} @@ -1432,6 +1436,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,  	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))  		imx_enable_ms(&sport->port); +	if (sport->dma_is_inited && !sport->dma_is_enabled) +		imx_enable_dma(sport);  	spin_unlock_irqrestore(&sport->port.lock, flags);  } @@ -1625,12 +1631,12 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	int locked = 1;  	int retval; -	retval = clk_enable(sport->clk_per); +	retval = clk_prepare_enable(sport->clk_per);  	if (retval)  		return; -	retval = clk_enable(sport->clk_ipg); +	retval = clk_prepare_enable(sport->clk_ipg);  	if (retval) { -		clk_disable(sport->clk_per); +		clk_disable_unprepare(sport->clk_per);  		return;  	} @@ -1669,8 +1675,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	if (locked)  		spin_unlock_irqrestore(&sport->port.lock, flags); -	clk_disable(sport->clk_ipg); -	clk_disable(sport->clk_per); +	clk_disable_unprepare(sport->clk_ipg); +	clk_disable_unprepare(sport->clk_per);  }  /* @@ -1771,15 +1777,7 @@ imx_console_setup(struct console *co, char *options)  	retval = uart_set_options(&sport->port, co, baud, parity, bits, flow); -	clk_disable(sport->clk_ipg); -	if (retval) { -		clk_unprepare(sport->clk_ipg); -		goto error_console; -	} - -	retval = clk_prepare(sport->clk_per); -	if (retval) -		clk_disable_unprepare(sport->clk_ipg); +	clk_disable_unprepare(sport->clk_ipg);  error_console:  	return retval; @@ -1811,36 +1809,6 @@ static struct uart_driver imx_reg = {  	.cons           = IMX_CONSOLE,  }; -static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) -{ -	struct imx_port *sport = platform_get_drvdata(dev); -	unsigned int val; - -	/* enable wakeup from i.MX UART */ -	val = readl(sport->port.membase + UCR3); -	val |= UCR3_AWAKEN; -	writel(val, sport->port.membase + UCR3); - -	uart_suspend_port(&imx_reg, &sport->port); - -	return 0; -} - -static int serial_imx_resume(struct platform_device *dev) -{ -	struct imx_port *sport = platform_get_drvdata(dev); -	unsigned int val; - -	/* disable wakeup from i.MX UART */ -	val = readl(sport->port.membase + UCR3); -	val &= ~UCR3_AWAKEN; -	writel(val, sport->port.membase + UCR3); - -	uart_resume_port(&imx_reg, &sport->port); - -	return 0; -} -  #ifdef CONFIG_OF  /*   * This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it @@ -1902,7 +1870,7 @@ static int serial_imx_probe(struct platform_device *pdev)  {  	struct imx_port *sport;  	void __iomem *base; -	int ret = 0; +	int ret = 0, reg;  	struct resource *res;  	int txirq, rxirq, rtsirq; @@ -1957,6 +1925,19 @@ static int serial_imx_probe(struct platform_device *pdev)  	sport->port.uartclk = clk_get_rate(sport->clk_per); +	/* For register access, we only need to enable the ipg clock. */ +	ret = clk_prepare_enable(sport->clk_ipg); +	if (ret) +		return ret; + +	/* Disable interrupts before requesting them */ +	reg = readl_relaxed(sport->port.membase + UCR1); +	reg &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | +		 UCR1_TXMPTYEN | UCR1_RTSDEN); +	writel_relaxed(reg, sport->port.membase + UCR1); + +	clk_disable_unprepare(sport->clk_ipg); +  	/*  	 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later  	 * chips only have one interrupt. @@ -1992,16 +1973,135 @@ static int serial_imx_remove(struct platform_device *pdev)  	return uart_remove_one_port(&imx_reg, &sport->port);  } +static void serial_imx_restore_context(struct imx_port *sport) +{ +	if (!sport->context_saved) +		return; + +	writel(sport->saved_reg[4], sport->port.membase + UFCR); +	writel(sport->saved_reg[5], sport->port.membase + UESC); +	writel(sport->saved_reg[6], sport->port.membase + UTIM); +	writel(sport->saved_reg[7], sport->port.membase + UBIR); +	writel(sport->saved_reg[8], sport->port.membase + UBMR); +	writel(sport->saved_reg[9], sport->port.membase + IMX21_UTS); +	writel(sport->saved_reg[0], sport->port.membase + UCR1); +	writel(sport->saved_reg[1] | UCR2_SRST, sport->port.membase + UCR2); +	writel(sport->saved_reg[2], sport->port.membase + UCR3); +	writel(sport->saved_reg[3], sport->port.membase + UCR4); +	sport->context_saved = false; +} + +static void serial_imx_save_context(struct imx_port *sport) +{ +	/* Save necessary regs */ +	sport->saved_reg[0] = readl(sport->port.membase + UCR1); +	sport->saved_reg[1] = readl(sport->port.membase + UCR2); +	sport->saved_reg[2] = readl(sport->port.membase + UCR3); +	sport->saved_reg[3] = readl(sport->port.membase + UCR4); +	sport->saved_reg[4] = readl(sport->port.membase + UFCR); +	sport->saved_reg[5] = readl(sport->port.membase + UESC); +	sport->saved_reg[6] = readl(sport->port.membase + UTIM); +	sport->saved_reg[7] = readl(sport->port.membase + UBIR); +	sport->saved_reg[8] = readl(sport->port.membase + UBMR); +	sport->saved_reg[9] = readl(sport->port.membase + IMX21_UTS); +	sport->context_saved = true; +} + +static void serial_imx_enable_wakeup(struct imx_port *sport, bool on) +{ +	unsigned int val; + +	val = readl(sport->port.membase + UCR3); +	if (on) +		val |= UCR3_AWAKEN; +	else +		val &= ~UCR3_AWAKEN; +	writel(val, sport->port.membase + UCR3); + +	val = readl(sport->port.membase + UCR1); +	if (on) +		val |= UCR1_RTSDEN; +	else +		val &= ~UCR1_RTSDEN; +	writel(val, sport->port.membase + UCR1); +} + +static int imx_serial_port_suspend_noirq(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct imx_port *sport = platform_get_drvdata(pdev); +	int ret; + +	ret = clk_enable(sport->clk_ipg); +	if (ret) +		return ret; + +	serial_imx_save_context(sport); + +	clk_disable(sport->clk_ipg); + +	return 0; +} + +static int imx_serial_port_resume_noirq(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct imx_port *sport = platform_get_drvdata(pdev); +	int ret; + +	ret = clk_enable(sport->clk_ipg); +	if (ret) +		return ret; + +	serial_imx_restore_context(sport); + +	clk_disable(sport->clk_ipg); + +	return 0; +} + +static int imx_serial_port_suspend(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct imx_port *sport = platform_get_drvdata(pdev); + +	/* enable wakeup from i.MX UART */ +	serial_imx_enable_wakeup(sport, true); + +	uart_suspend_port(&imx_reg, &sport->port); + +	return 0; +} + +static int imx_serial_port_resume(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct imx_port *sport = platform_get_drvdata(pdev); + +	/* disable wakeup from i.MX UART */ +	serial_imx_enable_wakeup(sport, false); + +	uart_resume_port(&imx_reg, &sport->port); + +	return 0; +} + +static const struct dev_pm_ops imx_serial_port_pm_ops = { +	.suspend_noirq = imx_serial_port_suspend_noirq, +	.resume_noirq = imx_serial_port_resume_noirq, +	.suspend = imx_serial_port_suspend, +	.resume = imx_serial_port_resume, +}; +  static struct platform_driver serial_imx_driver = {  	.probe		= serial_imx_probe,  	.remove		= serial_imx_remove, -	.suspend	= serial_imx_suspend, -	.resume		= serial_imx_resume,  	.id_table	= imx_uart_devtype,  	.driver		= {  		.name	= "imx-uart",  		.of_match_table = imx_uart_dt_ids, +		.pm	= &imx_serial_port_pm_ops,  	},  }; diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 4ccc0397664c..b88832e8ee82 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -21,7 +21,6 @@   */  #include <linux/slab.h> -#include <linux/module.h>  #include <linux/ioport.h>  #include <linux/init.h>  #include <linux/console.h> @@ -740,7 +739,6 @@ static const struct of_device_id ltq_asc_match[] = {  	{ .compatible = DRVNAME },  	{},  }; -MODULE_DEVICE_TABLE(of, ltq_asc_match);  static struct platform_driver lqasc_driver = {  	.driver		= { @@ -764,8 +762,4 @@ init_lqasc(void)  	return ret;  } - -module_init(init_lqasc); - -MODULE_DESCRIPTION("Lantiq serial port driver"); -MODULE_LICENSE("GPL"); +device_initcall(init_lqasc); diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 35c55505b3eb..b90e7b30468b 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -392,7 +392,6 @@ static irqreturn_t men_z135_intr(int irq, void *data)  	struct men_z135_port *uart = (struct men_z135_port *)data;  	struct uart_port *port = &uart->port;  	bool handled = false; -	unsigned long flags;  	int irq_id;  	uart->stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG); @@ -401,7 +400,7 @@ static irqreturn_t men_z135_intr(int irq, void *data)  	if (!irq_id)  		goto out; -	spin_lock_irqsave(&port->lock, flags); +	spin_lock(&port->lock);  	/* It's save to write to IIR[7:6] RXC[9:8] */  	iowrite8(irq_id, port->membase + MEN_Z135_STAT_REG); @@ -427,7 +426,7 @@ static irqreturn_t men_z135_intr(int irq, void *data)  		handled = true;  	} -	spin_unlock_irqrestore(&port->lock, flags); +	spin_unlock(&port->lock);  out:  	return IRQ_RETVAL(handled);  } @@ -717,7 +716,7 @@ static void men_z135_set_termios(struct uart_port *port,  	baud = uart_get_baud_rate(port, termios, old, 0, uart_freq / 16); -	spin_lock(&port->lock); +	spin_lock_irq(&port->lock);  	if (tty_termios_baud_rate(termios))  		tty_termios_encode_baud_rate(termios, baud, baud); @@ -725,7 +724,7 @@ static void men_z135_set_termios(struct uart_port *port,  	iowrite32(bd_reg, port->membase + MEN_Z135_BAUD_REG);  	uart_update_timeout(port, termios->c_cflag, baud); -	spin_unlock(&port->lock); +	spin_unlock_irq(&port->lock);  }  static const char *men_z135_type(struct uart_port *port) @@ -840,7 +839,6 @@ static int men_z135_probe(struct mcb_device *mdev,  	uart->port.membase = NULL;  	uart->mdev = mdev; -	spin_lock_init(&uart->port.lock);  	spin_lock_init(&uart->lock);  	err = uart_add_one_port(&men_z135_driver, &uart->port); diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 6fc07eb9d74e..41de374d9784 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -239,8 +239,9 @@ static int mpc52xx_psc_tx_rdy(struct uart_port *port)  static int mpc52xx_psc_tx_empty(struct uart_port *port)  { -	return in_be16(&PSC(port)->mpc52xx_psc_status) -	    & MPC52xx_PSC_SR_TXEMP; +	u16 sts = in_be16(&PSC(port)->mpc52xx_psc_status); + +	return (sts & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;  }  static void mpc52xx_psc_start_tx(struct uart_port *port) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 13cf7738fbdc..7c7f30809849 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -100,6 +100,8 @@  #define AUART_CTRL2_TXE				(1 << 8)  #define AUART_CTRL2_UARTEN			(1 << 0) +#define AUART_LINECTRL_BAUD_DIV_MAX		0x003fffc0 +#define AUART_LINECTRL_BAUD_DIV_MIN		0x000000ec  #define AUART_LINECTRL_BAUD_DIVINT_SHIFT	16  #define AUART_LINECTRL_BAUD_DIVINT_MASK		0xffff0000  #define AUART_LINECTRL_BAUD_DIVINT(v)		(((v) & 0xffff) << 16) @@ -659,7 +661,7 @@ static void mxs_auart_settermios(struct uart_port *u,  {  	struct mxs_auart_port *s = to_auart_port(u);  	u32 bm, ctrl, ctrl2, div; -	unsigned int cflag, baud; +	unsigned int cflag, baud, baud_min, baud_max;  	cflag = termios->c_cflag; @@ -752,7 +754,9 @@ static void mxs_auart_settermios(struct uart_port *u,  	}  	/* set baud rate */ -	baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); +	baud_min = DIV_ROUND_UP(u->uartclk * 32, AUART_LINECTRL_BAUD_DIV_MAX); +	baud_max = u->uartclk * 32 / AUART_LINECTRL_BAUD_DIV_MIN; +	baud = uart_get_baud_rate(u, termios, old, baud_min, baud_max);  	div = u->uartclk * 32 / baud;  	ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);  	ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6); @@ -842,7 +846,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)  	return IRQ_HANDLED;  } -static void mxs_auart_reset(struct uart_port *u) +static void mxs_auart_reset_deassert(struct uart_port *u)  {  	int i;  	unsigned int reg; @@ -858,6 +862,30 @@ static void mxs_auart_reset(struct uart_port *u)  	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);  } +static void mxs_auart_reset_assert(struct uart_port *u) +{ +	int i; +	u32 reg; + +	reg = readl(u->membase + AUART_CTRL0); +	/* if already in reset state, keep it untouched */ +	if (reg & AUART_CTRL0_SFTRST) +		return; + +	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); +	writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_SET); + +	for (i = 0; i < 1000; i++) { +		reg = readl(u->membase + AUART_CTRL0); +		/* reset is finished when the clock is gated */ +		if (reg & AUART_CTRL0_CLKGATE) +			return; +		udelay(10); +	} + +	dev_err(u->dev, "Failed to reset the unit."); +} +  static int mxs_auart_startup(struct uart_port *u)  {  	int ret; @@ -867,7 +895,13 @@ static int mxs_auart_startup(struct uart_port *u)  	if (ret)  		return ret; -	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); +	if (uart_console(u)) { +		writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); +	} else { +		/* reset the unit to a well known state */ +		mxs_auart_reset_assert(u); +		mxs_auart_reset_deassert(u); +	}  	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET); @@ -899,12 +933,14 @@ static void mxs_auart_shutdown(struct uart_port *u)  	if (auart_dma_enabled(s))  		mxs_auart_dma_exit(s); -	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); - -	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, -			u->membase + AUART_INTR_CLR); - -	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); +	if (uart_console(u)) { +		writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); +		writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, +				u->membase + AUART_INTR_CLR); +		writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); +	} else { +		mxs_auart_reset_assert(u); +	}  	clk_disable_unprepare(s->clk);  } @@ -1291,7 +1327,7 @@ static int mxs_auart_probe(struct platform_device *pdev)  	auart_port[s->port.line] = s; -	mxs_auart_reset(&s->port); +	mxs_auart_reset_deassert(&s->port);  	ret = uart_add_one_port(&auart_driver, &s->port);  	if (ret) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 67d0c213b1c7..856686d6dcdb 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -53,7 +53,6 @@  #include "samsung.h"  #if	defined(CONFIG_SERIAL_SAMSUNG_DEBUG) &&	\ -	defined(CONFIG_DEBUG_LL) &&		\  	!defined(MODULE)  extern void printascii(const char *); @@ -295,15 +294,6 @@ static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport,  	if (ourport->tx_mode != S3C24XX_TX_DMA)  		enable_tx_dma(ourport); -	while (xmit->tail & (dma_get_cache_alignment() - 1)) { -		if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) -			return 0; -		wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); -		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -		port->icount.tx++; -		count--; -	} -  	dma->tx_size = count & ~(dma_get_cache_alignment() - 1);  	dma->tx_transfer_addr = dma->tx_addr + xmit->tail; @@ -342,7 +332,9 @@ static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport)  		return;  	} -	if (!ourport->dma || !ourport->dma->tx_chan || count < port->fifosize) +	if (!ourport->dma || !ourport->dma->tx_chan || +	    count < ourport->min_dma_size || +	    xmit->tail & (dma_get_cache_alignment() - 1))  		s3c24xx_serial_start_tx_pio(ourport);  	else  		s3c24xx_serial_start_tx_dma(ourport, count); @@ -736,15 +728,20 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)  	struct uart_port *port = &ourport->port;  	struct circ_buf *xmit = &port->state->xmit;  	unsigned long flags; -	int count; +	int count, dma_count = 0;  	spin_lock_irqsave(&port->lock, flags);  	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); -	if (ourport->dma && ourport->dma->tx_chan && count >= port->fifosize) { -		s3c24xx_serial_start_tx_dma(ourport, count); -		goto out; +	if (ourport->dma && ourport->dma->tx_chan && +	    count >= ourport->min_dma_size) { +		int align = dma_get_cache_alignment() - +			(xmit->tail & (dma_get_cache_alignment() - 1)); +		if (count-align >= ourport->min_dma_size) { +			dma_count = count-align; +			count = align; +		}  	}  	if (port->x_char) { @@ -765,14 +762,24 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)  	/* try and drain the buffer... */ -	count = port->fifosize; -	while (!uart_circ_empty(xmit) && count-- > 0) { +	if (count > port->fifosize) { +		count = port->fifosize; +		dma_count = 0; +	} + +	while (!uart_circ_empty(xmit) && count > 0) {  		if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)  			break;  		wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);  		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);  		port->icount.tx++; +		count--; +	} + +	if (!count && dma_count) { +		s3c24xx_serial_start_tx_dma(ourport, dma_count); +		goto out;  	}  	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { @@ -1838,6 +1845,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)  	else if (ourport->info->fifosize)  		ourport->port.fifosize = ourport->info->fifosize; +	/* +	 * DMA transfers must be aligned at least to cache line size, +	 * so find minimal transfer size suitable for DMA mode +	 */ +	ourport->min_dma_size = max_t(int, ourport->port.fifosize, +				    dma_get_cache_alignment()); +  	probe_index++;  	dbg("%s: initialising port %p...\n", __func__, ourport); diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index d275032aa68d..fc5deaa4f382 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -82,6 +82,7 @@ struct s3c24xx_uart_port {  	unsigned char			tx_claimed;  	unsigned int			pm_level;  	unsigned long			baudclk_rate; +	unsigned int			min_dma_size;  	unsigned int			rx_irq;  	unsigned int			tx_irq; diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 9e6576004a42..72ffd0dcab78 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -11,6 +11,8 @@   *   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/bitops.h>  #include <linux/clk.h>  #include <linux/delay.h> @@ -29,6 +31,7 @@  #include <linux/uaccess.h>  #define SC16IS7XX_NAME			"sc16is7xx" +#define SC16IS7XX_MAX_DEVS		8  /* SC16IS7XX register definitions */  #define SC16IS7XX_RHR_REG		(0x00) /* RX FIFO */ @@ -312,14 +315,14 @@ struct sc16is7xx_one_config {  struct sc16is7xx_one {  	struct uart_port		port; +	u8				line;  	struct kthread_work		tx_work;  	struct kthread_work		reg_work;  	struct sc16is7xx_one_config	config;  };  struct sc16is7xx_port { -	struct uart_driver		uart; -	struct sc16is7xx_devtype	*devtype; +	const struct sc16is7xx_devtype	*devtype;  	struct regmap			*regmap;  	struct clk			*clk;  #ifdef CONFIG_GPIOLIB @@ -332,16 +335,31 @@ struct sc16is7xx_port {  	struct sc16is7xx_one		p[0];  }; +static unsigned long sc16is7xx_lines; + +static struct uart_driver sc16is7xx_uart = { +	.owner		= THIS_MODULE, +	.dev_name	= "ttySC", +	.nr		= SC16IS7XX_MAX_DEVS, +}; +  #define to_sc16is7xx_port(p,e)	((container_of((p), struct sc16is7xx_port, e)))  #define to_sc16is7xx_one(p,e)	((container_of((p), struct sc16is7xx_one, e))) +static int sc16is7xx_line(struct uart_port *port) +{ +	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); + +	return one->line; +} +  static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)  {  	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);  	unsigned int val = 0; +	const u8 line = sc16is7xx_line(port); -	regmap_read(s->regmap, -		    (reg << SC16IS7XX_REG_SHIFT) | port->line, &val); +	regmap_read(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, &val);  	return val;  } @@ -349,21 +367,55 @@ static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)  static void sc16is7xx_port_write(struct uart_port *port, u8 reg, u8 val)  {  	struct sc16is7xx_port *s = dev_get_drvdata(port->dev); +	const u8 line = sc16is7xx_line(port); + +	regmap_write(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, val); +} + +static void sc16is7xx_fifo_read(struct uart_port *port, unsigned int rxlen) +{ +	struct sc16is7xx_port *s = dev_get_drvdata(port->dev); +	const u8 line = sc16is7xx_line(port); +	u8 addr = (SC16IS7XX_RHR_REG << SC16IS7XX_REG_SHIFT) | line; + +	regcache_cache_bypass(s->regmap, true); +	regmap_raw_read(s->regmap, addr, s->buf, rxlen); +	regcache_cache_bypass(s->regmap, false); +} + +static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send) +{ +	struct sc16is7xx_port *s = dev_get_drvdata(port->dev); +	const u8 line = sc16is7xx_line(port); +	u8 addr = (SC16IS7XX_THR_REG << SC16IS7XX_REG_SHIFT) | line; -	regmap_write(s->regmap, -		     (reg << SC16IS7XX_REG_SHIFT) | port->line, val); +	regcache_cache_bypass(s->regmap, true); +	regmap_raw_write(s->regmap, addr, s->buf, to_send); +	regcache_cache_bypass(s->regmap, false);  }  static void sc16is7xx_port_update(struct uart_port *port, u8 reg,  				  u8 mask, u8 val)  {  	struct sc16is7xx_port *s = dev_get_drvdata(port->dev); +	const u8 line = sc16is7xx_line(port); -	regmap_update_bits(s->regmap, -			   (reg << SC16IS7XX_REG_SHIFT) | port->line, +	regmap_update_bits(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line,  			   mask, val);  } +static int sc16is7xx_alloc_line(void) +{ +	int i; + +	BUILD_BUG_ON(SC16IS7XX_MAX_DEVS > BITS_PER_LONG); + +	for (i = 0; i < SC16IS7XX_MAX_DEVS; i++) +		if (!test_and_set_bit(i, &sc16is7xx_lines)) +			break; + +	return i; +}  static void sc16is7xx_power(struct uart_port *port, int on)  { @@ -488,7 +540,7 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,  	if (unlikely(rxlen >= sizeof(s->buf))) {  		dev_warn_ratelimited(port->dev, -				     "Port %i: Possible RX FIFO overrun: %d\n", +				     "ttySC%i: Possible RX FIFO overrun: %d\n",  				     port->line, rxlen);  		port->icount.buf_overrun++;  		/* Ensure sanity of RX level */ @@ -508,10 +560,7 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,  			s->buf[0] = sc16is7xx_port_read(port, SC16IS7XX_RHR_REG);  			bytes_read = 1;  		} else { -			regcache_cache_bypass(s->regmap, true); -			regmap_raw_read(s->regmap, SC16IS7XX_RHR_REG, -					s->buf, rxlen); -			regcache_cache_bypass(s->regmap, false); +			sc16is7xx_fifo_read(port, rxlen);  			bytes_read = rxlen;  		} @@ -591,9 +640,8 @@ static void sc16is7xx_handle_tx(struct uart_port *port)  			s->buf[i] = xmit->buf[xmit->tail];  			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);  		} -		regcache_cache_bypass(s->regmap, true); -		regmap_raw_write(s->regmap, SC16IS7XX_THR_REG, s->buf, to_send); -		regcache_cache_bypass(s->regmap, false); + +		sc16is7xx_fifo_write(port, to_send);  	}  	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -633,7 +681,7 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)  			break;  		default:  			dev_err_ratelimited(port->dev, -					    "Port %i: Unexpected interrupt: %x", +					    "ttySC%i: Unexpected interrupt: %x",  					    port->line, iir);  			break;  		} @@ -645,7 +693,7 @@ static void sc16is7xx_ist(struct kthread_work *ws)  	struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work);  	int i; -	for (i = 0; i < s->uart.nr; ++i) +	for (i = 0; i < s->devtype->nr_uart; ++i)  		sc16is7xx_port_irq(s, i);  } @@ -1083,7 +1131,7 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip,  #endif  static int sc16is7xx_probe(struct device *dev, -			   struct sc16is7xx_devtype *devtype, +			   const struct sc16is7xx_devtype *devtype,  			   struct regmap *regmap, int irq, unsigned long flags)  {  	struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO / 2 }; @@ -1118,23 +1166,13 @@ static int sc16is7xx_probe(struct device *dev,  	s->devtype = devtype;  	dev_set_drvdata(dev, s); -	/* Register UART driver */ -	s->uart.owner		= THIS_MODULE; -	s->uart.dev_name	= "ttySC"; -	s->uart.nr		= devtype->nr_uart; -	ret = uart_register_driver(&s->uart); -	if (ret) { -		dev_err(dev, "Registering UART driver failed\n"); -		goto out_clk; -	} -  	init_kthread_worker(&s->kworker);  	init_kthread_work(&s->irq_work, sc16is7xx_ist);  	s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker,  				      "sc16is7xx");  	if (IS_ERR(s->kworker_task)) {  		ret = PTR_ERR(s->kworker_task); -		goto out_uart; +		goto out_clk;  	}  	sched_setscheduler(s->kworker_task, SCHED_FIFO, &sched_param); @@ -1158,8 +1196,8 @@ static int sc16is7xx_probe(struct device *dev,  #endif  	for (i = 0; i < devtype->nr_uart; ++i) { +		s->p[i].line		= i;  		/* Initialize port data */ -		s->p[i].port.line	= i;  		s->p[i].port.dev	= dev;  		s->p[i].port.irq	= irq;  		s->p[i].port.type	= PORT_SC16IS7XX; @@ -1169,6 +1207,12 @@ static int sc16is7xx_probe(struct device *dev,  		s->p[i].port.uartclk	= freq;  		s->p[i].port.rs485_config = sc16is7xx_config_rs485;  		s->p[i].port.ops	= &sc16is7xx_ops; +		s->p[i].port.line	= sc16is7xx_alloc_line(); +		if (s->p[i].port.line >= SC16IS7XX_MAX_DEVS) { +			ret = -ENOMEM; +			goto out_ports; +		} +  		/* Disable all interrupts */  		sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_IER_REG, 0);  		/* Disable TX/RX */ @@ -1179,7 +1223,7 @@ static int sc16is7xx_probe(struct device *dev,  		init_kthread_work(&s->p[i].tx_work, sc16is7xx_tx_proc);  		init_kthread_work(&s->p[i].reg_work, sc16is7xx_reg_proc);  		/* Register port */ -		uart_add_one_port(&s->uart, &s->p[i].port); +		uart_add_one_port(&sc16is7xx_uart, &s->p[i].port);  		/* Go to suspend mode */  		sc16is7xx_power(&s->p[i].port, 0);  	} @@ -1190,8 +1234,11 @@ static int sc16is7xx_probe(struct device *dev,  	if (!ret)  		return 0; -	for (i = 0; i < s->uart.nr; i++) -		uart_remove_one_port(&s->uart, &s->p[i].port); +out_ports: +	for (i--; i >= 0; i--) { +		uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); +		clear_bit(s->p[i].port.line, &sc16is7xx_lines); +	}  #ifdef CONFIG_GPIOLIB  	if (devtype->nr_gpio) @@ -1201,9 +1248,6 @@ out_thread:  #endif  	kthread_stop(s->kworker_task); -out_uart: -	uart_unregister_driver(&s->uart); -  out_clk:  	if (!IS_ERR(s->clk))  		clk_disable_unprepare(s->clk); @@ -1221,15 +1265,15 @@ static int sc16is7xx_remove(struct device *dev)  		gpiochip_remove(&s->gpio);  #endif -	for (i = 0; i < s->uart.nr; i++) { -		uart_remove_one_port(&s->uart, &s->p[i].port); +	for (i = 0; i < s->devtype->nr_uart; i++) { +		uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); +		clear_bit(s->p[i].port.line, &sc16is7xx_lines);  		sc16is7xx_power(&s->p[i].port, 0);  	}  	flush_kthread_worker(&s->kworker);  	kthread_stop(s->kworker_task); -	uart_unregister_driver(&s->uart);  	if (!IS_ERR(s->clk))  		clk_disable_unprepare(s->clk); @@ -1259,7 +1303,7 @@ static struct regmap_config regcfg = {  #ifdef CONFIG_SERIAL_SC16IS7XX_SPI  static int sc16is7xx_spi_probe(struct spi_device *spi)  { -	struct sc16is7xx_devtype *devtype; +	const struct sc16is7xx_devtype *devtype;  	unsigned long flags = 0;  	struct regmap *regmap;  	int ret; @@ -1328,7 +1372,7 @@ MODULE_ALIAS("spi:sc16is7xx");  static int sc16is7xx_i2c_probe(struct i2c_client *i2c,  			       const struct i2c_device_id *id)  { -	struct sc16is7xx_devtype *devtype; +	const struct sc16is7xx_devtype *devtype;  	unsigned long flags = 0;  	struct regmap *regmap; @@ -1369,7 +1413,6 @@ MODULE_DEVICE_TABLE(i2c, sc16is7xx_i2c_id_table);  static struct i2c_driver sc16is7xx_i2c_uart_driver = {  	.driver = {  		.name		= SC16IS7XX_NAME, -		.owner		= THIS_MODULE,  		.of_match_table	= of_match_ptr(sc16is7xx_dt_ids),  	},  	.probe		= sc16is7xx_i2c_probe, @@ -1382,7 +1425,14 @@ MODULE_ALIAS("i2c:sc16is7xx");  static int __init sc16is7xx_init(void)  { -	int ret = 0; +	int ret; + +	ret = uart_register_driver(&sc16is7xx_uart); +	if (ret) { +		pr_err("Registering UART driver failed\n"); +		return ret; +	} +  #ifdef CONFIG_SERIAL_SC16IS7XX_I2C  	ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver);  	if (ret < 0) { @@ -1411,6 +1461,7 @@ static void __exit sc16is7xx_exit(void)  #ifdef CONFIG_SERIAL_SC16IS7XX_SPI  	spi_unregister_driver(&sc16is7xx_spi_uart_driver);  #endif +	uart_unregister_driver(&sc16is7xx_uart);  }  module_exit(sc16is7xx_exit); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 7ae1592f7ec9..603d2cc3f424 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1377,7 +1377,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)  	struct uart_state *state = tty->driver_data;  	struct tty_port *port;  	struct uart_port *uport; -	unsigned long flags;  	if (!state) {  		struct uart_driver *drv = tty->driver->driver_state; @@ -1403,10 +1402,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)  	 * disable the receive line status interrupts.  	 */  	if (port->flags & ASYNC_INITIALIZED) { -		unsigned long flags; -		spin_lock_irqsave(&uport->lock, flags); +		spin_lock_irq(&uport->lock);  		uport->ops->stop_rx(uport); -		spin_unlock_irqrestore(&uport->lock, flags); +		spin_unlock_irq(&uport->lock);  		/*  		 * Before we drop DTR, make sure the UART transmitter  		 * has completely drained; this is especially @@ -1418,18 +1416,18 @@ static void uart_close(struct tty_struct *tty, struct file *filp)  	mutex_lock(&port->mutex);  	uart_shutdown(tty, state);  	tty_port_tty_set(port, NULL); -	tty->closing = 0; -	spin_lock_irqsave(&port->lock, flags); + +	spin_lock_irq(&port->lock);  	if (port->blocked_open) { -		spin_unlock_irqrestore(&port->lock, flags); +		spin_unlock_irq(&port->lock);  		if (port->close_delay)  			msleep_interruptible(jiffies_to_msecs(port->close_delay)); -		spin_lock_irqsave(&port->lock, flags); +		spin_lock_irq(&port->lock);  	} else if (!uart_console(uport)) { -		spin_unlock_irqrestore(&port->lock, flags); +		spin_unlock_irq(&port->lock);  		uart_change_pm(state, UART_PM_STATE_OFF); -		spin_lock_irqsave(&port->lock, flags); +		spin_lock_irq(&port->lock);  	}  	/* @@ -1437,13 +1435,14 @@ static void uart_close(struct tty_struct *tty, struct file *filp)  	 */  	clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);  	clear_bit(ASYNCB_CLOSING, &port->flags); -	spin_unlock_irqrestore(&port->lock, flags); +	spin_unlock_irq(&port->lock);  	wake_up_interruptible(&port->open_wait);  	wake_up_interruptible(&port->close_wait);  	mutex_unlock(&port->mutex);  	tty_ldisc_flush(tty); +	tty->closing = 0;  }  static void uart_wait_until_sent(struct tty_struct *tty, int timeout) @@ -1531,11 +1530,6 @@ static void uart_hangup(struct tty_struct *tty)  	mutex_unlock(&port->mutex);  } -static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) -{ -	return 0; -} -  static void uart_port_shutdown(struct tty_port *port)  {  	struct uart_state *state = container_of(port, struct uart_state, port); @@ -2378,8 +2372,6 @@ static const struct tty_operations uart_ops = {  };  static const struct tty_port_operations uart_port_ops = { -	.activate	= uart_port_activate, -	.shutdown	= uart_port_shutdown,  	.carrier_raised = uart_carrier_raised,  	.dtr_rts	= uart_dtr_rts,  }; diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 653cdd5fb508..c6657de78997 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -413,7 +413,6 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count)  			break;  	} -	sirfport->rx_io_count += rx_count;  	port->icount.rx += rx_count;  	return rx_count; @@ -600,7 +599,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port)  	struct sirfsoc_uart_port *sirfport = to_sirfport(port);  	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;  	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; -	sirfport->rx_io_count = 0;  	wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,  		rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) &  		~SIRFUART_IO_MODE); @@ -632,31 +630,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port)  				sirfport->uart_reg->uart_type));  } -static void sirfsoc_uart_start_rx(struct uart_port *port) -{ -	struct sirfsoc_uart_port *sirfport = to_sirfport(port); -	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; -	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; - -	sirfport->rx_io_count = 0; -	wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); -	wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); -	wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); -	if (sirfport->rx_dma_chan) -		sirfsoc_uart_start_next_rx_dma(port); -	else { -		if (!sirfport->is_atlas7) -			wr_regl(port, ureg->sirfsoc_int_en_reg, -				rd_regl(port, ureg->sirfsoc_int_en_reg) | -				SIRFUART_RX_IO_INT_EN(uint_en, -					sirfport->uart_reg->uart_type)); -		else -			wr_regl(port, ureg->sirfsoc_int_en_reg, -				SIRFUART_RX_IO_INT_EN(uint_en, -					sirfport->uart_reg->uart_type)); -	} -} -  static unsigned int  sirfsoc_usp_calc_sample_div(unsigned long set_rate,  		unsigned long ioclk_rate, unsigned long *sample_reg) @@ -850,7 +823,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,  	rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000);  	rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out);  	txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op); -	wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_STOP);  	wr_regl(port, ureg->sirfsoc_tx_fifo_op,  			(txfifo_op_reg & ~SIRFUART_FIFO_START));  	if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { @@ -886,9 +858,13 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,  	else  		wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE);  	if (sirfport->rx_dma_chan) -		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE); +		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, +			rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & +			~SIRFUART_IO_MODE);  	else -		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE); +		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, +			rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | +			SIRFUART_IO_MODE);  	sirfport->rx_period_time = 20000000;  	/* Reset Rx/Tx FIFO Threshold level for proper baudrate */  	if (set_baud < 1000000) @@ -902,7 +878,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,  	txfifo_op_reg |= SIRFUART_FIFO_START;  	wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg);  	uart_update_timeout(port, termios->c_cflag, set_baud); -	sirfsoc_uart_start_rx(port);  	wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN);  	spin_unlock_irqrestore(&port->lock, flags);  } @@ -921,6 +896,7 @@ static int sirfsoc_uart_startup(struct uart_port *port)  {  	struct sirfsoc_uart_port *sirfport	= to_sirfport(port);  	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; +	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;  	unsigned int index			= port->line;  	int ret;  	irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN); @@ -958,9 +934,9 @@ static int sirfsoc_uart_startup(struct uart_port *port)  	wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port));  	if (sirfport->rx_dma_chan)  		wr_regl(port, ureg->sirfsoc_rx_fifo_level_chk, -			SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) | -			SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) | -			SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b)); +			SIRFUART_RX_FIFO_CHK_SC(port->line, 0x1) | +			SIRFUART_RX_FIFO_CHK_LC(port->line, 0x2) | +			SIRFUART_RX_FIFO_CHK_HC(port->line, 0x4));  	if (sirfport->tx_dma_chan) {  		sirfport->tx_dma_state = TX_DMA_IDLE;  		wr_regl(port, ureg->sirfsoc_tx_fifo_level_chk, @@ -981,16 +957,41 @@ static int sirfsoc_uart_startup(struct uart_port *port)  			goto init_rx_err;  		}  	} -	enable_irq(port->irq); +	if (sirfport->uart_reg->uart_type == SIRF_REAL_UART && +		sirfport->rx_dma_chan) +		wr_regl(port, ureg->sirfsoc_swh_dma_io, +			SIRFUART_CLEAR_RX_ADDR_EN); +	if (sirfport->uart_reg->uart_type == SIRF_USP_UART && +			sirfport->rx_dma_chan) +		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, +			rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | +			SIRFSOC_USP_FRADDR_CLR_EN);  	if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) {  		sirfport->is_hrt_enabled = true;  		sirfport->rx_period_time = 20000000; +		sirfport->rx_last_pos = -1; +		sirfport->pio_fetch_cnt = 0;  		sirfport->rx_dma_items.xmit.tail =  			sirfport->rx_dma_items.xmit.head = 0;  		hrtimer_start(&sirfport->hrt,  			ns_to_ktime(sirfport->rx_period_time),  			HRTIMER_MODE_REL);  	} +	wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); +	if (sirfport->rx_dma_chan) +		sirfsoc_uart_start_next_rx_dma(port); +	else { +		if (!sirfport->is_atlas7) +			wr_regl(port, ureg->sirfsoc_int_en_reg, +				rd_regl(port, ureg->sirfsoc_int_en_reg) | +				SIRFUART_RX_IO_INT_EN(uint_en, +					sirfport->uart_reg->uart_type)); +		else +			wr_regl(port, ureg->sirfsoc_int_en_reg, +				SIRFUART_RX_IO_INT_EN(uint_en, +					sirfport->uart_reg->uart_type)); +	} +	enable_irq(port->irq);  	return 0;  init_rx_err: @@ -1003,6 +1004,9 @@ static void sirfsoc_uart_shutdown(struct uart_port *port)  {  	struct sirfsoc_uart_port *sirfport = to_sirfport(port);  	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; +	struct circ_buf *xmit; + +	xmit = &sirfport->rx_dma_items.xmit;  	if (!sirfport->is_atlas7)  		wr_regl(port, ureg->sirfsoc_int_en_reg, 0);  	else @@ -1019,8 +1023,10 @@ static void sirfsoc_uart_shutdown(struct uart_port *port)  	if (sirfport->tx_dma_chan)  		sirfport->tx_dma_state = TX_DMA_IDLE;  	if (sirfport->rx_dma_chan && sirfport->is_hrt_enabled) { -		while ((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & -			SIRFUART_RX_FIFO_MASK) > 0) +		while (((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & +			SIRFUART_RX_FIFO_MASK) > sirfport->pio_fetch_cnt) && +			!CIRC_CNT(xmit->head, xmit->tail, +			SIRFSOC_RX_DMA_BUF_SIZE))  			;  		sirfport->is_hrt_enabled = false;  		hrtimer_cancel(&sirfport->hrt); @@ -1169,6 +1175,8 @@ static enum hrtimer_restart  	struct tty_struct *tty;  	struct sirfsoc_register *ureg;  	struct circ_buf *xmit; +	struct sirfsoc_fifo_status *ufifo_st; +	int max_pio_cnt;  	sirfport = container_of(hrt, struct sirfsoc_uart_port, hrt);  	port = &sirfport->port; @@ -1176,9 +1184,16 @@ static enum hrtimer_restart  	tty = port->state->port.tty;  	ureg = &sirfport->uart_reg->uart_reg;  	xmit = &sirfport->rx_dma_items.xmit; +	ufifo_st = &sirfport->uart_reg->fifo_status; +  	dmaengine_tx_status(sirfport->rx_dma_chan, -		sirfport->rx_dma_items.cookie, &tx_state); -	xmit->head = SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; +			sirfport->rx_dma_items.cookie, &tx_state); +	if (SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue != +		sirfport->rx_last_pos) { +		xmit->head = SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; +		sirfport->rx_last_pos = xmit->head; +		sirfport->pio_fetch_cnt = 0; +	}  	count = CIRC_CNT_TO_END(xmit->head, xmit->tail,  			SIRFSOC_RX_DMA_BUF_SIZE);  	while (count > 0) { @@ -1200,23 +1215,38 @@ static enum hrtimer_restart  	 */  	if (!inserted && !count &&  		((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & -		SIRFUART_RX_FIFO_MASK) > 0)) { +		SIRFUART_RX_FIFO_MASK) > sirfport->pio_fetch_cnt)) { +		dmaengine_pause(sirfport->rx_dma_chan);  		/* switch to pio mode */  		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,  			rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) |  			SIRFUART_IO_MODE); -		while ((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & -			SIRFUART_RX_FIFO_MASK) > 0) { -			if (sirfsoc_uart_pio_rx_chars(port, 16) > 0) -				tty_flip_buffer_push(tty->port); +		/* +		 * UART controller SWH_DMA_IO register have CLEAR_RX_ADDR_EN +		 * When found changing I/O to DMA mode, it clears +		 * two low bits of read point; +		 * USP have similar FRADDR_CLR_EN bit in USP_RX_DMA_IO_CTRL. +		 * Fetch data out from rxfifo into DMA buffer in PIO mode, +		 * while switch back to DMA mode, the data fetched will override +		 * by DMA, as hardware have a strange behaviour: +		 * after switch back to DMA mode, check rxfifo status it will +		 * be the number PIO fetched, so record the fetched data count +		 * to avoid the repeated fetch +		 */ +		max_pio_cnt = 3; +		while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) & +			ufifo_st->ff_empty(port)) && max_pio_cnt--) { +			xmit->buf[xmit->head] = +				rd_regl(port, ureg->sirfsoc_rx_fifo_data); +			xmit->head = (xmit->head + 1) & +					(SIRFSOC_RX_DMA_BUF_SIZE - 1); +			sirfport->pio_fetch_cnt++;  		} -		wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); -		wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); -		wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START);  		/* switch back to dma mode */  		wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,  			rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) &  			~SIRFUART_IO_MODE); +		dmaengine_resume(sirfport->rx_dma_chan);  	}  next_hrt:  	hrtimer_forward_now(hrt, ns_to_ktime(sirfport->rx_period_time)); @@ -1239,7 +1269,7 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)  	struct resource *res;  	int ret;  	struct dma_slave_config slv_cfg = { -		.src_maxburst = 2, +		.src_maxburst = 1,  	};  	struct dma_slave_config tx_slv_cfg = {  		.dst_maxburst = 2, diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index eb162b012eec..c3a885b4d76a 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h @@ -296,6 +296,7 @@ struct sirfsoc_uart_register sirfsoc_uart = {  #define SIRFUART_DMA_MODE			0x0  #define SIRFUART_RX_DMA_FLUSH			0x4 +#define SIRFUART_CLEAR_RX_ADDR_EN		0x2  /* Baud Rate Calculation */  #define SIRF_USP_MIN_SAMPLE_DIV			0x1  #define SIRF_MIN_SAMPLE_DIV			0xf @@ -325,6 +326,7 @@ struct sirfsoc_uart_register sirfsoc_uart = {  #define SIRFSOC_USP_ASYNC_DIV2_MASK		0x3f  #define SIRFSOC_USP_ASYNC_DIV2_OFFSET		16  #define SIRFSOC_USP_LOOP_BACK_CTRL		BIT(2) +#define SIRFSOC_USP_FRADDR_CLR_EN		BIT(1)  /* USP-UART Common */  #define SIRFSOC_UART_RX_TIMEOUT(br, to)	(((br) * (((to) + 999) / 1000)) / 1000)  #define SIRFUART_RECV_TIMEOUT_VALUE(x)	\ @@ -421,7 +423,6 @@ struct sirfsoc_uart_port {  	struct dma_chan			*tx_dma_chan;  	dma_addr_t			tx_dma_addr;  	struct dma_async_tx_descriptor	*tx_dma_desc; -	unsigned int			rx_io_count;  	unsigned long			transfer_size;  	enum sirfsoc_tx_state		tx_dma_state;  	unsigned int			cts_gpio; @@ -431,6 +432,8 @@ struct sirfsoc_uart_port {  	struct hrtimer			hrt;  	bool				is_hrt_enabled;  	unsigned long			rx_period_time; +	unsigned long			rx_last_pos; +	unsigned long			pio_fetch_cnt;  };  /* Register Access Control */ diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index 33e94e56dcdb..d4692d888e9d 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c @@ -42,7 +42,7 @@  #include <linux/tty_flip.h>  #include <linux/serial.h>  #include <linux/console.h> -#include <linux/module.h> +#include <linux/init.h>  #include <linux/sysrq.h>  #include <linux/circ_buf.h>  #include <linux/serial_reg.h> @@ -659,7 +659,7 @@ static void sn_sal_timer_poll(unsigned long data)   * @port: Our sn_cons_port (which contains the uart port)   *   * So this is used by sn_sal_serial_console_init (early on, before we're - * registered with serial core).  It's also used by sn_sal_module_init + * registered with serial core).  It's also used by sn_sal_init   * right after we've registered with serial core.  The later only happens   * if we didn't already come through here via sn_sal_serial_console_init.   * @@ -709,7 +709,7 @@ static void __init sn_sal_switch_to_asynch(struct sn_cons_port *port)   * sn_sal_switch_to_interrupts - Switch to interrupt driven mode   * @port: Our sn_cons_port (which contains the uart port)   * - * In sn_sal_module_init, after we're registered with serial core and + * In sn_sal_init, after we're registered with serial core and   * the port is added, this function is called to switch us to interrupt   * mode.  We were previously in asynch/polling mode (using init_timer).   * @@ -773,7 +773,7 @@ static struct uart_driver sal_console_uart = {  };  /** - * sn_sal_module_init - When the kernel loads us, get us rolling w/ serial core + * sn_sal_init - When the kernel loads us, get us rolling w/ serial core   *   * Before this is called, we've been printing kernel messages in a special   * early mode not making use of the serial core infrastructure.  When our @@ -781,7 +781,7 @@ static struct uart_driver sal_console_uart = {   * core and try to enable interrupt driven mode.   *   */ -static int __init sn_sal_module_init(void) +static int __init sn_sal_init(void)  {  	int retval; @@ -811,7 +811,7 @@ static int __init sn_sal_module_init(void)  	if (uart_register_driver(&sal_console_uart) < 0) {  		printk -		    ("ERROR sn_sal_module_init failed uart_register_driver, line %d\n", +		    ("ERROR sn_sal_init failed uart_register_driver, line %d\n",  		     __LINE__);  		return -ENODEV;  	} @@ -832,33 +832,19 @@ static int __init sn_sal_module_init(void)  	/* when this driver is compiled in, the console initialization  	 * will have already switched us into asynchronous operation -	 * before we get here through the module initcalls */ +	 * before we get here through the initcalls */  	if (!sal_console_port.sc_is_asynch) {  		sn_sal_switch_to_asynch(&sal_console_port);  	} -	/* at this point (module_init) we can try to turn on interrupts */ +	/* at this point (device_init) we can try to turn on interrupts */  	if (!IS_RUNNING_ON_SIMULATOR()) {  		sn_sal_switch_to_interrupts(&sal_console_port);  	}  	sn_process_input = 1;  	return 0;  } - -/** - * sn_sal_module_exit - When we're unloaded, remove the driver/port - * - */ -static void __exit sn_sal_module_exit(void) -{ -	del_timer_sync(&sal_console_port.sc_timer); -	uart_remove_one_port(&sal_console_uart, &sal_console_port.sc_port); -	uart_unregister_driver(&sal_console_uart); -	misc_deregister(&misc); -} - -module_init(sn_sal_module_init); -module_exit(sn_sal_module_exit); +device_initcall(sn_sal_init);  /**   * puts_raw_fixed - sn_sal_console_write helper for adding \r's as required diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 4a6eab6da63e..e3de9c6d2226 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -6,7 +6,7 @@   * Inspired by st-asc.c from STMicroelectronics (c)   */ -#if defined(CONFIG_SERIAL_STM32_USART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#if defined(CONFIG_SERIAL_STM32_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)  #define SUPPORT_SYSRQ  #endif diff --git a/drivers/tty/serial/suncore.c b/drivers/tty/serial/suncore.c index 6e4ac8db2d79..127472bd6a7c 100644 --- a/drivers/tty/serial/suncore.c +++ b/drivers/tty/serial/suncore.c @@ -10,7 +10,6 @@   * Copyright (C) 2002 David S. Miller ([email protected])   */ -#include <linux/module.h>  #include <linux/kernel.h>  #include <linux/console.h>  #include <linux/tty.h> @@ -234,14 +233,10 @@ static int __init suncore_init(void)  {  	return 0;  } +device_initcall(suncore_init); -static void __exit suncore_exit(void) -{ -} - -module_init(suncore_init); -module_exit(suncore_exit); - +#if 0 /* ..def MODULE ; never supported as such */  MODULE_AUTHOR("Eddie C. Dost, David S. Miller");  MODULE_DESCRIPTION("Sun serial common layer");  MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 534754440fa8..064031870ba0 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -3,7 +3,6 @@   * Copyright (C) 2006, 2007 David S. Miller ([email protected])   */ -#include <linux/module.h>  #include <linux/kernel.h>  #include <linux/errno.h>  #include <linux/tty.h> @@ -621,7 +620,6 @@ static const struct of_device_id hv_match[] = {  	},  	{},  }; -MODULE_DEVICE_TABLE(of, hv_match);  static struct platform_driver hv_driver = {  	.driver = { @@ -639,16 +637,11 @@ static int __init sunhv_init(void)  	return platform_driver_register(&hv_driver);  } +device_initcall(sunhv_init); -static void __exit sunhv_exit(void) -{ -	platform_driver_unregister(&hv_driver); -} - -module_init(sunhv_init); -module_exit(sunhv_exit); - +#if 0 /* ...def MODULE ; never supported as such */  MODULE_AUTHOR("David S. Miller");  MODULE_DESCRIPTION("SUN4V Hypervisor console driver");  MODULE_VERSION("2.0");  MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 7d2532b23969..73190f5d2832 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -950,7 +950,7 @@ static void qe_uart_set_termios(struct uart_port *port,  	if ((termios->c_cflag & CREAD) == 0)  		port->read_status_mask &= ~BD_SC_EMPTY; -	baud = uart_get_baud_rate(port, termios, old, 0, 115200); +	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);  	/* Do we really need a spinlock here? */  	spin_lock_irqsave(&port->lock, flags); diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index b5b427888b24..95b330a9ea98 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -353,9 +353,16 @@ static struct sysrq_key_op sysrq_term_op = {  static void moom_callback(struct work_struct *ignored)  { +	const gfp_t gfp_mask = GFP_KERNEL; +	struct oom_control oc = { +		.zonelist = node_zonelist(first_memory_node, gfp_mask), +		.nodemask = NULL, +		.gfp_mask = gfp_mask, +		.order = -1, +	}; +  	mutex_lock(&oom_lock); -	if (!out_of_memory(node_zonelist(first_memory_node, GFP_KERNEL), -			   GFP_KERNEL, 0, NULL, true)) +	if (!out_of_memory(&oc))  		pr_info("OOM request ignored because killer is disabled\n");  	mutex_unlock(&oom_lock);  } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 4cf263d7dffc..5a3fa8913880 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -291,12 +291,11 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size,  			n->flags = flags;  			buf->tail = n;  			b->commit = b->used; -			/* paired w/ barrier in flush_to_ldisc(); ensures the +			/* paired w/ acquire in flush_to_ldisc(); ensures the  			 * latest commit value can be read before the head is  			 * advanced to the next buffer  			 */ -			smp_wmb(); -			b->next = n; +			smp_store_release(&b->next, n);  		} else if (change)  			size = 0;  		else @@ -445,7 +444,6 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)  		if (count)  			disc->ops->receive_buf(tty, p, f, count);  	} -	head->read += count;  	return count;  } @@ -488,12 +486,11 @@ static void flush_to_ldisc(struct work_struct *work)  		if (atomic_read(&buf->priority))  			break; -		next = head->next; -		/* paired w/ barrier in __tty_buffer_request_room(); +		/* paired w/ release in __tty_buffer_request_room();  		 * ensures commit value read is not stale if the head  		 * is advancing to the next buffer  		 */ -		smp_rmb(); +		next = smp_load_acquire(&head->next);  		count = head->commit - head->read;  		if (!count) {  			if (next == NULL) { @@ -508,6 +505,7 @@ static void flush_to_ldisc(struct work_struct *work)  		count = receive_buf(tty, head, count);  		if (!count)  			break; +		head->read += count;  	}  	mutex_unlock(&buf->lock); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 57fc6ee12332..02785d844354 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -106,6 +106,11 @@  #include <linux/nsproxy.h>  #undef TTY_DEBUG_HANGUP +#ifdef TTY_DEBUG_HANGUP +# define tty_debug_hangup(tty, f, args...)	tty_debug(tty, f, ##args) +#else +# define tty_debug_hangup(tty, f, args...)	do { } while (0) +#endif  #define TTY_PARANOIA_CHECK 1  #define CHECK_TTY_COUNT 1 @@ -388,33 +393,40 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver);  int tty_check_change(struct tty_struct *tty)  {  	unsigned long flags; +	struct pid *pgrp;  	int ret = 0;  	if (current->signal->tty != tty)  		return 0; +	rcu_read_lock(); +	pgrp = task_pgrp(current); +  	spin_lock_irqsave(&tty->ctrl_lock, flags);  	if (!tty->pgrp) {  		printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");  		goto out_unlock;  	} -	if (task_pgrp(current) == tty->pgrp) +	if (pgrp == tty->pgrp)  		goto out_unlock;  	spin_unlock_irqrestore(&tty->ctrl_lock, flags); +  	if (is_ignored(SIGTTOU)) -		goto out; +		goto out_rcuunlock;  	if (is_current_pgrp_orphaned()) {  		ret = -EIO; -		goto out; +		goto out_rcuunlock;  	} -	kill_pgrp(task_pgrp(current), SIGTTOU, 1); +	kill_pgrp(pgrp, SIGTTOU, 1); +	rcu_read_unlock();  	set_thread_flag(TIF_SIGPENDING);  	ret = -ERESTARTSYS; -out:  	return ret;  out_unlock:  	spin_unlock_irqrestore(&tty->ctrl_lock, flags); +out_rcuunlock: +	rcu_read_unlock();  	return ret;  } @@ -524,7 +536,8 @@ static void __proc_set_tty(struct tty_struct *tty)  	spin_unlock_irqrestore(&tty->ctrl_lock, flags);  	tty->session = get_pid(task_session(current));  	if (current->signal->tty) { -		printk(KERN_DEBUG "tty not NULL!!\n"); +		tty_debug(tty, "current tty %s not NULL!!\n", +			  current->signal->tty->name);  		tty_kref_put(current->signal->tty);  	}  	put_pid(current->signal->tty_old_pgrp); @@ -766,9 +779,7 @@ static void do_tty_hangup(struct work_struct *work)  void tty_hangup(struct tty_struct *tty)  { -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s hangup...\n", tty_name(tty)); -#endif +	tty_debug_hangup(tty, "\n");  	schedule_work(&tty->hangup_work);  } @@ -785,9 +796,7 @@ EXPORT_SYMBOL(tty_hangup);  void tty_vhangup(struct tty_struct *tty)  { -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty)); -#endif +	tty_debug_hangup(tty, "\n");  	__tty_hangup(tty, 0);  } @@ -824,9 +833,7 @@ void tty_vhangup_self(void)  static void tty_vhangup_session(struct tty_struct *tty)  { -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty)); -#endif +	tty_debug_hangup(tty, "\n");  	__tty_hangup(tty, 1);  } @@ -920,12 +927,8 @@ void disassociate_ctty(int on_exit)  		tty->pgrp = NULL;  		spin_unlock_irqrestore(&tty->ctrl_lock, flags);  		tty_kref_put(tty); -	} else { -#ifdef TTY_DEBUG_HANGUP -		printk(KERN_DEBUG "error attempted to write to tty [0x%p]" -		       " = NULL", tty); -#endif -	} +	} else +		tty_debug_hangup(tty, "no current tty\n");  	spin_unlock_irq(¤t->sighand->siglock);  	/* Now clear signal->tty under the lock */ @@ -1705,8 +1708,7 @@ static int tty_release_checks(struct tty_struct *tty, int idx)  {  #ifdef TTY_PARANOIA_CHECK  	if (idx < 0 || idx >= tty->driver->num) { -		printk(KERN_DEBUG "%s: bad idx when trying to free (%s)\n", -				__func__, tty->name); +		tty_debug(tty, "bad idx %d\n", idx);  		return -1;  	} @@ -1715,20 +1717,20 @@ static int tty_release_checks(struct tty_struct *tty, int idx)  		return 0;  	if (tty != tty->driver->ttys[idx]) { -		printk(KERN_DEBUG "%s: driver.table[%d] not tty for (%s)\n", -				__func__, idx, tty->name); +		tty_debug(tty, "bad driver table[%d] = %p\n", +			  idx, tty->driver->ttys[idx]);  		return -1;  	}  	if (tty->driver->other) {  		struct tty_struct *o_tty = tty->link;  		if (o_tty != tty->driver->other->ttys[idx]) { -			printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", -					__func__, idx, tty->name); +			tty_debug(tty, "bad other table[%d] = %p\n", +				  idx, tty->driver->other->ttys[idx]);  			return -1;  		}  		if (o_tty->link != tty) { -			printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); +			tty_debug(tty, "bad link = %p\n", o_tty->link);  			return -1;  		}  	} @@ -1782,10 +1784,7 @@ int tty_release(struct inode *inode, struct file *filp)  		return 0;  	} -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, -			tty_name(tty), tty->count); -#endif +	tty_debug_hangup(tty, "(tty count=%d)...\n", tty->count);  	if (tty->ops->close)  		tty->ops->close(tty, filp); @@ -1895,9 +1894,7 @@ int tty_release(struct inode *inode, struct file *filp)  	if (!final)  		return 0; -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty)); -#endif +	tty_debug_hangup(tty, "final close\n");  	/*  	 * Ask the line discipline code to release its structures  	 */ @@ -1906,10 +1903,7 @@ int tty_release(struct inode *inode, struct file *filp)  	/* Wait for pending work before tty destruction commmences */  	tty_flush_works(tty); -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, -	       tty_name(tty)); -#endif +	tty_debug_hangup(tty, "freeing structure...\n");  	/*  	 * The release_tty function takes care of the details of clearing  	 * the slots and preserving the termios structure. The tty_unlock_pair @@ -2098,9 +2092,9 @@ retry_open:  	if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&  	    tty->driver->subtype == PTY_TYPE_MASTER)  		noctty = 1; -#ifdef TTY_DEBUG_HANGUP -	printk(KERN_DEBUG "%s: opening %s...\n", __func__, tty->name); -#endif + +	tty_debug_hangup(tty, "(tty count=%d)\n", tty->count); +  	if (tty->ops->open)  		retval = tty->ops->open(tty, filp);  	else @@ -2108,10 +2102,8 @@ retry_open:  	filp->f_flags = saved_flags;  	if (retval) { -#ifdef TTY_DEBUG_HANGUP -		printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, -				retval, tty->name); -#endif +		tty_debug_hangup(tty, "error %d, releasing...\n", retval); +  		tty_unlock(tty); /* need to call tty_release without BTM */  		tty_release(inode, filp);  		if (retval != -ERESTARTSYS) @@ -3160,9 +3152,12 @@ static int tty_cdev_add(struct tty_driver *driver, dev_t dev,  		unsigned int index, unsigned int count)  {  	/* init here, since reused cdevs cause crashes */ -	cdev_init(&driver->cdevs[index], &tty_fops); -	driver->cdevs[index].owner = driver->owner; -	return cdev_add(&driver->cdevs[index], dev, count); +	driver->cdevs[index] = cdev_alloc(); +	if (!driver->cdevs[index]) +		return -ENOMEM; +	cdev_init(driver->cdevs[index], &tty_fops); +	driver->cdevs[index]->owner = driver->owner; +	return cdev_add(driver->cdevs[index], dev, count);  }  /** @@ -3268,8 +3263,10 @@ struct device *tty_register_device_attr(struct tty_driver *driver,  error:  	put_device(dev); -	if (cdev) -		cdev_del(&driver->cdevs[index]); +	if (cdev) { +		cdev_del(driver->cdevs[index]); +		driver->cdevs[index] = NULL; +	}  	return ERR_PTR(retval);  }  EXPORT_SYMBOL_GPL(tty_register_device_attr); @@ -3289,8 +3286,10 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index)  {  	device_destroy(tty_class,  		MKDEV(driver->major, driver->minor_start) + index); -	if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) -		cdev_del(&driver->cdevs[index]); +	if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { +		cdev_del(driver->cdevs[index]); +		driver->cdevs[index] = NULL; +	}  }  EXPORT_SYMBOL(tty_unregister_device); @@ -3355,6 +3354,7 @@ err_free_all:  	kfree(driver->ports);  	kfree(driver->ttys);  	kfree(driver->termios); +	kfree(driver->cdevs);  	kfree(driver);  	return ERR_PTR(err);  } @@ -3383,7 +3383,7 @@ static void destruct_tty_driver(struct kref *kref)  		}  		proc_tty_unregister_driver(driver);  		if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) -			cdev_del(&driver->cdevs[0]); +			cdev_del(driver->cdevs[0]);  	}  	kfree(driver->cdevs);  	kfree(driver->ports); diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 5232fb60b0b1..9c5aebfe7053 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -26,6 +26,12 @@  #undef TTY_DEBUG_WAIT_UNTIL_SENT +#ifdef TTY_DEBUG_WAIT_UNTIL_SENT +# define tty_debug_wait_until_sent(tty, f, args...)    tty_debug(tty, f, ##args) +#else +# define tty_debug_wait_until_sent(tty, f, args...)    do {} while (0) +#endif +  #undef	DEBUG  /* @@ -210,9 +216,8 @@ int tty_unthrottle_safe(struct tty_struct *tty)  void tty_wait_until_sent(struct tty_struct *tty, long timeout)  { -#ifdef TTY_DEBUG_WAIT_UNTIL_SENT -	printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty)); -#endif +	tty_debug_wait_until_sent(tty, "\n"); +  	if (!timeout)  		timeout = MAX_SCHEDULE_TIMEOUT; diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index c07fb5d9bcf9..71750cbac31f 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -22,9 +22,7 @@  #undef LDISC_DEBUG_HANGUP  #ifdef LDISC_DEBUG_HANGUP -#define tty_ldisc_debug(tty, f, args...) ({				  \ -	printk(KERN_DEBUG "%s: %s: " f, __func__, tty_name(tty), ##args); \ -}) +#define tty_ldisc_debug(tty, f, args...)	tty_debug(tty, f, ##args)  #else  #define tty_ldisc_debug(tty, f, args...)  #endif @@ -449,6 +447,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)  		ret = ld->ops->open(tty);  		if (ret)  			clear_bit(TTY_LDISC_OPEN, &tty->flags); + +		tty_ldisc_debug(tty, "%p: opened\n", tty->ldisc);  		return ret;  	}  	return 0; @@ -469,6 +469,7 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)  	clear_bit(TTY_LDISC_OPEN, &tty->flags);  	if (ld->ops->close)  		ld->ops->close(tty); +	tty_ldisc_debug(tty, "%p: closed\n", tty->ldisc);  }  /** @@ -662,7 +663,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)  	int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;  	int err = 0; -	tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); +	tty_ldisc_debug(tty, "%p: closing\n", tty->ldisc);  	ld = tty_ldisc_ref(tty);  	if (ld != NULL) { @@ -712,7 +713,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)  	if (reset)  		tty_reset_termios(tty); -	tty_ldisc_debug(tty, "re-opened ldisc: %p\n", tty->ldisc); +	tty_ldisc_debug(tty, "%p: re-opened\n", tty->ldisc);  }  /** @@ -776,8 +777,6 @@ void tty_ldisc_release(struct tty_struct *tty)  	 * it does not race with the set_ldisc code path.  	 */ -	tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); -  	tty_ldisc_lock_pair(tty, o_tty);  	tty_ldisc_kill(tty);  	if (o_tty) @@ -787,7 +786,7 @@ void tty_ldisc_release(struct tty_struct *tty)  	/* And the memory resources remaining (buffers, termios) will be  	   disposed of when the kref hits zero */ -	tty_ldisc_debug(tty, "ldisc closed\n"); +	tty_ldisc_debug(tty, "released\n");  }  /** diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index ea27804d87af..381a2b13682c 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -356,6 +356,7 @@ int paste_selection(struct tty_struct *tty)  			schedule();  			continue;  		} +		__set_current_state(TASK_RUNNING);  		count = sel_buffer_lth - pasted;  		count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL,  					      count); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 8fe52989b380..4462d167900c 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -742,6 +742,8 @@ static void visual_init(struct vc_data *vc, int num, int init)  	__module_get(vc->vc_sw->owner);  	vc->vc_num = num;  	vc->vc_display_fg = &master_display_fg; +	if (vc->vc_uni_pagedir_loc) +		con_free_unimap(vc);  	vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;  	vc->vc_uni_pagedir = NULL;  	vc->vc_hi_font_mask = 0;  |