From 99f60a25458ac553ff609f5bdbf4db7dade46d9a Mon Sep 17 00:00:00 2001 From: Yuichi Kusakabe Date: Sat, 10 Jun 2017 20:26:26 +0900 Subject: [PATCH] Fix for memory corruption during hibernate Signed-off-by: Yuichi Kusakabe --- 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