brintos

brintos / linux-shallow public Read only

0
0
Text · 10.8 KiB · e5310c6 Raw
447 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/*3 *  Driver for 8250/16550-type serial ports4 *5 *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.6 *7 *  Copyright (C) 2001 Russell King.8 */9 10#include <linux/bits.h>11#include <linux/serial_8250.h>12#include <linux/serial_core.h>13#include <linux/dmaengine.h>14 15#include "../serial_mctrl_gpio.h"16 17struct uart_8250_dma {18	int (*tx_dma)(struct uart_8250_port *p);19	int (*rx_dma)(struct uart_8250_port *p);20	void (*prepare_tx_dma)(struct uart_8250_port *p);21	void (*prepare_rx_dma)(struct uart_8250_port *p);22 23	/* Filter function */24	dma_filter_fn		fn;25	/* Parameter to the filter function */26	void			*rx_param;27	void			*tx_param;28 29	struct dma_slave_config	rxconf;30	struct dma_slave_config	txconf;31 32	struct dma_chan		*rxchan;33	struct dma_chan		*txchan;34 35	/* Device address base for DMA operations */36	phys_addr_t		rx_dma_addr;37	phys_addr_t		tx_dma_addr;38 39	/* DMA address of the buffer in memory */40	dma_addr_t		rx_addr;41	dma_addr_t		tx_addr;42 43	dma_cookie_t		rx_cookie;44	dma_cookie_t		tx_cookie;45 46	void			*rx_buf;47 48	size_t			rx_size;49	size_t			tx_size;50 51	unsigned char		tx_running;52	unsigned char		tx_err;53	unsigned char		rx_running;54};55 56struct old_serial_port {57	unsigned int uart;58	unsigned int baud_base;59	unsigned int port;60	unsigned int irq;61	upf_t        flags;62	unsigned char io_type;63	unsigned char __iomem *iomem_base;64	unsigned short iomem_reg_shift;65};66 67struct serial8250_config {68	const char	*name;69	unsigned short	fifo_size;70	unsigned short	tx_loadsz;71	unsigned char	fcr;72	unsigned char	rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];73	unsigned int	flags;74};75 76#define UART_CAP_FIFO	BIT(8)	/* UART has FIFO */77#define UART_CAP_EFR	BIT(9)	/* UART has EFR */78#define UART_CAP_SLEEP	BIT(10)	/* UART has IER sleep */79#define UART_CAP_AFE	BIT(11)	/* MCR-based hw flow control */80#define UART_CAP_UUE	BIT(12)	/* UART needs IER bit 6 set (Xscale) */81#define UART_CAP_RTOIE	BIT(13)	/* UART needs IER bit 4 set (Xscale, Tegra) */82#define UART_CAP_HFIFO	BIT(14)	/* UART has a "hidden" FIFO */83#define UART_CAP_RPM	BIT(15)	/* Runtime PM is active while idle */84#define UART_CAP_IRDA	BIT(16)	/* UART supports IrDA line discipline */85#define UART_CAP_MINI	BIT(17)	/* Mini UART on BCM283X family lacks:86					 * STOP PARITY EPAR SPAR WLEN5 WLEN687					 */88#define UART_CAP_NOTEMT	BIT(18)	/* UART without interrupt on TEMT available */89 90#define UART_BUG_QUOT	BIT(0)	/* UART has buggy quot LSB */91#define UART_BUG_TXEN	BIT(1)	/* UART has buggy TX IIR status */92#define UART_BUG_NOMSR	BIT(2)	/* UART has buggy MSR status bits (Au1x00) */93#define UART_BUG_THRE	BIT(3)	/* UART has buggy THRE reassertion */94#define UART_BUG_TXRACE	BIT(5)	/* UART Tx fails to set remote DR */95 96/* Module parameters */97#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS98 99extern unsigned int nr_uarts;100 101#ifdef CONFIG_SERIAL_8250_SHARE_IRQ102#define SERIAL8250_SHARE_IRQS 1103#else104#define SERIAL8250_SHARE_IRQS 0105#endif106 107extern unsigned int share_irqs;108extern unsigned int skip_txen_test;109 110#define SERIAL8250_PORT_FLAGS(_base, _irq, _flags)		\111	{							\112		.iobase		= _base,			\113		.irq		= _irq,				\114		.uartclk	= 1843200,			\115		.iotype		= UPIO_PORT,			\116		.flags		= UPF_BOOT_AUTOCONF | (_flags),	\117	}118 119#define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0)120 121extern struct uart_driver serial8250_reg;122void serial8250_register_ports(struct uart_driver *drv, struct device *dev);123 124/* Legacy ISA bus related APIs */125typedef void (*serial8250_isa_config_fn)(int, struct uart_port *, u32 *);126extern serial8250_isa_config_fn serial8250_isa_config;127 128void serial8250_isa_init_ports(void);129 130extern struct platform_device *serial8250_isa_devs;131 132extern const struct uart_ops *univ8250_port_base_ops;133extern struct uart_ops univ8250_port_ops;134 135static inline int serial_in(struct uart_8250_port *up, int offset)136{137	return up->port.serial_in(&up->port, offset);138}139 140static inline void serial_out(struct uart_8250_port *up, int offset, int value)141{142	up->port.serial_out(&up->port, offset, value);143}144 145/**146 *	serial_lsr_in - Read LSR register and preserve flags across reads147 *	@up:	uart 8250 port148 *149 *	Read LSR register and handle saving non-preserved flags across reads.150 *	The flags that are not preserved across reads are stored into151 *	up->lsr_saved_flags.152 *153 *	Returns LSR value or'ed with the preserved flags (if any).154 */155static inline u16 serial_lsr_in(struct uart_8250_port *up)156{157	u16 lsr = up->lsr_saved_flags;158 159	lsr |= serial_in(up, UART_LSR);160	up->lsr_saved_flags = lsr & up->lsr_save_mask;161 162	return lsr;163}164 165/*166 * For the 16C950167 */168static void serial_icr_write(struct uart_8250_port *up, int offset, int value)169{170	serial_out(up, UART_SCR, offset);171	serial_out(up, UART_ICR, value);172}173 174static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,175						   int offset)176{177	unsigned int value;178 179	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);180	serial_out(up, UART_SCR, offset);181	value = serial_in(up, UART_ICR);182	serial_icr_write(up, UART_ACR, up->acr);183 184	return value;185}186 187void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);188 189static inline u32 serial_dl_read(struct uart_8250_port *up)190{191	return up->dl_read(up);192}193 194static inline void serial_dl_write(struct uart_8250_port *up, u32 value)195{196	up->dl_write(up, value);197}198 199static inline bool serial8250_set_THRI(struct uart_8250_port *up)200{201	/* Port locked to synchronize UART_IER access against the console. */202	lockdep_assert_held_once(&up->port.lock);203 204	if (up->ier & UART_IER_THRI)205		return false;206	up->ier |= UART_IER_THRI;207	serial_out(up, UART_IER, up->ier);208	return true;209}210 211static inline bool serial8250_clear_THRI(struct uart_8250_port *up)212{213	/* Port locked to synchronize UART_IER access against the console. */214	lockdep_assert_held_once(&up->port.lock);215 216	if (!(up->ier & UART_IER_THRI))217		return false;218	up->ier &= ~UART_IER_THRI;219	serial_out(up, UART_IER, up->ier);220	return true;221}222 223struct uart_8250_port *serial8250_setup_port(int index);224struct uart_8250_port *serial8250_get_port(int line);225 226void serial8250_rpm_get(struct uart_8250_port *p);227void serial8250_rpm_put(struct uart_8250_port *p);228 229void serial8250_rpm_get_tx(struct uart_8250_port *p);230void serial8250_rpm_put_tx(struct uart_8250_port *p);231 232int serial8250_em485_config(struct uart_port *port, struct ktermios *termios,233			    struct serial_rs485 *rs485);234void serial8250_em485_start_tx(struct uart_8250_port *p);235void serial8250_em485_stop_tx(struct uart_8250_port *p);236void serial8250_em485_destroy(struct uart_8250_port *p);237extern struct serial_rs485 serial8250_em485_supported;238 239/* MCR <-> TIOCM conversion */240static inline int serial8250_TIOCM_to_MCR(int tiocm)241{242	int mcr = 0;243 244	if (tiocm & TIOCM_RTS)245		mcr |= UART_MCR_RTS;246	if (tiocm & TIOCM_DTR)247		mcr |= UART_MCR_DTR;248	if (tiocm & TIOCM_OUT1)249		mcr |= UART_MCR_OUT1;250	if (tiocm & TIOCM_OUT2)251		mcr |= UART_MCR_OUT2;252	if (tiocm & TIOCM_LOOP)253		mcr |= UART_MCR_LOOP;254 255	return mcr;256}257 258static inline int serial8250_MCR_to_TIOCM(int mcr)259{260	int tiocm = 0;261 262	if (mcr & UART_MCR_RTS)263		tiocm |= TIOCM_RTS;264	if (mcr & UART_MCR_DTR)265		tiocm |= TIOCM_DTR;266	if (mcr & UART_MCR_OUT1)267		tiocm |= TIOCM_OUT1;268	if (mcr & UART_MCR_OUT2)269		tiocm |= TIOCM_OUT2;270	if (mcr & UART_MCR_LOOP)271		tiocm |= TIOCM_LOOP;272 273	return tiocm;274}275 276/* MSR <-> TIOCM conversion */277static inline int serial8250_MSR_to_TIOCM(int msr)278{279	int tiocm = 0;280 281	if (msr & UART_MSR_DCD)282		tiocm |= TIOCM_CAR;283	if (msr & UART_MSR_RI)284		tiocm |= TIOCM_RNG;285	if (msr & UART_MSR_DSR)286		tiocm |= TIOCM_DSR;287	if (msr & UART_MSR_CTS)288		tiocm |= TIOCM_CTS;289 290	return tiocm;291}292 293static inline void serial8250_out_MCR(struct uart_8250_port *up, int value)294{295	serial_out(up, UART_MCR, value);296 297	if (up->gpios)298		mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value));299}300 301static inline int serial8250_in_MCR(struct uart_8250_port *up)302{303	int mctrl;304 305	mctrl = serial_in(up, UART_MCR);306 307	if (up->gpios) {308		unsigned int mctrl_gpio = 0;309 310		mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio);311		mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio);312	}313 314	return mctrl;315}316 317#ifdef CONFIG_SERIAL_8250_PNP318int serial8250_pnp_init(void);319void serial8250_pnp_exit(void);320#else321static inline int serial8250_pnp_init(void) { return 0; }322static inline void serial8250_pnp_exit(void) { }323#endif324 325#ifdef CONFIG_SERIAL_8250_RSA326void univ8250_rsa_support(struct uart_ops *ops);327#else328static inline void univ8250_rsa_support(struct uart_ops *ops) { }329#endif330 331#ifdef CONFIG_SERIAL_8250_FINTEK332int fintek_8250_probe(struct uart_8250_port *uart);333#else334static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; }335#endif336 337#ifdef CONFIG_ARCH_OMAP1338#include <linux/soc/ti/omap1-soc.h>339static inline int is_omap1_8250(struct uart_8250_port *pt)340{341	int res;342 343	switch (pt->port.mapbase) {344	case OMAP1_UART1_BASE:345	case OMAP1_UART2_BASE:346	case OMAP1_UART3_BASE:347		res = 1;348		break;349	default:350		res = 0;351		break;352	}353 354	return res;355}356 357static inline int is_omap1510_8250(struct uart_8250_port *pt)358{359	if (!cpu_is_omap1510())360		return 0;361 362	return is_omap1_8250(pt);363}364#else365static inline int is_omap1_8250(struct uart_8250_port *pt)366{367	return 0;368}369static inline int is_omap1510_8250(struct uart_8250_port *pt)370{371	return 0;372}373#endif374 375#ifdef CONFIG_SERIAL_8250_DMA376extern int serial8250_tx_dma(struct uart_8250_port *);377extern int serial8250_rx_dma(struct uart_8250_port *);378extern void serial8250_rx_dma_flush(struct uart_8250_port *);379extern int serial8250_request_dma(struct uart_8250_port *);380extern void serial8250_release_dma(struct uart_8250_port *);381 382static inline void serial8250_do_prepare_tx_dma(struct uart_8250_port *p)383{384	struct uart_8250_dma *dma = p->dma;385 386	if (dma->prepare_tx_dma)387		dma->prepare_tx_dma(p);388}389 390static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)391{392	struct uart_8250_dma *dma = p->dma;393 394	if (dma->prepare_rx_dma)395		dma->prepare_rx_dma(p);396}397 398static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)399{400	struct uart_8250_dma *dma = p->dma;401 402	return dma && dma->tx_running;403}404#else405static inline int serial8250_tx_dma(struct uart_8250_port *p)406{407	return -1;408}409static inline int serial8250_rx_dma(struct uart_8250_port *p)410{411	return -1;412}413static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { }414static inline int serial8250_request_dma(struct uart_8250_port *p)415{416	return -1;417}418static inline void serial8250_release_dma(struct uart_8250_port *p) { }419 420static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)421{422	return false;423}424#endif425 426static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)427{428	unsigned char status;429 430	status = serial_in(up, 0x04); /* EXCR2 */431#define PRESL(x) ((x) & 0x30)432	if (PRESL(status) == 0x10) {433		/* already in high speed mode */434		return 0;435	} else {436		status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */437		status |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */438		serial_out(up, 0x04, status);439	}440	return 1;441}442 443static inline int serial_index(struct uart_port *port)444{445	return port->minor - 64;446}447