| 
							
							
							
						 |  |  | @@ -0,0 +1,267 @@ | 
		
	
		
			
				|  |  |  |  | From patchwork Fri Feb 21 21:23:31 2020 | 
		
	
		
			
				|  |  |  |  | Content-Type: text/plain; charset="utf-8" | 
		
	
		
			
				|  |  |  |  | MIME-Version: 1.0 | 
		
	
		
			
				|  |  |  |  | Content-Transfer-Encoding: 7bit | 
		
	
		
			
				|  |  |  |  | X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> | 
		
	
		
			
				|  |  |  |  | X-Patchwork-Id: 1198835 | 
		
	
		
			
				|  |  |  |  | Date: Fri, 21 Feb 2020 22:23:31 +0100 | 
		
	
		
			
				|  |  |  |  | From: Daniel Golle <daniel@makrotopia.org> | 
		
	
		
			
				|  |  |  |  | To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org | 
		
	
		
			
				|  |  |  |  | Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, | 
		
	
		
			
				|  |  |  |  |  Jiri Slaby <jslaby@suse.com>, Petr =?utf-8?q?=C5=A0tetiar?= <ynezz@true.cz>, | 
		
	
		
			
				|  |  |  |  |  Chuanhong Guo <gch981213@gmail.com>, Piotr Dymacz <pepe2k@gmail.com> | 
		
	
		
			
				|  |  |  |  | Subject: [PATCH v2] serial: ar933x_uart: add RS485 support | 
		
	
		
			
				|  |  |  |  | Message-ID: <20200221212331.GA21467@makrotopia.org> | 
		
	
		
			
				|  |  |  |  | MIME-Version: 1.0 | 
		
	
		
			
				|  |  |  |  | Content-Disposition: inline | 
		
	
		
			
				|  |  |  |  | Sender: linux-kernel-owner@vger.kernel.org | 
		
	
		
			
				|  |  |  |  | Precedence: bulk | 
		
	
		
			
				|  |  |  |  | List-ID: <linux-kernel.vger.kernel.org> | 
		
	
		
			
				|  |  |  |  | X-Mailing-List: linux-kernel@vger.kernel.org | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Emulate half-duplex operation and use mctrl_gpio to add support for | 
		
	
		
			
				|  |  |  |  | RS485 tranceiver with transmit/receive switch hooked to RTS GPIO line. | 
		
	
		
			
				|  |  |  |  | This is needed to make use of the RS485 port found on Teltonika RUT955. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | 
		
	
		
			
				|  |  |  |  | --- | 
		
	
		
			
				|  |  |  |  | v2: use bool to indicate ongoing half-duplex send, use it afterwards | 
		
	
		
			
				|  |  |  |  |     to decide whether we've just been in a send operation. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  drivers/tty/serial/Kconfig       |   1 + | 
		
	
		
			
				|  |  |  |  |  drivers/tty/serial/ar933x_uart.c | 113 +++++++++++++++++++++++++++++-- | 
		
	
		
			
				|  |  |  |  |  2 files changed, 108 insertions(+), 6 deletions(-) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | --- a/drivers/tty/serial/Kconfig | 
		
	
		
			
				|  |  |  |  | +++ b/drivers/tty/serial/Kconfig | 
		
	
		
			
				|  |  |  |  | @@ -1279,6 +1279,7 @@ config SERIAL_AR933X | 
		
	
		
			
				|  |  |  |  |  	tristate "AR933X serial port support" | 
		
	
		
			
				|  |  |  |  |  	depends on HAVE_CLK && ATH79 | 
		
	
		
			
				|  |  |  |  |  	select SERIAL_CORE | 
		
	
		
			
				|  |  |  |  | +	select SERIAL_MCTRL_GPIO if GPIOLIB | 
		
	
		
			
				|  |  |  |  |  	help | 
		
	
		
			
				|  |  |  |  |  	  If you have an Atheros AR933X SOC based board and want to use the | 
		
	
		
			
				|  |  |  |  |  	  built-in UART of the SoC, say Y to this option. | 
		
	
		
			
				|  |  |  |  | --- a/drivers/tty/serial/ar933x_uart.c | 
		
	
		
			
				|  |  |  |  | +++ b/drivers/tty/serial/ar933x_uart.c | 
		
	
		
			
				|  |  |  |  | @@ -13,6 +13,7 @@ | 
		
	
		
			
				|  |  |  |  |  #include <linux/console.h> | 
		
	
		
			
				|  |  |  |  |  #include <linux/sysrq.h> | 
		
	
		
			
				|  |  |  |  |  #include <linux/delay.h> | 
		
	
		
			
				|  |  |  |  | +#include <linux/gpio/consumer.h> | 
		
	
		
			
				|  |  |  |  |  #include <linux/platform_device.h> | 
		
	
		
			
				|  |  |  |  |  #include <linux/of.h> | 
		
	
		
			
				|  |  |  |  |  #include <linux/of_platform.h> | 
		
	
		
			
				|  |  |  |  | @@ -29,6 +30,8 @@ | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  #include <asm/mach-ath79/ar933x_uart.h> | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +#include "serial_mctrl_gpio.h" | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  #define DRIVER_NAME "ar933x-uart" | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  #define AR933X_UART_MAX_SCALE	0xff | 
		
	
		
			
				|  |  |  |  | @@ -47,6 +50,8 @@ struct ar933x_uart_port { | 
		
	
		
			
				|  |  |  |  |  	unsigned int		min_baud; | 
		
	
		
			
				|  |  |  |  |  	unsigned int		max_baud; | 
		
	
		
			
				|  |  |  |  |  	struct clk		*clk; | 
		
	
		
			
				|  |  |  |  | +	struct mctrl_gpios	*gpios; | 
		
	
		
			
				|  |  |  |  | +	struct gpio_desc	*rts_gpiod; | 
		
	
		
			
				|  |  |  |  |  }; | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, | 
		
	
		
			
				|  |  |  |  | @@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_i | 
		
	
		
			
				|  |  |  |  |  	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | 
		
	
		
			
				|  |  |  |  |  } | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +static inline void ar933x_uart_start_rx_interrupt(struct ar933x_uart_port *up) | 
		
	
		
			
				|  |  |  |  | +{ | 
		
	
		
			
				|  |  |  |  | +	up->ier |= AR933X_UART_INT_RX_VALID; | 
		
	
		
			
				|  |  |  |  | +	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | 
		
	
		
			
				|  |  |  |  | +} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +static inline void ar933x_uart_stop_rx_interrupt(struct ar933x_uart_port *up) | 
		
	
		
			
				|  |  |  |  | +{ | 
		
	
		
			
				|  |  |  |  | +	up->ier &= ~AR933X_UART_INT_RX_VALID; | 
		
	
		
			
				|  |  |  |  | +	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | 
		
	
		
			
				|  |  |  |  | +} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch) | 
		
	
		
			
				|  |  |  |  |  { | 
		
	
		
			
				|  |  |  |  |  	unsigned int rdata; | 
		
	
		
			
				|  |  |  |  | @@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  static unsigned int ar933x_uart_get_mctrl(struct uart_port *port) | 
		
	
		
			
				|  |  |  |  |  { | 
		
	
		
			
				|  |  |  |  | -	return TIOCM_CAR; | 
		
	
		
			
				|  |  |  |  | +	struct ar933x_uart_port *up = | 
		
	
		
			
				|  |  |  |  | +		container_of(port, struct ar933x_uart_port, port); | 
		
	
		
			
				|  |  |  |  | +	int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	mctrl_gpio_get(up->gpios, &ret); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	return ret; | 
		
	
		
			
				|  |  |  |  |  } | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 
		
	
		
			
				|  |  |  |  |  { | 
		
	
		
			
				|  |  |  |  | +	struct ar933x_uart_port *up = | 
		
	
		
			
				|  |  |  |  | +		container_of(port, struct ar933x_uart_port, port); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	mctrl_gpio_set(up->gpios, mctrl); | 
		
	
		
			
				|  |  |  |  |  } | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  static void ar933x_uart_start_tx(struct uart_port *port) | 
		
	
		
			
				|  |  |  |  | @@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct | 
		
	
		
			
				|  |  |  |  |  	ar933x_uart_start_tx_interrupt(up); | 
		
	
		
			
				|  |  |  |  |  } | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +static void ar933x_uart_wait_tx_complete(struct ar933x_uart_port *up) | 
		
	
		
			
				|  |  |  |  | +{ | 
		
	
		
			
				|  |  |  |  | +	unsigned int status; | 
		
	
		
			
				|  |  |  |  | +	unsigned int timeout = 60000; | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	/* Wait up to 60ms for the character(s) to be sent. */ | 
		
	
		
			
				|  |  |  |  | +	do { | 
		
	
		
			
				|  |  |  |  | +		status = ar933x_uart_read(up, AR933X_UART_CS_REG); | 
		
	
		
			
				|  |  |  |  | +		if (--timeout == 0) | 
		
	
		
			
				|  |  |  |  | +			break; | 
		
	
		
			
				|  |  |  |  | +		udelay(1); | 
		
	
		
			
				|  |  |  |  | +	} while (status & AR933X_UART_CS_TX_BUSY); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	if (timeout == 0) | 
		
	
		
			
				|  |  |  |  | +		dev_err(up->port.dev, "waiting for TX timed out\n"); | 
		
	
		
			
				|  |  |  |  | +} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +static void ar933x_uart_rx_flush(struct ar933x_uart_port *up) | 
		
	
		
			
				|  |  |  |  | +{ | 
		
	
		
			
				|  |  |  |  | +	unsigned int status; | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	/* clear RX_VALID interrupt */ | 
		
	
		
			
				|  |  |  |  | +	ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_RX_VALID); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	/* remove characters from the RX FIFO */ | 
		
	
		
			
				|  |  |  |  | +	do { | 
		
	
		
			
				|  |  |  |  | +		ar933x_uart_write(up, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR); | 
		
	
		
			
				|  |  |  |  | +		status = ar933x_uart_read(up, AR933X_UART_DATA_REG); | 
		
	
		
			
				|  |  |  |  | +	} while (status & AR933X_UART_DATA_RX_CSR); | 
		
	
		
			
				|  |  |  |  | +} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  static void ar933x_uart_stop_tx(struct uart_port *port) | 
		
	
		
			
				|  |  |  |  |  { | 
		
	
		
			
				|  |  |  |  |  	struct ar933x_uart_port *up = | 
		
	
		
			
				|  |  |  |  | @@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct u | 
		
	
		
			
				|  |  |  |  |  	struct ar933x_uart_port *up = | 
		
	
		
			
				|  |  |  |  |  		container_of(port, struct ar933x_uart_port, port); | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | -	up->ier &= ~AR933X_UART_INT_RX_VALID; | 
		
	
		
			
				|  |  |  |  | -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | 
		
	
		
			
				|  |  |  |  | +	ar933x_uart_stop_rx_interrupt(up); | 
		
	
		
			
				|  |  |  |  |  } | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) | 
		
	
		
			
				|  |  |  |  | @@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct | 
		
	
		
			
				|  |  |  |  |  static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) | 
		
	
		
			
				|  |  |  |  |  { | 
		
	
		
			
				|  |  |  |  |  	struct circ_buf *xmit = &up->port.state->xmit; | 
		
	
		
			
				|  |  |  |  | +	struct serial_rs485 *rs485conf = &up->port.rs485; | 
		
	
		
			
				|  |  |  |  |  	int count; | 
		
	
		
			
				|  |  |  |  | +	bool half_duplex_send = false; | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  	if (uart_tx_stopped(&up->port)) | 
		
	
		
			
				|  |  |  |  |  		return; | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +	if ((rs485conf->flags & SER_RS485_ENABLED) && | 
		
	
		
			
				|  |  |  |  | +	    (up->port.x_char || !uart_circ_empty(xmit))) { | 
		
	
		
			
				|  |  |  |  | +		ar933x_uart_stop_rx_interrupt(up); | 
		
	
		
			
				|  |  |  |  | +		gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND)); | 
		
	
		
			
				|  |  |  |  | +		half_duplex_send = true; | 
		
	
		
			
				|  |  |  |  | +	} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  	count = up->port.fifosize; | 
		
	
		
			
				|  |  |  |  |  	do { | 
		
	
		
			
				|  |  |  |  |  		unsigned int rdata; | 
		
	
		
			
				|  |  |  |  | @@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct | 
		
	
		
			
				|  |  |  |  |  	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 
		
	
		
			
				|  |  |  |  |  		uart_write_wakeup(&up->port); | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | -	if (!uart_circ_empty(xmit)) | 
		
	
		
			
				|  |  |  |  | +	if (!uart_circ_empty(xmit)) { | 
		
	
		
			
				|  |  |  |  |  		ar933x_uart_start_tx_interrupt(up); | 
		
	
		
			
				|  |  |  |  | +	} else if (half_duplex_send) { | 
		
	
		
			
				|  |  |  |  | +		ar933x_uart_wait_tx_complete(up); | 
		
	
		
			
				|  |  |  |  | +		ar933x_uart_rx_flush(up); | 
		
	
		
			
				|  |  |  |  | +		ar933x_uart_start_rx_interrupt(up); | 
		
	
		
			
				|  |  |  |  | +		gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND)); | 
		
	
		
			
				|  |  |  |  | +	} | 
		
	
		
			
				|  |  |  |  |  } | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) | 
		
	
		
			
				|  |  |  |  | @@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct ua | 
		
	
		
			
				|  |  |  |  |  		AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE); | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  	/* Enable RX interrupts */ | 
		
	
		
			
				|  |  |  |  | -	up->ier = AR933X_UART_INT_RX_VALID; | 
		
	
		
			
				|  |  |  |  | -	ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | 
		
	
		
			
				|  |  |  |  | +	ar933x_uart_start_rx_interrupt(up); | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  	spin_unlock_irqrestore(&up->port.lock, flags); | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | @@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart | 
		
	
		
			
				|  |  |  |  |  	.verify_port	= ar933x_uart_verify_port, | 
		
	
		
			
				|  |  |  |  |  }; | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +static int ar933x_config_rs485(struct uart_port *port, | 
		
	
		
			
				|  |  |  |  | +				struct serial_rs485 *rs485conf) | 
		
	
		
			
				|  |  |  |  | +{ | 
		
	
		
			
				|  |  |  |  | +	struct ar933x_uart_port *up = | 
		
	
		
			
				|  |  |  |  | +		container_of(port, struct ar933x_uart_port, port); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	if ((rs485conf->flags & SER_RS485_ENABLED) && | 
		
	
		
			
				|  |  |  |  | +	    !up->rts_gpiod) { | 
		
	
		
			
				|  |  |  |  | +		dev_err(port->dev, "RS485 needs rts-gpio\n"); | 
		
	
		
			
				|  |  |  |  | +		return 1; | 
		
	
		
			
				|  |  |  |  | +	} | 
		
	
		
			
				|  |  |  |  | +	port->rs485 = *rs485conf; | 
		
	
		
			
				|  |  |  |  | +	return 0; | 
		
	
		
			
				|  |  |  |  | +} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  #ifdef CONFIG_SERIAL_AR933X_CONSOLE | 
		
	
		
			
				|  |  |  |  |  static struct ar933x_uart_port * | 
		
	
		
			
				|  |  |  |  |  ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; | 
		
	
		
			
				|  |  |  |  | @@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct plat | 
		
	
		
			
				|  |  |  |  |  		goto err_disable_clk; | 
		
	
		
			
				|  |  |  |  |  	} | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +	uart_get_rs485_mode(&pdev->dev, &port->rs485); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  	port->mapbase = mem_res->start; | 
		
	
		
			
				|  |  |  |  |  	port->line = id; | 
		
	
		
			
				|  |  |  |  |  	port->irq = irq_res->start; | 
		
	
		
			
				|  |  |  |  | @@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct plat | 
		
	
		
			
				|  |  |  |  |  	port->regshift = 2; | 
		
	
		
			
				|  |  |  |  |  	port->fifosize = AR933X_UART_FIFO_SIZE; | 
		
	
		
			
				|  |  |  |  |  	port->ops = &ar933x_uart_ops; | 
		
	
		
			
				|  |  |  |  | +	port->rs485_config = ar933x_config_rs485; | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |  	baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1); | 
		
	
		
			
				|  |  |  |  |  	up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD); | 
		
	
		
			
				|  |  |  |  | @@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct plat | 
		
	
		
			
				|  |  |  |  |  	baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); | 
		
	
		
			
				|  |  |  |  |  	up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  | +	up->gpios = mctrl_gpio_init(port, 0); | 
		
	
		
			
				|  |  |  |  | +	if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) | 
		
	
		
			
				|  |  |  |  | +		return PTR_ERR(up->gpios); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS); | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  | +	if ((port->rs485.flags & SER_RS485_ENABLED) && | 
		
	
		
			
				|  |  |  |  | +	    !up->rts_gpiod) { | 
		
	
		
			
				|  |  |  |  | +		dev_err(&pdev->dev, "lacking rts-gpio, disabling RS485\n"); | 
		
	
		
			
				|  |  |  |  | +		port->rs485.flags &= ~SER_RS485_ENABLED; | 
		
	
		
			
				|  |  |  |  | +	} | 
		
	
		
			
				|  |  |  |  | + | 
		
	
		
			
				|  |  |  |  |  #ifdef CONFIG_SERIAL_AR933X_CONSOLE | 
		
	
		
			
				|  |  |  |  |  	ar933x_console_ports[up->port.line] = up; | 
		
	
		
			
				|  |  |  |  |  #endif |