aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/mvebu-uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/mvebu-uart.c')
-rw-r--r--drivers/tty/serial/mvebu-uart.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index f503fab1e268..d04b5eeea3c6 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -71,6 +71,8 @@
71#define UART_BRDV 0x10 71#define UART_BRDV 0x10
72#define BRDV_BAUD_MASK 0x3FF 72#define BRDV_BAUD_MASK 0x3FF
73 73
74#define UART_OSAMP 0x14
75
74#define MVEBU_NR_UARTS 2 76#define MVEBU_NR_UARTS 2
75 77
76#define MVEBU_UART_TYPE "mvebu-uart" 78#define MVEBU_UART_TYPE "mvebu-uart"
@@ -108,6 +110,17 @@ struct mvebu_uart_driver_data {
108 struct uart_flags flags; 110 struct uart_flags flags;
109}; 111};
110 112
113/* Saved registers during suspend */
114struct mvebu_uart_pm_regs {
115 unsigned int rbr;
116 unsigned int tsh;
117 unsigned int ctrl;
118 unsigned int intr;
119 unsigned int stat;
120 unsigned int brdv;
121 unsigned int osamp;
122};
123
111/* MVEBU UART driver structure */ 124/* MVEBU UART driver structure */
112struct mvebu_uart { 125struct mvebu_uart {
113 struct uart_port *port; 126 struct uart_port *port;
@@ -115,6 +128,9 @@ struct mvebu_uart {
115 int irq[UART_IRQ_COUNT]; 128 int irq[UART_IRQ_COUNT];
116 unsigned char __iomem *nb; 129 unsigned char __iomem *nb;
117 struct mvebu_uart_driver_data *data; 130 struct mvebu_uart_driver_data *data;
131#if defined(CONFIG_PM)
132 struct mvebu_uart_pm_regs pm_regs;
133#endif /* CONFIG_PM */
118}; 134};
119 135
120static struct mvebu_uart *to_mvuart(struct uart_port *port) 136static struct mvebu_uart *to_mvuart(struct uart_port *port)
@@ -718,6 +734,51 @@ static struct uart_driver mvebu_uart_driver = {
718#endif 734#endif
719}; 735};
720 736
737#if defined(CONFIG_PM)
738static int mvebu_uart_suspend(struct device *dev)
739{
740 struct mvebu_uart *mvuart = dev_get_drvdata(dev);
741 struct uart_port *port = mvuart->port;
742
743 uart_suspend_port(&mvebu_uart_driver, port);
744
745 mvuart->pm_regs.rbr = readl(port->membase + UART_RBR(port));
746 mvuart->pm_regs.tsh = readl(port->membase + UART_TSH(port));
747 mvuart->pm_regs.ctrl = readl(port->membase + UART_CTRL(port));
748 mvuart->pm_regs.intr = readl(port->membase + UART_INTR(port));
749 mvuart->pm_regs.stat = readl(port->membase + UART_STAT);
750 mvuart->pm_regs.brdv = readl(port->membase + UART_BRDV);
751 mvuart->pm_regs.osamp = readl(port->membase + UART_OSAMP);
752
753 device_set_wakeup_enable(dev, true);
754
755 return 0;
756}
757
758static int mvebu_uart_resume(struct device *dev)
759{
760 struct mvebu_uart *mvuart = dev_get_drvdata(dev);
761 struct uart_port *port = mvuart->port;
762
763 writel(mvuart->pm_regs.rbr, port->membase + UART_RBR(port));
764 writel(mvuart->pm_regs.tsh, port->membase + UART_TSH(port));
765 writel(mvuart->pm_regs.ctrl, port->membase + UART_CTRL(port));
766 writel(mvuart->pm_regs.intr, port->membase + UART_INTR(port));
767 writel(mvuart->pm_regs.stat, port->membase + UART_STAT);
768 writel(mvuart->pm_regs.brdv, port->membase + UART_BRDV);
769 writel(mvuart->pm_regs.osamp, port->membase + UART_OSAMP);
770
771 uart_resume_port(&mvebu_uart_driver, port);
772
773 return 0;
774}
775
776static const struct dev_pm_ops mvebu_uart_pm_ops = {
777 .suspend = mvebu_uart_suspend,
778 .resume = mvebu_uart_resume,
779};
780#endif /* CONFIG_PM */
781
721static const struct of_device_id mvebu_uart_of_match[]; 782static const struct of_device_id mvebu_uart_of_match[];
722 783
723/* Counter to keep track of each UART port id when not using CONFIG_OF */ 784/* Counter to keep track of each UART port id when not using CONFIG_OF */
@@ -891,6 +952,9 @@ static struct platform_driver mvebu_uart_platform_driver = {
891 .name = "mvebu-uart", 952 .name = "mvebu-uart",
892 .of_match_table = of_match_ptr(mvebu_uart_of_match), 953 .of_match_table = of_match_ptr(mvebu_uart_of_match),
893 .suppress_bind_attrs = true, 954 .suppress_bind_attrs = true,
955#if defined(CONFIG_PM)
956 .pm = &mvebu_uart_pm_ops,
957#endif /* CONFIG_PM */
894 }, 958 },
895}; 959};
896 960