Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'rproc-v4.9' of git://github.com/andersson/remoteproc

Pull remoteproc updates from Bjorn Andersson:
"In addition to a slew of minor fixes and cleanups these patches
refactor how we deal with remoteprocs that will be auto-booting
themselves.

That does clean up the remote resource handling but makes for
additional work to clarify responsibilities and life cycles of
resources. We also revise how module locking of remoteproc drivers
work, so that they are locked as we hand out references to them to
third parties, rather than only when booted by anyone.

In addition to that we also introduce the Qualcomm Wireless Subsystem
remoteproc driver"

* tag 'rproc-v4.9' of git://github.com/andersson/remoteproc: (26 commits)
remoteproc: Refactor rproc module locking
remoteproc: Split driver and consumer dereferencing
remoteproc: Correct resource handling upon boot failure
remoteproc: Drop unnecessary NULL check
remoteproc: core: transform struct fw_rsc_vdev_vring reserved field in pa
remoteproc: Modify FW_RSC_ADDR_ANY definition
remoteproc: qcom: wcnss: Fix return value check in wcnss_probe()
remoteproc: qcom: Introduce WCNSS peripheral image loader
dt-binding: remoteproc: Introduce Qualcomm WCNSS loader binding
remoteproc: Only update table_ptr if we have a loaded table
remoteproc: Move handling of cached table to boot/shutdown
remoteproc: Move vdev handling to boot/shutdown
remoteproc: Calculate max_notifyid during load
remoteproc: Introduce auto-boot flag
remoteproc/omap: revise a minor error trace message
remoteproc/omap: fix various code formatting issues
remoteproc: print hex numbers with a leading 0x format
remoteproc: align code with open parenthesis
remoteproc: fix bare unsigned type usage
remoteproc: use variable names for sizeof() operator
...

