summaryrefslogtreecommitdiffstats
path: root/meta-agl-bsp/meta-renesas/recipes-kernel/mmngr-module/files/0001-Fix-for-memory-corruption-during-hibernate.patch
blob: de0365da592d6df86caee67924ff53e686b4536c (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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
From 99f60a25458ac553ff609f5bdbf4db7dade46d9a Mon Sep 17 00:00:00 2001
From: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
Date: Sat, 10 Jun 2017 20:26:26 +0900
Subject: [PATCH] Fix for memory corruption during hibernate

Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
---
 drv/mmngr_drv.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 106 insertions(+), 3 deletions(-)

diff --git a/drv/mmngr_drv.c b/drv/mmngr_drv.c
index 797800f..91f6c6e 100755
--- a/drv/mmngr_drv.c
+++ b/drv/mmngr_drv.c
@@ -844,7 +844,7 @@ static struct miscdevice misc = {
 extern struct cma *rcar_gen2_dma_contiguous;
 #endif
 
-static int mm_init(void)
+static int mmngr_probe(struct platform_device *pdev)
 {
 	int			ret = 0;
 	struct MM_DRVDATA	*p = NULL;
@@ -946,16 +946,16 @@ static int mm_init(void)
 	printk(KERN_ERR "MMD reserve area from 0x%08x to 0x%08x at physical\n",
 		(unsigned int)phy_addr,
 		(unsigned int)phy_addr + MM_KERNEL_RESERVE_SIZE - 1);
-#endif
 #ifdef MMNGR_IPMMU_ENABLE
 	r8a779x_ipmmu_startup();
 	r8a779x_ipmmu_initialize(IPMMUMX_DOMAIN);
 #endif
+#endif
 
 	return 0;
 }
 
-static void mm_exit(void)
+static int mmngr_remove(struct platform_device *pdev)
 {
 #ifdef MMNGR_IPMMU_ENABLE
 	r8a779x_ipmmu_cleanup();
@@ -983,6 +983,109 @@ static void mm_exit(void)
 #endif
 
 	kfree(mm_drvdata);
+	return 0;
+}
+static int mmngr_suspend(struct device *dev)
+{
+	return 0;
+}
+static int mmngr_resume(struct device *dev)
+{
+	return 0;
+}
+static int mmngr_freeze(struct device *dev)
+{
+#if defined(MMNGR_KOELSCH) || defined(MMNGR_LAGER) || \
+		defined(MMNGR_ALT) || defined(MMNGR_GOSE)
+	iowrite32((~MM_IMPCTR_VAL) & ioread32(top_impctr), top_impctr);
+#endif
+	mm_set_mxi_path(0, 0);
+	dma_free_coherent(mm_drvdata->mm_dev_reserve,
+			mm_drvdata->reserve_size,
+			(void *)mm_drvdata->reserve_kernel_virt_addr,
+			(dma_addr_t)mm_drvdata->reserve_phy_addr);
+	return 0;
+}
+static int mmngr_thaw(struct device *dev)
+{
+	void			*pkernel_virt_addr;
+	mm_set_mxi_path(MM_OMXBUF_MXI_ADDR,
+		MM_OMXBUF_MXI_ADDR + MM_OMXBUF_SIZE);
+	pkernel_virt_addr = dma_alloc_coherent(mm_drvdata->mm_dev_reserve,
+				MM_KERNEL_RESERVE_SIZE,
+				(dma_addr_t *)&mm_drvdata->reserve_phy_addr,
+				GFP_KERNEL);
+	mm_drvdata->reserve_kernel_virt_addr = (unsigned long)pkernel_virt_addr;
+	return 0;
+}
+static int mmngr_restore(struct device *dev)
+{
+	void			*pkernel_virt_addr;
+	mm_set_mxi_path(MM_OMXBUF_MXI_ADDR,
+		MM_OMXBUF_MXI_ADDR + MM_OMXBUF_SIZE);
+
+#ifdef MMNGR_KOELSCH
+	if ((MM_PRR_ESMASK & ioread32(top_prr)) >= MM_PRR_ES2) {
+		mm_enable_pmb();
+		mm_set_pmb_area(MM_OMXBUF_ADDR, top_impmba0, top_impmbd0);
+		mm_enable_vpc_utlb();
+	}
+#endif
+#ifdef MMNGR_LAGER
+	if ((MM_PRR_ESMASK & ioread32(top_prr)) >= MM_PRR_ES2) {
+		mm_enable_pmb();
+		mm_set_pmb_area(MM_OMXBUF_ADDR, top_impmba0, top_impmbd0);
+		mm_set_pmb_area(MM_OMXBUF_ADDR + MM_PMB_SIZE_128M,
+			top_impmba1, top_impmbd1);
+		mm_enable_vpc_utlb();
+	}
+#endif
+#ifdef MMNGR_ALT
+	mm_enable_pmb();
+	mm_set_pmb_area(MM_OMXBUF_ADDR, top_impmba0, top_impmbd0);
+	mm_enable_vpc_utlb();
+#endif
+#ifdef MMNGR_GOSE
+	mm_enable_pmb();
+	mm_set_pmb_area(MM_OMXBUF_ADDR, top_impmba0, top_impmbd0);
+	mm_enable_vpc_utlb();
+#endif
+	pkernel_virt_addr = dma_alloc_coherent(mm_drvdata->mm_dev_reserve,
+				MM_KERNEL_RESERVE_SIZE,
+				(dma_addr_t *)&mm_drvdata->reserve_phy_addr,
+				GFP_KERNEL);
+	mm_drvdata->reserve_kernel_virt_addr = (unsigned long)pkernel_virt_addr;
+
+	return 0;
+}
+static const struct dev_pm_ops mmngr_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mmngr_suspend, mmngr_resume)
+	.freeze = mmngr_freeze,
+	.thaw = mmngr_thaw,
+	.restore = mmngr_restore,
+};
+struct platform_driver mmngr_driver = {
+	.probe = mmngr_probe,
+	.remove = mmngr_remove,
+	.driver = {
+		.name = "mmngr",
+		.pm = &mmngr_pm_ops,
+	},
+};
+struct platform_device mmngr_device = {
+	.name = "mmngr",
+	.id = -1,
+};
+static int mm_init(void)
+{
+	platform_driver_register(&mmngr_driver);
+	platform_device_register(&mmngr_device);
+	return 0;
+}
+static void mm_exit(void)
+{
+	platform_device_unregister(&mmngr_device);
+	platform_driver_unregister(&mmngr_driver);
 }
 
 module_init(mm_init);
-- 
1.8.3.1