The SUPPORT_SYSRQ is messy: every .c source should define it before including "serial_core.h" if sysrq is supported or struct uart_port will differ in sizes. Also this prevents moving to serial_core.c functions: uart_handle_sysrq_char(), uart_prepare_sysrq_char(), uart_unlock_and_check_sysrq(). It doesn't save many bytes in the structure, and a better way to reduce it's size would be making rs485 and iso7816 pointers. Introduce `has_sysrq` member to be used by serial line drivers further.
Unified · Split
| @@ -240,14 +240,13 @@ struct uart_port { · 239 unmodified lines | ||
| 240 | 240 | resource_size_t mapsize; |
| 241 | 241 | struct device *dev; /* parent device */ |
| 242 | 242 | |
| 243 | −#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ) | |
| 244 | 243 | unsigned long sysrq; /* sysrq timeout */ |
| 245 | 244 | unsigned int sysrq_ch; /* char for sysrq */ |
| 246 | −#endif | |
| 245 | + unsigned char has_sysrq; | |
| 247 | 246 | |
| 248 | 247 | unsigned char hub6; /* this should be in the 8250 driver */ |
| 249 | 248 | unsigned char suspended; |
| 250 | − unsigned char unused[2]; | |
| 249 | + unsigned char unused; | |
| 251 | 250 | const char *name; /* port name */ |
| 252 | 251 | struct attribute_group *attr_group; /* port specific attributes */ |
| 253 | 252 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ |
| @@ -461,31 +460,46 @@ extern void uart_handle_cts_change(struct uart_port *uport, · 207 unmodified lines | ||
| 461 | 460 | extern void uart_insert_char(struct uart_port *port, unsigned int status, |
| 462 | 461 | unsigned int overrun, unsigned int ch, unsigned int flag); |
| 463 | 462 | |
| 464 | −#if defined(SUPPORT_SYSRQ) && defined(CONFIG_MAGIC_SYSRQ_SERIAL) | |
| 465 | 463 | static inline int |
| 466 | 464 | uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) |
| 467 | 465 | { |
| 468 | − if (port->sysrq) { | |
| 469 | − if (ch && time_before(jiffies, port->sysrq)) { | |
| 470 | − handle_sysrq(ch); | |
| 471 | − port->sysrq = 0; | |
| 472 | − return 1; | |
| 473 | − } | |
| 466 | + if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL)) | |
| 467 | + return 0; | |
| 468 | + | |
| 469 | + if (!port->has_sysrq && !IS_ENABLED(SUPPORT_SYSRQ)) | |
| 470 | + return 0; | |
| 471 | + | |
| 472 | + if (!port->sysrq) | |
| 473 | + return 0; | |
| 474 | + | |
| 475 | + if (ch && time_before(jiffies, port->sysrq)) { | |
| 476 | + handle_sysrq(ch); | |
| 474 | 477 | port->sysrq = 0; |
| 478 | + return 1; | |
| 475 | 479 | } |
| 480 | + port->sysrq = 0; | |
| 481 | + | |
| 476 | 482 | return 0; |
| 477 | 483 | } |
| 478 | 484 | static inline int |
| 479 | 485 | uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) |
| 480 | 486 | { |
| 481 | − if (port->sysrq) { | |
| 482 | − if (ch && time_before(jiffies, port->sysrq)) { | |
| 483 | − port->sysrq_ch = ch; | |
| 484 | − port->sysrq = 0; | |
| 485 | − return 1; | |
| 486 | − } | |
| 487 | + if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL)) | |
| 488 | + return 0; | |
| 489 | + | |
| 490 | + if (!port->has_sysrq && !IS_ENABLED(SUPPORT_SYSRQ)) | |
| 491 | + return 0; | |
| 492 | + | |
| 493 | + if (!port->sysrq) | |
| 494 | + return 0; | |
| 495 | + | |
| 496 | + if (ch && time_before(jiffies, port->sysrq)) { | |
| 497 | + port->sysrq_ch = ch; | |
| 487 | 498 | port->sysrq = 0; |
| 499 | + return 1; | |
| 488 | 500 | } |
| 501 | + port->sysrq = 0; | |
| 502 | + | |
| 489 | 503 | return 0; |
| 490 | 504 | } |
| 491 | 505 | static inline void |
| @@ -493,6 +507,11 @@ uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) · 1 unmodified line | ||
| 493 | 507 | { |
| 494 | 508 | int sysrq_ch; |
| 495 | 509 | |
| 510 | + if (!port->has_sysrq && !IS_ENABLED(SUPPORT_SYSRQ)) { | |
| 511 | + spin_unlock_irqrestore(&port->lock, irqflags); | |
| 512 | + return; | |
| 513 | + } | |
| 514 | + | |
| 496 | 515 | sysrq_ch = port->sysrq_ch; |
| 497 | 516 | port->sysrq_ch = 0; |
| 498 | 517 | |
| @@ -501,17 +520,6 @@ uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) · 2 unmodified lines | ||
| 501 | 520 | if (sysrq_ch) |
| 502 | 521 | handle_sysrq(sysrq_ch); |
| 503 | 522 | } |
| 504 | −#else | |
| 505 | −static inline int | |
| 506 | −uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) { return 0; } | |
| 507 | −static inline int | |
| 508 | −uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) { return 0; } | |
| 509 | −static inline void | |
| 510 | −uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) | |
| 511 | −{ | |
| 512 | − spin_unlock_irqrestore(&port->lock, irqflags); | |
| 513 | −} | |
| 514 | −#endif | |
| 515 | 523 | |
| 516 | 524 | /* |
| 517 | 525 | * We do the SysRQ and SAK checking like this... |
| @@ -523,15 +531,16 @@ static inline int uart_handle_break(struct uart_port *port) · 5 unmodified lines | ||
| 523 | 531 | if (port->handle_break) |
| 524 | 532 | port->handle_break(port); |
| 525 | 533 | |
| 526 | −#ifdef SUPPORT_SYSRQ | |
| 527 | − if (port->cons && port->cons->index == port->line) { | |
| 528 | − if (!port->sysrq) { | |
| 529 | − port->sysrq = jiffies + HZ*5; | |
| 530 | − return 1; | |
| 534 | + if (port->has_sysrq || IS_ENABLED(SUPPORT_SYSRQ)) { | |
| 535 | + if (port->cons && port->cons->index == port->line) { | |
| 536 | + if (!port->sysrq) { | |
| 537 | + port->sysrq = jiffies + HZ*5; | |
| 538 | + return 1; | |
| 539 | + } | |
| 540 | + port->sysrq = 0; | |
| 531 | 541 | } |
| 532 | − port->sysrq = 0; | |
| 533 | 542 | } |
| 534 | −#endif | |
| 543 | + | |
| 535 | 544 | if (port->flags & UPF_SAK) |
| 536 | 545 | do_SAK(state->port.tty); |
| 537 | 546 | return 0; |