999 lines · 26.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0+/* * PIC32 Integrated Serial Driver. * * Copyright (C) 2015 Microchip Technology, Inc. * * Authors: *   Sorin-Andrei Pistirica <andrei.pistirica@microchip.com> */ #include <linux/gpio/consumer.h>#include <linux/kernel.h>#include <linux/platform_device.h>#include <linux/of.h>#include <linux/of_irq.h>#include <linux/init.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/console.h>#include <linux/clk.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/serial_core.h>#include <linux/delay.h>#include <linux/platform_data/pic32.h> /* UART name and device definitions */#define PIC32_DEV_NAME		"pic32-uart"#define PIC32_MAX_UARTS		6#define PIC32_SDEV_NAME		"ttyPIC" #define PIC32_UART_DFLT_BRATE		9600#define PIC32_UART_TX_FIFO_DEPTH	8#define PIC32_UART_RX_FIFO_DEPTH	8 #define PIC32_UART_MODE		0x00#define PIC32_UART_STA		0x10#define PIC32_UART_TX		0x20#define PIC32_UART_RX		0x30#define PIC32_UART_BRG		0x40 /* struct pic32_sport - pic32 serial port descriptor * @port: uart port descriptor * @idx: port index * @irq_fault: virtual fault interrupt number * @irq_fault_name: irq fault name * @irq_rx: virtual rx interrupt number * @irq_rx_name: irq rx name * @irq_tx: virtual tx interrupt number * @irq_tx_name: irq tx name * @cts_gpiod: clear to send GPIO * @dev: device descriptor **/struct pic32_sport {	struct uart_port port;	int idx; 	int irq_fault;	const char *irq_fault_name;	int irq_rx;	const char *irq_rx_name;	int irq_tx;	const char *irq_tx_name;	bool enable_tx_irq; 	struct gpio_desc *cts_gpiod; 	struct clk *clk; 	struct device *dev;}; static inline struct pic32_sport *to_pic32_sport(struct uart_port *port){	return container_of(port, struct pic32_sport, port);} static inline void pic32_uart_writel(struct pic32_sport *sport,					u32 reg, u32 val){	__raw_writel(val, sport->port.membase + reg);} static inline u32 pic32_uart_readl(struct pic32_sport *sport, u32 reg){	return	__raw_readl(sport->port.membase + reg);} /* pic32 uart mode register bits */#define PIC32_UART_MODE_ON        BIT(15)#define PIC32_UART_MODE_FRZ       BIT(14)#define PIC32_UART_MODE_SIDL      BIT(13)#define PIC32_UART_MODE_IREN      BIT(12)#define PIC32_UART_MODE_RTSMD     BIT(11)#define PIC32_UART_MODE_RESV1     BIT(10)#define PIC32_UART_MODE_UEN1      BIT(9)#define PIC32_UART_MODE_UEN0      BIT(8)#define PIC32_UART_MODE_WAKE      BIT(7)#define PIC32_UART_MODE_LPBK      BIT(6)#define PIC32_UART_MODE_ABAUD     BIT(5)#define PIC32_UART_MODE_RXINV     BIT(4)#define PIC32_UART_MODE_BRGH      BIT(3)#define PIC32_UART_MODE_PDSEL1    BIT(2)#define PIC32_UART_MODE_PDSEL0    BIT(1)#define PIC32_UART_MODE_STSEL     BIT(0) /* pic32 uart status register bits */#define PIC32_UART_STA_UTXISEL1   BIT(15)#define PIC32_UART_STA_UTXISEL0   BIT(14)#define PIC32_UART_STA_UTXINV     BIT(13)#define PIC32_UART_STA_URXEN      BIT(12)#define PIC32_UART_STA_UTXBRK     BIT(11)#define PIC32_UART_STA_UTXEN      BIT(10)#define PIC32_UART_STA_UTXBF      BIT(9)#define PIC32_UART_STA_TRMT       BIT(8)#define PIC32_UART_STA_URXISEL1   BIT(7)#define PIC32_UART_STA_URXISEL0   BIT(6)#define PIC32_UART_STA_ADDEN      BIT(5)#define PIC32_UART_STA_RIDLE      BIT(4)#define PIC32_UART_STA_PERR       BIT(3)#define PIC32_UART_STA_FERR       BIT(2)#define PIC32_UART_STA_OERR       BIT(1)#define PIC32_UART_STA_URXDA      BIT(0) /* pic32_sport pointer for console use */static struct pic32_sport *pic32_sports[PIC32_MAX_UARTS]; static inline void pic32_wait_deplete_txbuf(struct pic32_sport *sport){	/* wait for tx empty, otherwise chars will be lost or corrupted */	while (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_TRMT))		udelay(1);} /* serial core request to check if uart tx buffer is empty */static unsigned int pic32_uart_tx_empty(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port);	u32 val = pic32_uart_readl(sport, PIC32_UART_STA); 	return (val & PIC32_UART_STA_TRMT) ? 1 : 0;} /* serial core request to set UART outputs */static void pic32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl){	struct pic32_sport *sport = to_pic32_sport(port); 	/* set loopback mode */	if (mctrl & TIOCM_LOOP)		pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),					PIC32_UART_MODE_LPBK);	else		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),					PIC32_UART_MODE_LPBK);} /* serial core request to return the state of misc UART input pins */static unsigned int pic32_uart_get_mctrl(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port);	unsigned int mctrl = 0; 	/* get the state of CTS input pin for this port */	if (!sport->cts_gpiod)		mctrl |= TIOCM_CTS;	else if (gpiod_get_value(sport->cts_gpiod))		mctrl |= TIOCM_CTS; 	/* DSR and CD are not supported in PIC32, so return 1	 * RI is not supported in PIC32, so return 0	 */	mctrl |= TIOCM_CD;	mctrl |= TIOCM_DSR; 	return mctrl;} /* stop tx and start tx are not called in pairs, therefore a flag indicates * the status of irq to control the irq-depth. */static inline void pic32_uart_irqtxen(struct pic32_sport *sport, u8 en){	if (en && !sport->enable_tx_irq) {		enable_irq(sport->irq_tx);		sport->enable_tx_irq = true;	} else if (!en && sport->enable_tx_irq) {		/* use disable_irq_nosync() and not disable_irq() to avoid self		 * imposed deadlock by not waiting for irq handler to end,		 * since this callback is called from interrupt context.		 */		disable_irq_nosync(sport->irq_tx);		sport->enable_tx_irq = false;	}} /* serial core request to disable tx ASAP (used for flow control) */static void pic32_uart_stop_tx(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port); 	if (!(pic32_uart_readl(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON))		return; 	if (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN))		return; 	/* wait for tx empty */	pic32_wait_deplete_txbuf(sport); 	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),				PIC32_UART_STA_UTXEN);	pic32_uart_irqtxen(sport, 0);} /* serial core request to (re)enable tx */static void pic32_uart_start_tx(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port); 	pic32_uart_irqtxen(sport, 1);	pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA),				PIC32_UART_STA_UTXEN);} /* serial core request to stop rx, called before port shutdown */static void pic32_uart_stop_rx(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port); 	/* disable rx interrupts */	disable_irq(sport->irq_rx); 	/* receiver Enable bit OFF */	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),				PIC32_UART_STA_URXEN);} /* serial core request to start/stop emitting break char */static void pic32_uart_break_ctl(struct uart_port *port, int ctl){	struct pic32_sport *sport = to_pic32_sport(port);	unsigned long flags; 	uart_port_lock_irqsave(port, &flags); 	if (ctl)		pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA),					PIC32_UART_STA_UTXBRK);	else		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),					PIC32_UART_STA_UTXBRK); 	uart_port_unlock_irqrestore(port, flags);} /* get port type in string format */static const char *pic32_uart_type(struct uart_port *port){	return (port->type == PORT_PIC32) ? PIC32_DEV_NAME : NULL;} /* read all chars in rx fifo and send them to core */static void pic32_uart_do_rx(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port);	struct tty_port *tty;	unsigned int max_count; 	/* limit number of char read in interrupt, should not be	 * higher than fifo size anyway since we're much faster than	 * serial port	 */	max_count = PIC32_UART_RX_FIFO_DEPTH; 	uart_port_lock(port); 	tty = &port->state->port; 	do {		u32 sta_reg, c;		char flag; 		/* get overrun/fifo empty information from status register */		sta_reg = pic32_uart_readl(sport, PIC32_UART_STA);		if (unlikely(sta_reg & PIC32_UART_STA_OERR)) { 			/* fifo reset is required to clear interrupt */			pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),						PIC32_UART_STA_OERR); 			port->icount.overrun++;			tty_insert_flip_char(tty, 0, TTY_OVERRUN);		} 		/* Can at least one more character can be read? */		if (!(sta_reg & PIC32_UART_STA_URXDA))			break; 		/* read the character and increment the rx counter */		c = pic32_uart_readl(sport, PIC32_UART_RX); 		port->icount.rx++;		flag = TTY_NORMAL;		c &= 0xff; 		if (unlikely((sta_reg & PIC32_UART_STA_PERR) ||			     (sta_reg & PIC32_UART_STA_FERR))) { 			/* do stats first */			if (sta_reg & PIC32_UART_STA_PERR)				port->icount.parity++;			if (sta_reg & PIC32_UART_STA_FERR)				port->icount.frame++; 			/* update flag wrt read_status_mask */			sta_reg &= port->read_status_mask; 			if (sta_reg & PIC32_UART_STA_FERR)				flag = TTY_FRAME;			if (sta_reg & PIC32_UART_STA_PERR)				flag = TTY_PARITY;		} 		if (uart_handle_sysrq_char(port, c))			continue; 		if ((sta_reg & port->ignore_status_mask) == 0)			tty_insert_flip_char(tty, c, flag); 	} while (--max_count); 	uart_port_unlock(port); 	tty_flip_buffer_push(tty);} /* fill tx fifo with chars to send, stop when fifo is about to be full * or when all chars have been sent. */static void pic32_uart_do_tx(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port);	struct tty_port *tport = &port->state->port;	unsigned int max_count = PIC32_UART_TX_FIFO_DEPTH; 	if (port->x_char) {		pic32_uart_writel(sport, PIC32_UART_TX, port->x_char);		port->icount.tx++;		port->x_char = 0;		return;	} 	if (uart_tx_stopped(port)) {		pic32_uart_stop_tx(port);		return;	} 	if (kfifo_is_empty(&tport->xmit_fifo))		goto txq_empty; 	/* keep stuffing chars into uart tx buffer	 * 1) until uart fifo is full	 * or	 * 2) until the circ buffer is empty	 * (all chars have been sent)	 * or	 * 3) until the max count is reached	 * (prevents lingering here for too long in certain cases)	 */	while (!(PIC32_UART_STA_UTXBF &		pic32_uart_readl(sport, PIC32_UART_STA))) {		unsigned char c; 		if (!uart_fifo_get(port, &c))			break;		pic32_uart_writel(sport, PIC32_UART_TX, c); 		if (--max_count == 0)			break;	} 	if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)		uart_write_wakeup(port); 	if (kfifo_is_empty(&tport->xmit_fifo))		goto txq_empty; 	return; txq_empty:	pic32_uart_irqtxen(sport, 0);} /* RX interrupt handler */static irqreturn_t pic32_uart_rx_interrupt(int irq, void *dev_id){	struct uart_port *port = dev_id; 	pic32_uart_do_rx(port); 	return IRQ_HANDLED;} /* TX interrupt handler */static irqreturn_t pic32_uart_tx_interrupt(int irq, void *dev_id){	struct uart_port *port = dev_id;	unsigned long flags; 	uart_port_lock_irqsave(port, &flags);	pic32_uart_do_tx(port);	uart_port_unlock_irqrestore(port, flags); 	return IRQ_HANDLED;} /* FAULT interrupt handler */static irqreturn_t pic32_uart_fault_interrupt(int irq, void *dev_id){	/* do nothing: pic32_uart_do_rx() handles faults. */	return IRQ_HANDLED;} /* enable rx & tx operation on uart */static void pic32_uart_en_and_unmask(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port); 	pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA),				PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN);	pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),				PIC32_UART_MODE_ON);} /* disable rx & tx operation on uart */static void pic32_uart_dsbl_and_mask(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port); 	/* wait for tx empty, otherwise chars will be lost or corrupted */	pic32_wait_deplete_txbuf(sport); 	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),				PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN);	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),				PIC32_UART_MODE_ON);} /* serial core request to initialize uart and start rx operation */static int pic32_uart_startup(struct uart_port *port){	struct pic32_sport *sport = to_pic32_sport(port);	u32 dflt_baud = (port->uartclk / PIC32_UART_DFLT_BRATE / 16) - 1;	unsigned long flags;	int ret; 	local_irq_save(flags); 	ret = clk_prepare_enable(sport->clk);	if (ret) {		local_irq_restore(flags);		goto out_done;	} 	/* clear status and mode registers */	pic32_uart_writel(sport, PIC32_UART_MODE, 0);	pic32_uart_writel(sport, PIC32_UART_STA, 0); 	/* disable uart and mask all interrupts */	pic32_uart_dsbl_and_mask(port); 	/* set default baud */	pic32_uart_writel(sport, PIC32_UART_BRG, dflt_baud); 	local_irq_restore(flags); 	/* Each UART of a PIC32 has three interrupts therefore,	 * we setup driver to register the 3 irqs for the device.	 *	 * For each irq request_irq() is called with interrupt disabled.	 * And the irq is enabled as soon as we are ready to handle them.	 */	sport->enable_tx_irq = false; 	sport->irq_fault_name = kasprintf(GFP_KERNEL, "%s%d-fault",					  pic32_uart_type(port),					  sport->idx);	if (!sport->irq_fault_name) {		dev_err(port->dev, "%s: kasprintf err!", __func__);		ret = -ENOMEM;		goto out_disable_clk;	}	irq_set_status_flags(sport->irq_fault, IRQ_NOAUTOEN);	ret = request_irq(sport->irq_fault, pic32_uart_fault_interrupt,			  IRQF_NO_THREAD, sport->irq_fault_name, port);	if (ret) {		dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",			__func__, sport->irq_fault, ret,			pic32_uart_type(port));

Lines 1–500 of 999.