14f5f5887SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0+ */
29bef3d41SPaul Gortmaker /*
39bef3d41SPaul Gortmaker * Driver for 8250/16550-type serial ports
49bef3d41SPaul Gortmaker *
59bef3d41SPaul Gortmaker * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
69bef3d41SPaul Gortmaker *
79bef3d41SPaul Gortmaker * Copyright (C) 2001 Russell King.
89bef3d41SPaul Gortmaker */
99bef3d41SPaul Gortmaker
101f06f571SAndrew Jeffery #include <linux/bits.h>
119bef3d41SPaul Gortmaker #include <linux/serial_8250.h>
12aef9a7bdSYoshihiro YUNOMAE #include <linux/serial_reg.h>
139ee4b83eSHeikki Krogerus #include <linux/dmaengine.h>
149ee4b83eSHeikki Krogerus
154a96895fSYegor Yefremov #include "../serial_mctrl_gpio.h"
164a96895fSYegor Yefremov
179ee4b83eSHeikki Krogerus struct uart_8250_dma {
18f1a297bbSSebastian Andrzej Siewior int (*tx_dma)(struct uart_8250_port *p);
1933d9b8b2SPeter Hurley int (*rx_dma)(struct uart_8250_port *p);
20e4fb03feSMiquel Raynal void (*prepare_tx_dma)(struct uart_8250_port *p);
21e4fb03feSMiquel Raynal void (*prepare_rx_dma)(struct uart_8250_port *p);
22f1a297bbSSebastian Andrzej Siewior
239a1870ceSAndy Shevchenko /* Filter function */
249ee4b83eSHeikki Krogerus dma_filter_fn fn;
259a1870ceSAndy Shevchenko /* Parameter to the filter function */
269ee4b83eSHeikki Krogerus void *rx_param;
279ee4b83eSHeikki Krogerus void *tx_param;
289ee4b83eSHeikki Krogerus
299ee4b83eSHeikki Krogerus struct dma_slave_config rxconf;
309ee4b83eSHeikki Krogerus struct dma_slave_config txconf;
319ee4b83eSHeikki Krogerus
329ee4b83eSHeikki Krogerus struct dma_chan *rxchan;
339ee4b83eSHeikki Krogerus struct dma_chan *txchan;
349ee4b83eSHeikki Krogerus
35d1834babSAndy Shevchenko /* Device address base for DMA operations */
36d1834babSAndy Shevchenko phys_addr_t rx_dma_addr;
37d1834babSAndy Shevchenko phys_addr_t tx_dma_addr;
38d1834babSAndy Shevchenko
39d1834babSAndy Shevchenko /* DMA address of the buffer in memory */
409ee4b83eSHeikki Krogerus dma_addr_t rx_addr;
419ee4b83eSHeikki Krogerus dma_addr_t tx_addr;
429ee4b83eSHeikki Krogerus
439ee4b83eSHeikki Krogerus dma_cookie_t rx_cookie;
449ee4b83eSHeikki Krogerus dma_cookie_t tx_cookie;
459ee4b83eSHeikki Krogerus
469ee4b83eSHeikki Krogerus void *rx_buf;
479ee4b83eSHeikki Krogerus
489ee4b83eSHeikki Krogerus size_t rx_size;
499ee4b83eSHeikki Krogerus size_t tx_size;
509ee4b83eSHeikki Krogerus
51eafb9eeaSJohn Ogness unsigned char tx_running;
52eafb9eeaSJohn Ogness unsigned char tx_err;
53eafb9eeaSJohn Ogness unsigned char rx_running;
549ee4b83eSHeikki Krogerus };
559bef3d41SPaul Gortmaker
569bef3d41SPaul Gortmaker struct old_serial_port {
579bef3d41SPaul Gortmaker unsigned int uart;
589bef3d41SPaul Gortmaker unsigned int baud_base;
599bef3d41SPaul Gortmaker unsigned int port;
609bef3d41SPaul Gortmaker unsigned int irq;
61079119a2SAndy Shevchenko upf_t flags;
629bef3d41SPaul Gortmaker unsigned char io_type;
637f1dc2f3SSudip Mukherjee unsigned char __iomem *iomem_base;
649bef3d41SPaul Gortmaker unsigned short iomem_reg_shift;
659bef3d41SPaul Gortmaker };
669bef3d41SPaul Gortmaker
679bef3d41SPaul Gortmaker struct serial8250_config {
689bef3d41SPaul Gortmaker const char *name;
699bef3d41SPaul Gortmaker unsigned short fifo_size;
709bef3d41SPaul Gortmaker unsigned short tx_loadsz;
719bef3d41SPaul Gortmaker unsigned char fcr;
72aef9a7bdSYoshihiro YUNOMAE unsigned char rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
739bef3d41SPaul Gortmaker unsigned int flags;
749bef3d41SPaul Gortmaker };
759bef3d41SPaul Gortmaker
761f06f571SAndrew Jeffery #define UART_CAP_FIFO BIT(8) /* UART has FIFO */
771f06f571SAndrew Jeffery #define UART_CAP_EFR BIT(9) /* UART has EFR */
781f06f571SAndrew Jeffery #define UART_CAP_SLEEP BIT(10) /* UART has IER sleep */
791f06f571SAndrew Jeffery #define UART_CAP_AFE BIT(11) /* MCR-based hw flow control */
801f06f571SAndrew Jeffery #define UART_CAP_UUE BIT(12) /* UART needs IER bit 6 set (Xscale) */
811f06f571SAndrew Jeffery #define UART_CAP_RTOIE BIT(13) /* UART needs IER bit 4 set (Xscale, Tegra) */
821f06f571SAndrew Jeffery #define UART_CAP_HFIFO BIT(14) /* UART has a "hidden" FIFO */
831f06f571SAndrew Jeffery #define UART_CAP_RPM BIT(15) /* Runtime PM is active while idle */
841f06f571SAndrew Jeffery #define UART_CAP_IRDA BIT(16) /* UART supports IrDA line discipline */
851f06f571SAndrew Jeffery #define UART_CAP_MINI BIT(17) /* Mini UART on BCM283X family lacks:
86d087e7a9SPhil Elwell * STOP PARITY EPAR SPAR WLEN5 WLEN6
87d087e7a9SPhil Elwell */
88f6f58610SEric Tremblay #define UART_CAP_NOTEMT BIT(18) /* UART without interrupt on TEMT available */
899bef3d41SPaul Gortmaker
901f06f571SAndrew Jeffery #define UART_BUG_QUOT BIT(0) /* UART has buggy quot LSB */
911f06f571SAndrew Jeffery #define UART_BUG_TXEN BIT(1) /* UART has buggy TX IIR status */
921f06f571SAndrew Jeffery #define UART_BUG_NOMSR BIT(2) /* UART has buggy MSR status bits (Au1x00) */
931f06f571SAndrew Jeffery #define UART_BUG_THRE BIT(3) /* UART has buggy THRE reassertion */
941f06f571SAndrew Jeffery #define UART_BUG_TXRACE BIT(5) /* UART Tx fails to set remote DR */
959bef3d41SPaul Gortmaker
969bef3d41SPaul Gortmaker
979bef3d41SPaul Gortmaker #ifdef CONFIG_SERIAL_8250_SHARE_IRQ
989bef3d41SPaul Gortmaker #define SERIAL8250_SHARE_IRQS 1
999bef3d41SPaul Gortmaker #else
1009bef3d41SPaul Gortmaker #define SERIAL8250_SHARE_IRQS 0
1019bef3d41SPaul Gortmaker #endif
1029bef3d41SPaul Gortmaker
103b3bd6668SAnton Wuerfel #define SERIAL8250_PORT_FLAGS(_base, _irq, _flags) \
104b3bd6668SAnton Wuerfel { \
105b3bd6668SAnton Wuerfel .iobase = _base, \
106b3bd6668SAnton Wuerfel .irq = _irq, \
107b3bd6668SAnton Wuerfel .uartclk = 1843200, \
108b3bd6668SAnton Wuerfel .iotype = UPIO_PORT, \
109b3bd6668SAnton Wuerfel .flags = UPF_BOOT_AUTOCONF | (_flags), \
110b3bd6668SAnton Wuerfel }
111b3bd6668SAnton Wuerfel
112b3bd6668SAnton Wuerfel #define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0)
113b3bd6668SAnton Wuerfel
114b3bd6668SAnton Wuerfel
serial_in(struct uart_8250_port * up,int offset)1153f0ab327SPaul Gortmaker static inline int serial_in(struct uart_8250_port *up, int offset)
1163f0ab327SPaul Gortmaker {
1173f0ab327SPaul Gortmaker return up->port.serial_in(&up->port, offset);
1183f0ab327SPaul Gortmaker }
1193f0ab327SPaul Gortmaker
serial_out(struct uart_8250_port * up,int offset,int value)1203f0ab327SPaul Gortmaker static inline void serial_out(struct uart_8250_port *up, int offset, int value)
1213f0ab327SPaul Gortmaker {
1223f0ab327SPaul Gortmaker up->port.serial_out(&up->port, offset, value);
1233f0ab327SPaul Gortmaker }
1243f0ab327SPaul Gortmaker
125bdb70c42SIlpo Järvinen /**
126bdb70c42SIlpo Järvinen * serial_lsr_in - Read LSR register and preserve flags across reads
127bdb70c42SIlpo Järvinen * @up: uart 8250 port
128bdb70c42SIlpo Järvinen *
129bdb70c42SIlpo Järvinen * Read LSR register and handle saving non-preserved flags across reads.
130bdb70c42SIlpo Järvinen * The flags that are not preserved across reads are stored into
131bdb70c42SIlpo Järvinen * up->lsr_saved_flags.
132bdb70c42SIlpo Järvinen *
133bdb70c42SIlpo Järvinen * Returns LSR value or'ed with the preserved flags (if any).
134bdb70c42SIlpo Järvinen */
serial_lsr_in(struct uart_8250_port * up)135f8ba5680SIlpo Järvinen static inline u16 serial_lsr_in(struct uart_8250_port *up)
136bdb70c42SIlpo Järvinen {
137f8ba5680SIlpo Järvinen u16 lsr = up->lsr_saved_flags;
138bdb70c42SIlpo Järvinen
139bdb70c42SIlpo Järvinen lsr |= serial_in(up, UART_LSR);
140507bd6fbSIlpo Järvinen up->lsr_saved_flags = lsr & up->lsr_save_mask;
141bdb70c42SIlpo Järvinen
142bdb70c42SIlpo Järvinen return lsr;
143bdb70c42SIlpo Järvinen }
144bdb70c42SIlpo Järvinen
145cb5a40e3SMaciej W. Rozycki /*
146cb5a40e3SMaciej W. Rozycki * For the 16C950
147cb5a40e3SMaciej W. Rozycki */
serial_icr_write(struct uart_8250_port * up,int offset,int value)148cb5a40e3SMaciej W. Rozycki static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
149cb5a40e3SMaciej W. Rozycki {
150cb5a40e3SMaciej W. Rozycki serial_out(up, UART_SCR, offset);
151cb5a40e3SMaciej W. Rozycki serial_out(up, UART_ICR, value);
152cb5a40e3SMaciej W. Rozycki }
153cb5a40e3SMaciej W. Rozycki
serial_icr_read(struct uart_8250_port * up,int offset)154cb5a40e3SMaciej W. Rozycki static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
155cb5a40e3SMaciej W. Rozycki int offset)
156cb5a40e3SMaciej W. Rozycki {
157cb5a40e3SMaciej W. Rozycki unsigned int value;
158cb5a40e3SMaciej W. Rozycki
159cb5a40e3SMaciej W. Rozycki serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
160cb5a40e3SMaciej W. Rozycki serial_out(up, UART_SCR, offset);
161cb5a40e3SMaciej W. Rozycki value = serial_in(up, UART_ICR);
162cb5a40e3SMaciej W. Rozycki serial_icr_write(up, UART_ACR, up->acr);
163cb5a40e3SMaciej W. Rozycki
164cb5a40e3SMaciej W. Rozycki return value;
165cb5a40e3SMaciej W. Rozycki }
166cb5a40e3SMaciej W. Rozycki
1670ad372b9SSudhakar Mamillapalli void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
1680ad372b9SSudhakar Mamillapalli
serial_dl_read(struct uart_8250_port * up)169b245aa0cSIlpo Järvinen static inline u32 serial_dl_read(struct uart_8250_port *up)
170cc419fa0SMagnus Damm {
171cc419fa0SMagnus Damm return up->dl_read(up);
172cc419fa0SMagnus Damm }
173cc419fa0SMagnus Damm
serial_dl_write(struct uart_8250_port * up,u32 value)174b245aa0cSIlpo Järvinen static inline void serial_dl_write(struct uart_8250_port *up, u32 value)
175cc419fa0SMagnus Damm {
176cc419fa0SMagnus Damm up->dl_write(up, value);
177cc419fa0SMagnus Damm }
178cc419fa0SMagnus Damm
serial8250_set_THRI(struct uart_8250_port * up)1797e267b29SAndy Shevchenko static inline bool serial8250_set_THRI(struct uart_8250_port *up)
1807e267b29SAndy Shevchenko {
181d0b309a5SJohn Ogness /* Port locked to synchronize UART_IER access against the console. */
182d0b309a5SJohn Ogness lockdep_assert_held_once(&up->port.lock);
183d0b309a5SJohn Ogness
1847e267b29SAndy Shevchenko if (up->ier & UART_IER_THRI)
1857e267b29SAndy Shevchenko return false;
1867e267b29SAndy Shevchenko up->ier |= UART_IER_THRI;
1877e267b29SAndy Shevchenko serial_out(up, UART_IER, up->ier);
1887e267b29SAndy Shevchenko return true;
1897e267b29SAndy Shevchenko }
1907e267b29SAndy Shevchenko
serial8250_clear_THRI(struct uart_8250_port * up)1917e267b29SAndy Shevchenko static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
1927e267b29SAndy Shevchenko {
193d0b309a5SJohn Ogness /* Port locked to synchronize UART_IER access against the console. */
194d0b309a5SJohn Ogness lockdep_assert_held_once(&up->port.lock);
195d0b309a5SJohn Ogness
1967e267b29SAndy Shevchenko if (!(up->ier & UART_IER_THRI))
1977e267b29SAndy Shevchenko return false;
1987e267b29SAndy Shevchenko up->ier &= ~UART_IER_THRI;
1997e267b29SAndy Shevchenko serial_out(up, UART_IER, up->ier);
2007e267b29SAndy Shevchenko return true;
2017e267b29SAndy Shevchenko }
2027e267b29SAndy Shevchenko
203ae14a795SSebastian Andrzej Siewior struct uart_8250_port *serial8250_get_port(int line);
2047d4e00c6SAndy Shevchenko
20577285243SSebastian Andrzej Siewior void serial8250_rpm_get(struct uart_8250_port *p);
20677285243SSebastian Andrzej Siewior void serial8250_rpm_put(struct uart_8250_port *p);
2077d4e00c6SAndy Shevchenko
2087d4e00c6SAndy Shevchenko void serial8250_rpm_get_tx(struct uart_8250_port *p);
2097d4e00c6SAndy Shevchenko void serial8250_rpm_put_tx(struct uart_8250_port *p);
2107d4e00c6SAndy Shevchenko
211ae50bb27SIlpo Järvinen int serial8250_em485_config(struct uart_port *port, struct ktermios *termios,
212ae50bb27SIlpo Järvinen struct serial_rs485 *rs485);
213058bc104SLukas Wunner void serial8250_em485_start_tx(struct uart_8250_port *p);
214058bc104SLukas Wunner void serial8250_em485_stop_tx(struct uart_8250_port *p);
215e490c914SMatwey V. Kornilov void serial8250_em485_destroy(struct uart_8250_port *p);
21643ee3413SIlpo Järvinen extern struct serial_rs485 serial8250_em485_supported;
217ae14a795SSebastian Andrzej Siewior
21842912081SStefan Roese /* MCR <-> TIOCM conversion */
serial8250_TIOCM_to_MCR(int tiocm)21942912081SStefan Roese static inline int serial8250_TIOCM_to_MCR(int tiocm)
22042912081SStefan Roese {
22142912081SStefan Roese int mcr = 0;
22242912081SStefan Roese
22342912081SStefan Roese if (tiocm & TIOCM_RTS)
22442912081SStefan Roese mcr |= UART_MCR_RTS;
22542912081SStefan Roese if (tiocm & TIOCM_DTR)
22642912081SStefan Roese mcr |= UART_MCR_DTR;
22742912081SStefan Roese if (tiocm & TIOCM_OUT1)
22842912081SStefan Roese mcr |= UART_MCR_OUT1;
22942912081SStefan Roese if (tiocm & TIOCM_OUT2)
23042912081SStefan Roese mcr |= UART_MCR_OUT2;
23142912081SStefan Roese if (tiocm & TIOCM_LOOP)
23242912081SStefan Roese mcr |= UART_MCR_LOOP;
23342912081SStefan Roese
23442912081SStefan Roese return mcr;
23542912081SStefan Roese }
23642912081SStefan Roese
serial8250_MCR_to_TIOCM(int mcr)23742912081SStefan Roese static inline int serial8250_MCR_to_TIOCM(int mcr)
23842912081SStefan Roese {
23942912081SStefan Roese int tiocm = 0;
24042912081SStefan Roese
24142912081SStefan Roese if (mcr & UART_MCR_RTS)
24242912081SStefan Roese tiocm |= TIOCM_RTS;
24342912081SStefan Roese if (mcr & UART_MCR_DTR)
24442912081SStefan Roese tiocm |= TIOCM_DTR;
24542912081SStefan Roese if (mcr & UART_MCR_OUT1)
24642912081SStefan Roese tiocm |= TIOCM_OUT1;
24742912081SStefan Roese if (mcr & UART_MCR_OUT2)
24842912081SStefan Roese tiocm |= TIOCM_OUT2;
24942912081SStefan Roese if (mcr & UART_MCR_LOOP)
25042912081SStefan Roese tiocm |= TIOCM_LOOP;
25142912081SStefan Roese
25242912081SStefan Roese return tiocm;
25342912081SStefan Roese }
25442912081SStefan Roese
25542912081SStefan Roese /* MSR <-> TIOCM conversion */
serial8250_MSR_to_TIOCM(int msr)25642912081SStefan Roese static inline int serial8250_MSR_to_TIOCM(int msr)
25742912081SStefan Roese {
25842912081SStefan Roese int tiocm = 0;
25942912081SStefan Roese
26042912081SStefan Roese if (msr & UART_MSR_DCD)
26142912081SStefan Roese tiocm |= TIOCM_CAR;
26242912081SStefan Roese if (msr & UART_MSR_RI)
26342912081SStefan Roese tiocm |= TIOCM_RNG;
26442912081SStefan Roese if (msr & UART_MSR_DSR)
26542912081SStefan Roese tiocm |= TIOCM_DSR;
26642912081SStefan Roese if (msr & UART_MSR_CTS)
26742912081SStefan Roese tiocm |= TIOCM_CTS;
26842912081SStefan Roese
26942912081SStefan Roese return tiocm;
27042912081SStefan Roese }
27142912081SStefan Roese
serial8250_out_MCR(struct uart_8250_port * up,int value)27236fd95b1SYegor Yefremov static inline void serial8250_out_MCR(struct uart_8250_port *up, int value)
27336fd95b1SYegor Yefremov {
27436fd95b1SYegor Yefremov serial_out(up, UART_MCR, value);
2754a96895fSYegor Yefremov
2764a96895fSYegor Yefremov if (up->gpios)
2774a96895fSYegor Yefremov mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value));
27836fd95b1SYegor Yefremov }
27936fd95b1SYegor Yefremov
serial8250_in_MCR(struct uart_8250_port * up)28036fd95b1SYegor Yefremov static inline int serial8250_in_MCR(struct uart_8250_port *up)
28136fd95b1SYegor Yefremov {
2824a96895fSYegor Yefremov int mctrl;
2834a96895fSYegor Yefremov
2844a96895fSYegor Yefremov mctrl = serial_in(up, UART_MCR);
2854a96895fSYegor Yefremov
2864a96895fSYegor Yefremov if (up->gpios) {
2874a96895fSYegor Yefremov unsigned int mctrl_gpio = 0;
2884a96895fSYegor Yefremov
2894a96895fSYegor Yefremov mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio);
2904a96895fSYegor Yefremov mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio);
2914a96895fSYegor Yefremov }
2924a96895fSYegor Yefremov
2934a96895fSYegor Yefremov return mctrl;
29436fd95b1SYegor Yefremov }
29536fd95b1SYegor Yefremov
296b4a29b94SLukas Wunner bool alpha_jensen(void);
297b4a29b94SLukas Wunner void alpha_jensen_set_mctrl(struct uart_port *port, unsigned int mctrl);
298835d844dSSean Young
299835d844dSSean Young #ifdef CONFIG_SERIAL_8250_PNP
300835d844dSSean Young int serial8250_pnp_init(void);
301835d844dSSean Young void serial8250_pnp_exit(void);
302835d844dSSean Young #else
serial8250_pnp_init(void)303835d844dSSean Young static inline int serial8250_pnp_init(void) { return 0; }
serial8250_pnp_exit(void)304835d844dSSean Young static inline void serial8250_pnp_exit(void) { }
305835d844dSSean Young #endif
306835d844dSSean Young
307fa01e2caSRicardo Ribalda Delgado #ifdef CONFIG_SERIAL_8250_FINTEK
308fa01e2caSRicardo Ribalda Delgado int fintek_8250_probe(struct uart_8250_port *uart);
309fa01e2caSRicardo Ribalda Delgado #else
fintek_8250_probe(struct uart_8250_port * uart)310fa01e2caSRicardo Ribalda Delgado static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; }
311fa01e2caSRicardo Ribalda Delgado #endif
312fa01e2caSRicardo Ribalda Delgado
31354ec52b6STony Lindgren #ifdef CONFIG_ARCH_OMAP1
3149fcd04ddSArnd Bergmann #include <linux/soc/ti/omap1-soc.h>
is_omap1_8250(struct uart_8250_port * pt)31554ec52b6STony Lindgren static inline int is_omap1_8250(struct uart_8250_port *pt)
31654ec52b6STony Lindgren {
31754ec52b6STony Lindgren int res;
31854ec52b6STony Lindgren
31954ec52b6STony Lindgren switch (pt->port.mapbase) {
32054ec52b6STony Lindgren case OMAP1_UART1_BASE:
32154ec52b6STony Lindgren case OMAP1_UART2_BASE:
32254ec52b6STony Lindgren case OMAP1_UART3_BASE:
32354ec52b6STony Lindgren res = 1;
32454ec52b6STony Lindgren break;
32554ec52b6STony Lindgren default:
32654ec52b6STony Lindgren res = 0;
32754ec52b6STony Lindgren break;
32854ec52b6STony Lindgren }
32954ec52b6STony Lindgren
33054ec52b6STony Lindgren return res;
33154ec52b6STony Lindgren }
33254ec52b6STony Lindgren
is_omap1510_8250(struct uart_8250_port * pt)33354ec52b6STony Lindgren static inline int is_omap1510_8250(struct uart_8250_port *pt)
33454ec52b6STony Lindgren {
33554ec52b6STony Lindgren if (!cpu_is_omap1510())
33654ec52b6STony Lindgren return 0;
33754ec52b6STony Lindgren
33854ec52b6STony Lindgren return is_omap1_8250(pt);
33954ec52b6STony Lindgren }
34054ec52b6STony Lindgren #else
is_omap1_8250(struct uart_8250_port * pt)34154ec52b6STony Lindgren static inline int is_omap1_8250(struct uart_8250_port *pt)
34254ec52b6STony Lindgren {
34354ec52b6STony Lindgren return 0;
34454ec52b6STony Lindgren }
is_omap1510_8250(struct uart_8250_port * pt)34554ec52b6STony Lindgren static inline int is_omap1510_8250(struct uart_8250_port *pt)
34654ec52b6STony Lindgren {
34754ec52b6STony Lindgren return 0;
34854ec52b6STony Lindgren }
34954ec52b6STony Lindgren #endif
3509ee4b83eSHeikki Krogerus
3519ee4b83eSHeikki Krogerus #ifdef CONFIG_SERIAL_8250_DMA
3529ee4b83eSHeikki Krogerus extern int serial8250_tx_dma(struct uart_8250_port *);
353*5e00346dSJohn Keeping extern void serial8250_tx_dma_flush(struct uart_8250_port *);
35433d9b8b2SPeter Hurley extern int serial8250_rx_dma(struct uart_8250_port *);
35533d9b8b2SPeter Hurley extern void serial8250_rx_dma_flush(struct uart_8250_port *);
3569ee4b83eSHeikki Krogerus extern int serial8250_request_dma(struct uart_8250_port *);
3579ee4b83eSHeikki Krogerus extern void serial8250_release_dma(struct uart_8250_port *);
358e4fb03feSMiquel Raynal
serial8250_do_prepare_tx_dma(struct uart_8250_port * p)359e4fb03feSMiquel Raynal static inline void serial8250_do_prepare_tx_dma(struct uart_8250_port *p)
360e4fb03feSMiquel Raynal {
361e4fb03feSMiquel Raynal struct uart_8250_dma *dma = p->dma;
362e4fb03feSMiquel Raynal
363e4fb03feSMiquel Raynal if (dma->prepare_tx_dma)
364e4fb03feSMiquel Raynal dma->prepare_tx_dma(p);
365e4fb03feSMiquel Raynal }
366e4fb03feSMiquel Raynal
serial8250_do_prepare_rx_dma(struct uart_8250_port * p)367e4fb03feSMiquel Raynal static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
368e4fb03feSMiquel Raynal {
369e4fb03feSMiquel Raynal struct uart_8250_dma *dma = p->dma;
370e4fb03feSMiquel Raynal
371e4fb03feSMiquel Raynal if (dma->prepare_rx_dma)
372e4fb03feSMiquel Raynal dma->prepare_rx_dma(p);
373e4fb03feSMiquel Raynal }
374146a37e0SIlpo Järvinen
serial8250_tx_dma_running(struct uart_8250_port * p)375146a37e0SIlpo Järvinen static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
376146a37e0SIlpo Järvinen {
377146a37e0SIlpo Järvinen struct uart_8250_dma *dma = p->dma;
378146a37e0SIlpo Järvinen
379146a37e0SIlpo Järvinen return dma && dma->tx_running;
380146a37e0SIlpo Järvinen }
3819ee4b83eSHeikki Krogerus #else
serial8250_tx_dma(struct uart_8250_port * p)3829ee4b83eSHeikki Krogerus static inline int serial8250_tx_dma(struct uart_8250_port *p)
3839ee4b83eSHeikki Krogerus {
3849ee4b83eSHeikki Krogerus return -1;
3859ee4b83eSHeikki Krogerus }
serial8250_tx_dma_flush(struct uart_8250_port * p)386*5e00346dSJohn Keeping static inline void serial8250_tx_dma_flush(struct uart_8250_port *p) { }
serial8250_rx_dma(struct uart_8250_port * p)38733d9b8b2SPeter Hurley static inline int serial8250_rx_dma(struct uart_8250_port *p)
3889ee4b83eSHeikki Krogerus {
3899ee4b83eSHeikki Krogerus return -1;
3909ee4b83eSHeikki Krogerus }
serial8250_rx_dma_flush(struct uart_8250_port * p)39133d9b8b2SPeter Hurley static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { }
serial8250_request_dma(struct uart_8250_port * p)3929ee4b83eSHeikki Krogerus static inline int serial8250_request_dma(struct uart_8250_port *p)
3939ee4b83eSHeikki Krogerus {
3949ee4b83eSHeikki Krogerus return -1;
3959ee4b83eSHeikki Krogerus }
serial8250_release_dma(struct uart_8250_port * p)3969ee4b83eSHeikki Krogerus static inline void serial8250_release_dma(struct uart_8250_port *p) { }
397146a37e0SIlpo Järvinen
serial8250_tx_dma_running(struct uart_8250_port * p)398146a37e0SIlpo Järvinen static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
399146a37e0SIlpo Järvinen {
400146a37e0SIlpo Järvinen return false;
401146a37e0SIlpo Järvinen }
4029ee4b83eSHeikki Krogerus #endif
403d81e50f6SPeter Hurley
ns16550a_goto_highspeed(struct uart_8250_port * up)404d81e50f6SPeter Hurley static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
405d81e50f6SPeter Hurley {
406d81e50f6SPeter Hurley unsigned char status;
407d81e50f6SPeter Hurley
408d81e50f6SPeter Hurley status = serial_in(up, 0x04); /* EXCR2 */
409d81e50f6SPeter Hurley #define PRESL(x) ((x) & 0x30)
410d81e50f6SPeter Hurley if (PRESL(status) == 0x10) {
411d81e50f6SPeter Hurley /* already in high speed mode */
412d81e50f6SPeter Hurley return 0;
413d81e50f6SPeter Hurley } else {
414d81e50f6SPeter Hurley status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
415d81e50f6SPeter Hurley status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
416d81e50f6SPeter Hurley serial_out(up, 0x04, status);
417d81e50f6SPeter Hurley }
418d81e50f6SPeter Hurley return 1;
419d81e50f6SPeter Hurley }
420b6830f6dSPeter Hurley
serial_index(struct uart_port * port)421b6830f6dSPeter Hurley static inline int serial_index(struct uart_port *port)
422b6830f6dSPeter Hurley {
423b6830f6dSPeter Hurley return port->minor - 64;
424b6830f6dSPeter Hurley }
425