Skip to content

Commit 81100b9

Browse files
geertugregkh
authored andcommitted
serial: sh-sci: Save and restore more registers
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 <geert+renesas@glider.be> Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Link: https://lore.kernel.org/r/11c2eab45d48211e75d8b8202cce60400880fe55.1741114989.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent b5ad18a commit 81100b9

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
};
@@ -3563,6 +3568,10 @@ static void sci_console_save(struct sci_port *s)
35633568
struct sci_suspend_regs *regs = &s->suspend_regs;
35643569
struct uart_port *port = &s->port;
35653570

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

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

0 commit comments

Comments
 (0)