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

Commit 6022f05f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: pil: Use subsys_set_error to indicate firmware errors"

parents 1661803e a17478be
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ static int proxy_timeout_ms = -1;
module_param(proxy_timeout_ms, int, S_IRUGO | S_IWUSR);

static bool disable_timeouts;
static const char firmware_error_msg[] = "firmware_error\n";
/**
 * struct pil_mdt - Representation of <name>.mdt file in memory
 * @hdr: ELF32 header
@@ -669,12 +670,14 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
		if (ret < 0) {
			pil_err(desc, "Failed to locate blob %s or blob is too big.\n",
				fw_name);
			subsys_set_error(desc->subsys_dev, firmware_error_msg);
			return ret;
		}

		if (ret != seg->filesz) {
			pil_err(desc, "Blob size %u doesn't match %lu\n",
					ret, seg->filesz);
			subsys_set_error(desc->subsys_dev, firmware_error_msg);
			return -EPERM;
		}
		ret = 0;
@@ -703,8 +706,10 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)

	if (desc->ops->verify_blob) {
		ret = desc->ops->verify_blob(desc, seg->paddr, seg->sz);
		if (ret)
		if (ret) {
			pil_err(desc, "Blob%u failed verification\n", num);
			subsys_set_error(desc->subsys_dev, firmware_error_msg);
		}
	}

	return ret;
@@ -785,6 +790,7 @@ int pil_boot(struct pil_desc *desc)

	if (fw->size < sizeof(*ehdr)) {
		pil_err(desc, "Not big enough to be an elf header\n");
		subsys_set_error(desc->subsys_dev, firmware_error_msg);
		ret = -EIO;
		goto release_fw;
	}
@@ -794,18 +800,21 @@ int pil_boot(struct pil_desc *desc)

	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
		pil_err(desc, "Not an elf header\n");
		subsys_set_error(desc->subsys_dev, firmware_error_msg);
		ret = -EIO;
		goto release_fw;
	}

	if (ehdr->e_phnum == 0) {
		pil_err(desc, "No loadable segments\n");
		subsys_set_error(desc->subsys_dev, firmware_error_msg);
		ret = -EIO;
		goto release_fw;
	}
	if (sizeof(struct elf32_phdr) * ehdr->e_phnum +
	    sizeof(struct elf32_hdr) > fw->size) {
		pil_err(desc, "Program headers not within mdt\n");
		subsys_set_error(desc->subsys_dev, firmware_error_msg);
		ret = -EIO;
		goto release_fw;
	}
@@ -825,6 +834,7 @@ int pil_boot(struct pil_desc *desc)
		ret = desc->ops->init_image(desc, fw->data, fw->size);
	if (ret) {
		pil_err(desc, "Invalid firmware metadata\n");
		subsys_set_error(desc->subsys_dev, firmware_error_msg);
		goto err_boot;
	}

@@ -880,6 +890,7 @@ int pil_boot(struct pil_desc *desc)
	ret = desc->ops->auth_and_reset(desc);
	if (ret) {
		pil_err(desc, "Failed to bring out of reset\n");
		subsys_set_error(desc->subsys_dev, firmware_error_msg);
		goto err_auth_and_reset;
	}
	pil_info(desc, "Brought out of reset\n");
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ struct pil_desc {
	const char *name;
	const char *fw_name;
	struct device *dev;
	struct subsys_device *subsys_dev;
	const struct pil_reset_ops *ops;
	struct module *owner;
	unsigned long proxy_timeout;
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -222,6 +222,7 @@ static int pil_subsys_init(struct modem_data *drv,
		goto err_subsys;
	}

	drv->q6->desc.subsys_dev = drv->subsys;
	drv->ramdump_dev = create_ramdump_device("modem", &pdev->dev);
	if (!drv->ramdump_dev) {
		pr_err("%s: Unable to create a modem ramdump device.\n",
+14 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ struct subsys_device {
	struct work_struct work;
	struct wakeup_source ssr_wlock;
	char wlname[64];
	char error_buf[64];
	struct work_struct device_restart_work;
	struct subsys_tracking track;

@@ -351,6 +352,12 @@ static void subsys_set_state(struct subsys_device *subsys,
	spin_unlock_irqrestore(&subsys->track.s_lock, flags);
}

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

/**
 * subsytem_default_online() - Mark a subsystem as online by default
 * @dev: subsystem to mark as online
@@ -369,6 +376,7 @@ static struct device_attribute subsys_attrs[] = {
	__ATTR_RO(name),
	__ATTR_RO(state),
	__ATTR_RO(crash_count),
	__ATTR_RO(error),
	__ATTR(restart_level, 0644, restart_level_show, restart_level_store),
	__ATTR(firmware_name, 0644, firmware_name_show, firmware_name_store),
	__ATTR(system_debug, 0644, system_debug_show, system_debug_store),
@@ -1180,6 +1188,12 @@ bool subsys_get_crash_status(struct subsys_device *dev)
	return dev->crashed;
}

void subsys_set_error(struct subsys_device *dev, const char *error_msg)
{
	snprintf(dev->error_buf, sizeof(dev->error_buf), "%s", error_msg);
	sysfs_notify(&dev->dev.kobj, NULL, "error");
}

static struct subsys_device *desc_to_subsys(struct device *d)
{
	struct subsys_device *device, *subsys_dev = 0;
+1 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ extern void subsys_unregister(struct subsys_device *dev);
extern void subsys_default_online(struct subsys_device *dev);
extern void subsys_set_crash_status(struct subsys_device *dev, bool crashed);
extern bool subsys_get_crash_status(struct subsys_device *dev);
extern void subsys_set_error(struct subsys_device *dev, const char *error_msg);
void notify_proxy_vote(struct device *device);
void notify_proxy_unvote(struct device *device);
void complete_err_ready(struct subsys_device *subsys);