// 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. Load more
// 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));