Add kernel Hibernation code for porter board.
[AGL/meta-agl.git] / meta-agl-bsp / meta-renesas / recipes-kernel / linux / linux / hibernation / 0013-Add-rcar-spi-hibernation-code.patch
1 From c1b129172a91046a7555a3c198b49eb1b45aafd7 Mon Sep 17 00:00:00 2001
2 From: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
3 Date: Thu, 18 May 2017 17:58:28 +0900
4 Subject: [PATCH 13/15] Add rcar-spi hibernation code
5
6 Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
7 ---
8  drivers/spi/spi-rspi.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++-
9  1 file changed, 108 insertions(+), 1 deletion(-)
10
11 diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
12 index 215be3b..a2432de 100644
13 --- a/drivers/spi/spi-rspi.c
14 +++ b/drivers/spi/spi-rspi.c
15 @@ -38,6 +38,7 @@
16  #include <linux/sh_dma.h>
17  #include <linux/spi/spi.h>
18  #include <linux/spi/rspi.h>
19 +#include <linux/delay.h>
20  
21  #define RSPI_SPCR              0x00    /* Control Register */
22  #define RSPI_SSLP              0x01    /* Slave Select Polarity Register */
23 @@ -208,6 +209,12 @@ struct rspi_data {
24         u8 sppcr;
25         int rx_irq, tx_irq;
26         const struct spi_ops *ops;
27 +       u32 save_spbmul0;
28 +       u32 save_spbmul1;
29 +       u32 save_spbmul2;
30 +       u32 save_spbmul3;
31 +       u8 save_spbfcr;
32 +       u8 save_spscr;
33  
34         unsigned dma_callbacked:1;
35         unsigned byte_access:1;
36 @@ -238,6 +245,11 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
37         return ioread16(rspi->addr + offset);
38  }
39  
40 +static u16 rspi_read32(const struct rspi_data *rspi, u16 offset)
41 +{
42 +       return ioread32(rspi->addr + offset);
43 +}
44 +
45  #define rspi_update8(spi, mask, val, reg) \
46         rspi_write8(spi, (rspi_read8(spi, reg) & ~mask) | val, reg);
47  
48 @@ -504,7 +516,6 @@ static int rspi_pio_transfer_in(struct rspi_data *rspi, u8 *rx, unsigned int n)
49         if (!rx)
50                 return 0;
51  
52 -
53         while (n > 0) {
54                 count = min(n, SPI_BUFFER_SIZE);
55                 if (count >= SPI_BUFFER_SIZE) {
56 @@ -1278,6 +1289,101 @@ error1:
57         return ret;
58  }
59  
60 +int rspi_suspend(struct device *dev)
61 +{
62 +       struct rspi_data *rspi = platform_get_drvdata(to_platform_device(dev));
63 +       clk_disable_unprepare(rspi->clk);
64 +       return 0;
65 +}
66 +
67 +int rspi_resume(struct device *dev)
68 +{
69 +       struct rspi_data *rspi = platform_get_drvdata(to_platform_device(dev));
70 +       clk_prepare_enable(rspi->clk);
71 +       return 0;
72 +}
73 +
74 +#define PR_REG8(dev, rspi, reg) \
75 +       dev_dbg(dev, "QSPI REG: " #reg " = %08x\n", \
76 +                       rspi_read8(rspi, reg))
77 +#define PR_REG16(dev, rspi, reg) \
78 +       dev_dbg(dev, "QSPI REG: " #reg " = %08x\n", \
79 +                       rspi_read16(rspi, reg))
80 +#define PR_REG32(dev, rspi, reg) \
81 +       dev_dbg(dev, "QSPI REG: " #reg " = %08x\n", \
82 +                       rspi_read32(rspi, reg))
83 +
84 +#ifdef DEBUG
85 +static void pr_regs(struct device *dev)
86 +{
87 +       struct rspi_data *rspi = platform_get_drvdata(to_platform_device(dev));
88 +       PR_REG8(dev, rspi, RSPI_SPCR);
89 +       PR_REG8(dev, rspi, RSPI_SSLP);
90 +       PR_REG8(dev, rspi, RSPI_SPPCR);
91 +       PR_REG8(dev, rspi, RSPI_SPDR);
92 +       PR_REG8(dev, rspi, RSPI_SPSCR);
93 +       PR_REG8(dev, rspi, RSPI_SPBR);
94 +       PR_REG8(dev, rspi, RSPI_SPDCR);
95 +       PR_REG8(dev, rspi, RSPI_SPCKD);
96 +       PR_REG8(dev, rspi, RSPI_SSLND);
97 +       PR_REG8(dev, rspi, RSPI_SPND);
98 +       PR_REG16(dev, rspi, RSPI_SPCMD0);
99 +       PR_REG16(dev, rspi, RSPI_SPCMD1);
100 +       PR_REG16(dev, rspi, RSPI_SPCMD2);
101 +       PR_REG16(dev, rspi, RSPI_SPCMD3);
102 +       PR_REG8(dev, rspi, QSPI_SPBFCR);
103 +       PR_REG16(dev, rspi, QSPI_SPBDCR);
104 +       PR_REG32(dev, rspi, QSPI_SPBMUL0);
105 +       PR_REG32(dev, rspi, QSPI_SPBMUL1);
106 +       PR_REG32(dev, rspi, QSPI_SPBMUL2);
107 +       PR_REG32(dev, rspi, QSPI_SPBMUL3);
108 +}
109 +#endif
110 +
111 +int rspi_freeze(struct device *dev)
112 +{
113 +       struct rspi_data *rspi = platform_get_drvdata(to_platform_device(dev));
114 +       rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
115 +       rspi->save_spbmul0 = rspi_read32(rspi, QSPI_SPBMUL0);
116 +       rspi->save_spbmul1 = rspi_read32(rspi, QSPI_SPBMUL1);
117 +       rspi->save_spbmul2 = rspi_read32(rspi, QSPI_SPBMUL2);
118 +       rspi->save_spbmul3 = rspi_read32(rspi, QSPI_SPBMUL3);
119 +       rspi->save_spbfcr = rspi_read8(rspi, QSPI_SPBFCR);
120 +       rspi->save_spscr = rspi_read8(rspi, RSPI_SPSCR);
121 +       dev_info(dev, "freeze\n");
122 +#ifdef DEBUG
123 +       pr_regs(dev);
124 +#endif
125 +       return 0;
126 +}
127 +
128 +
129 +int rspi_restore(struct device *dev)
130 +{
131 +       struct rspi_data *rspi = platform_get_drvdata(to_platform_device(dev));
132 +       clk_prepare_enable(rspi->clk);
133 +       udelay(16);
134 +       set_config_register(rspi, 8);
135 +       rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
136 +       rspi_write8(rspi, rspi->save_spscr, RSPI_SPSCR);
137 +       rspi_write8(rspi, rspi->save_spbfcr, QSPI_SPBFCR);
138 +       rspi_write32(rspi, rspi->save_spbmul3, QSPI_SPBMUL3);
139 +       rspi_write32(rspi, rspi->save_spbmul2, QSPI_SPBMUL2);
140 +       rspi_write32(rspi, rspi->save_spbmul1, QSPI_SPBMUL1);
141 +       rspi_write32(rspi, rspi->save_spbmul0, QSPI_SPBMUL0);
142 +       dev_info(dev, "restore\n");
143 +#ifdef DEBUG
144 +       pr_regs(dev);
145 +#endif
146 +       return 0;
147 +}
148 +
149 +const struct dev_pm_ops rspi_pm_ops = {
150 +       SET_SYSTEM_SLEEP_PM_OPS(rspi_suspend, rspi_resume)
151 +       .restore = rspi_restore,
152 +       .freeze = rspi_freeze,
153 +};
154 +
155  static struct platform_device_id spi_driver_ids[] = {
156         { "rspi",       (kernel_ulong_t)&rspi_ops },
157         { "rspi-rz",    (kernel_ulong_t)&rspi_rz_ops },
158 @@ -1295,6 +1401,7 @@ static struct platform_driver rspi_driver = {
159                 .name = "renesas_spi",
160                 .owner  = THIS_MODULE,
161                 .of_match_table = of_match_ptr(rspi_of_match),
162 +               .pm = &rspi_pm_ops,
163         },
164  };
165  module_platform_driver(rspi_driver);
166 -- 
167 1.8.3.1
168