Skip to content

Commit 1b04c4e

Browse files
geertuSasha Levin
authored andcommitted
serial: sh-sci: Save and restore more registers
[ Upstream commit 81100b9 ] On (H)SCIF with a Baud Rate Generator for External Clock (BRG), there are multiple ways to configure the requested serial speed. If firmware uses a different method than Linux, and if any debug info is printed after the Bit Rate Register (SCBRR) is restored, but before termios is reconfigured (which configures the alternative method), the system may lock-up during resume. Fix this by saving and restoring the contents of the BRG Frequency Division (SCDL) and Clock Select (SCCKS) registers as well. Also save and restore the HSCIF's Sampling Rate Register (HSSRR), which configures the sampling point, and the SCIFA/SCIFB's Serial Port Control and Data Registers (SCPCR/SCPDR), which configure the optional control flow signals. After this, all registers that are not saved/restored are either: - read-only, - write-only, - status registers containing flags with clear-after-set semantics, - FIFO Data Count Trigger registers, which do not matter much for the serial console. Fixes: 22a6984 ("serial: sh-sci: Update the suspend/resume support") Signed-off-by: Geert Uytterhoeven <[email protected]> Tested-by: Claudiu Beznea <[email protected]> Reviewed-by: Claudiu Beznea <[email protected]> Link: https://lore.kernel.org/r/11c2eab45d48211e75d8b8202cce60400880fe55.1741114989.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent d55f0f8 commit 1b04c4e

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

drivers/tty/serial/sh-sci.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,15 @@ struct plat_sci_reg {
105105
};
106106

107107
struct sci_suspend_regs {
108+
u16 scdl;
109+
u16 sccks;
108110
u16 scsmr;
109111
u16 scscr;
110112
u16 scfcr;
111113
u16 scsptr;
114+
u16 hssrr;
115+
u16 scpcr;
116+
u16 scpdr;
112117
u8 scbrr;
113118
u8 semr;
114119
};
@@ -3564,6 +3569,10 @@ static void sci_console_save(struct sci_port *s)
35643569
struct sci_suspend_regs *regs = &s->suspend_regs;
35653570
struct uart_port *port = &s->port;
35663571

3572+
if (sci_getreg(port, SCDL)->size)
3573+
regs->scdl = sci_serial_in(port, SCDL);
3574+
if (sci_getreg(port, SCCKS)->size)
3575+
regs->sccks = sci_serial_in(port, SCCKS);
35673576
if (sci_getreg(port, SCSMR)->size)
35683577
regs->scsmr = sci_serial_in(port, SCSMR);
35693578
if (sci_getreg(port, SCSCR)->size)
@@ -3574,6 +3583,12 @@ static void sci_console_save(struct sci_port *s)
35743583
regs->scsptr = sci_serial_in(port, SCSPTR);
35753584
if (sci_getreg(port, SCBRR)->size)
35763585
regs->scbrr = sci_serial_in(port, SCBRR);
3586+
if (sci_getreg(port, HSSRR)->size)
3587+
regs->hssrr = sci_serial_in(port, HSSRR);
3588+
if (sci_getreg(port, SCPCR)->size)
3589+
regs->scpcr = sci_serial_in(port, SCPCR);
3590+
if (sci_getreg(port, SCPDR)->size)
3591+
regs->scpdr = sci_serial_in(port, SCPDR);
35773592
if (sci_getreg(port, SEMR)->size)
35783593
regs->semr = sci_serial_in(port, SEMR);
35793594
}
@@ -3583,6 +3598,10 @@ static void sci_console_restore(struct sci_port *s)
35833598
struct sci_suspend_regs *regs = &s->suspend_regs;
35843599
struct uart_port *port = &s->port;
35853600

3601+
if (sci_getreg(port, SCDL)->size)
3602+
sci_serial_out(port, SCDL, regs->scdl);
3603+
if (sci_getreg(port, SCCKS)->size)
3604+
sci_serial_out(port, SCCKS, regs->sccks);
35863605
if (sci_getreg(port, SCSMR)->size)
35873606
sci_serial_out(port, SCSMR, regs->scsmr);
35883607
if (sci_getreg(port, SCSCR)->size)
@@ -3593,6 +3612,12 @@ static void sci_console_restore(struct sci_port *s)
35933612
sci_serial_out(port, SCSPTR, regs->scsptr);
35943613
if (sci_getreg(port, SCBRR)->size)
35953614
sci_serial_out(port, SCBRR, regs->scbrr);
3615+
if (sci_getreg(port, HSSRR)->size)
3616+
sci_serial_out(port, HSSRR, regs->hssrr);
3617+
if (sci_getreg(port, SCPCR)->size)
3618+
sci_serial_out(port, SCPCR, regs->scpcr);
3619+
if (sci_getreg(port, SCPDR)->size)
3620+
sci_serial_out(port, SCPDR, regs->scpdr);
35963621
if (sci_getreg(port, SEMR)->size)
35973622
sci_serial_out(port, SEMR, regs->semr);
35983623
}

0 commit comments

Comments
 (0)