Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 997e6185 authored by Naveen Krishna's avatar Naveen Krishna Committed by Harshit Agarwal
Browse files

Add subsystem crash reason record and notify it by uevent

Change-Id: I366e4336b76727718a09c58ce9b81827fed80933
parent 37dfcbf1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -821,6 +821,7 @@ static void log_failure_reason(const struct pil_tz_data *d)
						__builtin_return_address(0));
	save_dump_reason_to_smem(reason, function_name);
	pr_err("%s subsystem failure reason: %s.\n", name, reason);
	subsys_store_crash_reason(d->subsys, reason);
}

static int subsys_shutdown(const struct subsys_desc *subsys, bool force_stop)
+43 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ struct subsys_device {
	int id;
	int restart_level;
	int crash_count;
	char crash_reason[256];
	struct subsys_soc_restart_order *restart_order;
	bool do_ramdump_on_put;
	struct cdev char_dev;
@@ -254,6 +255,13 @@ static ssize_t crash_count_show(struct device *dev,
}
static DEVICE_ATTR_RO(crash_count);

static ssize_t crash_reason_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%s\n", to_subsys(dev)->crash_reason);
}
static DEVICE_ATTR_RO(crash_reason);

static ssize_t
restart_level_show(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -380,10 +388,44 @@ void subsys_default_online(struct subsys_device *dev)
}
EXPORT_SYMBOL(subsys_default_online);

static void subsys_send_uevent_notify(struct subsys_desc *desc,	int crash_count)
{
	char *envp[4];
	struct subsys_device *dev;

	if (!desc)
		return;

	dev = find_subsys_device(desc->name);
		if (!dev)
			return;

	envp[0] = kasprintf(GFP_KERNEL, "SUBSYSTEM=%s", desc->name);
	envp[1] = kasprintf(GFP_KERNEL, "CRASHCOUNT=%d", crash_count);
	envp[2] = kasprintf(GFP_KERNEL, "CRASHREASON=%s", dev->crash_reason);
	envp[3] = NULL;
	kobject_uevent_env(&desc->dev->kobj, KOBJ_CHANGE, envp);
	pr_err("%s %s %s\n", envp[0], envp[1], envp[2]);
	kfree(envp[2]);
	kfree(envp[1]);
	kfree(envp[0]);
}

void subsys_store_crash_reason(struct subsys_device *dev, char *reason)
{
	if (dev == NULL)
		return;

	if (reason != NULL)
		strlcpy(dev->crash_reason, reason, sizeof(dev->crash_reason));
}
EXPORT_SYMBOL(subsys_store_crash_reason);

static struct attribute *subsys_attrs[] = {
	&dev_attr_name.attr,
	&dev_attr_state.attr,
	&dev_attr_crash_count.attr,
	&dev_attr_crash_reason.attr,
	&dev_attr_restart_level.attr,
	&dev_attr_firmware_name.attr,
	&dev_attr_system_debug.attr,
@@ -749,6 +791,7 @@ static int subsystem_shutdown(struct subsys_device *dev, void *data)
	subsys_set_state(dev, SUBSYS_OFFLINE);
	disable_all_irqs(dev);

	subsys_send_uevent_notify(dev->desc, dev->crash_count);
	return 0;
}

+4 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ struct notif_data {

extern int subsys_get_restart_level(struct subsys_device *dev);
extern int subsystem_restart_dev(struct subsys_device *dev);
extern void subsys_store_crash_reason(struct subsys_device *dev, char *reason);
extern int subsystem_restart(const char *name);
extern int subsystem_crashed(const char *name);

@@ -180,6 +181,9 @@ static inline int subsystem_restart_dev(struct subsys_device *dev)
	return 0;
}

static inline void subsys_store_crash_reason(struct subsys_device *dev,
					     char *reason) { }

static inline int subsystem_restart(const char *name)
{
	return 0;