| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/drivers/char/serial_core.h |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2000 Deep Blue Solutions Ltd. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | | - * GNU General Public License for more details. |
|---|
| 15 | | - * |
|---|
| 16 | | - * You should have received a copy of the GNU General Public License |
|---|
| 17 | | - * along with this program; if not, write to the Free Software |
|---|
| 18 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 19 | 6 | */ |
|---|
| 20 | 7 | #ifndef LINUX_SERIAL_CORE_H |
|---|
| 21 | 8 | #define LINUX_SERIAL_CORE_H |
|---|
| 22 | 9 | |
|---|
| 23 | 10 | #include <linux/bitops.h> |
|---|
| 24 | 11 | #include <linux/compiler.h> |
|---|
| 12 | +#include <linux/console.h> |
|---|
| 25 | 13 | #include <linux/interrupt.h> |
|---|
| 26 | 14 | #include <linux/circ_buf.h> |
|---|
| 27 | 15 | #include <linux/spinlock.h> |
|---|
| .. | .. |
|---|
| 29 | 17 | #include <linux/tty.h> |
|---|
| 30 | 18 | #include <linux/mutex.h> |
|---|
| 31 | 19 | #include <linux/sysrq.h> |
|---|
| 20 | +#include <linux/android_kabi.h> |
|---|
| 32 | 21 | #include <uapi/linux/serial_core.h> |
|---|
| 33 | 22 | |
|---|
| 34 | 23 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
|---|
| .. | .. |
|---|
| 41 | 30 | struct uart_port; |
|---|
| 42 | 31 | struct serial_struct; |
|---|
| 43 | 32 | struct device; |
|---|
| 33 | +struct gpio_desc; |
|---|
| 44 | 34 | |
|---|
| 45 | 35 | /* |
|---|
| 46 | 36 | * This structure describes all the operations that can be done on the |
|---|
| 47 | | - * physical hardware. See Documentation/serial/driver for details. |
|---|
| 37 | + * physical hardware. See Documentation/driver-api/serial/driver.rst for details. |
|---|
| 48 | 38 | */ |
|---|
| 49 | 39 | struct uart_ops { |
|---|
| 50 | 40 | unsigned int (*tx_empty)(struct uart_port *); |
|---|
| .. | .. |
|---|
| 91 | 81 | void (*poll_put_char)(struct uart_port *, unsigned char); |
|---|
| 92 | 82 | int (*poll_get_char)(struct uart_port *); |
|---|
| 93 | 83 | #endif |
|---|
| 84 | + |
|---|
| 85 | + ANDROID_KABI_RESERVE(1); |
|---|
| 86 | + ANDROID_KABI_RESERVE(2); |
|---|
| 94 | 87 | }; |
|---|
| 95 | 88 | |
|---|
| 96 | 89 | #define NO_POLL_CHAR 0x00ff0000 |
|---|
| .. | .. |
|---|
| 144 | 137 | void (*handle_break)(struct uart_port *); |
|---|
| 145 | 138 | int (*rs485_config)(struct uart_port *, |
|---|
| 146 | 139 | struct serial_rs485 *rs485); |
|---|
| 140 | + int (*iso7816_config)(struct uart_port *, |
|---|
| 141 | + struct serial_iso7816 *iso7816); |
|---|
| 147 | 142 | unsigned int irq; /* irq number */ |
|---|
| 148 | 143 | unsigned long irqflags; /* irq flags */ |
|---|
| 149 | 144 | unsigned int uartclk; /* base uart clock */ |
|---|
| .. | .. |
|---|
| 171 | 166 | struct uart_icount icount; /* statistics */ |
|---|
| 172 | 167 | |
|---|
| 173 | 168 | struct console *cons; /* struct console, if any */ |
|---|
| 174 | | -#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ) |
|---|
| 175 | | - unsigned long sysrq; /* sysrq timeout */ |
|---|
| 176 | | - unsigned int sysrq_ch; /* char for sysrq */ |
|---|
| 177 | | -#endif |
|---|
| 178 | | - |
|---|
| 179 | 169 | /* flags must be updated while holding port mutex */ |
|---|
| 180 | 170 | upf_t flags; |
|---|
| 181 | 171 | |
|---|
| .. | .. |
|---|
| 254 | 244 | resource_size_t mapbase; /* for ioremap */ |
|---|
| 255 | 245 | resource_size_t mapsize; |
|---|
| 256 | 246 | struct device *dev; /* parent device */ |
|---|
| 247 | + |
|---|
| 248 | + unsigned long sysrq; /* sysrq timeout */ |
|---|
| 249 | + unsigned int sysrq_ch; /* char for sysrq */ |
|---|
| 250 | + unsigned char has_sysrq; |
|---|
| 251 | + unsigned char sysrq_seq; /* index in sysrq_toggle_seq */ |
|---|
| 252 | + |
|---|
| 257 | 253 | unsigned char hub6; /* this should be in the 8250 driver */ |
|---|
| 258 | 254 | unsigned char suspended; |
|---|
| 259 | | - unsigned char unused[2]; |
|---|
| 255 | + unsigned char console_reinit; |
|---|
| 260 | 256 | const char *name; /* port name */ |
|---|
| 261 | 257 | struct attribute_group *attr_group; /* port specific attributes */ |
|---|
| 262 | 258 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ |
|---|
| 263 | 259 | struct serial_rs485 rs485; |
|---|
| 260 | + struct gpio_desc *rs485_term_gpio; /* enable RS485 bus termination */ |
|---|
| 261 | + struct serial_iso7816 iso7816; |
|---|
| 264 | 262 | void *private_data; /* generic platform data pointer */ |
|---|
| 263 | + |
|---|
| 264 | + ANDROID_KABI_RESERVE(1); |
|---|
| 265 | + ANDROID_KABI_RESERVE(2); |
|---|
| 265 | 266 | }; |
|---|
| 266 | 267 | |
|---|
| 267 | 268 | static inline int serial_port_in(struct uart_port *up, int offset) |
|---|
| .. | .. |
|---|
| 306 | 307 | /* number of characters left in xmit buffer before we ask for more */ |
|---|
| 307 | 308 | #define WAKEUP_CHARS 256 |
|---|
| 308 | 309 | |
|---|
| 310 | +/** |
|---|
| 311 | + * uart_xmit_advance - Advance xmit buffer and account Tx'ed chars |
|---|
| 312 | + * @up: uart_port structure describing the port |
|---|
| 313 | + * @chars: number of characters sent |
|---|
| 314 | + * |
|---|
| 315 | + * This function advances the tail of circular xmit buffer by the number of |
|---|
| 316 | + * @chars transmitted and handles accounting of transmitted bytes (into |
|---|
| 317 | + * @up's icount.tx). |
|---|
| 318 | + */ |
|---|
| 319 | +static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars) |
|---|
| 320 | +{ |
|---|
| 321 | + struct circ_buf *xmit = &up->state->xmit; |
|---|
| 322 | + |
|---|
| 323 | + xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1); |
|---|
| 324 | + up->icount.tx += chars; |
|---|
| 325 | +} |
|---|
| 326 | + |
|---|
| 309 | 327 | struct module; |
|---|
| 310 | 328 | struct tty_driver; |
|---|
| 311 | 329 | |
|---|
| .. | .. |
|---|
| 324 | 342 | */ |
|---|
| 325 | 343 | struct uart_state *state; |
|---|
| 326 | 344 | struct tty_driver *tty_driver; |
|---|
| 345 | + |
|---|
| 346 | + ANDROID_KABI_RESERVE(1); |
|---|
| 327 | 347 | }; |
|---|
| 328 | 348 | |
|---|
| 329 | 349 | void uart_write_wakeup(struct uart_port *port); |
|---|
| .. | .. |
|---|
| 379 | 399 | .compatible = compat, \ |
|---|
| 380 | 400 | .setup = fn }; \ |
|---|
| 381 | 401 | static const struct earlycon_id EARLYCON_USED_OR_UNUSED \ |
|---|
| 382 | | - __section(__earlycon_table) \ |
|---|
| 402 | + __section("__earlycon_table") \ |
|---|
| 383 | 403 | * const __PASTE(__p, unique_id) = &unique_id |
|---|
| 384 | 404 | |
|---|
| 385 | 405 | #define OF_EARLYCON_DECLARE(_name, compat, fn) \ |
|---|
| .. | .. |
|---|
| 399 | 419 | static const bool earlycon_acpi_spcr_enable EARLYCON_USED_OR_UNUSED; |
|---|
| 400 | 420 | static inline int setup_earlycon(char *buf) { return 0; } |
|---|
| 401 | 421 | #endif |
|---|
| 422 | + |
|---|
| 423 | +static inline bool uart_console_enabled(struct uart_port *port) |
|---|
| 424 | +{ |
|---|
| 425 | + return uart_console(port) && (port->cons->flags & CON_ENABLED); |
|---|
| 426 | +} |
|---|
| 402 | 427 | |
|---|
| 403 | 428 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, |
|---|
| 404 | 429 | struct console *c); |
|---|
| .. | .. |
|---|
| 469 | 494 | extern void uart_insert_char(struct uart_port *port, unsigned int status, |
|---|
| 470 | 495 | unsigned int overrun, unsigned int ch, unsigned int flag); |
|---|
| 471 | 496 | |
|---|
| 472 | | -#if defined(SUPPORT_SYSRQ) && defined(CONFIG_MAGIC_SYSRQ_SERIAL) |
|---|
| 473 | | -static inline int |
|---|
| 474 | | -uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) |
|---|
| 497 | +void uart_xchar_out(struct uart_port *uport, int offset); |
|---|
| 498 | + |
|---|
| 499 | +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL |
|---|
| 500 | +#define SYSRQ_TIMEOUT (HZ * 5) |
|---|
| 501 | + |
|---|
| 502 | +bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch); |
|---|
| 503 | + |
|---|
| 504 | +static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) |
|---|
| 475 | 505 | { |
|---|
| 476 | | - if (port->sysrq) { |
|---|
| 477 | | - if (ch && time_before(jiffies, port->sysrq)) { |
|---|
| 506 | + if (!port->sysrq) |
|---|
| 507 | + return 0; |
|---|
| 508 | + |
|---|
| 509 | + if (ch && time_before(jiffies, port->sysrq)) { |
|---|
| 510 | + if (sysrq_mask()) { |
|---|
| 478 | 511 | handle_sysrq(ch); |
|---|
| 479 | 512 | port->sysrq = 0; |
|---|
| 480 | 513 | return 1; |
|---|
| 481 | 514 | } |
|---|
| 482 | | - port->sysrq = 0; |
|---|
| 515 | + if (uart_try_toggle_sysrq(port, ch)) |
|---|
| 516 | + return 1; |
|---|
| 483 | 517 | } |
|---|
| 518 | + port->sysrq = 0; |
|---|
| 519 | + |
|---|
| 484 | 520 | return 0; |
|---|
| 485 | 521 | } |
|---|
| 486 | | -static inline int |
|---|
| 487 | | -uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) |
|---|
| 522 | + |
|---|
| 523 | +static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) |
|---|
| 488 | 524 | { |
|---|
| 489 | | - if (port->sysrq) { |
|---|
| 490 | | - if (ch && time_before(jiffies, port->sysrq)) { |
|---|
| 525 | + if (!port->sysrq) |
|---|
| 526 | + return 0; |
|---|
| 527 | + |
|---|
| 528 | + if (ch && time_before(jiffies, port->sysrq)) { |
|---|
| 529 | + if (sysrq_mask()) { |
|---|
| 491 | 530 | port->sysrq_ch = ch; |
|---|
| 492 | 531 | port->sysrq = 0; |
|---|
| 493 | 532 | return 1; |
|---|
| 494 | 533 | } |
|---|
| 495 | | - port->sysrq = 0; |
|---|
| 534 | + if (uart_try_toggle_sysrq(port, ch)) |
|---|
| 535 | + return 1; |
|---|
| 496 | 536 | } |
|---|
| 537 | + port->sysrq = 0; |
|---|
| 538 | + |
|---|
| 497 | 539 | return 0; |
|---|
| 498 | 540 | } |
|---|
| 499 | | -static inline void |
|---|
| 500 | | -uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) |
|---|
| 541 | + |
|---|
| 542 | +static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) |
|---|
| 501 | 543 | { |
|---|
| 502 | 544 | int sysrq_ch; |
|---|
| 545 | + |
|---|
| 546 | + if (!port->has_sysrq) { |
|---|
| 547 | + spin_unlock_irqrestore(&port->lock, irqflags); |
|---|
| 548 | + return; |
|---|
| 549 | + } |
|---|
| 503 | 550 | |
|---|
| 504 | 551 | sysrq_ch = port->sysrq_ch; |
|---|
| 505 | 552 | port->sysrq_ch = 0; |
|---|
| .. | .. |
|---|
| 509 | 556 | if (sysrq_ch) |
|---|
| 510 | 557 | handle_sysrq(sysrq_ch); |
|---|
| 511 | 558 | } |
|---|
| 512 | | -#else |
|---|
| 513 | | -static inline int |
|---|
| 514 | | -uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) { return 0; } |
|---|
| 515 | | -static inline int |
|---|
| 516 | | -uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) { return 0; } |
|---|
| 517 | | -static inline void |
|---|
| 518 | | -uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) |
|---|
| 559 | +#else /* CONFIG_MAGIC_SYSRQ_SERIAL */ |
|---|
| 560 | +static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) |
|---|
| 561 | +{ |
|---|
| 562 | + return 0; |
|---|
| 563 | +} |
|---|
| 564 | +static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) |
|---|
| 565 | +{ |
|---|
| 566 | + return 0; |
|---|
| 567 | +} |
|---|
| 568 | +static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) |
|---|
| 519 | 569 | { |
|---|
| 520 | 570 | spin_unlock_irqrestore(&port->lock, irqflags); |
|---|
| 521 | 571 | } |
|---|
| 522 | | -#endif |
|---|
| 572 | +#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */ |
|---|
| 523 | 573 | |
|---|
| 524 | 574 | /* |
|---|
| 525 | 575 | * We do the SysRQ and SAK checking like this... |
|---|
| .. | .. |
|---|
| 531 | 581 | if (port->handle_break) |
|---|
| 532 | 582 | port->handle_break(port); |
|---|
| 533 | 583 | |
|---|
| 534 | | -#ifdef SUPPORT_SYSRQ |
|---|
| 535 | | - if (port->cons && port->cons->index == port->line) { |
|---|
| 584 | +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL |
|---|
| 585 | + if (port->has_sysrq && uart_console(port)) { |
|---|
| 536 | 586 | if (!port->sysrq) { |
|---|
| 537 | | - port->sysrq = jiffies + HZ*5; |
|---|
| 587 | + port->sysrq = jiffies + SYSRQ_TIMEOUT; |
|---|
| 538 | 588 | return 1; |
|---|
| 539 | 589 | } |
|---|
| 540 | 590 | port->sysrq = 0; |
|---|
| .. | .. |
|---|
| 552 | 602 | (cflag) & CRTSCTS || \ |
|---|
| 553 | 603 | !((cflag) & CLOCAL)) |
|---|
| 554 | 604 | |
|---|
| 555 | | -void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf); |
|---|
| 605 | +int uart_get_rs485_mode(struct uart_port *port); |
|---|
| 556 | 606 | #endif /* LINUX_SERIAL_CORE_H */ |
|---|