Skip to content

Commit a8a34fb

Browse files
geertugregkh
authored andcommitted
serial: sh-sci: Save and restore more registers
commit 81100b9 upstream. 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: Greg Kroah-Hartman <[email protected]>
1 parent 80eb737 commit a8a34fb

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
};
@@ -3550,6 +3555,10 @@ static void sci_console_save(struct sci_port *s)
35503555
struct sci_suspend_regs *regs = &s->suspend_regs;
35513556
struct uart_port *port = &s->port;
35523557

3558+
if (sci_getreg(port, SCDL)->size)
3559+
regs->scdl = sci_serial_in(port, SCDL);
3560+
if (sci_getreg(port, SCCKS)->size)
3561+
regs->sccks = sci_serial_in(port, SCCKS);
35533562
if (sci_getreg(port, SCSMR)->size)
35543563
regs->scsmr = sci_serial_in(port, SCSMR);
35553564
if (sci_getreg(port, SCSCR)->size)
@@ -3560,6 +3569,12 @@ static void sci_console_save(struct sci_port *s)
35603569
regs->scsptr = sci_serial_in(port, SCSPTR);
35613570
if (sci_getreg(port, SCBRR)->size)
35623571
regs->scbrr = sci_serial_in(port, SCBRR);
3572+
if (sci_getreg(port, HSSRR)->size)
3573+
regs->hssrr = sci_serial_in(port, HSSRR);
3574+
if (sci_getreg(port, SCPCR)->size)
3575+
regs->scpcr = sci_serial_in(port, SCPCR);
3576+
if (sci_getreg(port, SCPDR)->size)
3577+
regs->scpdr = sci_serial_in(port, SCPDR);
35633578
if (sci_getreg(port, SEMR)->size)
35643579
regs->semr = sci_serial_in(port, SEMR);
35653580
}
@@ -3569,6 +3584,10 @@ static void sci_console_restore(struct sci_port *s)
35693584
struct sci_suspend_regs *regs = &s->suspend_regs;
35703585
struct uart_port *port = &s->port;
35713586

3587+
if (sci_getreg(port, SCDL)->size)
3588+
sci_serial_out(port, SCDL, regs->scdl);
3589+
if (sci_getreg(port, SCCKS)->size)
3590+
sci_serial_out(port, SCCKS, regs->sccks);
35723591
if (sci_getreg(port, SCSMR)->size)
35733592
sci_serial_out(port, SCSMR, regs->scsmr);
35743593
if (sci_getreg(port, SCSCR)->size)
@@ -3579,6 +3598,12 @@ static void sci_console_restore(struct sci_port *s)
35793598
sci_serial_out(port, SCSPTR, regs->scsptr);
35803599
if (sci_getreg(port, SCBRR)->size)
35813600
sci_serial_out(port, SCBRR, regs->scbrr);
3601+
if (sci_getreg(port, HSSRR)->size)
3602+
sci_serial_out(port, HSSRR, regs->hssrr);
3603+
if (sci_getreg(port, SCPCR)->size)
3604+
sci_serial_out(port, SCPCR, regs->scpcr);
3605+
if (sci_getreg(port, SCPDR)->size)
3606+
sci_serial_out(port, SCPDR, regs->scpdr);
35823607
if (sci_getreg(port, SEMR)->size)
35833608
sci_serial_out(port, SEMR, regs->semr);
35843609
}

0 commit comments

Comments
 (0)