Loading drivers/soc/qcom/peripheral-loader.c +12 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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"); Loading drivers/soc/qcom/peripheral-loader.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading drivers/soc/qcom/pil-q6v5-mss.c +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 Loading Loading @@ -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", Loading drivers/soc/qcom/subsystem_restart.c +14 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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), Loading Loading @@ -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; Loading include/soc/qcom/subsystem_restart.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
drivers/soc/qcom/peripheral-loader.c +12 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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"); Loading
drivers/soc/qcom/peripheral-loader.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
drivers/soc/qcom/pil-q6v5-mss.c +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 Loading Loading @@ -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", Loading
drivers/soc/qcom/subsystem_restart.c +14 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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), Loading Loading @@ -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; Loading
include/soc/qcom/subsystem_restart.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading