aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-4.14/0136-mtd-mtk-nor-add-suspend-resume-support.patch
blob: 8bfba8953db7c35a342aedb6b73a6e77c1f7022f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From 8947f8cd407a55db816cd03fc03b59096210978e Mon Sep 17 00:00:00 2001
From: Guochun Mao <guochun.mao@mediatek.com>
Date: Thu, 21 Sep 2017 20:45:06 +0800
Subject: [PATCH 136/224] mtd: mtk-nor: add suspend/resume support

Abstract functions of clock setting, to avoid duplicated code,
these functions been used in new feature.
Implement suspend/resume functions.

Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
---
 drivers/mtd/spi-nor/mtk-quadspi.c | 70 ++++++++++++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 12 deletions(-)

--- a/drivers/mtd/spi-nor/mtk-quadspi.c
+++ b/drivers/mtd/spi-nor/mtk-quadspi.c
@@ -404,6 +404,29 @@ static int mt8173_nor_write_reg(struct s
 	return ret;
 }
 
+static void mt8173_nor_disable_clk(struct mt8173_nor *mt8173_nor)
+{
+	clk_disable_unprepare(mt8173_nor->spi_clk);
+	clk_disable_unprepare(mt8173_nor->nor_clk);
+}
+
+static int mt8173_nor_enable_clk(struct mt8173_nor *mt8173_nor)
+{
+	int ret;
+
+	ret = clk_prepare_enable(mt8173_nor->spi_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(mt8173_nor->nor_clk);
+	if (ret) {
+		clk_disable_unprepare(mt8173_nor->spi_clk);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
 			struct device_node *flash_node)
 {
@@ -468,15 +491,11 @@ static int mtk_nor_drv_probe(struct plat
 		return PTR_ERR(mt8173_nor->nor_clk);
 
 	mt8173_nor->dev = &pdev->dev;
-	ret = clk_prepare_enable(mt8173_nor->spi_clk);
+
+	ret = mt8173_nor_enable_clk(mt8173_nor);
 	if (ret)
 		return ret;
 
-	ret = clk_prepare_enable(mt8173_nor->nor_clk);
-	if (ret) {
-		clk_disable_unprepare(mt8173_nor->spi_clk);
-		return ret;
-	}
 	/* only support one attached flash */
 	flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
 	if (!flash_np) {
@@ -487,10 +506,9 @@ static int mtk_nor_drv_probe(struct plat
 	ret = mtk_nor_init(mt8173_nor, flash_np);
 
 nor_free:
-	if (ret) {
-		clk_disable_unprepare(mt8173_nor->spi_clk);
-		clk_disable_unprepare(mt8173_nor->nor_clk);
-	}
+	if (ret)
+		mt8173_nor_disable_clk(mt8173_nor);
+
 	return ret;
 }
 
@@ -498,11 +516,38 @@ static int mtk_nor_drv_remove(struct pla
 {
 	struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
 
-	clk_disable_unprepare(mt8173_nor->spi_clk);
-	clk_disable_unprepare(mt8173_nor->nor_clk);
+	mt8173_nor_disable_clk(mt8173_nor);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_nor_suspend(struct device *dev)
+{
+	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
+
+	mt8173_nor_disable_clk(mt8173_nor);
+
 	return 0;
 }
 
+static int mtk_nor_resume(struct device *dev)
+{
+	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
+
+	return mt8173_nor_enable_clk(mt8173_nor);
+}
+
+static const struct dev_pm_ops mtk_nor_dev_pm_ops = {
+	.suspend = mtk_nor_suspend,
+	.resume = mtk_nor_resume,
+};
+
+#define MTK_NOR_DEV_PM_OPS	(&mtk_nor_dev_pm_ops)
+#else
+#define MTK_NOR_DEV_PM_OPS	NULL
+#endif
+
 static const struct of_device_id mtk_nor_of_ids[] = {
 	{ .compatible = "mediatek,mt8173-nor"},
 	{ /* sentinel */ }
@@ -514,6 +559,7 @@ static struct platform_driver mtk_nor_dr
 	.remove = mtk_nor_drv_remove,
 	.driver = {
 		.name = "mtk-nor",
+		.pm = MTK_NOR_DEV_PM_OPS,
 		.of_match_table = mtk_nor_of_ids,
 	},
 };