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

Commit f4674e29 authored by Deepak Katragadda's avatar Deepak Katragadda
Browse files

qcom: ssr: Allow taking system ramdumps when system_debug is set



Add a new system_debug subsystem property. This is set as
"reset" by default. When this parameter is listed as "set"
for a subsystem and a wdog bite happens, the SSR framework
goes ahead and triggers a kernel panic.
This feature is strictly intented only for debugging cases
where a system ramdump is more desirable than subsystem
ramdumps.

CRs-Fixed: 746414
Change-Id: Ie8f364fe0f9fd8f417f080135ab497e816f7fcf4
Signed-off-by: default avatarDeepak Katragadda <dkatraga@codeaurora.org>
parent e098c293
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -186,7 +186,12 @@ static irqreturn_t modem_wdog_bite_intr_handler(int irq, void *dev_id)
	struct modem_data *drv = subsys_to_drv(dev_id);
	if (drv->ignore_errors)
		return IRQ_HANDLED;

	pr_err("Watchdog bite received from modem software!\n");
	if (drv->subsys_desc.system_debug &&
			!gpio_get_value(drv->subsys_desc.err_fatal_gpio))
		panic("%s: System ramdump requested. Triggering device restart!\n",
							__func__);
	subsys_set_crash_status(drv->subsys, true);
	restart_modem(drv);
	return IRQ_HANDLED;
+5 −0
Original line number Diff line number Diff line
@@ -849,6 +849,11 @@ static irqreturn_t subsys_wdog_bite_irq_handler(int irq, void *dev_id)
							d->subsys_desc.name);
		return IRQ_HANDLED;
	}

	if (d->subsys_desc.system_debug &&
			!gpio_get_value(d->subsys_desc.err_fatal_gpio))
		panic("%s: System ramdump requested. Triggering device restart!\n",
							__func__);
	subsys_set_crash_status(d->subsys, true);
	log_failure_reason(d);
	subsystem_restart_dev(d->subsys);
+33 −0
Original line number Diff line number Diff line
@@ -226,6 +226,38 @@ static ssize_t restart_level_store(struct device *dev,
	return -EPERM;
}

static ssize_t system_debug_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct subsys_device *subsys = to_subsys(dev);
	char p[6] = "set";

	if (!subsys->desc->system_debug)
		strlcpy(p, "reset", sizeof(p));

	return snprintf(buf, PAGE_SIZE, "%s\n", p);
}

static ssize_t system_debug_store(struct device *dev,
				struct device_attribute *attr, const char *buf,
				size_t count)
{
	struct subsys_device *subsys = to_subsys(dev);
	const char *p;

	p = memchr(buf, '\n', count);
	if (p)
		count = p - buf;

	if (!strncasecmp(buf, "set", count))
		subsys->desc->system_debug = true;
	else if (!strncasecmp(buf, "reset", count))
		subsys->desc->system_debug = false;
	else
		return -EPERM;
	return count;
}

int subsys_get_restart_level(struct subsys_device *dev)
{
	return dev->restart_level;
@@ -266,6 +298,7 @@ static struct device_attribute subsys_attrs[] = {
	__ATTR_RO(state),
	__ATTR_RO(crash_count),
	__ATTR(restart_level, 0644, restart_level_show, restart_level_store),
	__ATTR(system_debug, 0644, system_debug_show, system_debug_store),
	__ATTR_NULL,
};

+3 −0
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ struct module;
 * @ssctl_instance_id: Instance id used to connect with SSCTL service
 * @sysmon_pid:	pdev id that sysmon is probed with for the subsystem
 * @sysmon_shutdown_ret: Return value for the call to sysmon_send_shutdown
 * @system_debug: If "set", triggers a device restart when the
 * subsystem's wdog bite handler is invoked.
 */
struct subsys_desc {
	const char *name;
@@ -72,6 +74,7 @@ struct subsys_desc {
	int ssctl_instance_id;
	u32 sysmon_pid;
	int sysmon_shutdown_ret;
	bool system_debug;
};

/**