android_kernel_xiaomi_sm8350/drivers/soc/qcom/dump_boot_log.c
Vinay Sudra cfae3c5911 soc: qcom: Remove reserved-memory free operation for xbl log dump
Remove reserved-memory free operation perform after successful
copy log into driver buffer which may lead to boot failure.

Change-Id: I8833eb1d2ab0d10c88c6904f55f99cd7ada8ccb5
Signed-off-by: Vinay Sudra <vsudra@codeaurora.org>
2021-03-30 15:41:24 +05:30

126 lines
2.8 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/memblock.h>
#include <linux/of_address.h>
#include <linux/kthread.h>
#include <linux/slab.h>
static char *xbl_log_buf;
size_t xbl_log_size;
static ssize_t xbl_log_show(struct file *fp,
struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t offset, size_t count)
{
if (offset < xbl_log_size)
return scnprintf(buf, count, "%s", xbl_log_buf + offset);
return 0;
}
static struct bin_attribute attribute =
__BIN_ATTR(xbl_log, 0444, xbl_log_show, NULL, 0);
static int xbl_log_kthread(void *arg)
{
int err = 1;
struct module_kobject *mkobj;
struct device_node *parent = NULL, *node = NULL;
struct resource res_log = {0,};
phys_addr_t xbl_log_paddr = 0;
void *addr = NULL;
mkobj = kcalloc(1, sizeof(*mkobj), GFP_KERNEL);
if (!mkobj)
return 1;
mkobj->mod = THIS_MODULE;
mkobj->kobj.kset = module_kset;
err = kobject_init_and_add(&mkobj->kobj, &module_ktype, NULL, "xbl_log");
if (err) {
pr_err("xbl_log: cannot create kobject\n");
goto kobj_fail;
}
kobject_get(&mkobj->kobj);
if (IS_ERR_OR_NULL(&mkobj->kobj)) {
err = PTR_ERR(&mkobj->kobj);
goto kobj_fail;
}
err = sysfs_create_bin_file(&mkobj->kobj, &attribute);
if (err) {
pr_err("xbl_log: sysfs entry creation failed\n");
goto kobj_fail;
}
parent = of_find_node_by_path("/reserved-memory");
if (!parent) {
pr_err("xbl_log: reserved-memory node missing\n");
goto kobj_fail;
}
node = of_find_node_by_name(parent, "uefi_log");
if (!node) {
pr_err("xbl_log: uefi_log node missing\n");
goto node_fail;
}
if (of_address_to_resource(node, 0, &res_log))
goto node_fail;
xbl_log_paddr = res_log.start;
xbl_log_size = resource_size(&res_log) - 1;
pr_debug("xbl_log_addr = %x, size=%d\n", xbl_log_paddr, xbl_log_size);
addr = memremap(xbl_log_paddr, xbl_log_size, MEMREMAP_WB);
if (!addr) {
pr_err("xbl_log: memremap failed\n");
goto remap_fail;
}
xbl_log_buf = kzalloc(xbl_log_size, GFP_KERNEL);
if (xbl_log_buf) {
memcpy(xbl_log_buf, addr, xbl_log_size);
xbl_log_buf[xbl_log_size-1] = '\0';
memunmap(addr);
return 0;
}
kfree(xbl_log_buf);
remap_fail:
if (node)
of_node_put(node);
node_fail:
if (parent)
of_node_put(parent);
kobj_fail:
kobject_del(&mkobj->kobj);
kfree(mkobj);
return 1;
}
static int __init dump_boot_log_init(void)
{
struct task_struct *xbl_log_task =
kthread_run(xbl_log_kthread, NULL, "xbl_log");
if (PTR_ERR_OR_ZERO(xbl_log_task))
return PTR_ERR(xbl_log_task);
else
return 0;
}
subsys_initcall(dump_boot_log_init);
MODULE_DESCRIPTION("dump xbl log");
MODULE_LICENSE("GPL v2");