brintos

brintos / linux-shallow public Read only

0
0
Text · 23.3 KiB · 8aea59f Raw
977 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * st-asc.c: ST Asynchronous serial controller (ASC) driver4 *5 * Copyright (C) 2003-2013 STMicroelectronics (R&D) Limited6 */7 8#include <linux/module.h>9#include <linux/serial.h>10#include <linux/console.h>11#include <linux/sysrq.h>12#include <linux/pinctrl/consumer.h>13#include <linux/platform_device.h>14#include <linux/io.h>15#include <linux/irq.h>16#include <linux/tty.h>17#include <linux/tty_flip.h>18#include <linux/delay.h>19#include <linux/spinlock.h>20#include <linux/of.h>21#include <linux/of_platform.h>22#include <linux/serial_core.h>23#include <linux/clk.h>24#include <linux/gpio/consumer.h>25 26#define DRIVER_NAME "st-asc"27#define ASC_SERIAL_NAME "ttyAS"28#define ASC_FIFO_SIZE 1629#define ASC_MAX_PORTS 830 31/* Pinctrl states */32#define DEFAULT		033#define NO_HW_FLOWCTRL	134 35struct asc_port {36	struct uart_port port;37	struct gpio_desc *rts;38	struct clk *clk;39	struct pinctrl *pinctrl;40	struct pinctrl_state *states[2];41	unsigned int hw_flow_control:1;42	unsigned int force_m1:1;43};44 45static struct asc_port asc_ports[ASC_MAX_PORTS];46static struct uart_driver asc_uart_driver;47 48/*---- UART Register definitions ------------------------------*/49 50/* Register offsets */51 52#define ASC_BAUDRATE			0x0053#define ASC_TXBUF			0x0454#define ASC_RXBUF			0x0855#define ASC_CTL				0x0C56#define ASC_INTEN			0x1057#define ASC_STA				0x1458#define ASC_GUARDTIME			0x1859#define ASC_TIMEOUT			0x1C60#define ASC_TXRESET			0x2061#define ASC_RXRESET			0x2462#define ASC_RETRIES			0x2863 64/* ASC_RXBUF */65#define ASC_RXBUF_PE			0x10066#define ASC_RXBUF_FE			0x20067/*68 * Some of status comes from higher bits of the character and some come from69 * the status register. Combining both of them in to single status using dummy70 * bits.71 */72#define ASC_RXBUF_DUMMY_RX		0x1000073#define ASC_RXBUF_DUMMY_BE		0x2000074#define ASC_RXBUF_DUMMY_OE		0x4000075 76/* ASC_CTL */77 78#define ASC_CTL_MODE_MSK		0x000779#define  ASC_CTL_MODE_8BIT		0x000180#define  ASC_CTL_MODE_7BIT_PAR		0x000381#define  ASC_CTL_MODE_9BIT		0x000482#define  ASC_CTL_MODE_8BIT_WKUP		0x000583#define  ASC_CTL_MODE_8BIT_PAR		0x000784#define ASC_CTL_STOP_MSK		0x001885#define  ASC_CTL_STOP_HALFBIT		0x000086#define  ASC_CTL_STOP_1BIT		0x000887#define  ASC_CTL_STOP_1_HALFBIT		0x001088#define  ASC_CTL_STOP_2BIT		0x001889#define ASC_CTL_PARITYODD		0x002090#define ASC_CTL_LOOPBACK		0x004091#define ASC_CTL_RUN			0x008092#define ASC_CTL_RXENABLE		0x010093#define ASC_CTL_SCENABLE		0x020094#define ASC_CTL_FIFOENABLE		0x040095#define ASC_CTL_CTSENABLE		0x080096#define ASC_CTL_BAUDMODE		0x100097 98/* ASC_GUARDTIME */99 100#define ASC_GUARDTIME_MSK		0x00FF101 102/* ASC_INTEN */103 104#define ASC_INTEN_RBE			0x0001105#define ASC_INTEN_TE			0x0002106#define ASC_INTEN_THE			0x0004107#define ASC_INTEN_PE			0x0008108#define ASC_INTEN_FE			0x0010109#define ASC_INTEN_OE			0x0020110#define ASC_INTEN_TNE			0x0040111#define ASC_INTEN_TOI			0x0080112#define ASC_INTEN_RHF			0x0100113 114/* ASC_RETRIES */115 116#define ASC_RETRIES_MSK			0x00FF117 118/* ASC_RXBUF */119 120#define ASC_RXBUF_MSK			0x03FF121 122/* ASC_STA */123 124#define ASC_STA_RBF			0x0001125#define ASC_STA_TE			0x0002126#define ASC_STA_THE			0x0004127#define ASC_STA_PE			0x0008128#define ASC_STA_FE			0x0010129#define ASC_STA_OE			0x0020130#define ASC_STA_TNE			0x0040131#define ASC_STA_TOI			0x0080132#define ASC_STA_RHF			0x0100133#define ASC_STA_TF			0x0200134#define ASC_STA_NKD			0x0400135 136/* ASC_TIMEOUT */137 138#define ASC_TIMEOUT_MSK			0x00FF139 140/* ASC_TXBUF */141 142#define ASC_TXBUF_MSK			0x01FF143 144/*---- Inline function definitions ---------------------------*/145 146static inline struct asc_port *to_asc_port(struct uart_port *port)147{148	return container_of(port, struct asc_port, port);149}150 151static inline u32 asc_in(struct uart_port *port, u32 offset)152{153#ifdef readl_relaxed154	return readl_relaxed(port->membase + offset);155#else156	return readl(port->membase + offset);157#endif158}159 160static inline void asc_out(struct uart_port *port, u32 offset, u32 value)161{162#ifdef writel_relaxed163	writel_relaxed(value, port->membase + offset);164#else165	writel(value, port->membase + offset);166#endif167}168 169/*170 * Some simple utility functions to enable and disable interrupts.171 * Note that these need to be called with interrupts disabled.172 */173static inline void asc_disable_tx_interrupts(struct uart_port *port)174{175	u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_THE;176	asc_out(port, ASC_INTEN, intenable);177	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */178}179 180static inline void asc_enable_tx_interrupts(struct uart_port *port)181{182	u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_THE;183	asc_out(port, ASC_INTEN, intenable);184}185 186static inline void asc_disable_rx_interrupts(struct uart_port *port)187{188	u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_RBE;189	asc_out(port, ASC_INTEN, intenable);190	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */191}192 193static inline void asc_enable_rx_interrupts(struct uart_port *port)194{195	u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_RBE;196	asc_out(port, ASC_INTEN, intenable);197}198 199static inline u32 asc_txfifo_is_empty(struct uart_port *port)200{201	return asc_in(port, ASC_STA) & ASC_STA_TE;202}203 204static inline u32 asc_txfifo_is_half_empty(struct uart_port *port)205{206	return asc_in(port, ASC_STA) & ASC_STA_THE;207}208 209static inline const char *asc_port_name(struct uart_port *port)210{211	return to_platform_device(port->dev)->name;212}213 214/*----------------------------------------------------------------------*/215 216/*217 * This section contains code to support the use of the ASC as a218 * generic serial port.219 */220 221static inline unsigned asc_hw_txroom(struct uart_port *port)222{223	u32 status = asc_in(port, ASC_STA);224 225	if (status & ASC_STA_THE)226		return port->fifosize / 2;227	else if (!(status & ASC_STA_TF))228		return 1;229 230	return 0;231}232 233/*234 * Start transmitting chars.235 * This is called from both interrupt and task level.236 * Either way interrupts are disabled.237 */238static void asc_transmit_chars(struct uart_port *port)239{240	u8 ch;241 242	uart_port_tx_limited(port, ch, asc_hw_txroom(port),243		true,244		asc_out(port, ASC_TXBUF, ch),245		({}));246}247 248static void asc_receive_chars(struct uart_port *port)249{250	struct tty_port *tport = &port->state->port;251	unsigned long status, mode;252	unsigned long c = 0;253	u8 flag;254	bool ignore_pe = false;255 256	/*257	 * Datasheet states: If the MODE field selects an 8-bit frame then258	 * this [parity error] bit is undefined. Software should ignore this259	 * bit when reading 8-bit frames.260	 */261	mode = asc_in(port, ASC_CTL) & ASC_CTL_MODE_MSK;262	if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR)263		ignore_pe = true;264 265	if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))266		pm_wakeup_event(tport->tty->dev, 0);267 268	while ((status = asc_in(port, ASC_STA)) & ASC_STA_RBF) {269		c = asc_in(port, ASC_RXBUF) | ASC_RXBUF_DUMMY_RX;270		flag = TTY_NORMAL;271		port->icount.rx++;272 273		if (status & ASC_STA_OE || c & ASC_RXBUF_FE ||274		    (c & ASC_RXBUF_PE && !ignore_pe)) {275 276			if (c & ASC_RXBUF_FE) {277				if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {278					port->icount.brk++;279					if (uart_handle_break(port))280						continue;281					c |= ASC_RXBUF_DUMMY_BE;282				} else {283					port->icount.frame++;284				}285			} else if (c & ASC_RXBUF_PE) {286				port->icount.parity++;287			}288			/*289			 * Reading any data from the RX FIFO clears the290			 * overflow error condition.291			 */292			if (status & ASC_STA_OE) {293				port->icount.overrun++;294				c |= ASC_RXBUF_DUMMY_OE;295			}296 297			c &= port->read_status_mask;298 299			if (c & ASC_RXBUF_DUMMY_BE)300				flag = TTY_BREAK;301			else if (c & ASC_RXBUF_PE)302				flag = TTY_PARITY;303			else if (c & ASC_RXBUF_FE)304				flag = TTY_FRAME;305		}306 307		if (uart_handle_sysrq_char(port, c & 0xff))308			continue;309 310		uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag);311	}312 313	/* Tell the rest of the system the news. New characters! */314	tty_flip_buffer_push(tport);315}316 317static irqreturn_t asc_interrupt(int irq, void *ptr)318{319	struct uart_port *port = ptr;320	u32 status;321 322	uart_port_lock(port);323 324	status = asc_in(port, ASC_STA);325 326	if (status & ASC_STA_RBF) {327		/* Receive FIFO not empty */328		asc_receive_chars(port);329	}330 331	if ((status & ASC_STA_THE) &&332	    (asc_in(port, ASC_INTEN) & ASC_INTEN_THE)) {333		/* Transmitter FIFO at least half empty */334		asc_transmit_chars(port);335	}336 337	uart_port_unlock(port);338 339	return IRQ_HANDLED;340}341 342/*----------------------------------------------------------------------*/343 344/*345 * UART Functions346 */347 348static unsigned int asc_tx_empty(struct uart_port *port)349{350	return asc_txfifo_is_empty(port) ? TIOCSER_TEMT : 0;351}352 353static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)354{355	struct asc_port *ascport = to_asc_port(port);356 357	/*358	 * This routine is used for seting signals of: DTR, DCD, CTS and RTS.359	 * We use ASC's hardware for CTS/RTS when hardware flow-control is360	 * enabled, however if the RTS line is required for another purpose,361	 * commonly controlled using HUP from userspace, then we need to toggle362	 * it manually, using GPIO.363	 *364	 * Some boards also have DTR and DCD implemented using PIO pins, code to365	 * do this should be hooked in here.366	 */367 368	if (!ascport->rts)369		return;370 371	/* If HW flow-control is enabled, we can't fiddle with the RTS line */372	if (asc_in(port, ASC_CTL) & ASC_CTL_CTSENABLE)373		return;374 375	gpiod_set_value(ascport->rts, mctrl & TIOCM_RTS);376}377 378static unsigned int asc_get_mctrl(struct uart_port *port)379{380	/*381	 * This routine is used for geting signals of: DTR, DCD, DSR, RI,382	 * and CTS/RTS383	 */384	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;385}386 387/* There are probably characters waiting to be transmitted. */388static void asc_start_tx(struct uart_port *port)389{390	struct tty_port *tport = &port->state->port;391 392	if (!kfifo_is_empty(&tport->xmit_fifo))393		asc_enable_tx_interrupts(port);394}395 396/* Transmit stop */397static void asc_stop_tx(struct uart_port *port)398{399	asc_disable_tx_interrupts(port);400}401 402/* Receive stop */403static void asc_stop_rx(struct uart_port *port)404{405	asc_disable_rx_interrupts(port);406}407 408/* Handle breaks - ignored by us */409static void asc_break_ctl(struct uart_port *port, int break_state)410{411	/* Nothing here yet .. */412}413 414/*415 * Enable port for reception.416 */417static int asc_startup(struct uart_port *port)418{419	if (request_irq(port->irq, asc_interrupt, 0,420			asc_port_name(port), port)) {421		dev_err(port->dev, "cannot allocate irq.\n");422		return -ENODEV;423	}424 425	asc_transmit_chars(port);426	asc_enable_rx_interrupts(port);427 428	return 0;429}430 431static void asc_shutdown(struct uart_port *port)432{433	asc_disable_tx_interrupts(port);434	asc_disable_rx_interrupts(port);435	free_irq(port->irq, port);436}437 438static void asc_pm(struct uart_port *port, unsigned int state,439		unsigned int oldstate)440{441	struct asc_port *ascport = to_asc_port(port);442	unsigned long flags;443	u32 ctl;444 445	switch (state) {446	case UART_PM_STATE_ON:447		clk_prepare_enable(ascport->clk);448		break;449	case UART_PM_STATE_OFF:450		/*451		 * Disable the ASC baud rate generator, which is as close as452		 * we can come to turning it off. Note this is not called with453		 * the port spinlock held.454		 */455		uart_port_lock_irqsave(port, &flags);456		ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN;457		asc_out(port, ASC_CTL, ctl);458		uart_port_unlock_irqrestore(port, flags);459		clk_disable_unprepare(ascport->clk);460		break;461	}462}463 464static void asc_set_termios(struct uart_port *port, struct ktermios *termios,465			    const struct ktermios *old)466{467	struct asc_port *ascport = to_asc_port(port);468	bool manual_rts, toggle_rts = false;469	struct gpio_desc *gpiod;470	unsigned int baud;471	u32 ctrl_val;472	tcflag_t cflag;473	unsigned long flags;474 475	/* Update termios to reflect hardware capabilities */476	termios->c_cflag &= ~(CMSPAR |477			 (ascport->hw_flow_control ? 0 : CRTSCTS));478 479	port->uartclk = clk_get_rate(ascport->clk);480 481	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);482	cflag = termios->c_cflag;483 484	uart_port_lock_irqsave(port, &flags);485 486	/* read control register */487	ctrl_val = asc_in(port, ASC_CTL);488 489	/* stop serial port and reset value */490	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));491	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;492 493	/* reset fifo rx & tx */494	asc_out(port, ASC_TXRESET, 1);495	asc_out(port, ASC_RXRESET, 1);496 497	/* set character length */498	if ((cflag & CSIZE) == CS7) {499		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;500		cflag |= PARENB;501	} else {502		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :503						ASC_CTL_MODE_8BIT;504		cflag &= ~CSIZE;505		cflag |= CS8;506	}507	termios->c_cflag = cflag;508 509	/* set stop bit */510	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;511 512	/* odd parity */513	if (cflag & PARODD)514		ctrl_val |= ASC_CTL_PARITYODD;515 516	/* hardware flow control */517	if ((cflag & CRTSCTS)) {518		ctrl_val |= ASC_CTL_CTSENABLE;519 520		/* If flow-control selected, stop handling RTS manually */521		if (ascport->rts) {522			toggle_rts = true;523			manual_rts = false;524		}525	} else {526		/* If flow-control disabled, it's safe to handle RTS manually */527		if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL])528			manual_rts = toggle_rts = true;529	}530 531	if ((baud < 19200) && !ascport->force_m1) {532		asc_out(port, ASC_BAUDRATE, (port->uartclk / (16 * baud)));533	} else {534		/*535		 * MODE 1: recommended for high bit rates (above 19.2K)536		 *537		 *                   baudrate * 16 * 2^16538		 * ASCBaudRate =   ------------------------539		 *                          inputclock540		 *541		 * To keep maths inside 64bits, we divide inputclock by 16.542		 */543		u64 dividend = (u64)baud * (1 << 16);544 545		do_div(dividend, port->uartclk / 16);546		asc_out(port, ASC_BAUDRATE, dividend);547		ctrl_val |= ASC_CTL_BAUDMODE;548	}549 550	uart_update_timeout(port, cflag, baud);551 552	ascport->port.read_status_mask = ASC_RXBUF_DUMMY_OE;553	if (termios->c_iflag & INPCK)554		ascport->port.read_status_mask |= ASC_RXBUF_FE | ASC_RXBUF_PE;555	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))556		ascport->port.read_status_mask |= ASC_RXBUF_DUMMY_BE;557 558	/*559	 * Characters to ignore560	 */561	ascport->port.ignore_status_mask = 0;562	if (termios->c_iflag & IGNPAR)563		ascport->port.ignore_status_mask |= ASC_RXBUF_FE | ASC_RXBUF_PE;564	if (termios->c_iflag & IGNBRK) {565		ascport->port.ignore_status_mask |= ASC_RXBUF_DUMMY_BE;566		/*567		 * If we're ignoring parity and break indicators,568		 * ignore overruns too (for real raw support).569		 */570		if (termios->c_iflag & IGNPAR)571			ascport->port.ignore_status_mask |= ASC_RXBUF_DUMMY_OE;572	}573 574	/*575	 * Ignore all characters if CREAD is not set.576	 */577	if (!(termios->c_cflag & CREAD))578		ascport->port.ignore_status_mask |= ASC_RXBUF_DUMMY_RX;579 580	/* Set the timeout */581	asc_out(port, ASC_TIMEOUT, 20);582 583	/* write final value and enable port */584	asc_out(port, ASC_CTL, (ctrl_val | ASC_CTL_RUN));585 586	uart_port_unlock_irqrestore(port, flags);587 588	if (toggle_rts) {589		if (manual_rts) {590			pinctrl_select_state(ascport->pinctrl,591					     ascport->states[NO_HW_FLOWCTRL]);592 593			gpiod = devm_gpiod_get(port->dev, "rts", GPIOD_OUT_LOW);594			if (!IS_ERR(gpiod)) {595				gpiod_set_consumer_name(gpiod,596							port->dev->of_node->name);597				ascport->rts = gpiod;598			}599		} else {600				devm_gpiod_put(port->dev, ascport->rts);601				ascport->rts = NULL;602				pinctrl_select_state(ascport->pinctrl,603						     ascport->states[DEFAULT]);604		}605	}606}607 608static const char *asc_type(struct uart_port *port)609{610	return (port->type == PORT_ASC) ? DRIVER_NAME : NULL;611}612 613static void asc_release_port(struct uart_port *port)614{615}616 617static int asc_request_port(struct uart_port *port)618{619	return 0;620}621 622/*623 * Called when the port is opened, and UPF_BOOT_AUTOCONF flag is set624 * Set type field if successful625 */626static void asc_config_port(struct uart_port *port, int flags)627{628	if ((flags & UART_CONFIG_TYPE))629		port->type = PORT_ASC;630}631 632static int633asc_verify_port(struct uart_port *port, struct serial_struct *ser)634{635	/* No user changeable parameters */636	return -EINVAL;637}638 639#ifdef CONFIG_CONSOLE_POLL640/*641 * Console polling routines for writing and reading from the uart while642 * in an interrupt or debug context (i.e. kgdb).643 */644 645static int asc_get_poll_char(struct uart_port *port)646{647	if (!(asc_in(port, ASC_STA) & ASC_STA_RBF))648		return NO_POLL_CHAR;649 650	return asc_in(port, ASC_RXBUF);651}652 653static void asc_put_poll_char(struct uart_port *port, unsigned char c)654{655	while (!asc_txfifo_is_half_empty(port))656		cpu_relax();657	asc_out(port, ASC_TXBUF, c);658}659 660#endif /* CONFIG_CONSOLE_POLL */661 662/*---------------------------------------------------------------------*/663 664static const struct uart_ops asc_uart_ops = {665	.tx_empty	= asc_tx_empty,666	.set_mctrl	= asc_set_mctrl,667	.get_mctrl	= asc_get_mctrl,668	.start_tx	= asc_start_tx,669	.stop_tx	= asc_stop_tx,670	.stop_rx	= asc_stop_rx,671	.break_ctl	= asc_break_ctl,672	.startup	= asc_startup,673	.shutdown	= asc_shutdown,674	.set_termios	= asc_set_termios,675	.type		= asc_type,676	.release_port	= asc_release_port,677	.request_port	= asc_request_port,678	.config_port	= asc_config_port,679	.verify_port	= asc_verify_port,680	.pm		= asc_pm,681#ifdef CONFIG_CONSOLE_POLL682	.poll_get_char = asc_get_poll_char,683	.poll_put_char = asc_put_poll_char,684#endif /* CONFIG_CONSOLE_POLL */685};686 687static int asc_init_port(struct asc_port *ascport,688			  struct platform_device *pdev)689{690	struct uart_port *port = &ascport->port;691	struct resource *res;692	int ret;693 694	port->iotype	= UPIO_MEM;695	port->flags	= UPF_BOOT_AUTOCONF;696	port->ops	= &asc_uart_ops;697	port->fifosize	= ASC_FIFO_SIZE;698	port->dev	= &pdev->dev;699	port->irq	= platform_get_irq(pdev, 0);700	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_ST_ASC_CONSOLE);701 702	port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);703	if (IS_ERR(port->membase))704		return PTR_ERR(port->membase);705	port->mapbase = res->start;706 707	spin_lock_init(&port->lock);708 709	ascport->clk = devm_clk_get(&pdev->dev, NULL);710 711	if (WARN_ON(IS_ERR(ascport->clk)))712		return -EINVAL;713	/* ensure that clk rate is correct by enabling the clk */714	ret = clk_prepare_enable(ascport->clk);715	if (ret)716		return ret;717	ascport->port.uartclk = clk_get_rate(ascport->clk);718	WARN_ON(ascport->port.uartclk == 0);719	clk_disable_unprepare(ascport->clk);720 721	ascport->pinctrl = devm_pinctrl_get(&pdev->dev);722	if (IS_ERR(ascport->pinctrl)) {723		ret = PTR_ERR(ascport->pinctrl);724		dev_err(&pdev->dev, "Failed to get Pinctrl: %d\n", ret);725		return ret;726	}727 728	ascport->states[DEFAULT] =729		pinctrl_lookup_state(ascport->pinctrl, "default");730	if (IS_ERR(ascport->states[DEFAULT])) {731		ret = PTR_ERR(ascport->states[DEFAULT]);732		dev_err(&pdev->dev,733			"Failed to look up Pinctrl state 'default': %d\n", ret);734		return ret;735	}736 737	/* "no-hw-flowctrl" state is optional */738	ascport->states[NO_HW_FLOWCTRL] =739		pinctrl_lookup_state(ascport->pinctrl, "no-hw-flowctrl");740	if (IS_ERR(ascport->states[NO_HW_FLOWCTRL]))741		ascport->states[NO_HW_FLOWCTRL] = NULL;742 743	return 0;744}745 746static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev)747{748	struct device_node *np = pdev->dev.of_node;749	int id;750 751	if (!np)752		return NULL;753 754	id = of_alias_get_id(np, "serial");755	if (id < 0)756		id = of_alias_get_id(np, ASC_SERIAL_NAME);757 758	if (id < 0)759		id = 0;760 761	if (WARN_ON(id >= ASC_MAX_PORTS))762		return NULL;763 764	asc_ports[id].hw_flow_control = of_property_read_bool(np,765							"uart-has-rtscts");766	asc_ports[id].force_m1 =  of_property_read_bool(np, "st,force-m1");767	asc_ports[id].port.line = id;768	asc_ports[id].rts = NULL;769 770	return &asc_ports[id];771}772 773#ifdef CONFIG_OF774static const struct of_device_id asc_match[] = {775	{ .compatible = "st,asc", },776	{},777};778 779MODULE_DEVICE_TABLE(of, asc_match);780#endif781 782static int asc_serial_probe(struct platform_device *pdev)783{784	int ret;785	struct asc_port *ascport;786 787	ascport = asc_of_get_asc_port(pdev);788	if (!ascport)789		return -ENODEV;790 791	ret = asc_init_port(ascport, pdev);792	if (ret)793		return ret;794 795	ret = uart_add_one_port(&asc_uart_driver, &ascport->port);796	if (ret)797		return ret;798 799	platform_set_drvdata(pdev, &ascport->port);800 801	return 0;802}803 804static void asc_serial_remove(struct platform_device *pdev)805{806	struct uart_port *port = platform_get_drvdata(pdev);807 808	uart_remove_one_port(&asc_uart_driver, port);809}810 811static int asc_serial_suspend(struct device *dev)812{813	struct uart_port *port = dev_get_drvdata(dev);814 815	return uart_suspend_port(&asc_uart_driver, port);816}817 818static int asc_serial_resume(struct device *dev)819{820	struct uart_port *port = dev_get_drvdata(dev);821 822	return uart_resume_port(&asc_uart_driver, port);823}824 825/*----------------------------------------------------------------------*/826 827#ifdef CONFIG_SERIAL_ST_ASC_CONSOLE828static void asc_console_putchar(struct uart_port *port, unsigned char ch)829{830	unsigned int timeout = 1000000;831 832	/* Wait for upto 1 second in case flow control is stopping us. */833	while (--timeout && !asc_txfifo_is_half_empty(port))834		udelay(1);835 836	asc_out(port, ASC_TXBUF, ch);837}838 839/*840 *  Print a string to the serial port trying not to disturb841 *  any possible real use of the port...842 */843 844static void asc_console_write(struct console *co, const char *s, unsigned count)845{846	struct uart_port *port = &asc_ports[co->index].port;847	unsigned long flags;848	unsigned long timeout = 1000000;849	int locked = 1;850	u32 intenable;851 852	if (port->sysrq)853		locked = 0; /* asc_interrupt has already claimed the lock */854	else if (oops_in_progress)855		locked = uart_port_trylock_irqsave(port, &flags);856	else857		uart_port_lock_irqsave(port, &flags);858 859	/*860	 * Disable interrupts so we don't get the IRQ line bouncing861	 * up and down while interrupts are disabled.862	 */863	intenable = asc_in(port, ASC_INTEN);864	asc_out(port, ASC_INTEN, 0);865	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */866 867	uart_console_write(port, s, count, asc_console_putchar);868 869	while (--timeout && !asc_txfifo_is_empty(port))870		udelay(1);871 872	asc_out(port, ASC_INTEN, intenable);873 874	if (locked)875		uart_port_unlock_irqrestore(port, flags);876}877 878static int asc_console_setup(struct console *co, char *options)879{880	struct asc_port *ascport;881	int baud = 115200;882	int bits = 8;883	int parity = 'n';884	int flow = 'n';885 886	if (co->index >= ASC_MAX_PORTS)887		return -ENODEV;888 889	ascport = &asc_ports[co->index];890 891	/*892	 * This driver does not support early console initialization893	 * (use ARM early printk support instead), so we only expect894	 * this to be called during the uart port registration when the895	 * driver gets probed and the port should be mapped at that point.896	 */897	if (ascport->port.mapbase == 0 || ascport->port.membase == NULL)898		return -ENXIO;899 900	if (options)901		uart_parse_options(options, &baud, &parity, &bits, &flow);902 903	return uart_set_options(&ascport->port, co, baud, parity, bits, flow);904}905 906static struct console asc_console = {907	.name		= ASC_SERIAL_NAME,908	.device		= uart_console_device,909	.write		= asc_console_write,910	.setup		= asc_console_setup,911	.flags		= CON_PRINTBUFFER,912	.index		= -1,913	.data		= &asc_uart_driver,914};915 916#define ASC_SERIAL_CONSOLE (&asc_console)917 918#else919#define ASC_SERIAL_CONSOLE NULL920#endif /* CONFIG_SERIAL_ST_ASC_CONSOLE */921 922static struct uart_driver asc_uart_driver = {923	.owner		= THIS_MODULE,924	.driver_name	= DRIVER_NAME,925	.dev_name	= ASC_SERIAL_NAME,926	.major		= 0,927	.minor		= 0,928	.nr		= ASC_MAX_PORTS,929	.cons		= ASC_SERIAL_CONSOLE,930};931 932static DEFINE_SIMPLE_DEV_PM_OPS(asc_serial_pm_ops, asc_serial_suspend,933						   asc_serial_resume);934 935static struct platform_driver asc_serial_driver = {936	.probe		= asc_serial_probe,937	.remove_new	= asc_serial_remove,938	.driver	= {939		.name	= DRIVER_NAME,940		.pm	= pm_sleep_ptr(&asc_serial_pm_ops),941		.of_match_table = of_match_ptr(asc_match),942	},943};944 945static int __init asc_init(void)946{947	int ret;948	static const char banner[] __initconst =949		KERN_INFO "STMicroelectronics ASC driver initialized\n";950 951	printk(banner);952 953	ret = uart_register_driver(&asc_uart_driver);954	if (ret)955		return ret;956 957	ret = platform_driver_register(&asc_serial_driver);958	if (ret)959		uart_unregister_driver(&asc_uart_driver);960 961	return ret;962}963 964static void __exit asc_exit(void)965{966	platform_driver_unregister(&asc_serial_driver);967	uart_unregister_driver(&asc_uart_driver);968}969 970module_init(asc_init);971module_exit(asc_exit);972 973MODULE_ALIAS("platform:" DRIVER_NAME);974MODULE_AUTHOR("STMicroelectronics (R&D) Limited");975MODULE_DESCRIPTION("STMicroelectronics ASC serial port driver");976MODULE_LICENSE("GPL");977