diff options
Diffstat (limited to 'drivers/tty/serial/clps711x.c')
| -rw-r--r-- | drivers/tty/serial/clps711x.c | 457 | 
1 files changed, 262 insertions, 195 deletions
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 7e4e4088471..14aaea0d413 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -21,44 +21,66 @@  #include <linux/console.h>  #include <linux/serial_core.h>  #include <linux/serial.h> -#include <linux/io.h>  #include <linux/clk.h> +#include <linux/io.h>  #include <linux/tty.h>  #include <linux/tty_flip.h>  #include <linux/ioport.h> +#include <linux/of.h>  #include <linux/platform_device.h> +#include <linux/regmap.h> -#include <mach/hardware.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/clps711x.h> -#define UART_CLPS711X_NAME	"uart-clps711x" +#define UART_CLPS711X_DEVNAME	"ttyCL"  #define UART_CLPS711X_NR	2  #define UART_CLPS711X_MAJOR	204  #define UART_CLPS711X_MINOR	40 -#define UBRLCR(port)		((port)->line ? UBRLCR2 : UBRLCR1) -#define UARTDR(port)		((port)->line ? UARTDR2 : UARTDR1) -#define SYSFLG(port)		((port)->line ? SYSFLG2 : SYSFLG1) -#define SYSCON(port)		((port)->line ? SYSCON2 : SYSCON1) -#define TX_IRQ(port)		((port)->line ? IRQ_UTXINT2 : IRQ_UTXINT1) -#define RX_IRQ(port)		((port)->line ? IRQ_URXINT2 : IRQ_URXINT1) +#define UARTDR_OFFSET		(0x00) +#define UBRLCR_OFFSET		(0x40) + +#define UARTDR_FRMERR		(1 << 8) +#define UARTDR_PARERR		(1 << 9) +#define UARTDR_OVERR		(1 << 10) + +#define UBRLCR_BAUD_MASK	((1 << 12) - 1) +#define UBRLCR_BREAK		(1 << 12) +#define UBRLCR_PRTEN		(1 << 13) +#define UBRLCR_EVENPRT		(1 << 14) +#define UBRLCR_XSTOP		(1 << 15) +#define UBRLCR_FIFOEN		(1 << 16) +#define UBRLCR_WRDLEN5		(0 << 17) +#define UBRLCR_WRDLEN6		(1 << 17) +#define UBRLCR_WRDLEN7		(2 << 17) +#define UBRLCR_WRDLEN8		(3 << 17) +#define UBRLCR_WRDLEN_MASK	(3 << 17)  struct clps711x_port { -	struct uart_driver	uart; -	struct clk		*uart_clk; -	struct uart_port	port[UART_CLPS711X_NR]; -	int			tx_enabled[UART_CLPS711X_NR]; -#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE -	struct console		console; -#endif +	struct uart_port	port; +	unsigned int		tx_enabled; +	int			rx_irq; +	struct regmap		*syscon; +	bool			use_ms; +}; + +static struct uart_driver clps711x_uart = { +	.owner		= THIS_MODULE, +	.driver_name	= UART_CLPS711X_DEVNAME, +	.dev_name	= UART_CLPS711X_DEVNAME, +	.major		= UART_CLPS711X_MAJOR, +	.minor		= UART_CLPS711X_MINOR, +	.nr		= UART_CLPS711X_NR,  };  static void uart_clps711x_stop_tx(struct uart_port *port)  {  	struct clps711x_port *s = dev_get_drvdata(port->dev); -	if (s->tx_enabled[port->line]) { -		disable_irq(TX_IRQ(port)); -		s->tx_enabled[port->line] = 0; +	if (s->tx_enabled) { +		disable_irq(port->irq); +		s->tx_enabled = 0;  	}  } @@ -66,33 +88,27 @@ static void uart_clps711x_start_tx(struct uart_port *port)  {  	struct clps711x_port *s = dev_get_drvdata(port->dev); -	if (!s->tx_enabled[port->line]) { -		enable_irq(TX_IRQ(port)); -		s->tx_enabled[port->line] = 1; +	if (!s->tx_enabled) { +		s->tx_enabled = 1; +		enable_irq(port->irq);  	}  } -static void uart_clps711x_stop_rx(struct uart_port *port) -{ -	disable_irq(RX_IRQ(port)); -} - -static void uart_clps711x_enable_ms(struct uart_port *port) -{ -	/* Do nothing */ -} -  static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id)  {  	struct uart_port *port = dev_id; -	unsigned int status, ch, flg; +	struct clps711x_port *s = dev_get_drvdata(port->dev); +	unsigned int status, flg; +	u16 ch;  	for (;;) { -		status = clps_readl(SYSFLG(port)); -		if (status & SYSFLG_URXFE) +		u32 sysflg = 0; + +		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); +		if (sysflg & SYSFLG_URXFE)  			break; -		ch = clps_readw(UARTDR(port)); +		ch = readw(port->membase + UARTDR_OFFSET);  		status = ch & (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR);  		ch &= 0xff; @@ -138,23 +154,29 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)  	struct circ_buf *xmit = &port->state->xmit;  	if (port->x_char) { -		clps_writew(port->x_char, UARTDR(port)); +		writew(port->x_char, port->membase + UARTDR_OFFSET);  		port->icount.tx++;  		port->x_char = 0;  		return IRQ_HANDLED;  	}  	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { -		disable_irq_nosync(TX_IRQ(port)); -		s->tx_enabled[port->line] = 0; +		if (s->tx_enabled) { +			disable_irq_nosync(port->irq); +			s->tx_enabled = 0; +		}  		return IRQ_HANDLED;  	}  	while (!uart_circ_empty(xmit)) { -		clps_writew(xmit->buf[xmit->tail], UARTDR(port)); +		u32 sysflg = 0; + +		writew(xmit->buf[xmit->tail], port->membase + UARTDR_OFFSET);  		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);  		port->icount.tx++; -		if (clps_readl(SYSFLG(port) & SYSFLG_UTXFF)) + +		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); +		if (sysflg & SYSFLG_UTXFF)  			break;  	} @@ -166,20 +188,28 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)  static unsigned int uart_clps711x_tx_empty(struct uart_port *port)  { -	return (clps_readl(SYSFLG(port) & SYSFLG_UBUSY)) ? 0 : TIOCSER_TEMT; +	struct clps711x_port *s = dev_get_drvdata(port->dev); +	u32 sysflg = 0; + +	regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); + +	return (sysflg & SYSFLG_UBUSY) ? 0 : TIOCSER_TEMT;  }  static unsigned int uart_clps711x_get_mctrl(struct uart_port *port)  { -	unsigned int status, result = 0; +	struct clps711x_port *s = dev_get_drvdata(port->dev); +	unsigned int result = 0; + +	if (s->use_ms) { +		u32 sysflg = 0; -	if (port->line == 0) { -		status = clps_readl(SYSFLG1); -		if (status & SYSFLG1_DCD) +		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); +		if (sysflg & SYSFLG1_DCD)  			result |= TIOCM_CAR; -		if (status & SYSFLG1_DSR) +		if (sysflg & SYSFLG1_DSR)  			result |= TIOCM_DSR; -		if (status & SYSFLG1_CTS) +		if (sysflg & SYSFLG1_CTS)  			result |= TIOCM_CTS;  	} else  		result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; @@ -194,65 +224,53 @@ static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl)  static void uart_clps711x_break_ctl(struct uart_port *port, int break_state)  { -	unsigned long flags;  	unsigned int ubrlcr; -	spin_lock_irqsave(&port->lock, flags); - -	ubrlcr = clps_readl(UBRLCR(port)); +	ubrlcr = readl(port->membase + UBRLCR_OFFSET);  	if (break_state)  		ubrlcr |= UBRLCR_BREAK;  	else  		ubrlcr &= ~UBRLCR_BREAK; -	clps_writel(ubrlcr, UBRLCR(port)); +	writel(ubrlcr, port->membase + UBRLCR_OFFSET); +} + +static void uart_clps711x_set_ldisc(struct uart_port *port, int ld) +{ +	if (!port->line) { +		struct clps711x_port *s = dev_get_drvdata(port->dev); -	spin_unlock_irqrestore(&port->lock, flags); +		regmap_update_bits(s->syscon, SYSCON_OFFSET, SYSCON1_SIREN, +				   (ld == N_IRDA) ? SYSCON1_SIREN : 0); +	}  }  static int uart_clps711x_startup(struct uart_port *port)  {  	struct clps711x_port *s = dev_get_drvdata(port->dev); -	int ret; - -	s->tx_enabled[port->line] = 1; -	/* Allocate the IRQs */ -	ret = devm_request_irq(port->dev, TX_IRQ(port), uart_clps711x_int_tx, -			       0, UART_CLPS711X_NAME " TX", port); -	if (ret) -		return ret; - -	ret = devm_request_irq(port->dev, RX_IRQ(port), uart_clps711x_int_rx, -			       0, UART_CLPS711X_NAME " RX", port); -	if (ret) { -		devm_free_irq(port->dev, TX_IRQ(port), port); -		return ret; -	}  	/* Disable break */ -	clps_writel(clps_readl(UBRLCR(port)) & ~UBRLCR_BREAK, UBRLCR(port)); +	writel(readl(port->membase + UBRLCR_OFFSET) & ~UBRLCR_BREAK, +	       port->membase + UBRLCR_OFFSET);  	/* Enable the port */ -	clps_writel(clps_readl(SYSCON(port)) | SYSCON_UARTEN, SYSCON(port)); - -	return 0; +	return regmap_update_bits(s->syscon, SYSCON_OFFSET, +				  SYSCON_UARTEN, SYSCON_UARTEN);  }  static void uart_clps711x_shutdown(struct uart_port *port)  { -	/* Free the interrupts */ -	devm_free_irq(port->dev, TX_IRQ(port), port); -	devm_free_irq(port->dev, RX_IRQ(port), port); +	struct clps711x_port *s = dev_get_drvdata(port->dev);  	/* Disable the port */ -	clps_writel(clps_readl(SYSCON(port)) & ~SYSCON_UARTEN, SYSCON(port)); +	regmap_update_bits(s->syscon, SYSCON_OFFSET, SYSCON_UARTEN, 0);  }  static void uart_clps711x_set_termios(struct uart_port *port,  				      struct ktermios *termios,  				      struct ktermios *old)  { -	unsigned int ubrlcr, baud, quot; -	unsigned long flags; +	u32 ubrlcr; +	unsigned int baud, quot;  	/* Mask termios capabilities we don't support */  	termios->c_cflag &= ~CMSPAR; @@ -291,8 +309,6 @@ static void uart_clps711x_set_termios(struct uart_port *port,  	/* Enable FIFO */  	ubrlcr |= UBRLCR_FIFOEN; -	spin_lock_irqsave(&port->lock, flags); -  	/* Set read status mask */  	port->read_status_mask = UARTDR_OVERR;  	if (termios->c_iflag & INPCK) @@ -306,9 +322,7 @@ static void uart_clps711x_set_termios(struct uart_port *port,  	uart_update_timeout(port, termios->c_cflag, baud); -	clps_writel(ubrlcr | (quot - 1), UBRLCR(port)); - -	spin_unlock_irqrestore(&port->lock, flags); +	writel(ubrlcr | (quot - 1), port->membase + UBRLCR_OFFSET);  }  static const char *uart_clps711x_type(struct uart_port *port) @@ -322,14 +336,12 @@ static void uart_clps711x_config_port(struct uart_port *port, int flags)  		port->type = PORT_CLPS711X;  } -static void uart_clps711x_release_port(struct uart_port *port) +static void uart_clps711x_nop_void(struct uart_port *port)  { -	/* Do nothing */  } -static int uart_clps711x_request_port(struct uart_port *port) +static int uart_clps711x_nop_int(struct uart_port *port)  { -	/* Do nothing */  	return 0;  } @@ -339,183 +351,238 @@ static const struct uart_ops uart_clps711x_ops = {  	.get_mctrl	= uart_clps711x_get_mctrl,  	.stop_tx	= uart_clps711x_stop_tx,  	.start_tx	= uart_clps711x_start_tx, -	.stop_rx	= uart_clps711x_stop_rx, -	.enable_ms	= uart_clps711x_enable_ms, +	.stop_rx	= uart_clps711x_nop_void, +	.enable_ms	= uart_clps711x_nop_void,  	.break_ctl	= uart_clps711x_break_ctl, +	.set_ldisc	= uart_clps711x_set_ldisc,  	.startup	= uart_clps711x_startup,  	.shutdown	= uart_clps711x_shutdown,  	.set_termios	= uart_clps711x_set_termios,  	.type		= uart_clps711x_type,  	.config_port	= uart_clps711x_config_port, -	.release_port	= uart_clps711x_release_port, -	.request_port	= uart_clps711x_request_port, +	.release_port	= uart_clps711x_nop_void, +	.request_port	= uart_clps711x_nop_int,  };  #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE  static void uart_clps711x_console_putchar(struct uart_port *port, int ch)  { -	while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) -		barrier(); +	struct clps711x_port *s = dev_get_drvdata(port->dev); +	u32 sysflg = 0; + +	/* Wait for FIFO is not full */ +	do { +		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); +	} while (sysflg & SYSFLG_UTXFF); -	clps_writew(ch, UARTDR(port)); +	writew(ch, port->membase + UARTDR_OFFSET);  }  static void uart_clps711x_console_write(struct console *co, const char *c,  					unsigned n)  { -	struct clps711x_port *s = (struct clps711x_port *)co->data; -	struct uart_port *port = &s->port[co->index]; -	u32 syscon; - -	/* Ensure that the port is enabled */ -	syscon = clps_readl(SYSCON(port)); -	clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); +	struct uart_port *port = clps711x_uart.state[co->index].uart_port; +	struct clps711x_port *s = dev_get_drvdata(port->dev); +	u32 sysflg = 0;  	uart_console_write(port, c, n, uart_clps711x_console_putchar);  	/* Wait for transmitter to become empty */ -	while (clps_readl(SYSFLG(port)) & SYSFLG_UBUSY) -		barrier(); - -	/* Restore the uart state */ -	clps_writel(syscon, SYSCON(port)); +	do { +		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); +	} while (sysflg & SYSFLG_UBUSY);  } -static void uart_clps711x_console_get_options(struct uart_port *port, -					      int *baud, int *parity, -					      int *bits) +static int uart_clps711x_console_setup(struct console *co, char *options)  { -	if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) { -		unsigned int ubrlcr, quot; +	int baud = 38400, bits = 8, parity = 'n', flow = 'n'; +	int ret, index = co->index; +	struct clps711x_port *s; +	struct uart_port *port; +	unsigned int quot; +	u32 ubrlcr; -		ubrlcr = clps_readl(UBRLCR(port)); +	if (index < 0 || index >= UART_CLPS711X_NR) +		return -EINVAL; -		*parity = 'n'; -		if (ubrlcr & UBRLCR_PRTEN) { -			if (ubrlcr & UBRLCR_EVENPRT) -				*parity = 'e'; -			else -				*parity = 'o'; -		} +	port = clps711x_uart.state[index].uart_port; +	if (!port) +		return -ENODEV; -		if ((ubrlcr & UBRLCR_WRDLEN_MASK) == UBRLCR_WRDLEN7) -			*bits = 7; -		else -			*bits = 8; +	s = dev_get_drvdata(port->dev); -		quot = ubrlcr & UBRLCR_BAUD_MASK; -		*baud = port->uartclk / (16 * (quot + 1)); -	} -} +	if (!options) { +		u32 syscon = 0; -static int uart_clps711x_console_setup(struct console *co, char *options) -{ -	int baud = 38400, bits = 8, parity = 'n', flow = 'n'; -	struct clps711x_port *s = (struct clps711x_port *)co->data; -	struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0]; +		regmap_read(s->syscon, SYSCON_OFFSET, &syscon); +		if (syscon & SYSCON_UARTEN) { +			ubrlcr = readl(port->membase + UBRLCR_OFFSET); + +			if (ubrlcr & UBRLCR_PRTEN) { +				if (ubrlcr & UBRLCR_EVENPRT) +					parity = 'e'; +				else +					parity = 'o'; +			} + +			if ((ubrlcr & UBRLCR_WRDLEN_MASK) == UBRLCR_WRDLEN7) +				bits = 7; -	if (options) +			quot = ubrlcr & UBRLCR_BAUD_MASK; +			baud = port->uartclk / (16 * (quot + 1)); +		} +	} else  		uart_parse_options(options, &baud, &parity, &bits, &flow); -	else -		uart_clps711x_console_get_options(port, &baud, &parity, &bits); -	return uart_set_options(port, co, baud, parity, bits, flow); +	ret = uart_set_options(port, co, baud, parity, bits, flow); +	if (ret) +		return ret; + +	return regmap_update_bits(s->syscon, SYSCON_OFFSET, +				  SYSCON_UARTEN, SYSCON_UARTEN);  } + +static struct console clps711x_console = { +	.name	= UART_CLPS711X_DEVNAME, +	.device	= uart_console_device, +	.write	= uart_clps711x_console_write, +	.setup	= uart_clps711x_console_setup, +	.flags	= CON_PRINTBUFFER, +	.index	= -1, +};  #endif  static int uart_clps711x_probe(struct platform_device *pdev)  { +	struct device_node *np = pdev->dev.of_node; +	int ret, index = np ? of_alias_get_id(np, "serial") : pdev->id;  	struct clps711x_port *s; -	int ret, i; +	struct resource *res; +	struct clk *uart_clk; -	s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL); -	if (!s) { -		dev_err(&pdev->dev, "Error allocating port structure\n"); +	if (index < 0 || index >= UART_CLPS711X_NR) +		return -EINVAL; + +	s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL); +	if (!s)  		return -ENOMEM; + +	uart_clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(uart_clk)) +		return PTR_ERR(uart_clk); + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	s->port.membase = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(s->port.membase)) +		return PTR_ERR(s->port.membase); + +	s->port.irq = platform_get_irq(pdev, 0); +	if (IS_ERR_VALUE(s->port.irq)) +		return s->port.irq; + +	s->rx_irq = platform_get_irq(pdev, 1); +	if (IS_ERR_VALUE(s->rx_irq)) +		return s->rx_irq; + +	if (!np) { +		char syscon_name[9]; + +		sprintf(syscon_name, "syscon.%i", index + 1); +		s->syscon = syscon_regmap_lookup_by_pdevname(syscon_name); +		if (IS_ERR(s->syscon)) +			return PTR_ERR(s->syscon); + +		s->use_ms = !index; +	} else { +		s->syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); +		if (IS_ERR(s->syscon)) +			return PTR_ERR(s->syscon); + +		if (!index) +			s->use_ms = of_property_read_bool(np, "uart-use-ms");  	} + +	s->port.line		= index; +	s->port.dev		= &pdev->dev; +	s->port.iotype		= UPIO_MEM32; +	s->port.mapbase		= res->start; +	s->port.type		= PORT_CLPS711X; +	s->port.fifosize	= 16; +	s->port.flags		= UPF_SKIP_TEST | UPF_FIXED_TYPE; +	s->port.uartclk		= clk_get_rate(uart_clk); +	s->port.ops		= &uart_clps711x_ops; +  	platform_set_drvdata(pdev, s); -	s->uart_clk = devm_clk_get(&pdev->dev, "uart"); -	if (IS_ERR(s->uart_clk)) { -		dev_err(&pdev->dev, "Can't get UART clocks\n"); -		return PTR_ERR(s->uart_clk); -	} +	ret = uart_add_one_port(&clps711x_uart, &s->port); +	if (ret) +		return ret; -	s->uart.owner		= THIS_MODULE; -	s->uart.dev_name	= "ttyCL"; -	s->uart.major		= UART_CLPS711X_MAJOR; -	s->uart.minor		= UART_CLPS711X_MINOR; -	s->uart.nr		= UART_CLPS711X_NR; -#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE -	s->uart.cons		= &s->console; -	s->uart.cons->device	= uart_console_device; -	s->uart.cons->write	= uart_clps711x_console_write; -	s->uart.cons->setup	= uart_clps711x_console_setup; -	s->uart.cons->flags	= CON_PRINTBUFFER; -	s->uart.cons->index	= -1; -	s->uart.cons->data	= s; -	strcpy(s->uart.cons->name, "ttyCL"); -#endif -	ret = uart_register_driver(&s->uart); +	/* Disable port */ +	if (!uart_console(&s->port)) +		regmap_update_bits(s->syscon, SYSCON_OFFSET, SYSCON_UARTEN, 0); + +	s->tx_enabled = 1; + +	ret = devm_request_irq(&pdev->dev, s->port.irq, uart_clps711x_int_tx, 0, +			       dev_name(&pdev->dev), &s->port);  	if (ret) { -		dev_err(&pdev->dev, "Registering UART driver failed\n"); -		devm_clk_put(&pdev->dev, s->uart_clk); +		uart_remove_one_port(&clps711x_uart, &s->port);  		return ret;  	} -	for (i = 0; i < UART_CLPS711X_NR; i++) { -		s->port[i].line		= i; -		s->port[i].dev		= &pdev->dev; -		s->port[i].irq		= TX_IRQ(&s->port[i]); -		s->port[i].iobase	= SYSCON(&s->port[i]); -		s->port[i].type		= PORT_CLPS711X; -		s->port[i].fifosize	= 16; -		s->port[i].flags	= UPF_SKIP_TEST | UPF_FIXED_TYPE; -		s->port[i].uartclk	= clk_get_rate(s->uart_clk); -		s->port[i].ops		= &uart_clps711x_ops; -		WARN_ON(uart_add_one_port(&s->uart, &s->port[i])); -	} +	ret = devm_request_irq(&pdev->dev, s->rx_irq, uart_clps711x_int_rx, 0, +			       dev_name(&pdev->dev), &s->port); +	if (ret) +		uart_remove_one_port(&clps711x_uart, &s->port); -	return 0; +	return ret;  }  static int uart_clps711x_remove(struct platform_device *pdev)  {  	struct clps711x_port *s = platform_get_drvdata(pdev); -	int i; -	for (i = 0; i < UART_CLPS711X_NR; i++) -		uart_remove_one_port(&s->uart, &s->port[i]); - -	devm_clk_put(&pdev->dev, s->uart_clk); -	uart_unregister_driver(&s->uart); - -	return 0; +	return uart_remove_one_port(&clps711x_uart, &s->port);  } -static struct platform_driver clps711x_uart_driver = { +static const struct of_device_id __maybe_unused clps711x_uart_dt_ids[] = { +	{ .compatible = "cirrus,clps711x-uart", }, +	{ } +}; +MODULE_DEVICE_TABLE(of, clps711x_uart_dt_ids); + +static struct platform_driver clps711x_uart_platform = {  	.driver = { -		.name	= UART_CLPS711X_NAME, -		.owner	= THIS_MODULE, +		.name		= "clps711x-uart", +		.owner		= THIS_MODULE, +		.of_match_table	= of_match_ptr(clps711x_uart_dt_ids),  	},  	.probe	= uart_clps711x_probe,  	.remove	= uart_clps711x_remove,  }; -module_platform_driver(clps711x_uart_driver); - -static struct platform_device clps711x_uart_device = { -	.name	= UART_CLPS711X_NAME, -};  static int __init uart_clps711x_init(void)  { -	return platform_device_register(&clps711x_uart_device); +	int ret; + +#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE +	clps711x_uart.cons = &clps711x_console; +	clps711x_console.data = &clps711x_uart; +#endif + +	ret = uart_register_driver(&clps711x_uart); +	if (ret) +		return ret; + +	return platform_driver_register(&clps711x_uart_platform);  }  module_init(uart_clps711x_init);  static void __exit uart_clps711x_exit(void)  { -	platform_device_unregister(&clps711x_uart_device); +	platform_driver_unregister(&clps711x_uart_platform); +	uart_unregister_driver(&clps711x_uart);  }  module_exit(uart_clps711x_exit);  | 
