mediatek: backport upstream mediatek patches
[openwrt/openwrt.git] / target / linux / mediatek / patches-4.14 / 0136-mtd-mtk-nor-add-suspend-resume-support.patch
1 From 8947f8cd407a55db816cd03fc03b59096210978e Mon Sep 17 00:00:00 2001
2 From: Guochun Mao <guochun.mao@mediatek.com>
3 Date: Thu, 21 Sep 2017 20:45:06 +0800
4 Subject: [PATCH 136/224] mtd: mtk-nor: add suspend/resume support
5
6 Abstract functions of clock setting, to avoid duplicated code,
7 these functions been used in new feature.
8 Implement suspend/resume functions.
9
10 Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
11 Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
12 ---
13 drivers/mtd/spi-nor/mtk-quadspi.c | 70 ++++++++++++++++++++++++++++++++-------
14 1 file changed, 58 insertions(+), 12 deletions(-)
15
16 diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
17 index c258c7adf1c5..abe455ccd68b 100644
18 --- a/drivers/mtd/spi-nor/mtk-quadspi.c
19 +++ b/drivers/mtd/spi-nor/mtk-quadspi.c
20 @@ -404,6 +404,29 @@ static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
21 return ret;
22 }
23
24 +static void mt8173_nor_disable_clk(struct mt8173_nor *mt8173_nor)
25 +{
26 + clk_disable_unprepare(mt8173_nor->spi_clk);
27 + clk_disable_unprepare(mt8173_nor->nor_clk);
28 +}
29 +
30 +static int mt8173_nor_enable_clk(struct mt8173_nor *mt8173_nor)
31 +{
32 + int ret;
33 +
34 + ret = clk_prepare_enable(mt8173_nor->spi_clk);
35 + if (ret)
36 + return ret;
37 +
38 + ret = clk_prepare_enable(mt8173_nor->nor_clk);
39 + if (ret) {
40 + clk_disable_unprepare(mt8173_nor->spi_clk);
41 + return ret;
42 + }
43 +
44 + return 0;
45 +}
46 +
47 static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
48 struct device_node *flash_node)
49 {
50 @@ -468,15 +491,11 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
51 return PTR_ERR(mt8173_nor->nor_clk);
52
53 mt8173_nor->dev = &pdev->dev;
54 - ret = clk_prepare_enable(mt8173_nor->spi_clk);
55 +
56 + ret = mt8173_nor_enable_clk(mt8173_nor);
57 if (ret)
58 return ret;
59
60 - ret = clk_prepare_enable(mt8173_nor->nor_clk);
61 - if (ret) {
62 - clk_disable_unprepare(mt8173_nor->spi_clk);
63 - return ret;
64 - }
65 /* only support one attached flash */
66 flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
67 if (!flash_np) {
68 @@ -487,10 +506,9 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
69 ret = mtk_nor_init(mt8173_nor, flash_np);
70
71 nor_free:
72 - if (ret) {
73 - clk_disable_unprepare(mt8173_nor->spi_clk);
74 - clk_disable_unprepare(mt8173_nor->nor_clk);
75 - }
76 + if (ret)
77 + mt8173_nor_disable_clk(mt8173_nor);
78 +
79 return ret;
80 }
81
82 @@ -498,11 +516,38 @@ static int mtk_nor_drv_remove(struct platform_device *pdev)
83 {
84 struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
85
86 - clk_disable_unprepare(mt8173_nor->spi_clk);
87 - clk_disable_unprepare(mt8173_nor->nor_clk);
88 + mt8173_nor_disable_clk(mt8173_nor);
89 +
90 + return 0;
91 +}
92 +
93 +#ifdef CONFIG_PM_SLEEP
94 +static int mtk_nor_suspend(struct device *dev)
95 +{
96 + struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
97 +
98 + mt8173_nor_disable_clk(mt8173_nor);
99 +
100 return 0;
101 }
102
103 +static int mtk_nor_resume(struct device *dev)
104 +{
105 + struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
106 +
107 + return mt8173_nor_enable_clk(mt8173_nor);
108 +}
109 +
110 +static const struct dev_pm_ops mtk_nor_dev_pm_ops = {
111 + .suspend = mtk_nor_suspend,
112 + .resume = mtk_nor_resume,
113 +};
114 +
115 +#define MTK_NOR_DEV_PM_OPS (&mtk_nor_dev_pm_ops)
116 +#else
117 +#define MTK_NOR_DEV_PM_OPS NULL
118 +#endif
119 +
120 static const struct of_device_id mtk_nor_of_ids[] = {
121 { .compatible = "mediatek,mt8173-nor"},
122 { /* sentinel */ }
123 @@ -514,6 +559,7 @@ static struct platform_driver mtk_nor_driver = {
124 .remove = mtk_nor_drv_remove,
125 .driver = {
126 .name = "mtk-nor",
127 + .pm = MTK_NOR_DEV_PM_OPS,
128 .of_match_table = mtk_nor_of_ids,
129 },
130 };
131 --
132 2.11.0
133