Skip to content

Commit

Permalink
serial: sh-sci: console Runtime PM support
Browse files Browse the repository at this point in the history
Add Runtime PM context save/restore support to
the SCIF driver. Tested on the AP4EVB console.

Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Aug 3, 2011
1 parent c84b51e commit 1ba7622
Showing 1 changed file with 58 additions and 10 deletions.
68 changes: 58 additions & 10 deletions drivers/tty/serial/sh-sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ struct sci_port {
#endif

struct notifier_block freq_transition;

#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
unsigned short saved_smr;
unsigned short saved_fcr;
unsigned char saved_brr;
#endif
};

/* Function prototypes */
Expand Down Expand Up @@ -1634,11 +1640,25 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
return ((freq + 16 * bps) / (32 * bps) - 1);
}

static void sci_reset(struct uart_port *port)
{
unsigned int status;

do {
status = sci_in(port, SCxSR);
} while (!(status & SCxSR_TEND(port)));

sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */

if (port->type != PORT_SCI)
sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
}

static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct sci_port *s = to_sci_port(port);
unsigned int status, baud, smr_val, max_baud;
unsigned int baud, smr_val, max_baud;
int t = -1;
u16 scfcr = 0;

Expand All @@ -1658,14 +1678,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,

sci_port_enable(s);

do {
status = sci_in(port, SCxSR);
} while (!(status & SCxSR_TEND(port)));

sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */

if (port->type != PORT_SCI)
sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST);
sci_reset(port);

smr_val = sci_in(port, SCSMR) & 3;

Expand Down Expand Up @@ -2037,7 +2050,8 @@ static int __devinit serial_console_setup(struct console *co, char *options)
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);

/* TODO: disable clock */
sci_port_disable(sci_port);

return uart_set_options(port, co, baud, parity, bits, flow);
}

Expand Down Expand Up @@ -2080,6 +2094,36 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
return 0;
}

#define uart_console(port) ((port)->cons->index == (port)->line)

static int sci_runtime_suspend(struct device *dev)
{
struct sci_port *sci_port = dev_get_drvdata(dev);
struct uart_port *port = &sci_port->port;

if (uart_console(port)) {
sci_port->saved_smr = sci_in(port, SCSMR);
sci_port->saved_brr = sci_in(port, SCBRR);
sci_port->saved_fcr = sci_in(port, SCFCR);
}
return 0;
}

static int sci_runtime_resume(struct device *dev)
{
struct sci_port *sci_port = dev_get_drvdata(dev);
struct uart_port *port = &sci_port->port;

if (uart_console(port)) {
sci_reset(port);
sci_out(port, SCSMR, sci_port->saved_smr);
sci_out(port, SCBRR, sci_port->saved_brr);
sci_out(port, SCFCR, sci_port->saved_fcr);
sci_out(port, SCSCR, sci_port->cfg->scscr);
}
return 0;
}

#define SCI_CONSOLE (&serial_console)

#else
Expand All @@ -2089,6 +2133,8 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
}

#define SCI_CONSOLE NULL
#define sci_runtime_suspend NULL
#define sci_runtime_resume NULL

#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */

Expand Down Expand Up @@ -2204,6 +2250,8 @@ static int sci_resume(struct device *dev)
}

static const struct dev_pm_ops sci_dev_pm_ops = {
.runtime_suspend = sci_runtime_suspend,
.runtime_resume = sci_runtime_resume,
.suspend = sci_suspend,
.resume = sci_resume,
};
Expand Down

0 comments on commit 1ba7622

Please sign in to comment.