From f145928d496df35fdca86d8af77fe9610fd0055f Mon Sep 17 00:00:00 2001 From: "Anna, Suman" Date: Fri, 12 Aug 2016 18:42:19 -0500 Subject: remoteproc: fix bare unsigned type usage While there is nothing wrong with defining an unsigned integer variable or argument using the bare unsigned type, it is better to use the checkpatch preferred 'unsigned int' type. Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- include/linux/remoteproc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 1c457a8dd5a6..f575f1ba42a1 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -435,7 +435,7 @@ struct rproc { struct idr notifyids; int index; struct work_struct crash_handler; - unsigned crash_cnt; + unsigned int crash_cnt; struct completion crash_comp; bool recovery_disabled; int max_notifyid; -- cgit v1.2.3 From 730f84ce6d59732d070a1dfb0d2591ff110e3e5d Mon Sep 17 00:00:00 2001 From: "Anna, Suman" Date: Fri, 12 Aug 2016 18:42:20 -0500 Subject: remoteproc: align code with open parenthesis This patch fixes the existing alignment checkpatch check warnings of the type "Alignment should match open parenthesis" in the remoteproc core source files. Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 27 +++++++++++++-------------- drivers/remoteproc/remoteproc_debugfs.c | 20 ++++++++++---------- drivers/remoteproc/remoteproc_elf_loader.c | 6 +++--- drivers/remoteproc/remoteproc_internal.h | 15 ++++++++------- drivers/remoteproc/remoteproc_virtio.c | 10 +++++----- include/linux/remoteproc.h | 4 ++-- 6 files changed, 41 insertions(+), 41 deletions(-) (limited to 'include') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 140b580477e3..fb92b8084a4e 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -78,7 +78,7 @@ static const char *rproc_crash_to_string(enum rproc_crash_type type) * will try to access an unmapped device address. */ static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, - unsigned long iova, int flags, void *token) + unsigned long iova, int flags, void *token) { struct rproc *rproc = token; @@ -264,7 +264,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i) struct rproc_vring *rvring = &rvdev->vring[i]; dev_dbg(dev, "vdev rsc: vring%d: da %x, qsz %d, align %d\n", - i, vring->da, vring->num, vring->align); + i, vring->da, vring->num, vring->align); /* make sure reserved bytes are zeroes */ if (vring->reserved) { @@ -275,7 +275,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i) /* verify queue size and vring alignment are sane */ if (!vring->num || !vring->align) { dev_err(dev, "invalid qsz (%d) or alignment (%d)\n", - vring->num, vring->align); + vring->num, vring->align); return -EINVAL; } @@ -330,7 +330,7 @@ void rproc_free_vring(struct rproc_vring *rvring) * Returns 0 on success, or an appropriate error code otherwise */ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, - int offset, int avail) + int offset, int avail) { struct device *dev = &rproc->dev; struct rproc_vdev *rvdev; @@ -407,7 +407,7 @@ free_rvdev: * Returns 0 on success, or an appropriate error code otherwise */ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, - int offset, int avail) + int offset, int avail) { struct rproc_mem_entry *trace; struct device *dev = &rproc->dev; @@ -487,7 +487,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, * are outside those ranges. */ static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc, - int offset, int avail) + int offset, int avail) { struct rproc_mem_entry *mapping; struct device *dev = &rproc->dev; @@ -530,7 +530,7 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc, list_add_tail(&mapping->node, &rproc->mappings); dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n", - rsc->pa, rsc->da, rsc->len); + rsc->pa, rsc->da, rsc->len); return 0; @@ -558,9 +558,8 @@ out: * pressure is important; it may have a substantial impact on performance. */ static int rproc_handle_carveout(struct rproc *rproc, - struct fw_rsc_carveout *rsc, - int offset, int avail) - + struct fw_rsc_carveout *rsc, + int offset, int avail) { struct rproc_mem_entry *carveout, *mapping; struct device *dev = &rproc->dev; @@ -622,7 +621,7 @@ static int rproc_handle_carveout(struct rproc *rproc, } ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len, - rsc->flags); + rsc->flags); if (ret) { dev_err(dev, "iommu_map failed: %d\n", ret); goto free_mapping; @@ -775,7 +774,7 @@ static void rproc_resource_cleanup(struct rproc *rproc) if (unmapped != entry->len) { /* nothing much to do besides complaining */ dev_err(dev, "failed to unmap %u/%zu\n", entry->len, - unmapped); + unmapped); } list_del(&entry->node); @@ -1338,8 +1337,8 @@ static struct device_type rproc_type = { * yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). */ struct rproc *rproc_alloc(struct device *dev, const char *name, - const struct rproc_ops *ops, - const char *firmware, int len) + const struct rproc_ops *ops, + const char *firmware, int len) { struct rproc *rproc; char *p, *template = "rproc-%s-fw"; diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index 74a120b6e206..374797206c79 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c @@ -45,7 +45,7 @@ static struct dentry *rproc_dbg; * as it provides very early tracing with little to no dependencies at all. */ static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { struct rproc_mem_entry *trace = filp->private_data; int len = strnlen(trace->va, trace->len); @@ -73,7 +73,7 @@ static const char * const rproc_state_string[] = { /* expose the state of the remote processor via debugfs */ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { struct rproc *rproc = filp->private_data; unsigned int state; @@ -83,7 +83,7 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf, state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state; i = scnprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state], - rproc->state); + rproc->state); return simple_read_from_buffer(userbuf, count, ppos, buf, i); } @@ -130,7 +130,7 @@ static const struct file_operations rproc_state_ops = { /* expose the name of the remote processor via debugfs */ static ssize_t rproc_name_read(struct file *filp, char __user *userbuf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { struct rproc *rproc = filp->private_data; /* need room for the name, a newline and a terminating null */ @@ -230,12 +230,12 @@ void rproc_remove_trace_file(struct dentry *tfile) } struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, - struct rproc_mem_entry *trace) + struct rproc_mem_entry *trace) { struct dentry *tfile; - tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, - trace, &trace_rproc_ops); + tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, trace, + &trace_rproc_ops); if (!tfile) { dev_err(&rproc->dev, "failed to create debugfs trace entry\n"); return NULL; @@ -264,11 +264,11 @@ void rproc_create_debug_dir(struct rproc *rproc) return; debugfs_create_file("name", 0400, rproc->dbg_dir, - rproc, &rproc_name_ops); + rproc, &rproc_name_ops); debugfs_create_file("state", 0400, rproc->dbg_dir, - rproc, &rproc_state_ops); + rproc, &rproc_state_ops); debugfs_create_file("recovery", 0400, rproc->dbg_dir, - rproc, &rproc_recovery_ops); + rproc, &rproc_recovery_ops); } void __init rproc_init_debugfs(void) diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c index ce283a5b42a1..c523983a4aec 100644 --- a/drivers/remoteproc/remoteproc_elf_loader.c +++ b/drivers/remoteproc/remoteproc_elf_loader.c @@ -166,18 +166,18 @@ rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) continue; dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", - phdr->p_type, da, memsz, filesz); + phdr->p_type, da, memsz, filesz); if (filesz > memsz) { dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", - filesz, memsz); + filesz, memsz); ret = -EINVAL; break; } if (offset + filesz > fw->size) { dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", - offset + filesz, fw->size); + offset + filesz, fw->size); ret = -EINVAL; break; } diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index 57e1de59bec8..4cf93ca2816e 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -36,10 +36,10 @@ struct rproc; */ struct rproc_fw_ops { struct resource_table *(*find_rsc_table)(struct rproc *rproc, - const struct firmware *fw, - int *tablesz); - struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc, - const struct firmware *fw); + const struct firmware *fw, + int *tablesz); + struct resource_table *(*find_loaded_rsc_table)( + struct rproc *rproc, const struct firmware *fw); int (*load)(struct rproc *rproc, const struct firmware *fw); int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); @@ -57,7 +57,7 @@ void rproc_remove_virtio_dev(struct rproc_vdev *rvdev); /* from remoteproc_debugfs.c */ void rproc_remove_trace_file(struct dentry *tfile); struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, - struct rproc_mem_entry *trace); + struct rproc_mem_entry *trace); void rproc_delete_debug_dir(struct rproc *rproc); void rproc_create_debug_dir(struct rproc *rproc); void rproc_init_debugfs(void); @@ -98,7 +98,8 @@ int rproc_load_segments(struct rproc *rproc, const struct firmware *fw) static inline struct resource_table *rproc_find_rsc_table(struct rproc *rproc, - const struct firmware *fw, int *tablesz) + const struct firmware *fw, + int *tablesz) { if (rproc->fw_ops->find_rsc_table) return rproc->fw_ops->find_rsc_table(rproc, fw, tablesz); @@ -108,7 +109,7 @@ struct resource_table *rproc_find_rsc_table(struct rproc *rproc, static inline struct resource_table *rproc_find_loaded_rsc_table(struct rproc *rproc, - const struct firmware *fw) + const struct firmware *fw) { if (rproc->fw_ops->find_loaded_rsc_table) return rproc->fw_ops->find_loaded_rsc_table(rproc, fw); diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 62cffe92e40d..93bf00d9c64e 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -101,14 +101,14 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, memset(addr, 0, size); dev_dbg(dev, "vring%d: va %p qsz %d notifyid %d\n", - id, addr, len, rvring->notifyid); + id, addr, len, rvring->notifyid); /* * Create the new vq, and tell virtio we're not interested in * the 'weak' smp barriers, since we're talking with a real device. */ vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, addr, - rproc_virtio_notify, callback, name); + rproc_virtio_notify, callback, name); if (!vq) { dev_err(dev, "vring_new_virtqueue %s failed\n", name); rproc_free_vring(rvring); @@ -145,9 +145,9 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev) } static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, - struct virtqueue *vqs[], - vq_callback_t *callbacks[], - const char * const names[]) + struct virtqueue *vqs[], + vq_callback_t *callbacks[], + const char * const names[]) { struct rproc *rproc = vdev_to_rproc(vdev); int i, ret; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index f575f1ba42a1..8229523f70a5 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -489,8 +489,8 @@ struct rproc_vdev { struct rproc *rproc_get_by_phandle(phandle phandle); struct rproc *rproc_alloc(struct device *dev, const char *name, - const struct rproc_ops *ops, - const char *firmware, int len); + const struct rproc_ops *ops, + const char *firmware, int len); void rproc_put(struct rproc *rproc); int rproc_add(struct rproc *rproc); int rproc_del(struct rproc *rproc); -- cgit v1.2.3 From 334765f45b4db607768b64f4afe9fccf85bd6c0a Mon Sep 17 00:00:00 2001 From: "Anna, Suman" Date: Fri, 12 Aug 2016 18:42:22 -0500 Subject: remoteproc/omap: fix various code formatting issues This patch fixes some of the existing checkpatch warnings in OMAP remoteproc code. The fixes are to the following warnings: 1. WARNING: missing space after return type 2. WARNING: Unnecessary space after function pointer name 3. CHECK: Alignment should match open parenthesis Signed-off-by: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/remoteproc/omap_remoteproc.c | 2 +- include/linux/platform_data/remoteproc-omap.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index b74368a91235..ddc1a12d75e0 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -196,7 +196,7 @@ static int omap_rproc_probe(struct platform_device *pdev) } rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops, - pdata->firmware, sizeof(*oproc)); + pdata->firmware, sizeof(*oproc)); if (!rproc) return -ENOMEM; diff --git a/include/linux/platform_data/remoteproc-omap.h b/include/linux/platform_data/remoteproc-omap.h index bfbd12b41162..71a1b2399c48 100644 --- a/include/linux/platform_data/remoteproc-omap.h +++ b/include/linux/platform_data/remoteproc-omap.h @@ -39,9 +39,9 @@ struct omap_rproc_pdata { const char *firmware; const char *mbox_name; const struct rproc_ops *ops; - int (*device_enable) (struct platform_device *pdev); - int (*device_shutdown) (struct platform_device *pdev); - void(*set_bootaddr)(u32); + int (*device_enable)(struct platform_device *pdev); + int (*device_shutdown)(struct platform_device *pdev); + void (*set_bootaddr)(u32); }; #if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE) -- cgit v1.2.3 From ddf711872c9d2b05b0fb25db3e6e0c2a50be39e3 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 11 Aug 2016 14:52:50 -0700 Subject: remoteproc: Introduce auto-boot flag Introduce an "auto-boot" flag on rprocs to make it possible to flag remote processors without vdevs to automatically boot once the firmware is found. Preserve previous behavior of the wkup_m3 processor being explicitly booted by a consumer. Cc: Lee Jones Cc: Loic Pallardy Cc: Suman Anna Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 28 +++++++++++++++++++++++++++- drivers/remoteproc/remoteproc_virtio.c | 13 ------------- drivers/remoteproc/wkup_m3_rproc.c | 2 ++ include/linux/remoteproc.h | 1 + 4 files changed, 30 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 0f85f7eb476d..d3b812e85250 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -932,6 +932,10 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context) /* look for virtio devices and register them */ ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler); + /* if rproc is marked always-on, request it to boot */ + if (rproc->auto_boot) + rproc_boot_nowait(rproc); + out: release_firmware(fw); /* allow rproc_del() contexts, if any, to proceed */ @@ -977,11 +981,16 @@ static int rproc_add_virtio_devices(struct rproc *rproc) int rproc_trigger_recovery(struct rproc *rproc) { struct rproc_vdev *rvdev, *rvtmp; + int ret; dev_err(&rproc->dev, "recovering %s\n", rproc->name); init_completion(&rproc->crash_comp); + /* shut down the remote */ + /* TODO: make sure this works with rproc->power > 1 */ + rproc_shutdown(rproc); + /* clean up remote vdev entries */ list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) rproc_remove_virtio_dev(rvdev); @@ -992,7 +1001,18 @@ int rproc_trigger_recovery(struct rproc *rproc) /* Free the copy of the resource table */ kfree(rproc->cached_table); - return rproc_add_virtio_devices(rproc); + ret = rproc_add_virtio_devices(rproc); + if (ret) + return ret; + + /* + * boot the remote processor up again, if the async firmware loader + * didn't do so already, waiting for the async fw load to finish + */ + if (!rproc->auto_boot) + rproc_boot(rproc); + + return 0; } /** @@ -1373,6 +1393,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, rproc->name = name; rproc->ops = ops; rproc->priv = &rproc[1]; + rproc->auto_boot = true; device_initialize(&rproc->dev); rproc->dev.parent = dev; @@ -1451,6 +1472,11 @@ int rproc_del(struct rproc *rproc) /* if rproc is just being registered, wait */ wait_for_completion(&rproc->firmware_loading_complete); + /* if rproc is marked always-on, rproc_add() booted it */ + /* TODO: make sure this works with rproc->power > 1 */ + if (rproc->auto_boot) + rproc_shutdown(rproc); + /* clean up remote vdev entries */ list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) rproc_remove_virtio_dev(rvdev); diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 93bf00d9c64e..01870a16d6d2 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -136,11 +136,6 @@ static void __rproc_virtio_del_vqs(struct virtio_device *vdev) static void rproc_virtio_del_vqs(struct virtio_device *vdev) { - struct rproc *rproc = vdev_to_rproc(vdev); - - /* power down the remote processor before deleting vqs */ - rproc_shutdown(rproc); - __rproc_virtio_del_vqs(vdev); } @@ -149,7 +144,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, vq_callback_t *callbacks[], const char * const names[]) { - struct rproc *rproc = vdev_to_rproc(vdev); int i, ret; for (i = 0; i < nvqs; ++i) { @@ -160,13 +154,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, } } - /* now that the vqs are all set, boot the remote processor */ - ret = rproc_boot_nowait(rproc); - if (ret) { - dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret); - goto error; - } - return 0; error: diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c index 02d271d101b4..3811cb522af3 100644 --- a/drivers/remoteproc/wkup_m3_rproc.c +++ b/drivers/remoteproc/wkup_m3_rproc.c @@ -167,6 +167,8 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev) goto err; } + rproc->auto_boot = false; + wkupm3 = rproc->priv; wkupm3->rproc = rproc; wkupm3->pdev = pdev; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 8229523f70a5..4783c8c4645a 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -443,6 +443,7 @@ struct rproc { struct resource_table *cached_table; u32 table_csum; bool has_iommu; + bool auto_boot; }; /* we currently support only two vrings per rvdev */ -- cgit v1.2.3 From 988d204cdaf604c59316dadb98eba2da2188b762 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 11 Aug 2016 14:52:53 -0700 Subject: remoteproc: Move handling of cached table to boot/shutdown As we moved the vdev handling to the main boot/shutdown code path we can further simplify the resource table handling by moving the parsing spet to boot as well. The lifespan of the resource table is changed to live from rproc_boot() to rproc_shutdown(). Cc: Lee Jones Cc: Loic Pallardy Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 55 ++++++++++++------------------------ include/linux/remoteproc.h | 2 -- 2 files changed, 18 insertions(+), 39 deletions(-) (limited to 'include') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index a83429ccf862..e2c569151fe7 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -801,9 +801,6 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) struct resource_table *table, *loaded_table; int ret, tablesz; - if (!rproc->table_ptr) - return -ENOMEM; - ret = rproc_fw_sanity_check(rproc, fw); if (ret) return ret; @@ -830,11 +827,17 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) goto clean_up; } - /* Verify that resource table in loaded fw is unchanged */ - if (rproc->table_csum != crc32(0, table, tablesz)) { - dev_err(dev, "resource checksum failed, fw changed?\n"); + /* + * Create a copy of the resource table. When a virtio device starts + * and calls vring_new_virtqueue() the address of the allocated vring + * will be stored in the cached_table. Before the device is started, + * cached_table will be copied into device memory. + */ + rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); + if (!rproc->cached_table) goto clean_up; - } + + rproc->table_ptr = rproc->cached_table; /* reset max_notifyid */ rproc->max_notifyid = -1; @@ -892,6 +895,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) return 0; clean_up: + kfree(rproc->cached_table); + rproc->cached_table = NULL; + rproc->table_ptr = NULL; + rproc_resource_cleanup(rproc); rproc_disable_iommu(rproc); return ret; @@ -908,36 +915,11 @@ clean_up: static void rproc_fw_config_virtio(const struct firmware *fw, void *context) { struct rproc *rproc = context; - struct resource_table *table; - int tablesz; - - if (rproc_fw_sanity_check(rproc, fw) < 0) - goto out; - - /* look for the resource table */ - table = rproc_find_rsc_table(rproc, fw, &tablesz); - if (!table) - goto out; - - rproc->table_csum = crc32(0, table, tablesz); - - /* - * Create a copy of the resource table. When a virtio device starts - * and calls vring_new_virtqueue() the address of the allocated vring - * will be stored in the cached_table. Before the device is started, - * cached_table will be copied into device memory. - */ - rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); - if (!rproc->cached_table) - goto out; - - rproc->table_ptr = rproc->cached_table; /* if rproc is marked always-on, request it to boot */ if (rproc->auto_boot) rproc_boot_nowait(rproc); -out: release_firmware(fw); /* allow rproc_del() contexts, if any, to proceed */ complete_all(&rproc->firmware_loading_complete); @@ -1177,8 +1159,10 @@ void rproc_shutdown(struct rproc *rproc) rproc_disable_iommu(rproc); - /* Give the next start a clean resource table */ - rproc->table_ptr = rproc->cached_table; + /* Free the copy of the resource table */ + kfree(rproc->cached_table); + rproc->cached_table = NULL; + rproc->table_ptr = NULL; /* if in crash state, unlock crash handler */ if (rproc->state == RPROC_CRASHED) @@ -1466,9 +1450,6 @@ int rproc_del(struct rproc *rproc) list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) rproc_remove_virtio_dev(rvdev); - /* Free the copy of the resource table */ - kfree(rproc->cached_table); - /* the rproc is downref'ed as soon as it's removed from the klist */ mutex_lock(&rproc_list_mutex); list_del(&rproc->node); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 4783c8c4645a..d488f9e1e08c 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -409,7 +409,6 @@ enum rproc_crash_type { * @max_notifyid: largest allocated notify id. * @table_ptr: pointer to the resource table in effect * @cached_table: copy of the resource table - * @table_csum: checksum of the resource table * @has_iommu: flag to indicate if remote processor is behind an MMU */ struct rproc { @@ -441,7 +440,6 @@ struct rproc { int max_notifyid; struct resource_table *table_ptr; struct resource_table *cached_table; - u32 table_csum; bool has_iommu; bool auto_boot; }; -- cgit v1.2.3 From cd5830512044d301d397d1499738ee00a8836247 Mon Sep 17 00:00:00 2001 From: Loic PALLARDY Date: Tue, 6 Sep 2016 09:39:42 +0200 Subject: remoteproc: Modify FW_RSC_ADDR_ANY definition Replace 0xFFFFFFFFFFFFFFFF by -1 to fit any type. Signed-off-by: Loic Pallardy Signed-off-by: Bjorn Andersson --- include/linux/remoteproc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index d488f9e1e08c..80e1cba78a04 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -118,7 +118,7 @@ enum fw_resource_type { RSC_LAST = 4, }; -#define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF) +#define FW_RSC_ADDR_ANY (-1) /** * struct fw_rsc_carveout - physically contiguous memory request -- cgit v1.2.3 From 21b6657ef4458f90d64b696105e3898257dea221 Mon Sep 17 00:00:00 2001 From: Loic PALLARDY Date: Tue, 6 Sep 2016 09:39:43 +0200 Subject: remoteproc: core: transform struct fw_rsc_vdev_vring reserved field in pa In current implementation, struct fw_rsc_vdev_vring which describes vring resource in firmware resource table owns only device address, because it assumes that host is responsible of vring allocation and only device address is needed by coprocessor. But if vrings need to be fixed in system memory map for any reasons (security, SoC charactieristics...), physical address is needed exatly identified the memory chunck by host. For that let's transform reserved field of struct fw_rsc_vdev_vring to pa (physical address). Signed-off-by: Loic Pallardy Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 6 ------ include/linux/remoteproc.h | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 18f428618cf6..0d3c191b6bc3 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -266,12 +266,6 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i) dev_dbg(dev, "vdev rsc: vring%d: da 0x%x, qsz %d, align %d\n", i, vring->da, vring->num, vring->align); - /* make sure reserved bytes are zeroes */ - if (vring->reserved) { - dev_err(dev, "vring rsc has non zero reserved bytes\n"); - return -EINVAL; - } - /* verify queue size and vring alignment are sane */ if (!vring->num || !vring->align) { dev_err(dev, "invalid qsz (%d) or alignment (%d)\n", diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 80e1cba78a04..c321eab5054e 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -241,7 +241,7 @@ struct fw_rsc_trace { * @notifyid is a unique rproc-wide notify index for this vring. This notify * index is used when kicking a remote processor, to let it know that this * vring is triggered. - * @reserved: reserved (must be zero) + * @pa: physical address * * This descriptor is not a resource entry by itself; it is part of the * vdev resource type (see below). @@ -255,7 +255,7 @@ struct fw_rsc_vdev_vring { u32 align; u32 num; u32 notifyid; - u32 reserved; + u32 pa; } __packed; /** -- cgit v1.2.3 From 433c0e04bc06da6d049c691a9ef238d61edb841c Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sun, 2 Oct 2016 17:46:38 -0700 Subject: remoteproc: Split driver and consumer dereferencing In order to be able to lock a rproc driver implementations only when used by a client, we must differ between the dereference operation of a client and the implementation itself. This patch brings no functional change. Signed-off-by: Bjorn Andersson --- Documentation/remoteproc.txt | 6 +++--- drivers/remoteproc/da8xx_remoteproc.c | 4 ++-- drivers/remoteproc/omap_remoteproc.c | 4 ++-- drivers/remoteproc/qcom_q6v5_pil.c | 4 ++-- drivers/remoteproc/qcom_wcnss.c | 4 ++-- drivers/remoteproc/remoteproc_core.c | 21 ++++++++++++++++++--- drivers/remoteproc/st_remoteproc.c | 4 ++-- drivers/remoteproc/ste_modem_rproc.c | 4 ++-- drivers/remoteproc/wkup_m3_rproc.c | 4 ++-- include/linux/remoteproc.h | 1 + 10 files changed, 36 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt index ef0219fa4bb4..f07597482351 100644 --- a/Documentation/remoteproc.txt +++ b/Documentation/remoteproc.txt @@ -101,9 +101,9 @@ int dummy_rproc_example(struct rproc *my_rproc) On success, the new rproc is returned, and on failure, NULL. Note: _never_ directly deallocate @rproc, even if it was not registered - yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). + yet. Instead, when you need to unroll rproc_alloc(), use rproc_free(). - void rproc_put(struct rproc *rproc) + void rproc_free(struct rproc *rproc) - Free an rproc handle that was allocated by rproc_alloc. This function essentially unrolls rproc_alloc(), by decrementing the rproc's refcount. It doesn't directly free rproc; that would happen @@ -131,7 +131,7 @@ int dummy_rproc_example(struct rproc *my_rproc) has completed successfully. After rproc_del() returns, @rproc is still valid, and its - last refcount should be decremented by calling rproc_put(). + last refcount should be decremented by calling rproc_free(). Returns 0 on success and -EINVAL if @rproc isn't valid. diff --git a/drivers/remoteproc/da8xx_remoteproc.c b/drivers/remoteproc/da8xx_remoteproc.c index 12823d078e1e..1afac8f31be0 100644 --- a/drivers/remoteproc/da8xx_remoteproc.c +++ b/drivers/remoteproc/da8xx_remoteproc.c @@ -261,7 +261,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -290,7 +290,7 @@ static int da8xx_rproc_remove(struct platform_device *pdev) disable_irq(drproc->irq); rproc_del(rproc); - rproc_put(rproc); + rproc_free(rproc); return 0; } diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 01e234cb9157..fa63bf2eb885 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -215,7 +215,7 @@ static int omap_rproc_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -224,7 +224,7 @@ static int omap_rproc_remove(struct platform_device *pdev) struct rproc *rproc = platform_get_drvdata(pdev); rproc_del(rproc); - rproc_put(rproc); + rproc_free(rproc); return 0; } diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c index 05b04573e87d..2e0caaaa766a 100644 --- a/drivers/remoteproc/qcom_q6v5_pil.c +++ b/drivers/remoteproc/qcom_q6v5_pil.c @@ -875,7 +875,7 @@ static int q6v5_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -885,7 +885,7 @@ static int q6v5_remove(struct platform_device *pdev) struct q6v5 *qproc = platform_get_drvdata(pdev); rproc_del(qproc->rproc); - rproc_put(qproc->rproc); + rproc_free(qproc->rproc); return 0; } diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index 1917de7db91c..f5cedeaafba1 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -585,7 +585,7 @@ static int wcnss_probe(struct platform_device *pdev) return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -598,7 +598,7 @@ static int wcnss_remove(struct platform_device *pdev) qcom_smem_state_put(wcnss->state); rproc_del(wcnss->rproc); - rproc_put(wcnss->rproc); + rproc_free(wcnss->rproc); return 0; } diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 3da566b0d437..ede3af14b9d0 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1307,7 +1307,7 @@ static struct device_type rproc_type = { * On success the new rproc is returned, and on failure, NULL. * * Note: _never_ directly deallocate @rproc, even if it was not registered - * yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). + * yet. Instead, when you need to unroll rproc_alloc(), use rproc_free(). */ struct rproc *rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops, @@ -1386,7 +1386,22 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, EXPORT_SYMBOL(rproc_alloc); /** - * rproc_put() - unroll rproc_alloc() + * rproc_free() - unroll rproc_alloc() + * @rproc: the remote processor handle + * + * This function decrements the rproc dev refcount. + * + * If no one holds any reference to rproc anymore, then its refcount would + * now drop to zero, and it would be freed. + */ +void rproc_free(struct rproc *rproc) +{ + put_device(&rproc->dev); +} +EXPORT_SYMBOL(rproc_free); + +/** + * rproc_put() - release rproc reference * @rproc: the remote processor handle * * This function decrements the rproc dev refcount. @@ -1411,7 +1426,7 @@ EXPORT_SYMBOL(rproc_put); * * After rproc_del() returns, @rproc isn't freed yet, because * of the outstanding reference created by rproc_alloc. To decrement that - * one last refcount, one still needs to call rproc_put(). + * one last refcount, one still needs to call rproc_free(). * * Returns 0 on success and -EINVAL if @rproc isn't valid. */ diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c index 6f056caa8a56..ae8963fcc8c8 100644 --- a/drivers/remoteproc/st_remoteproc.c +++ b/drivers/remoteproc/st_remoteproc.c @@ -262,7 +262,7 @@ static int st_rproc_probe(struct platform_device *pdev) return 0; free_rproc: - rproc_put(rproc); + rproc_free(rproc); return ret; } @@ -277,7 +277,7 @@ static int st_rproc_remove(struct platform_device *pdev) of_reserved_mem_device_release(&pdev->dev); - rproc_put(rproc); + rproc_free(rproc); return 0; } diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c index 53dc17bdd54e..03d69a9a3c5b 100644 --- a/drivers/remoteproc/ste_modem_rproc.c +++ b/drivers/remoteproc/ste_modem_rproc.c @@ -257,7 +257,7 @@ static int sproc_drv_remove(struct platform_device *pdev) rproc_del(sproc->rproc); dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE, sproc->fw_addr, sproc->fw_dma_addr); - rproc_put(sproc->rproc); + rproc_free(sproc->rproc); mdev->drv_data = NULL; @@ -325,7 +325,7 @@ free_mem: free_rproc: /* Reset device data upon error */ mdev->drv_data = NULL; - rproc_put(rproc); + rproc_free(rproc); return err; } diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c index 3811cb522af3..18175d0331fd 100644 --- a/drivers/remoteproc/wkup_m3_rproc.c +++ b/drivers/remoteproc/wkup_m3_rproc.c @@ -208,7 +208,7 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev) return 0; err_put_rproc: - rproc_put(rproc); + rproc_free(rproc); err: pm_runtime_put_noidle(dev); pm_runtime_disable(dev); @@ -220,7 +220,7 @@ static int wkup_m3_rproc_remove(struct platform_device *pdev) struct rproc *rproc = platform_get_drvdata(pdev); rproc_del(rproc); - rproc_put(rproc); + rproc_free(rproc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index c321eab5054e..930023b7c825 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -493,6 +493,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, void rproc_put(struct rproc *rproc); int rproc_add(struct rproc *rproc); int rproc_del(struct rproc *rproc); +void rproc_free(struct rproc *rproc); int rproc_boot(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc); -- cgit v1.2.3