+1168 -205
+132
Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt
··· 1 + Qualcomm WCNSS Peripheral Image Loader 2 + 3 + This document defines the binding for a component that loads and boots firmware 4 + on the Qualcomm WCNSS core. 5 + 6 + - compatible: 7 + Usage: required 8 + Value type: <string> 9 + Definition: must be one of: 10 + "qcom,riva-pil", 11 + "qcom,pronto-v1-pil", 12 + "qcom,pronto-v2-pil" 13 + 14 + - reg: 15 + Usage: required 16 + Value type: <prop-encoded-array> 17 + Definition: must specify the base address and size of the CCU, DXE and 18 + PMU register blocks 19 + 20 + - reg-names: 21 + Usage: required 22 + Value type: <stringlist> 23 + Definition: must be "ccu", "dxe", "pmu" 24 + 25 + - interrupts-extended: 26 + Usage: required 27 + Value type: <prop-encoded-array> 28 + Definition: must list the watchdog and fatal IRQs and may specify the 29 + ready, handover and stop-ack IRQs 30 + 31 + - interrupt-names: 32 + Usage: required 33 + Value type: <stringlist> 34 + Definition: should be "wdog", "fatal", optionally followed by "ready", 35 + "handover", "stop-ack" 36 + 37 + - vddmx-supply: 38 + - vddcx-supply: 39 + - vddpx-supply: 40 + Usage: required 41 + Value type: <phandle> 42 + Definition: reference to the regulators to be held on behalf of the 43 + booting of the WCNSS core 44 + 45 + - qcom,smem-states: 46 + Usage: optional 47 + Value type: <prop-encoded-array> 48 + Definition: reference to the SMEM state used to indicate to WCNSS that 49 + it should shut down 50 + 51 + - qcom,smem-state-names: 52 + Usage: optional 53 + Value type: <stringlist> 54 + Definition: should be "stop" 55 + 56 + - memory-region: 57 + Usage: required 58 + Value type: <prop-encoded-array> 59 + Definition: reference to reserved-memory node for the remote processor 60 + see ../reserved-memory/reserved-memory.txt 61 + 62 + = SUBNODES 63 + A single subnode of the WCNSS PIL describes the attached rf module and its 64 + resource dependencies. 65 + 66 + - compatible: 67 + Usage: required 68 + Value type: <string> 69 + Definition: must be one of: 70 + "qcom,wcn3620", 71 + "qcom,wcn3660", 72 + "qcom,wcn3680" 73 + 74 + - clocks: 75 + Usage: required 76 + Value type: <prop-encoded-array> 77 + Definition: should specify the xo clock and optionally the rf clock 78 + 79 + - clock-names: 80 + Usage: required 81 + Value type: <stringlist> 82 + Definition: should be "xo", optionally followed by "rf" 83 + 84 + - vddxo-supply: 85 + - vddrfa-supply: 86 + - vddpa-supply: 87 + - vdddig-supply: 88 + Usage: required 89 + Value type: <phandle> 90 + Definition: reference to the regulators to be held on behalf of the 91 + booting of the WCNSS core 92 + 93 + = EXAMPLE 94 + The following example describes the resources needed to boot control the WCNSS, 95 + with attached WCN3680, as it is commonly found on MSM8974 boards. 96 + 97 + pronto@fb204000 { 98 + compatible = "qcom,pronto-v2-pil"; 99 + reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>; 100 + reg-names = "ccu", "dxe", "pmu"; 101 + 102 + interrupts-extended = <&intc 0 149 1>, 103 + <&wcnss_smp2p_slave 0 0>, 104 + <&wcnss_smp2p_slave 1 0>, 105 + <&wcnss_smp2p_slave 2 0>, 106 + <&wcnss_smp2p_slave 3 0>; 107 + interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; 108 + 109 + vddmx-supply = <&pm8841_s1>; 110 + vddcx-supply = <&pm8841_s2>; 111 + vddpx-supply = <&pm8941_s3>; 112 + 113 + qcom,smem-states = <&wcnss_smp2p_out 0>; 114 + qcom,smem-state-names = "stop"; 115 + 116 + memory-region = <&wcnss_region>; 117 + 118 + pinctrl-names = "default"; 119 + pinctrl-0 = <&wcnss_pin_a>; 120 + 121 + iris { 122 + compatible = "qcom,wcn3680"; 123 + 124 + clocks = <&rpmcc RPM_CXO_CLK_SRC>, <&rpmcc RPM_CXO_A2>; 125 + clock-names = "xo", "rf"; 126 + 127 + vddxo-supply = <&pm8941_l6>; 128 + vddrfa-supply = <&pm8941_l11>; 129 + vddpa-supply = <&pm8941_l19>; 130 + vdddig-supply = <&pm8941_s3>; 131 + }; 132 + };
+3 -3
Documentation/remoteproc.txt
··· 101 101 On success, the new rproc is returned, and on failure, NULL. 102 102 103 103 Note: _never_ directly deallocate @rproc, even if it was not registered 104 - yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). 104 + yet. Instead, when you need to unroll rproc_alloc(), use rproc_free(). 105 105 106 - void rproc_put(struct rproc *rproc) 106 + void rproc_free(struct rproc *rproc) 107 107 - Free an rproc handle that was allocated by rproc_alloc. 108 108 This function essentially unrolls rproc_alloc(), by decrementing the 109 109 rproc's refcount. It doesn't directly free rproc; that would happen ··· 131 131 has completed successfully. 132 132 133 133 After rproc_del() returns, @rproc is still valid, and its 134 - last refcount should be decremented by calling rproc_put(). 134 + last refcount should be decremented by calling rproc_free(). 135 135 136 136 Returns 0 on success and -EINVAL if @rproc isn't valid. 137 137
+16
drivers/remoteproc/Kconfig
··· 91 91 Say y here to support the Qualcomm Peripherial Image Loader for the 92 92 Hexagon V5 based remote processors. 93 93 94 + config QCOM_WCNSS_IRIS 95 + tristate 96 + depends on OF && ARCH_QCOM 97 + 98 + config QCOM_WCNSS_PIL 99 + tristate "Qualcomm WCNSS Peripheral Image Loader" 100 + depends on OF && ARCH_QCOM 101 + depends on QCOM_SMEM 102 + select QCOM_MDT_LOADER 103 + select QCOM_SCM 104 + select QCOM_WCNSS_IRIS 105 + select REMOTEPROC 106 + help 107 + Say y here to support the Peripheral Image Loader for the Qualcomm 108 + Wireless Connectivity Subsystem. 109 + 94 110 config ST_REMOTEPROC 95 111 tristate "ST remoteproc support" 96 112 depends on ARCH_STI
+2
drivers/remoteproc/Makefile
··· 13 13 obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o 14 14 obj-$(CONFIG_QCOM_MDT_LOADER) += qcom_mdt_loader.o 15 15 obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o 16 + obj-$(CONFIG_QCOM_WCNSS_IRIS) += qcom_wcnss_iris.o 17 + obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss.o 16 18 obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o
+3 -3
drivers/remoteproc/da8xx_remoteproc.c
··· 147 147 { 148 148 struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv; 149 149 150 - /* Interupt remote proc */ 150 + /* Interrupt remote proc */ 151 151 writel(SYSCFG_CHIPSIG2, drproc->chipsig); 152 152 } 153 153 ··· 261 261 return 0; 262 262 263 263 free_rproc: 264 - rproc_put(rproc); 264 + rproc_free(rproc); 265 265 266 266 return ret; 267 267 } ··· 290 290 disable_irq(drproc->irq); 291 291 292 292 rproc_del(rproc); 293 - rproc_put(rproc); 293 + rproc_free(rproc); 294 294 295 295 return 0; 296 296 }
+5 -4
drivers/remoteproc/omap_remoteproc.c
··· 96 96 /* send the index of the triggered virtqueue in the mailbox payload */ 97 97 ret = mbox_send_message(oproc->mbox, (void *)vqid); 98 98 if (ret < 0) 99 - dev_err(dev, "omap_mbox_msg_send failed: %d\n", ret); 99 + dev_err(dev, "failed to send mailbox message, status = %d\n", 100 + ret); 100 101 } 101 102 102 103 /* ··· 197 196 } 198 197 199 198 rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops, 200 - pdata->firmware, sizeof(*oproc)); 199 + pdata->firmware, sizeof(*oproc)); 201 200 if (!rproc) 202 201 return -ENOMEM; 203 202 ··· 215 214 return 0; 216 215 217 216 free_rproc: 218 - rproc_put(rproc); 217 + rproc_free(rproc); 219 218 return ret; 220 219 } 221 220 ··· 224 223 struct rproc *rproc = platform_get_drvdata(pdev); 225 224 226 225 rproc_del(rproc); 227 - rproc_put(rproc); 226 + rproc_free(rproc); 228 227 229 228 return 0; 230 229 }
+5 -3
drivers/remoteproc/qcom_q6v5_pil.c
··· 863 863 goto free_rproc; 864 864 865 865 qproc->state = qcom_smem_state_get(&pdev->dev, "stop", &qproc->stop_bit); 866 - if (IS_ERR(qproc->state)) 866 + if (IS_ERR(qproc->state)) { 867 + ret = PTR_ERR(qproc->state); 867 868 goto free_rproc; 869 + } 868 870 869 871 ret = rproc_add(rproc); 870 872 if (ret) ··· 875 873 return 0; 876 874 877 875 free_rproc: 878 - rproc_put(rproc); 876 + rproc_free(rproc); 879 877 880 878 return ret; 881 879 } ··· 885 883 struct q6v5 *qproc = platform_get_drvdata(pdev); 886 884 887 885 rproc_del(qproc->rproc); 888 - rproc_put(qproc->rproc); 886 + rproc_free(qproc->rproc); 889 887 890 888 return 0; 891 889 }
+624
drivers/remoteproc/qcom_wcnss.c
··· 1 + /* 2 + * Qualcomm Wireless Connectivity Subsystem Peripheral Image Loader 3 + * 4 + * Copyright (C) 2016 Linaro Ltd 5 + * Copyright (C) 2014 Sony Mobile Communications AB 6 + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/clk.h> 19 + #include <linux/delay.h> 20 + #include <linux/firmware.h> 21 + #include <linux/interrupt.h> 22 + #include <linux/kernel.h> 23 + #include <linux/module.h> 24 + #include <linux/io.h> 25 + #include <linux/of_address.h> 26 + #include <linux/of_device.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/qcom_scm.h> 29 + #include <linux/regulator/consumer.h> 30 + #include <linux/remoteproc.h> 31 + #include <linux/soc/qcom/smem.h> 32 + #include <linux/soc/qcom/smem_state.h> 33 + 34 + #include "qcom_mdt_loader.h" 35 + #include "remoteproc_internal.h" 36 + #include "qcom_wcnss.h" 37 + 38 + #define WCNSS_CRASH_REASON_SMEM 422 39 + #define WCNSS_FIRMWARE_NAME "wcnss.mdt" 40 + #define WCNSS_PAS_ID 6 41 + 42 + #define WCNSS_SPARE_NVBIN_DLND BIT(25) 43 + 44 + #define WCNSS_PMU_IRIS_XO_CFG BIT(3) 45 + #define WCNSS_PMU_IRIS_XO_EN BIT(4) 46 + #define WCNSS_PMU_GC_BUS_MUX_SEL_TOP BIT(5) 47 + #define WCNSS_PMU_IRIS_XO_CFG_STS BIT(6) /* 1: in progress, 0: done */ 48 + 49 + #define WCNSS_PMU_IRIS_RESET BIT(7) 50 + #define WCNSS_PMU_IRIS_RESET_STS BIT(8) /* 1: in progress, 0: done */ 51 + #define WCNSS_PMU_IRIS_XO_READ BIT(9) 52 + #define WCNSS_PMU_IRIS_XO_READ_STS BIT(10) 53 + 54 + #define WCNSS_PMU_XO_MODE_MASK GENMASK(2, 1) 55 + #define WCNSS_PMU_XO_MODE_19p2 0 56 + #define WCNSS_PMU_XO_MODE_48 3 57 + 58 + struct wcnss_data { 59 + size_t pmu_offset; 60 + size_t spare_offset; 61 + 62 + const struct wcnss_vreg_info *vregs; 63 + size_t num_vregs; 64 + }; 65 + 66 + struct qcom_wcnss { 67 + struct device *dev; 68 + struct rproc *rproc; 69 + 70 + void __iomem *pmu_cfg; 71 + void __iomem *spare_out; 72 + 73 + bool use_48mhz_xo; 74 + 75 + int wdog_irq; 76 + int fatal_irq; 77 + int ready_irq; 78 + int handover_irq; 79 + int stop_ack_irq; 80 + 81 + struct qcom_smem_state *state; 82 + unsigned stop_bit; 83 + 84 + struct mutex iris_lock; 85 + struct qcom_iris *iris; 86 + 87 + struct regulator_bulk_data *vregs; 88 + size_t num_vregs; 89 + 90 + struct completion start_done; 91 + struct completion stop_done; 92 + 93 + phys_addr_t mem_phys; 94 + phys_addr_t mem_reloc; 95 + void *mem_region; 96 + size_t mem_size; 97 + }; 98 + 99 + static const struct wcnss_data riva_data = { 100 + .pmu_offset = 0x28, 101 + .spare_offset = 0xb4, 102 + 103 + .vregs = (struct wcnss_vreg_info[]) { 104 + { "vddmx", 1050000, 1150000, 0 }, 105 + { "vddcx", 1050000, 1150000, 0 }, 106 + { "vddpx", 1800000, 1800000, 0 }, 107 + }, 108 + .num_vregs = 3, 109 + }; 110 + 111 + static const struct wcnss_data pronto_v1_data = { 112 + .pmu_offset = 0x1004, 113 + .spare_offset = 0x1088, 114 + 115 + .vregs = (struct wcnss_vreg_info[]) { 116 + { "vddmx", 950000, 1150000, 0 }, 117 + { "vddcx", .super_turbo = true}, 118 + { "vddpx", 1800000, 1800000, 0 }, 119 + }, 120 + .num_vregs = 3, 121 + }; 122 + 123 + static const struct wcnss_data pronto_v2_data = { 124 + .pmu_offset = 0x1004, 125 + .spare_offset = 0x1088, 126 + 127 + .vregs = (struct wcnss_vreg_info[]) { 128 + { "vddmx", 1287500, 1287500, 0 }, 129 + { "vddcx", .super_turbo = true }, 130 + { "vddpx", 1800000, 1800000, 0 }, 131 + }, 132 + .num_vregs = 3, 133 + }; 134 + 135 + void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, 136 + struct qcom_iris *iris, 137 + bool use_48mhz_xo) 138 + { 139 + mutex_lock(&wcnss->iris_lock); 140 + 141 + wcnss->iris = iris; 142 + wcnss->use_48mhz_xo = use_48mhz_xo; 143 + 144 + mutex_unlock(&wcnss->iris_lock); 145 + } 146 + EXPORT_SYMBOL_GPL(qcom_wcnss_assign_iris); 147 + 148 + static int wcnss_load(struct rproc *rproc, const struct firmware *fw) 149 + { 150 + struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; 151 + phys_addr_t fw_addr; 152 + size_t fw_size; 153 + bool relocate; 154 + int ret; 155 + 156 + ret = qcom_scm_pas_init_image(WCNSS_PAS_ID, fw->data, fw->size); 157 + if (ret) { 158 + dev_err(&rproc->dev, "invalid firmware metadata\n"); 159 + return ret; 160 + } 161 + 162 + ret = qcom_mdt_parse(fw, &fw_addr, &fw_size, &relocate); 163 + if (ret) { 164 + dev_err(&rproc->dev, "failed to parse mdt header\n"); 165 + return ret; 166 + } 167 + 168 + if (relocate) { 169 + wcnss->mem_reloc = fw_addr; 170 + 171 + ret = qcom_scm_pas_mem_setup(WCNSS_PAS_ID, wcnss->mem_phys, fw_size); 172 + if (ret) { 173 + dev_err(&rproc->dev, "unable to setup memory for image\n"); 174 + return ret; 175 + } 176 + } 177 + 178 + return qcom_mdt_load(rproc, fw, rproc->firmware); 179 + } 180 + 181 + static const struct rproc_fw_ops wcnss_fw_ops = { 182 + .find_rsc_table = qcom_mdt_find_rsc_table, 183 + .load = wcnss_load, 184 + }; 185 + 186 + static void wcnss_indicate_nv_download(struct qcom_wcnss *wcnss) 187 + { 188 + u32 val; 189 + 190 + /* Indicate NV download capability */ 191 + val = readl(wcnss->spare_out); 192 + val |= WCNSS_SPARE_NVBIN_DLND; 193 + writel(val, wcnss->spare_out); 194 + } 195 + 196 + static void wcnss_configure_iris(struct qcom_wcnss *wcnss) 197 + { 198 + u32 val; 199 + 200 + /* Clear PMU cfg register */ 201 + writel(0, wcnss->pmu_cfg); 202 + 203 + val = WCNSS_PMU_GC_BUS_MUX_SEL_TOP | WCNSS_PMU_IRIS_XO_EN; 204 + writel(val, wcnss->pmu_cfg); 205 + 206 + /* Clear XO_MODE */ 207 + val &= ~WCNSS_PMU_XO_MODE_MASK; 208 + if (wcnss->use_48mhz_xo) 209 + val |= WCNSS_PMU_XO_MODE_48 << 1; 210 + else 211 + val |= WCNSS_PMU_XO_MODE_19p2 << 1; 212 + writel(val, wcnss->pmu_cfg); 213 + 214 + /* Reset IRIS */ 215 + val |= WCNSS_PMU_IRIS_RESET; 216 + writel(val, wcnss->pmu_cfg); 217 + 218 + /* Wait for PMU.iris_reg_reset_sts */ 219 + while (readl(wcnss->pmu_cfg) & WCNSS_PMU_IRIS_RESET_STS) 220 + cpu_relax(); 221 + 222 + /* Clear IRIS reset */ 223 + val &= ~WCNSS_PMU_IRIS_RESET; 224 + writel(val, wcnss->pmu_cfg); 225 + 226 + /* Start IRIS XO configuration */ 227 + val |= WCNSS_PMU_IRIS_XO_CFG; 228 + writel(val, wcnss->pmu_cfg); 229 + 230 + /* Wait for XO configuration to finish */ 231 + while (readl(wcnss->pmu_cfg) & WCNSS_PMU_IRIS_XO_CFG_STS) 232 + cpu_relax(); 233 + 234 + /* Stop IRIS XO configuration */ 235 + val &= ~WCNSS_PMU_GC_BUS_MUX_SEL_TOP; 236 + val &= ~WCNSS_PMU_IRIS_XO_CFG; 237 + writel(val, wcnss->pmu_cfg); 238 + 239 + /* Add some delay for XO to settle */ 240 + msleep(20); 241 + } 242 + 243 + static int wcnss_start(struct rproc *rproc) 244 + { 245 + struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; 246 + int ret; 247 + 248 + mutex_lock(&wcnss->iris_lock); 249 + if (!wcnss->iris) { 250 + dev_err(wcnss->dev, "no iris registered\n"); 251 + ret = -EINVAL; 252 + goto release_iris_lock; 253 + } 254 + 255 + ret = regulator_bulk_enable(wcnss->num_vregs, wcnss->vregs); 256 + if (ret) 257 + goto release_iris_lock; 258 + 259 + ret = qcom_iris_enable(wcnss->iris); 260 + if (ret) 261 + goto disable_regulators; 262 + 263 + wcnss_indicate_nv_download(wcnss); 264 + wcnss_configure_iris(wcnss); 265 + 266 + ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID); 267 + if (ret) { 268 + dev_err(wcnss->dev, 269 + "failed to authenticate image and release reset\n"); 270 + goto disable_iris; 271 + } 272 + 273 + ret = wait_for_completion_timeout(&wcnss->start_done, 274 + msecs_to_jiffies(5000)); 275 + if (wcnss->ready_irq > 0 && ret == 0) { 276 + /* We have a ready_irq, but it didn't fire in time. */ 277 + dev_err(wcnss->dev, "start timed out\n"); 278 + qcom_scm_pas_shutdown(WCNSS_PAS_ID); 279 + ret = -ETIMEDOUT; 280 + goto disable_iris; 281 + } 282 + 283 + ret = 0; 284 + 285 + disable_iris: 286 + qcom_iris_disable(wcnss->iris); 287 + disable_regulators: 288 + regulator_bulk_disable(wcnss->num_vregs, wcnss->vregs); 289 + release_iris_lock: 290 + mutex_unlock(&wcnss->iris_lock); 291 + 292 + return ret; 293 + } 294 + 295 + static int wcnss_stop(struct rproc *rproc) 296 + { 297 + struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; 298 + int ret; 299 + 300 + if (wcnss->state) { 301 + qcom_smem_state_update_bits(wcnss->state, 302 + BIT(wcnss->stop_bit), 303 + BIT(wcnss->stop_bit)); 304 + 305 + ret = wait_for_completion_timeout(&wcnss->stop_done, 306 + msecs_to_jiffies(5000)); 307 + if (ret == 0) 308 + dev_err(wcnss->dev, "timed out on wait\n"); 309 + 310 + qcom_smem_state_update_bits(wcnss->state, 311 + BIT(wcnss->stop_bit), 312 + 0); 313 + } 314 + 315 + ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID); 316 + if (ret) 317 + dev_err(wcnss->dev, "failed to shutdown: %d\n", ret); 318 + 319 + return ret; 320 + } 321 + 322 + static void *wcnss_da_to_va(struct rproc *rproc, u64 da, int len) 323 + { 324 + struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; 325 + int offset; 326 + 327 + offset = da - wcnss->mem_reloc; 328 + if (offset < 0 || offset + len > wcnss->mem_size) 329 + return NULL; 330 + 331 + return wcnss->mem_region + offset; 332 + } 333 + 334 + static const struct rproc_ops wcnss_ops = { 335 + .start = wcnss_start, 336 + .stop = wcnss_stop, 337 + .da_to_va = wcnss_da_to_va, 338 + }; 339 + 340 + static irqreturn_t wcnss_wdog_interrupt(int irq, void *dev) 341 + { 342 + struct qcom_wcnss *wcnss = dev; 343 + 344 + rproc_report_crash(wcnss->rproc, RPROC_WATCHDOG); 345 + 346 + return IRQ_HANDLED; 347 + } 348 + 349 + static irqreturn_t wcnss_fatal_interrupt(int irq, void *dev) 350 + { 351 + struct qcom_wcnss *wcnss = dev; 352 + size_t len; 353 + char *msg; 354 + 355 + msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, WCNSS_CRASH_REASON_SMEM, &len); 356 + if (!IS_ERR(msg) && len > 0 && msg[0]) 357 + dev_err(wcnss->dev, "fatal error received: %s\n", msg); 358 + 359 + rproc_report_crash(wcnss->rproc, RPROC_FATAL_ERROR); 360 + 361 + if (!IS_ERR(msg)) 362 + msg[0] = '\0'; 363 + 364 + return IRQ_HANDLED; 365 + } 366 + 367 + static irqreturn_t wcnss_ready_interrupt(int irq, void *dev) 368 + { 369 + struct qcom_wcnss *wcnss = dev; 370 + 371 + complete(&wcnss->start_done); 372 + 373 + return IRQ_HANDLED; 374 + } 375 + 376 + static irqreturn_t wcnss_handover_interrupt(int irq, void *dev) 377 + { 378 + /* 379 + * XXX: At this point we're supposed to release the resources that we 380 + * have been holding on behalf of the WCNSS. Unfortunately this 381 + * interrupt comes way before the other side seems to be done. 382 + * 383 + * So we're currently relying on the ready interrupt firing later then 384 + * this and we just disable the resources at the end of wcnss_start(). 385 + */ 386 + 387 + return IRQ_HANDLED; 388 + } 389 + 390 + static irqreturn_t wcnss_stop_ack_interrupt(int irq, void *dev) 391 + { 392 + struct qcom_wcnss *wcnss = dev; 393 + 394 + complete(&wcnss->stop_done); 395 + 396 + return IRQ_HANDLED; 397 + } 398 + 399 + static int wcnss_init_regulators(struct qcom_wcnss *wcnss, 400 + const struct wcnss_vreg_info *info, 401 + int num_vregs) 402 + { 403 + struct regulator_bulk_data *bulk; 404 + int ret; 405 + int i; 406 + 407 + bulk = devm_kcalloc(wcnss->dev, 408 + num_vregs, sizeof(struct regulator_bulk_data), 409 + GFP_KERNEL); 410 + if (!bulk) 411 + return -ENOMEM; 412 + 413 + for (i = 0; i < num_vregs; i++) 414 + bulk[i].supply = info[i].name; 415 + 416 + ret = devm_regulator_bulk_get(wcnss->dev, num_vregs, bulk); 417 + if (ret) 418 + return ret; 419 + 420 + for (i = 0; i < num_vregs; i++) { 421 + if (info[i].max_voltage) 422 + regulator_set_voltage(bulk[i].consumer, 423 + info[i].min_voltage, 424 + info[i].max_voltage); 425 + 426 + if (info[i].load_uA) 427 + regulator_set_load(bulk[i].consumer, info[i].load_uA); 428 + } 429 + 430 + wcnss->vregs = bulk; 431 + wcnss->num_vregs = num_vregs; 432 + 433 + return 0; 434 + } 435 + 436 + static int wcnss_request_irq(struct qcom_wcnss *wcnss, 437 + struct platform_device *pdev, 438 + const char *name, 439 + bool optional, 440 + irq_handler_t thread_fn) 441 + { 442 + int ret; 443 + 444 + ret = platform_get_irq_byname(pdev, name); 445 + if (ret < 0 && optional) { 446 + dev_dbg(&pdev->dev, "no %s IRQ defined, ignoring\n", name); 447 + return 0; 448 + } else if (ret < 0) { 449 + dev_err(&pdev->dev, "no %s IRQ defined\n", name); 450 + return ret; 451 + } 452 + 453 + ret = devm_request_threaded_irq(&pdev->dev, ret, 454 + NULL, thread_fn, 455 + IRQF_TRIGGER_RISING | IRQF_ONESHOT, 456 + "wcnss", wcnss); 457 + if (ret) 458 + dev_err(&pdev->dev, "request %s IRQ failed\n", name); 459 + 460 + return ret; 461 + } 462 + 463 + static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss) 464 + { 465 + struct device_node *node; 466 + struct resource r; 467 + int ret; 468 + 469 + node = of_parse_phandle(wcnss->dev->of_node, "memory-region", 0); 470 + if (!node) { 471 + dev_err(wcnss->dev, "no memory-region specified\n"); 472 + return -EINVAL; 473 + } 474 + 475 + ret = of_address_to_resource(node, 0, &r); 476 + if (ret) 477 + return ret; 478 + 479 + wcnss->mem_phys = wcnss->mem_reloc = r.start; 480 + wcnss->mem_size = resource_size(&r); 481 + wcnss->mem_region = devm_ioremap_wc(wcnss->dev, wcnss->mem_phys, wcnss->mem_size); 482 + if (!wcnss->mem_region) { 483 + dev_err(wcnss->dev, "unable to map memory region: %pa+%zx\n", 484 + &r.start, wcnss->mem_size); 485 + return -EBUSY; 486 + } 487 + 488 + return 0; 489 + } 490 + 491 + static int wcnss_probe(struct platform_device *pdev) 492 + { 493 + const struct wcnss_data *data; 494 + struct qcom_wcnss *wcnss; 495 + struct resource *res; 496 + struct rproc *rproc; 497 + void __iomem *mmio; 498 + int ret; 499 + 500 + data = of_device_get_match_data(&pdev->dev); 501 + 502 + if (!qcom_scm_is_available()) 503 + return -EPROBE_DEFER; 504 + 505 + if (!qcom_scm_pas_supported(WCNSS_PAS_ID)) { 506 + dev_err(&pdev->dev, "PAS is not available for WCNSS\n"); 507 + return -ENXIO; 508 + } 509 + 510 + rproc = rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops, 511 + WCNSS_FIRMWARE_NAME, sizeof(*wcnss)); 512 + if (!rproc) { 513 + dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 514 + return -ENOMEM; 515 + } 516 + 517 + rproc->fw_ops = &wcnss_fw_ops; 518 + 519 + wcnss = (struct qcom_wcnss *)rproc->priv; 520 + wcnss->dev = &pdev->dev; 521 + wcnss->rproc = rproc; 522 + platform_set_drvdata(pdev, wcnss); 523 + 524 + init_completion(&wcnss->start_done); 525 + init_completion(&wcnss->stop_done); 526 + 527 + mutex_init(&wcnss->iris_lock); 528 + 529 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmu"); 530 + mmio = devm_ioremap_resource(&pdev->dev, res); 531 + if (IS_ERR(mmio)) { 532 + ret = PTR_ERR(mmio); 533 + goto free_rproc; 534 + }; 535 + 536 + ret = wcnss_alloc_memory_region(wcnss); 537 + if (ret) 538 + goto free_rproc; 539 + 540 + wcnss->pmu_cfg = mmio + data->pmu_offset; 541 + wcnss->spare_out = mmio + data->spare_offset; 542 + 543 + ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs); 544 + if (ret) 545 + goto free_rproc; 546 + 547 + ret = wcnss_request_irq(wcnss, pdev, "wdog", false, wcnss_wdog_interrupt); 548 + if (ret < 0) 549 + goto free_rproc; 550 + wcnss->wdog_irq = ret; 551 + 552 + ret = wcnss_request_irq(wcnss, pdev, "fatal", false, wcnss_fatal_interrupt); 553 + if (ret < 0) 554 + goto free_rproc; 555 + wcnss->fatal_irq = ret; 556 + 557 + ret = wcnss_request_irq(wcnss, pdev, "ready", true, wcnss_ready_interrupt); 558 + if (ret < 0) 559 + goto free_rproc; 560 + wcnss->ready_irq = ret; 561 + 562 + ret = wcnss_request_irq(wcnss, pdev, "handover", true, wcnss_handover_interrupt); 563 + if (ret < 0) 564 + goto free_rproc; 565 + wcnss->handover_irq = ret; 566 + 567 + ret = wcnss_request_irq(wcnss, pdev, "stop-ack", true, wcnss_stop_ack_interrupt); 568 + if (ret < 0) 569 + goto free_rproc; 570 + wcnss->stop_ack_irq = ret; 571 + 572 + if (wcnss->stop_ack_irq) { 573 + wcnss->state = qcom_smem_state_get(&pdev->dev, "stop", 574 + &wcnss->stop_bit); 575 + if (IS_ERR(wcnss->state)) { 576 + ret = PTR_ERR(wcnss->state); 577 + goto free_rproc; 578 + } 579 + } 580 + 581 + ret = rproc_add(rproc); 582 + if (ret) 583 + goto free_rproc; 584 + 585 + return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 586 + 587 + free_rproc: 588 + rproc_free(rproc); 589 + 590 + return ret; 591 + } 592 + 593 + static int wcnss_remove(struct platform_device *pdev) 594 + { 595 + struct qcom_wcnss *wcnss = platform_get_drvdata(pdev); 596 + 597 + of_platform_depopulate(&pdev->dev); 598 + 599 + qcom_smem_state_put(wcnss->state); 600 + rproc_del(wcnss->rproc); 601 + rproc_free(wcnss->rproc); 602 + 603 + return 0; 604 + } 605 + 606 + static const struct of_device_id wcnss_of_match[] = { 607 + { .compatible = "qcom,riva-pil", &riva_data }, 608 + { .compatible = "qcom,pronto-v1-pil", &pronto_v1_data }, 609 + { .compatible = "qcom,pronto-v2-pil", &pronto_v2_data }, 610 + { }, 611 + }; 612 + 613 + static struct platform_driver wcnss_driver = { 614 + .probe = wcnss_probe, 615 + .remove = wcnss_remove, 616 + .driver = { 617 + .name = "qcom-wcnss-pil", 618 + .of_match_table = wcnss_of_match, 619 + }, 620 + }; 621 + 622 + module_platform_driver(wcnss_driver); 623 + MODULE_DESCRIPTION("Qualcomm Peripherial Image Loader for Wireless Subsystem"); 624 + MODULE_LICENSE("GPL v2");
+22
drivers/remoteproc/qcom_wcnss.h
··· 1 + #ifndef __QCOM_WNCSS_H__ 2 + #define __QCOM_WNCSS_H__ 3 + 4 + struct qcom_iris; 5 + struct qcom_wcnss; 6 + 7 + struct wcnss_vreg_info { 8 + const char * const name; 9 + int min_voltage; 10 + int max_voltage; 11 + 12 + int load_uA; 13 + 14 + bool super_turbo; 15 + }; 16 + 17 + int qcom_iris_enable(struct qcom_iris *iris); 18 + void qcom_iris_disable(struct qcom_iris *iris); 19 + 20 + void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, struct qcom_iris *iris, bool use_48mhz_xo); 21 + 22 + #endif
+188
drivers/remoteproc/qcom_wcnss_iris.c
··· 1 + /* 2 + * Qualcomm Wireless Connectivity Subsystem Iris driver 3 + * 4 + * Copyright (C) 2016 Linaro Ltd 5 + * Copyright (C) 2014 Sony Mobile Communications AB 6 + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/clk.h> 19 + #include <linux/kernel.h> 20 + #include <linux/module.h> 21 + #include <linux/of_device.h> 22 + #include <linux/platform_device.h> 23 + #include <linux/regulator/consumer.h> 24 + 25 + #include "qcom_wcnss.h" 26 + 27 + struct qcom_iris { 28 + struct device *dev; 29 + 30 + struct clk *xo_clk; 31 + 32 + struct regulator_bulk_data *vregs; 33 + size_t num_vregs; 34 + }; 35 + 36 + struct iris_data { 37 + const struct wcnss_vreg_info *vregs; 38 + size_t num_vregs; 39 + 40 + bool use_48mhz_xo; 41 + }; 42 + 43 + static const struct iris_data wcn3620_data = { 44 + .vregs = (struct wcnss_vreg_info[]) { 45 + { "vddxo", 1800000, 1800000, 10000 }, 46 + { "vddrfa", 1300000, 1300000, 100000 }, 47 + { "vddpa", 3300000, 3300000, 515000 }, 48 + { "vdddig", 1800000, 1800000, 10000 }, 49 + }, 50 + .num_vregs = 4, 51 + .use_48mhz_xo = false, 52 + }; 53 + 54 + static const struct iris_data wcn3660_data = { 55 + .vregs = (struct wcnss_vreg_info[]) { 56 + { "vddxo", 1800000, 1800000, 10000 }, 57 + { "vddrfa", 1300000, 1300000, 100000 }, 58 + { "vddpa", 2900000, 3000000, 515000 }, 59 + { "vdddig", 1200000, 1225000, 10000 }, 60 + }, 61 + .num_vregs = 4, 62 + .use_48mhz_xo = true, 63 + }; 64 + 65 + static const struct iris_data wcn3680_data = { 66 + .vregs = (struct wcnss_vreg_info[]) { 67 + { "vddxo", 1800000, 1800000, 10000 }, 68 + { "vddrfa", 1300000, 1300000, 100000 }, 69 + { "vddpa", 3300000, 3300000, 515000 }, 70 + { "vdddig", 1800000, 1800000, 10000 }, 71 + }, 72 + .num_vregs = 4, 73 + .use_48mhz_xo = true, 74 + }; 75 + 76 + int qcom_iris_enable(struct qcom_iris *iris) 77 + { 78 + int ret; 79 + 80 + ret = regulator_bulk_enable(iris->num_vregs, iris->vregs); 81 + if (ret) 82 + return ret; 83 + 84 + ret = clk_prepare_enable(iris->xo_clk); 85 + if (ret) { 86 + dev_err(iris->dev, "failed to enable xo clk\n"); 87 + goto disable_regulators; 88 + } 89 + 90 + return 0; 91 + 92 + disable_regulators: 93 + regulator_bulk_disable(iris->num_vregs, iris->vregs); 94 + 95 + return ret; 96 + } 97 + EXPORT_SYMBOL_GPL(qcom_iris_enable); 98 + 99 + void qcom_iris_disable(struct qcom_iris *iris) 100 + { 101 + clk_disable_unprepare(iris->xo_clk); 102 + regulator_bulk_disable(iris->num_vregs, iris->vregs); 103 + } 104 + EXPORT_SYMBOL_GPL(qcom_iris_disable); 105 + 106 + static int qcom_iris_probe(struct platform_device *pdev) 107 + { 108 + const struct iris_data *data; 109 + struct qcom_wcnss *wcnss; 110 + struct qcom_iris *iris; 111 + int ret; 112 + int i; 113 + 114 + iris = devm_kzalloc(&pdev->dev, sizeof(struct qcom_iris), GFP_KERNEL); 115 + if (!iris) 116 + return -ENOMEM; 117 + 118 + data = of_device_get_match_data(&pdev->dev); 119 + wcnss = dev_get_drvdata(pdev->dev.parent); 120 + 121 + iris->xo_clk = devm_clk_get(&pdev->dev, "xo"); 122 + if (IS_ERR(iris->xo_clk)) { 123 + if (PTR_ERR(iris->xo_clk) != -EPROBE_DEFER) 124 + dev_err(&pdev->dev, "failed to acquire xo clk\n"); 125 + return PTR_ERR(iris->xo_clk); 126 + } 127 + 128 + iris->num_vregs = data->num_vregs; 129 + iris->vregs = devm_kcalloc(&pdev->dev, 130 + iris->num_vregs, 131 + sizeof(struct regulator_bulk_data), 132 + GFP_KERNEL); 133 + if (!iris->vregs) 134 + return -ENOMEM; 135 + 136 + for (i = 0; i < iris->num_vregs; i++) 137 + iris->vregs[i].supply = data->vregs[i].name; 138 + 139 + ret = devm_regulator_bulk_get(&pdev->dev, iris->num_vregs, iris->vregs); 140 + if (ret) { 141 + dev_err(&pdev->dev, "failed to get regulators\n"); 142 + return ret; 143 + } 144 + 145 + for (i = 0; i < iris->num_vregs; i++) { 146 + if (data->vregs[i].max_voltage) 147 + regulator_set_voltage(iris->vregs[i].consumer, 148 + data->vregs[i].min_voltage, 149 + data->vregs[i].max_voltage); 150 + 151 + if (data->vregs[i].load_uA) 152 + regulator_set_load(iris->vregs[i].consumer, 153 + data->vregs[i].load_uA); 154 + } 155 + 156 + qcom_wcnss_assign_iris(wcnss, iris, data->use_48mhz_xo); 157 + 158 + return 0; 159 + } 160 + 161 + static int qcom_iris_remove(struct platform_device *pdev) 162 + { 163 + struct qcom_wcnss *wcnss = dev_get_drvdata(pdev->dev.parent); 164 + 165 + qcom_wcnss_assign_iris(wcnss, NULL, false); 166 + 167 + return 0; 168 + } 169 + 170 + static const struct of_device_id iris_of_match[] = { 171 + { .compatible = "qcom,wcn3620", .data = &wcn3620_data }, 172 + { .compatible = "qcom,wcn3660", .data = &wcn3660_data }, 173 + { .compatible = "qcom,wcn3680", .data = &wcn3680_data }, 174 + {} 175 + }; 176 + 177 + static struct platform_driver wcnss_driver = { 178 + .probe = qcom_iris_probe, 179 + .remove = qcom_iris_remove, 180 + .driver = { 181 + .name = "qcom-iris", 182 + .of_match_table = iris_of_match, 183 + }, 184 + }; 185 + 186 + module_platform_driver(wcnss_driver); 187 + MODULE_DESCRIPTION("Qualcomm Wireless Subsystem Iris driver"); 188 + MODULE_LICENSE("GPL v2");
+117 -131
drivers/remoteproc/remoteproc_core.c
··· 78 78 * will try to access an unmapped device address. 79 79 */ 80 80 static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, 81 - unsigned long iova, int flags, void *token) 81 + unsigned long iova, int flags, void *token) 82 82 { 83 83 struct rproc *rproc = token; 84 84 ··· 236 236 } 237 237 notifyid = ret; 238 238 239 - dev_dbg(dev, "vring%d: va %p dma %llx size %x idr %d\n", i, va, 240 - (unsigned long long)dma, size, notifyid); 239 + dev_dbg(dev, "vring%d: va %p dma %pad size 0x%x idr %d\n", 240 + i, va, &dma, size, notifyid); 241 241 242 242 rvring->va = va; 243 243 rvring->dma = dma; ··· 263 263 struct fw_rsc_vdev_vring *vring = &rsc->vring[i]; 264 264 struct rproc_vring *rvring = &rvdev->vring[i]; 265 265 266 - dev_dbg(dev, "vdev rsc: vring%d: da %x, qsz %d, align %d\n", 267 - i, vring->da, vring->num, vring->align); 268 - 269 - /* make sure reserved bytes are zeroes */ 270 - if (vring->reserved) { 271 - dev_err(dev, "vring rsc has non zero reserved bytes\n"); 272 - return -EINVAL; 273 - } 266 + dev_dbg(dev, "vdev rsc: vring%d: da 0x%x, qsz %d, align %d\n", 267 + i, vring->da, vring->num, vring->align); 274 268 275 269 /* verify queue size and vring alignment are sane */ 276 270 if (!vring->num || !vring->align) { 277 271 dev_err(dev, "invalid qsz (%d) or alignment (%d)\n", 278 - vring->num, vring->align); 272 + vring->num, vring->align); 279 273 return -EINVAL; 280 274 } 281 275 ··· 324 330 * Returns 0 on success, or an appropriate error code otherwise 325 331 */ 326 332 static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, 327 - int offset, int avail) 333 + int offset, int avail) 328 334 { 329 335 struct device *dev = &rproc->dev; 330 336 struct rproc_vdev *rvdev; ··· 343 349 return -EINVAL; 344 350 } 345 351 346 - dev_dbg(dev, "vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n", 352 + dev_dbg(dev, "vdev rsc: id %d, dfeatures 0x%x, cfg len %d, %d vrings\n", 347 353 rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings); 348 354 349 355 /* we currently support only two vrings per rvdev */ ··· 352 358 return -EINVAL; 353 359 } 354 360 355 - rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL); 361 + rvdev = kzalloc(sizeof(*rvdev), GFP_KERNEL); 356 362 if (!rvdev) 357 363 return -ENOMEM; 358 364 ··· 401 407 * Returns 0 on success, or an appropriate error code otherwise 402 408 */ 403 409 static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, 404 - int offset, int avail) 410 + int offset, int avail) 405 411 { 406 412 struct rproc_mem_entry *trace; 407 413 struct device *dev = &rproc->dev; ··· 449 455 450 456 rproc->num_traces++; 451 457 452 - dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", name, ptr, 453 - rsc->da, rsc->len); 458 + dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", 459 + name, ptr, rsc->da, rsc->len); 454 460 455 461 return 0; 456 462 } ··· 481 487 * are outside those ranges. 482 488 */ 483 489 static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc, 484 - int offset, int avail) 490 + int offset, int avail) 485 491 { 486 492 struct rproc_mem_entry *mapping; 487 493 struct device *dev = &rproc->dev; ··· 524 530 list_add_tail(&mapping->node, &rproc->mappings); 525 531 526 532 dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n", 527 - rsc->pa, rsc->da, rsc->len); 533 + rsc->pa, rsc->da, rsc->len); 528 534 529 535 return 0; 530 536 ··· 552 558 * pressure is important; it may have a substantial impact on performance. 553 559 */ 554 560 static int rproc_handle_carveout(struct rproc *rproc, 555 - struct fw_rsc_carveout *rsc, 556 - int offset, int avail) 557 - 561 + struct fw_rsc_carveout *rsc, 562 + int offset, int avail) 558 563 { 559 564 struct rproc_mem_entry *carveout, *mapping; 560 565 struct device *dev = &rproc->dev; ··· 572 579 return -EINVAL; 573 580 } 574 581 575 - dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n", 576 - rsc->da, rsc->pa, rsc->len, rsc->flags); 582 + dev_dbg(dev, "carveout rsc: name: %s, da 0x%x, pa 0x%x, len 0x%x, flags 0x%x\n", 583 + rsc->name, rsc->da, rsc->pa, rsc->len, rsc->flags); 577 584 578 585 carveout = kzalloc(sizeof(*carveout), GFP_KERNEL); 579 586 if (!carveout) ··· 581 588 582 589 va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL); 583 590 if (!va) { 584 - dev_err(dev->parent, "dma_alloc_coherent err: %d\n", rsc->len); 591 + dev_err(dev->parent, 592 + "failed to allocate dma memory: len 0x%x\n", rsc->len); 585 593 ret = -ENOMEM; 586 594 goto free_carv; 587 595 } 588 596 589 - dev_dbg(dev, "carveout va %p, dma %llx, len 0x%x\n", va, 590 - (unsigned long long)dma, rsc->len); 597 + dev_dbg(dev, "carveout va %p, dma %pad, len 0x%x\n", 598 + va, &dma, rsc->len); 591 599 592 600 /* 593 601 * Ok, this is non-standard. ··· 610 616 if (rproc->domain) { 611 617 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 612 618 if (!mapping) { 613 - dev_err(dev, "kzalloc mapping failed\n"); 614 619 ret = -ENOMEM; 615 620 goto dma_free; 616 621 } 617 622 618 623 ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len, 619 - rsc->flags); 624 + rsc->flags); 620 625 if (ret) { 621 626 dev_err(dev, "iommu_map failed: %d\n", ret); 622 627 goto free_mapping; ··· 632 639 mapping->len = rsc->len; 633 640 list_add_tail(&mapping->node, &rproc->mappings); 634 641 635 - dev_dbg(dev, "carveout mapped 0x%x to 0x%llx\n", 636 - rsc->da, (unsigned long long)dma); 642 + dev_dbg(dev, "carveout mapped 0x%x to %pad\n", 643 + rsc->da, &dma); 637 644 } 638 645 639 646 /* ··· 690 697 [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout, 691 698 [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem, 692 699 [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace, 693 - [RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */ 700 + [RSC_VDEV] = (rproc_handle_resource_t)rproc_count_vrings, 694 701 }; 695 702 696 703 static rproc_handle_resource_t rproc_vdev_handler[RSC_LAST] = { 697 704 [RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev, 698 - }; 699 - 700 - static rproc_handle_resource_t rproc_count_vrings_handler[RSC_LAST] = { 701 - [RSC_VDEV] = (rproc_handle_resource_t)rproc_count_vrings, 702 705 }; 703 706 704 707 /* handle firmware resource entries before booting the remote processor */ ··· 746 757 static void rproc_resource_cleanup(struct rproc *rproc) 747 758 { 748 759 struct rproc_mem_entry *entry, *tmp; 760 + struct rproc_vdev *rvdev, *rvtmp; 749 761 struct device *dev = &rproc->dev; 750 762 751 763 /* clean up debugfs trace entries */ ··· 765 775 if (unmapped != entry->len) { 766 776 /* nothing much to do besides complaining */ 767 777 dev_err(dev, "failed to unmap %u/%zu\n", entry->len, 768 - unmapped); 778 + unmapped); 769 779 } 770 780 771 781 list_del(&entry->node); ··· 779 789 list_del(&entry->node); 780 790 kfree(entry); 781 791 } 792 + 793 + /* clean up remote vdev entries */ 794 + list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) 795 + rproc_remove_virtio_dev(rvdev); 782 796 } 783 797 784 798 /* ··· 794 800 const char *name = rproc->firmware; 795 801 struct resource_table *table, *loaded_table; 796 802 int ret, tablesz; 797 - 798 - if (!rproc->table_ptr) 799 - return -ENOMEM; 800 803 801 804 ret = rproc_fw_sanity_check(rproc, fw); 802 805 if (ret) ··· 821 830 goto clean_up; 822 831 } 823 832 824 - /* Verify that resource table in loaded fw is unchanged */ 825 - if (rproc->table_csum != crc32(0, table, tablesz)) { 826 - dev_err(dev, "resource checksum failed, fw changed?\n"); 833 + /* 834 + * Create a copy of the resource table. When a virtio device starts 835 + * and calls vring_new_virtqueue() the address of the allocated vring 836 + * will be stored in the cached_table. Before the device is started, 837 + * cached_table will be copied into device memory. 838 + */ 839 + rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); 840 + if (!rproc->cached_table) 841 + goto clean_up; 842 + 843 + rproc->table_ptr = rproc->cached_table; 844 + 845 + /* reset max_notifyid */ 846 + rproc->max_notifyid = -1; 847 + 848 + /* look for virtio devices and register them */ 849 + ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler); 850 + if (ret) { 851 + dev_err(dev, "Failed to handle vdev resources: %d\n", ret); 827 852 goto clean_up; 828 853 } 829 854 ··· 847 840 ret = rproc_handle_resources(rproc, tablesz, rproc_loading_handlers); 848 841 if (ret) { 849 842 dev_err(dev, "Failed to process resources: %d\n", ret); 850 - goto clean_up; 843 + goto clean_up_resources; 851 844 } 852 845 853 846 /* load the ELF segments to memory */ 854 847 ret = rproc_load_segments(rproc, fw); 855 848 if (ret) { 856 849 dev_err(dev, "Failed to load program segments: %d\n", ret); 857 - goto clean_up; 850 + goto clean_up_resources; 858 851 } 859 852 860 853 /* 861 854 * The starting device has been given the rproc->cached_table as the 862 855 * resource table. The address of the vring along with the other 863 856 * allocated resources (carveouts etc) is stored in cached_table. 864 - * In order to pass this information to the remote device we must 865 - * copy this information to device memory. 857 + * In order to pass this information to the remote device we must copy 858 + * this information to device memory. We also update the table_ptr so 859 + * that any subsequent changes will be applied to the loaded version. 866 860 */ 867 861 loaded_table = rproc_find_loaded_rsc_table(rproc, fw); 868 - if (loaded_table) 862 + if (loaded_table) { 869 863 memcpy(loaded_table, rproc->cached_table, tablesz); 864 + rproc->table_ptr = loaded_table; 865 + } 870 866 871 867 /* power up the remote processor */ 872 868 ret = rproc->ops->start(rproc); 873 869 if (ret) { 874 870 dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret); 875 - goto clean_up; 871 + goto clean_up_resources; 876 872 } 877 - 878 - /* 879 - * Update table_ptr so that all subsequent vring allocations and 880 - * virtio fields manipulation update the actual loaded resource table 881 - * in device memory. 882 - */ 883 - rproc->table_ptr = loaded_table; 884 873 885 874 rproc->state = RPROC_RUNNING; 886 875 ··· 884 881 885 882 return 0; 886 883 887 - clean_up: 884 + clean_up_resources: 888 885 rproc_resource_cleanup(rproc); 886 + clean_up: 887 + kfree(rproc->cached_table); 888 + rproc->cached_table = NULL; 889 + rproc->table_ptr = NULL; 890 + 889 891 rproc_disable_iommu(rproc); 890 892 return ret; 891 893 } ··· 906 898 static void rproc_fw_config_virtio(const struct firmware *fw, void *context) 907 899 { 908 900 struct rproc *rproc = context; 909 - struct resource_table *table; 910 - int ret, tablesz; 911 901 912 - if (rproc_fw_sanity_check(rproc, fw) < 0) 913 - goto out; 902 + /* if rproc is marked always-on, request it to boot */ 903 + if (rproc->auto_boot) 904 + rproc_boot_nowait(rproc); 914 905 915 - /* look for the resource table */ 916 - table = rproc_find_rsc_table(rproc, fw, &tablesz); 917 - if (!table) 918 - goto out; 919 - 920 - rproc->table_csum = crc32(0, table, tablesz); 921 - 922 - /* 923 - * Create a copy of the resource table. When a virtio device starts 924 - * and calls vring_new_virtqueue() the address of the allocated vring 925 - * will be stored in the cached_table. Before the device is started, 926 - * cached_table will be copied into devic memory. 927 - */ 928 - rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); 929 - if (!rproc->cached_table) 930 - goto out; 931 - 932 - rproc->table_ptr = rproc->cached_table; 933 - 934 - /* count the number of notify-ids */ 935 - rproc->max_notifyid = -1; 936 - ret = rproc_handle_resources(rproc, tablesz, 937 - rproc_count_vrings_handler); 938 - if (ret) 939 - goto out; 940 - 941 - /* look for virtio devices and register them */ 942 - ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler); 943 - 944 - out: 945 906 release_firmware(fw); 946 907 /* allow rproc_del() contexts, if any, to proceed */ 947 908 complete_all(&rproc->firmware_loading_complete); ··· 946 969 * rproc_trigger_recovery() - recover a remoteproc 947 970 * @rproc: the remote processor 948 971 * 949 - * The recovery is done by reseting all the virtio devices, that way all the 972 + * The recovery is done by resetting all the virtio devices, that way all the 950 973 * rpmsg drivers will be reseted along with the remote processor making the 951 974 * remoteproc functional again. 952 975 * ··· 954 977 */ 955 978 int rproc_trigger_recovery(struct rproc *rproc) 956 979 { 957 - struct rproc_vdev *rvdev, *rvtmp; 958 - 959 980 dev_err(&rproc->dev, "recovering %s\n", rproc->name); 960 981 961 982 init_completion(&rproc->crash_comp); 962 983 963 - /* clean up remote vdev entries */ 964 - list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) 965 - rproc_remove_virtio_dev(rvdev); 984 + /* shut down the remote */ 985 + /* TODO: make sure this works with rproc->power > 1 */ 986 + rproc_shutdown(rproc); 966 987 967 988 /* wait until there is no more rproc users */ 968 989 wait_for_completion(&rproc->crash_comp); 969 990 970 - /* Free the copy of the resource table */ 971 - kfree(rproc->cached_table); 991 + /* 992 + * boot the remote processor up again 993 + */ 994 + rproc_boot(rproc); 972 995 973 - return rproc_add_virtio_devices(rproc); 996 + return 0; 974 997 } 975 998 976 999 /** ··· 1035 1058 return ret; 1036 1059 } 1037 1060 1038 - /* loading a firmware is required */ 1039 - if (!rproc->firmware) { 1040 - dev_err(dev, "%s: no firmware to load\n", __func__); 1041 - ret = -EINVAL; 1042 - goto unlock_mutex; 1043 - } 1044 - 1045 - /* prevent underlying implementation from being removed */ 1046 - if (!try_module_get(dev->parent->driver->owner)) { 1047 - dev_err(dev, "%s: can't get owner\n", __func__); 1048 - ret = -EINVAL; 1049 - goto unlock_mutex; 1050 - } 1051 - 1052 1061 /* skip the boot process if rproc is already powered up */ 1053 1062 if (atomic_inc_return(&rproc->power) > 1) { 1054 1063 ret = 0; ··· 1059 1096 release_firmware(firmware_p); 1060 1097 1061 1098 downref_rproc: 1062 - if (ret) { 1063 - module_put(dev->parent->driver->owner); 1099 + if (ret) 1064 1100 atomic_dec(&rproc->power); 1065 - } 1066 1101 unlock_mutex: 1067 1102 mutex_unlock(&rproc->lock); 1068 1103 return ret; ··· 1134 1173 1135 1174 rproc_disable_iommu(rproc); 1136 1175 1137 - /* Give the next start a clean resource table */ 1138 - rproc->table_ptr = rproc->cached_table; 1176 + /* Free the copy of the resource table */ 1177 + kfree(rproc->cached_table); 1178 + rproc->cached_table = NULL; 1179 + rproc->table_ptr = NULL; 1139 1180 1140 1181 /* if in crash state, unlock crash handler */ 1141 1182 if (rproc->state == RPROC_CRASHED) ··· 1149 1186 1150 1187 out: 1151 1188 mutex_unlock(&rproc->lock); 1152 - if (!ret) 1153 - module_put(dev->parent->driver->owner); 1154 1189 } 1155 1190 EXPORT_SYMBOL(rproc_shutdown); 1156 1191 ··· 1177 1216 mutex_lock(&rproc_list_mutex); 1178 1217 list_for_each_entry(r, &rproc_list, node) { 1179 1218 if (r->dev.parent && r->dev.parent->of_node == np) { 1219 + /* prevent underlying implementation from being removed */ 1220 + if (!try_module_get(r->dev.parent->driver->owner)) { 1221 + dev_err(&r->dev, "can't get owner\n"); 1222 + break; 1223 + } 1224 + 1180 1225 rproc = r; 1181 1226 get_device(&rproc->dev); 1182 1227 break; ··· 1302 1335 * On success the new rproc is returned, and on failure, NULL. 1303 1336 * 1304 1337 * Note: _never_ directly deallocate @rproc, even if it was not registered 1305 - * yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). 1338 + * yet. Instead, when you need to unroll rproc_alloc(), use rproc_free(). 1306 1339 */ 1307 1340 struct rproc *rproc_alloc(struct device *dev, const char *name, 1308 - const struct rproc_ops *ops, 1309 - const char *firmware, int len) 1341 + const struct rproc_ops *ops, 1342 + const char *firmware, int len) 1310 1343 { 1311 1344 struct rproc *rproc; 1312 1345 char *p, *template = "rproc-%s-fw"; ··· 1326 1359 */ 1327 1360 name_len = strlen(name) + strlen(template) - 2 + 1; 1328 1361 1329 - rproc = kzalloc(sizeof(struct rproc) + len + name_len, GFP_KERNEL); 1362 + rproc = kzalloc(sizeof(*rproc) + len + name_len, GFP_KERNEL); 1330 1363 if (!rproc) 1331 1364 return NULL; 1332 1365 ··· 1341 1374 rproc->name = name; 1342 1375 rproc->ops = ops; 1343 1376 rproc->priv = &rproc[1]; 1377 + rproc->auto_boot = true; 1344 1378 1345 1379 device_initialize(&rproc->dev); 1346 1380 rproc->dev.parent = dev; ··· 1381 1413 EXPORT_SYMBOL(rproc_alloc); 1382 1414 1383 1415 /** 1384 - * rproc_put() - unroll rproc_alloc() 1416 + * rproc_free() - unroll rproc_alloc() 1417 + * @rproc: the remote processor handle 1418 + * 1419 + * This function decrements the rproc dev refcount. 1420 + * 1421 + * If no one holds any reference to rproc anymore, then its refcount would 1422 + * now drop to zero, and it would be freed. 1423 + */ 1424 + void rproc_free(struct rproc *rproc) 1425 + { 1426 + put_device(&rproc->dev); 1427 + } 1428 + EXPORT_SYMBOL(rproc_free); 1429 + 1430 + /** 1431 + * rproc_put() - release rproc reference 1385 1432 * @rproc: the remote processor handle 1386 1433 * 1387 1434 * This function decrements the rproc dev refcount. ··· 1406 1423 */ 1407 1424 void rproc_put(struct rproc *rproc) 1408 1425 { 1426 + module_put(rproc->dev.parent->driver->owner); 1409 1427 put_device(&rproc->dev); 1410 1428 } 1411 1429 EXPORT_SYMBOL(rproc_put); ··· 1422 1438 * 1423 1439 * After rproc_del() returns, @rproc isn't freed yet, because 1424 1440 * of the outstanding reference created by rproc_alloc. To decrement that 1425 - * one last refcount, one still needs to call rproc_put(). 1441 + * one last refcount, one still needs to call rproc_free(). 1426 1442 * 1427 1443 * Returns 0 on success and -EINVAL if @rproc isn't valid. 1428 1444 */ ··· 1436 1452 /* if rproc is just being registered, wait */ 1437 1453 wait_for_completion(&rproc->firmware_loading_complete); 1438 1454 1455 + /* if rproc is marked always-on, rproc_add() booted it */ 1456 + /* TODO: make sure this works with rproc->power > 1 */ 1457 + if (rproc->auto_boot) 1458 + rproc_shutdown(rproc); 1459 + 1439 1460 /* clean up remote vdev entries */ 1440 1461 list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) 1441 1462 rproc_remove_virtio_dev(rvdev); 1442 - 1443 - /* Free the copy of the resource table */ 1444 - kfree(rproc->cached_table); 1445 1463 1446 1464 /* the rproc is downref'ed as soon as it's removed from the klist */ 1447 1465 mutex_lock(&rproc_list_mutex);
+10 -10
drivers/remoteproc/remoteproc_debugfs.c
··· 45 45 * as it provides very early tracing with little to no dependencies at all. 46 46 */ 47 47 static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, 48 - size_t count, loff_t *ppos) 48 + size_t count, loff_t *ppos) 49 49 { 50 50 struct rproc_mem_entry *trace = filp->private_data; 51 51 int len = strnlen(trace->va, trace->len); ··· 73 73 74 74 /* expose the state of the remote processor via debugfs */ 75 75 static ssize_t rproc_state_read(struct file *filp, char __user *userbuf, 76 - size_t count, loff_t *ppos) 76 + size_t count, loff_t *ppos) 77 77 { 78 78 struct rproc *rproc = filp->private_data; 79 79 unsigned int state; ··· 83 83 state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state; 84 84 85 85 i = scnprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state], 86 - rproc->state); 86 + rproc->state); 87 87 88 88 return simple_read_from_buffer(userbuf, count, ppos, buf, i); 89 89 } ··· 130 130 131 131 /* expose the name of the remote processor via debugfs */ 132 132 static ssize_t rproc_name_read(struct file *filp, char __user *userbuf, 133 - size_t count, loff_t *ppos) 133 + size_t count, loff_t *ppos) 134 134 { 135 135 struct rproc *rproc = filp->private_data; 136 136 /* need room for the name, a newline and a terminating null */ ··· 230 230 } 231 231 232 232 struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, 233 - struct rproc_mem_entry *trace) 233 + struct rproc_mem_entry *trace) 234 234 { 235 235 struct dentry *tfile; 236 236 237 - tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, 238 - trace, &trace_rproc_ops); 237 + tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, trace, 238 + &trace_rproc_ops); 239 239 if (!tfile) { 240 240 dev_err(&rproc->dev, "failed to create debugfs trace entry\n"); 241 241 return NULL; ··· 264 264 return; 265 265 266 266 debugfs_create_file("name", 0400, rproc->dbg_dir, 267 - rproc, &rproc_name_ops); 267 + rproc, &rproc_name_ops); 268 268 debugfs_create_file("state", 0400, rproc->dbg_dir, 269 - rproc, &rproc_state_ops); 269 + rproc, &rproc_state_ops); 270 270 debugfs_create_file("recovery", 0400, rproc->dbg_dir, 271 - rproc, &rproc_recovery_ops); 271 + rproc, &rproc_recovery_ops); 272 272 } 273 273 274 274 void __init rproc_init_debugfs(void)
+3 -3
drivers/remoteproc/remoteproc_elf_loader.c
··· 166 166 continue; 167 167 168 168 dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", 169 - phdr->p_type, da, memsz, filesz); 169 + phdr->p_type, da, memsz, filesz); 170 170 171 171 if (filesz > memsz) { 172 172 dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", 173 - filesz, memsz); 173 + filesz, memsz); 174 174 ret = -EINVAL; 175 175 break; 176 176 } 177 177 178 178 if (offset + filesz > fw->size) { 179 179 dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", 180 - offset + filesz, fw->size); 180 + offset + filesz, fw->size); 181 181 ret = -EINVAL; 182 182 break; 183 183 }
+8 -7
drivers/remoteproc/remoteproc_internal.h
··· 36 36 */ 37 37 struct rproc_fw_ops { 38 38 struct resource_table *(*find_rsc_table)(struct rproc *rproc, 39 - const struct firmware *fw, 40 - int *tablesz); 41 - struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc, 42 - const struct firmware *fw); 39 + const struct firmware *fw, 40 + int *tablesz); 41 + struct resource_table *(*find_loaded_rsc_table)( 42 + struct rproc *rproc, const struct firmware *fw); 43 43 int (*load)(struct rproc *rproc, const struct firmware *fw); 44 44 int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); 45 45 u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); ··· 57 57 /* from remoteproc_debugfs.c */ 58 58 void rproc_remove_trace_file(struct dentry *tfile); 59 59 struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, 60 - struct rproc_mem_entry *trace); 60 + struct rproc_mem_entry *trace); 61 61 void rproc_delete_debug_dir(struct rproc *rproc); 62 62 void rproc_create_debug_dir(struct rproc *rproc); 63 63 void rproc_init_debugfs(void); ··· 98 98 99 99 static inline 100 100 struct resource_table *rproc_find_rsc_table(struct rproc *rproc, 101 - const struct firmware *fw, int *tablesz) 101 + const struct firmware *fw, 102 + int *tablesz) 102 103 { 103 104 if (rproc->fw_ops->find_rsc_table) 104 105 return rproc->fw_ops->find_rsc_table(rproc, fw, tablesz); ··· 109 108 110 109 static inline 111 110 struct resource_table *rproc_find_loaded_rsc_table(struct rproc *rproc, 112 - const struct firmware *fw) 111 + const struct firmware *fw) 113 112 { 114 113 if (rproc->fw_ops->find_loaded_rsc_table) 115 114 return rproc->fw_ops->find_loaded_rsc_table(rproc, fw);
+11 -24
drivers/remoteproc/remoteproc_virtio.c
··· 69 69 EXPORT_SYMBOL(rproc_vq_interrupt); 70 70 71 71 static struct virtqueue *rp_find_vq(struct virtio_device *vdev, 72 - unsigned id, 72 + unsigned int id, 73 73 void (*callback)(struct virtqueue *vq), 74 74 const char *name) 75 75 { ··· 101 101 memset(addr, 0, size); 102 102 103 103 dev_dbg(dev, "vring%d: va %p qsz %d notifyid %d\n", 104 - id, addr, len, rvring->notifyid); 104 + id, addr, len, rvring->notifyid); 105 105 106 106 /* 107 107 * Create the new vq, and tell virtio we're not interested in 108 108 * the 'weak' smp barriers, since we're talking with a real device. 109 109 */ 110 110 vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, addr, 111 - rproc_virtio_notify, callback, name); 111 + rproc_virtio_notify, callback, name); 112 112 if (!vq) { 113 113 dev_err(dev, "vring_new_virtqueue %s failed\n", name); 114 114 rproc_free_vring(rvring); ··· 136 136 137 137 static void rproc_virtio_del_vqs(struct virtio_device *vdev) 138 138 { 139 - struct rproc *rproc = vdev_to_rproc(vdev); 140 - 141 - /* power down the remote processor before deleting vqs */ 142 - rproc_shutdown(rproc); 143 - 144 139 __rproc_virtio_del_vqs(vdev); 145 140 } 146 141 147 - static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, 148 - struct virtqueue *vqs[], 149 - vq_callback_t *callbacks[], 150 - const char * const names[]) 142 + static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, 143 + struct virtqueue *vqs[], 144 + vq_callback_t *callbacks[], 145 + const char * const names[]) 151 146 { 152 - struct rproc *rproc = vdev_to_rproc(vdev); 153 147 int i, ret; 154 148 155 149 for (i = 0; i < nvqs; ++i) { ··· 152 158 ret = PTR_ERR(vqs[i]); 153 159 goto error; 154 160 } 155 - } 156 - 157 - /* now that the vqs are all set, boot the remote processor */ 158 - ret = rproc_boot_nowait(rproc); 159 - if (ret) { 160 - dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret); 161 - goto error; 162 161 } 163 162 164 163 return 0; ··· 226 239 return 0; 227 240 } 228 241 229 - static void rproc_virtio_get(struct virtio_device *vdev, unsigned offset, 230 - void *buf, unsigned len) 242 + static void rproc_virtio_get(struct virtio_device *vdev, unsigned int offset, 243 + void *buf, unsigned int len) 231 244 { 232 245 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); 233 246 struct fw_rsc_vdev *rsc; ··· 244 257 memcpy(buf, cfg + offset, len); 245 258 } 246 259 247 - static void rproc_virtio_set(struct virtio_device *vdev, unsigned offset, 248 - const void *buf, unsigned len) 260 + static void rproc_virtio_set(struct virtio_device *vdev, unsigned int offset, 261 + const void *buf, unsigned int len) 249 262 { 250 263 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); 251 264 struct fw_rsc_vdev *rsc;
+2 -2
drivers/remoteproc/st_remoteproc.c
··· 262 262 return 0; 263 263 264 264 free_rproc: 265 - rproc_put(rproc); 265 + rproc_free(rproc); 266 266 return ret; 267 267 } 268 268 ··· 277 277 278 278 of_reserved_mem_device_release(&pdev->dev); 279 279 280 - rproc_put(rproc); 280 + rproc_free(rproc); 281 281 282 282 return 0; 283 283 }
+2 -2
drivers/remoteproc/ste_modem_rproc.c
··· 257 257 rproc_del(sproc->rproc); 258 258 dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE, 259 259 sproc->fw_addr, sproc->fw_dma_addr); 260 - rproc_put(sproc->rproc); 260 + rproc_free(sproc->rproc); 261 261 262 262 mdev->drv_data = NULL; 263 263 ··· 325 325 free_rproc: 326 326 /* Reset device data upon error */ 327 327 mdev->drv_data = NULL; 328 - rproc_put(rproc); 328 + rproc_free(rproc); 329 329 return err; 330 330 } 331 331
+4 -2
drivers/remoteproc/wkup_m3_rproc.c
··· 167 167 goto err; 168 168 } 169 169 170 + rproc->auto_boot = false; 171 + 170 172 wkupm3 = rproc->priv; 171 173 wkupm3->rproc = rproc; 172 174 wkupm3->pdev = pdev; ··· 208 206 return 0; 209 207 210 208 err_put_rproc: 211 - rproc_put(rproc); 209 + rproc_free(rproc); 212 210 err: 213 211 pm_runtime_put_noidle(dev); 214 212 pm_runtime_disable(dev); ··· 220 218 struct rproc *rproc = platform_get_drvdata(pdev); 221 219 222 220 rproc_del(rproc); 223 - rproc_put(rproc); 221 + rproc_free(rproc); 224 222 pm_runtime_put_sync(&pdev->dev); 225 223 pm_runtime_disable(&pdev->dev); 226 224
+3 -3
include/linux/platform_data/remoteproc-omap.h
··· 39 39 const char *firmware; 40 40 const char *mbox_name; 41 41 const struct rproc_ops *ops; 42 - int (*device_enable) (struct platform_device *pdev); 43 - int (*device_shutdown) (struct platform_device *pdev); 44 - void(*set_bootaddr)(u32); 42 + int (*device_enable)(struct platform_device *pdev); 43 + int (*device_shutdown)(struct platform_device *pdev); 44 + void (*set_bootaddr)(u32); 45 45 }; 46 46 47 47 #if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE)
+8 -8
include/linux/remoteproc.h
··· 118 118 RSC_LAST = 4, 119 119 }; 120 120 121 - #define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF) 121 + #define FW_RSC_ADDR_ANY (-1) 122 122 123 123 /** 124 124 * struct fw_rsc_carveout - physically contiguous memory request ··· 241 241 * @notifyid is a unique rproc-wide notify index for this vring. This notify 242 242 * index is used when kicking a remote processor, to let it know that this 243 243 * vring is triggered. 244 - * @reserved: reserved (must be zero) 244 + * @pa: physical address 245 245 * 246 246 * This descriptor is not a resource entry by itself; it is part of the 247 247 * vdev resource type (see below). ··· 255 255 u32 align; 256 256 u32 num; 257 257 u32 notifyid; 258 - u32 reserved; 258 + u32 pa; 259 259 } __packed; 260 260 261 261 /** ··· 409 409 * @max_notifyid: largest allocated notify id. 410 410 * @table_ptr: pointer to the resource table in effect 411 411 * @cached_table: copy of the resource table 412 - * @table_csum: checksum of the resource table 413 412 * @has_iommu: flag to indicate if remote processor is behind an MMU 414 413 */ 415 414 struct rproc { ··· 434 435 struct idr notifyids; 435 436 int index; 436 437 struct work_struct crash_handler; 437 - unsigned crash_cnt; 438 + unsigned int crash_cnt; 438 439 struct completion crash_comp; 439 440 bool recovery_disabled; 440 441 int max_notifyid; 441 442 struct resource_table *table_ptr; 442 443 struct resource_table *cached_table; 443 - u32 table_csum; 444 444 bool has_iommu; 445 + bool auto_boot; 445 446 }; 446 447 447 448 /* we currently support only two vrings per rvdev */ ··· 488 489 489 490 struct rproc *rproc_get_by_phandle(phandle phandle); 490 491 struct rproc *rproc_alloc(struct device *dev, const char *name, 491 - const struct rproc_ops *ops, 492 - const char *firmware, int len); 492 + const struct rproc_ops *ops, 493 + const char *firmware, int len); 493 494 void rproc_put(struct rproc *rproc); 494 495 int rproc_add(struct rproc *rproc); 495 496 int rproc_del(struct rproc *rproc); 497 + void rproc_free(struct rproc *rproc); 496 498 497 499 int rproc_boot(struct rproc *rproc); 498 500 void rproc_shutdown(struct rproc *rproc);