android_kernel_xiaomi_sm8450/drivers/dma-buf/heaps/qcom_dma_heap.c
Auditya Bhattaram b4e4dd39b6 dma-heaps: Add hibernation callbacks to secure heaps
Add suspend and resume callbacks to all secure heaps. All
hyp-assigned memory which HLOS does not have access cannot
be saved during hibernation, so free all such memory back
to the system from secure pools. Abort hibernation if
clients have not freed such memory by tracking all the
allocations.

Change-Id: I8a3ba617fef5ea3fdbc60a72412af90564d75052
Signed-off-by: Vivek Kumar <quic_vivekuma@quicinc.com>
Signed-off-by: Shreyas K K <quic_shrekk@quicinc.com>
Signed-off-by: Auditya Bhattaram <quic_audityab@quicinc.com>
2024-05-16 01:39:07 -07:00

149 lines
3.6 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/qcom_dma_heap.h>
#include "qcom_cma_heap.h"
#include "qcom_dt_parser.h"
#include "qcom_system_heap.h"
#include "qcom_carveout_heap.h"
#include "qcom_secure_system_heap.h"
#include "qcom_bitstream_contig_heap.h"
static int qcom_dma_heap_probe(struct platform_device *pdev)
{
int ret = 0;
int i;
struct platform_data *heaps;
qcom_system_heap_create("qcom,system", "system", false);
#ifdef CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED
qcom_system_heap_create("qcom,system-uncached", NULL, true);
#endif
qcom_secure_system_heap_create("qcom,secure-pixel", NULL,
QCOM_DMA_HEAP_FLAG_CP_PIXEL);
qcom_secure_system_heap_create("qcom,secure-non-pixel", NULL,
QCOM_DMA_HEAP_FLAG_CP_NON_PIXEL);
heaps = parse_heap_dt(pdev);
if (IS_ERR_OR_NULL(heaps))
return PTR_ERR(heaps);
for (i = 0; i < heaps->nr; i++) {
struct platform_heap *heap_data = &heaps->heaps[i];
switch (heap_data->type) {
case HEAP_TYPE_SECURE_CARVEOUT:
ret = qcom_secure_carveout_heap_create(heap_data);
if (ret < 0)
pr_err("%s: DMA-BUF Heap: Failed to create %s, error is %d\n",
__func__, heap_data->name, ret);
else if (!ret)
pr_info("%s: DMA-BUF Heap: Created %s\n", __func__,
heap_data->name);
break;
case HEAP_TYPE_CARVEOUT:
ret = qcom_carveout_heap_create(heap_data);
if (ret < 0)
pr_err("%s: DMA-BUF Heap: Failed to create %s, error is %d\n",
__func__, heap_data->name, ret);
else if (!ret)
pr_info("%s: DMA-BUF Heap: Created %s\n", __func__,
heap_data->name);
break;
case HEAP_TYPE_CMA:
ret = qcom_add_cma_heap(heap_data);
if (ret < 0)
pr_err("%s: DMA-BUF Heap: Failed to create %s, error is %d\n",
__func__, heap_data->name, ret);
else if (!ret)
pr_info("%s: DMA-BUF Heap: Created %s\n", __func__,
heap_data->name);
break;
default:
pr_err("%s: Unknown heap type %u\n", __func__, heap_data->type);
break;
}
}
qcom_add_bitstream_contig_heap("system-secure");
free_pdata(heaps);
return ret;
}
static int qcom_dma_heaps_freeze(struct device *dev)
{
int ret;
ret = qcom_secure_carveout_freeze();
if (ret) {
pr_err("Failed to freeze secure carveout heap: %d\n", ret);
return ret;
}
ret = qcom_secure_system_freeze();
if (ret) {
pr_err("Failed to freeze secure system heap: %d\n", ret);
goto err;
}
return 0;
err:
ret = qcom_secure_carveout_restore();
if (ret) {
pr_err("Failed to restore secure carveout heap: %d\n", ret);
return ret;
}
return -EBUSY;
}
static int qcom_dma_heaps_restore(struct device *dev)
{
int ret;
ret = qcom_secure_carveout_restore();
if (ret)
pr_err("Failed to restore secure carveout heap: %d\n", ret);
ret = qcom_secure_system_restore();
if (ret)
pr_err("Failed to restore secure system heap: %d\n", ret);
return ret;
}
static const struct dev_pm_ops qcom_dma_heaps_pm_ops = {
.freeze = qcom_dma_heaps_freeze,
.restore = qcom_dma_heaps_restore,
};
static const struct of_device_id qcom_dma_heap_match_table[] = {
{.compatible = "qcom,dma-heaps"},
{},
};
static struct platform_driver qcom_dma_heap_driver = {
.probe = qcom_dma_heap_probe,
.driver = {
.name = "qcom-dma-heap",
.of_match_table = qcom_dma_heap_match_table,
.pm = &qcom_dma_heaps_pm_ops,
},
};
static int __init init_heap_driver(void)
{
return platform_driver_register(&qcom_dma_heap_driver);
}
module_init(init_heap_driver);
MODULE_LICENSE("GPL v2");