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

Merge tag 'rproc-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull remoteproc updates from Bjorn Andersson:

- Enable coredump support for the i.MX HiFi core remoteproc, and clean
up the i.MX remoteproc driver.

- Introduce remoteprocs on the Qualcomm Milos platform. Gracefully shut
own the ADSP remoteproc when bootloader has loaded the "Lite"
firmware on X Elite. Improve the resource handover procedure to avoid
possibly duplicate handling.

- Transition the TI DA8xx, TI Keystone, and TI Wakeup M3 remoteproc
drivers to handle resources using devres.

* tag 'rproc-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (29 commits)
remoteproc: pru: Fix potential NULL pointer dereference in pru_rproc_set_ctable()
remoteproc: qcom: pas: Drop redundant assignment to ret
remoteproc: qcom: pas: Shutdown lite ADSP DTB on X1E
remoteproc: qcom: q6v5: Avoid handling handover twice
remoteproc: qcom: q6v5: Avoid disabling handover IRQ twice
remoteproc: qcom: pas: Add Milos remoteproc support
dt-bindings: remoteproc: qcom,milos-pas: Document remoteprocs
remoteproc: qcom_q6v5_mss: support loading MBN file on msm8974
remoteproc: imx_rproc: Clean up after ops introduction
remoteproc: imx_rproc: Simplify IMX_RPROC_SMC switch case
remoteproc: imx_rproc: Simplify IMX_RPROC_SCU_API switch case
remoteproc: imx_rproc: Simplify IMX_RPROC_MMIO switch case
remoteproc: imx_rproc: Move imx_rproc_dcfg closer to imx_rproc_of_match
remoteproc: imx_rproc: Introduce start/stop/detect_mode ops for imx_rproc_dcfg
remoteproc: k3: Correctly release some resources allocated in k3_rproc_request_mbox()
remoteproc: wkup_m3: Use devm_rproc_add() helper
remoteproc: wkup_m3: Use devm_rproc_alloc() helper
remoteproc: wkup_m3: Use devm action to call PM runtime put sync
remoteproc: wkup_m3: Use devm_pm_runtime_enable() helper
remoteproc: keystone: Use devm_rproc_add() helper
...

+636 -365
+198
Documentation/devicetree/bindings/remoteproc/qcom,milos-pas.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/remoteproc/qcom,milos-pas.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Milos SoC Peripheral Authentication Service 8 + 9 + maintainers: 10 + - Luca Weiss <luca.weiss@fairphone.com> 11 + 12 + description: 13 + Qualcomm Milos SoC Peripheral Authentication Service loads and boots firmware 14 + on the Qualcomm DSP Hexagon cores. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - qcom,milos-adsp-pas 20 + - qcom,milos-cdsp-pas 21 + - qcom,milos-mpss-pas 22 + - qcom,milos-wpss-pas 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + clocks: 28 + items: 29 + - description: XO clock 30 + 31 + clock-names: 32 + items: 33 + - const: xo 34 + 35 + interrupts: 36 + minItems: 6 37 + maxItems: 6 38 + 39 + interrupt-names: 40 + minItems: 6 41 + maxItems: 6 42 + 43 + qcom,qmp: 44 + $ref: /schemas/types.yaml#/definitions/phandle 45 + description: Reference to the AOSS side-channel message RAM. 46 + 47 + smd-edge: false 48 + 49 + firmware-name: 50 + minItems: 1 51 + items: 52 + - description: Firmware name of the Hexagon core 53 + - description: Firmware name of the Hexagon Devicetree 54 + 55 + memory-region: 56 + minItems: 1 57 + items: 58 + - description: Memory region for core Firmware authentication 59 + - description: Memory region for Devicetree Firmware authentication 60 + 61 + required: 62 + - compatible 63 + - reg 64 + - memory-region 65 + 66 + allOf: 67 + - $ref: /schemas/remoteproc/qcom,pas-common.yaml# 68 + - if: 69 + properties: 70 + compatible: 71 + enum: 72 + - qcom,milos-adsp-pas 73 + - qcom,milos-cdsp-pas 74 + then: 75 + properties: 76 + memory-region: 77 + minItems: 2 78 + firmware-name: 79 + minItems: 2 80 + else: 81 + properties: 82 + memory-region: 83 + maxItems: 1 84 + firmware-name: 85 + maxItems: 1 86 + 87 + - if: 88 + properties: 89 + compatible: 90 + contains: 91 + enum: 92 + - qcom,milos-adsp-pas 93 + then: 94 + properties: 95 + power-domains: 96 + items: 97 + - description: LCX power domain 98 + - description: LMX power domain 99 + power-domain-names: 100 + items: 101 + - const: lcx 102 + - const: lmx 103 + 104 + - if: 105 + properties: 106 + compatible: 107 + enum: 108 + - qcom,milos-cdsp-pas 109 + - qcom,milos-wpss-pas 110 + then: 111 + properties: 112 + power-domains: 113 + items: 114 + - description: CX power domain 115 + - description: MX power domain 116 + power-domain-names: 117 + items: 118 + - const: cx 119 + - const: mx 120 + 121 + - if: 122 + properties: 123 + compatible: 124 + enum: 125 + - qcom,milos-mpss-pas 126 + then: 127 + properties: 128 + power-domains: 129 + items: 130 + - description: CX power domain 131 + - description: MSS power domain 132 + power-domain-names: 133 + items: 134 + - const: cx 135 + - const: mss 136 + 137 + unevaluatedProperties: false 138 + 139 + examples: 140 + - | 141 + #include <dt-bindings/clock/qcom,rpmh.h> 142 + #include <dt-bindings/interconnect/qcom,icc.h> 143 + #include <dt-bindings/interconnect/qcom,milos-rpmh.h> 144 + #include <dt-bindings/interrupt-controller/irq.h> 145 + #include <dt-bindings/mailbox/qcom-ipcc.h> 146 + #include <dt-bindings/power/qcom,rpmhpd.h> 147 + 148 + remoteproc@3000000 { 149 + compatible = "qcom,milos-adsp-pas"; 150 + reg = <0x03000000 0x10000>; 151 + 152 + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, 153 + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, 154 + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, 155 + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, 156 + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>, 157 + <&smp2p_adsp_in 7 IRQ_TYPE_EDGE_RISING>; 158 + interrupt-names = "wdog", 159 + "fatal", 160 + "ready", 161 + "handover", 162 + "stop-ack", 163 + "shutdown-ack"; 164 + 165 + clocks = <&rpmhcc RPMH_CXO_CLK>; 166 + clock-names = "xo"; 167 + 168 + power-domains = <&rpmhpd RPMHPD_LCX>, 169 + <&rpmhpd RPMHPD_LMX>; 170 + power-domain-names = "lcx", 171 + "lmx"; 172 + 173 + interconnects = <&lpass_ag_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS 174 + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; 175 + 176 + memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; 177 + 178 + firmware-name = "qcom/milos/vendor/device/adsp.mbn", 179 + "qcom/milos/vendor/device/adsp_dtb.mbn"; 180 + 181 + qcom,qmp = <&aoss_qmp>; 182 + 183 + qcom,smem-states = <&smp2p_adsp_out 0>; 184 + qcom,smem-state-names = "stop"; 185 + 186 + glink-edge { 187 + interrupts-extended = <&ipcc IPCC_CLIENT_LPASS 188 + IPCC_MPROC_SIGNAL_GLINK_QMP 189 + IRQ_TYPE_EDGE_RISING>; 190 + mboxes = <&ipcc IPCC_CLIENT_LPASS 191 + IPCC_MPROC_SIGNAL_GLINK_QMP>; 192 + 193 + label = "lpass"; 194 + qcom,remote-pid = <2>; 195 + 196 + /* ... */ 197 + }; 198 + };
+17 -40
drivers/remoteproc/da8xx_remoteproc.c
··· 233 233 return 0; 234 234 } 235 235 236 + static void da8xx_rproc_mem_release(void *data) 237 + { 238 + struct device *dev = data; 239 + 240 + of_reserved_mem_device_release(dev); 241 + } 242 + 236 243 static int da8xx_rproc_probe(struct platform_device *pdev) 237 244 { 238 245 struct device *dev = &pdev->dev; ··· 281 274 ret = of_reserved_mem_device_init(dev); 282 275 if (ret) 283 276 return dev_err_probe(dev, ret, "device does not have specific CMA pool\n"); 277 + devm_add_action_or_reset(&pdev->dev, da8xx_rproc_mem_release, &pdev->dev); 284 278 } 285 279 286 - rproc = rproc_alloc(dev, "dsp", &da8xx_rproc_ops, da8xx_fw_name, 287 - sizeof(*drproc)); 288 - if (!rproc) { 289 - ret = -ENOMEM; 290 - goto free_mem; 291 - } 280 + rproc = devm_rproc_alloc(dev, "dsp", &da8xx_rproc_ops, da8xx_fw_name, 281 + sizeof(*drproc)); 282 + if (!rproc) 283 + return -ENOMEM; 292 284 293 285 /* error recovery is not supported at present */ 294 286 rproc->recovery_disabled = true; ··· 300 294 301 295 ret = da8xx_rproc_get_internal_memories(pdev, drproc); 302 296 if (ret) 303 - goto free_rproc; 304 - 305 - platform_set_drvdata(pdev, rproc); 297 + return ret; 306 298 307 299 /* everything the ISR needs is now setup, so hook it up */ 308 300 ret = devm_request_threaded_irq(dev, irq, da8xx_rproc_callback, ··· 308 304 rproc); 309 305 if (ret) { 310 306 dev_err(dev, "devm_request_threaded_irq error: %d\n", ret); 311 - goto free_rproc; 307 + return ret; 312 308 } 313 309 314 310 /* ··· 318 314 */ 319 315 ret = reset_control_assert(dsp_reset); 320 316 if (ret) 321 - goto free_rproc; 317 + return ret; 322 318 323 319 drproc->chipsig = chipsig; 324 320 drproc->bootreg = bootreg; ··· 326 322 drproc->irq_data = irq_data; 327 323 drproc->irq = irq; 328 324 329 - ret = rproc_add(rproc); 325 + ret = devm_rproc_add(dev, rproc); 330 326 if (ret) { 331 327 dev_err(dev, "rproc_add failed: %d\n", ret); 332 - goto free_rproc; 328 + return ret; 333 329 } 334 330 335 331 return 0; 336 - 337 - free_rproc: 338 - rproc_free(rproc); 339 - free_mem: 340 - if (dev->of_node) 341 - of_reserved_mem_device_release(dev); 342 - return ret; 343 - } 344 - 345 - static void da8xx_rproc_remove(struct platform_device *pdev) 346 - { 347 - struct rproc *rproc = platform_get_drvdata(pdev); 348 - struct da8xx_rproc *drproc = rproc->priv; 349 - struct device *dev = &pdev->dev; 350 - 351 - /* 352 - * The devm subsystem might end up releasing things before 353 - * freeing the irq, thus allowing an interrupt to sneak in while 354 - * the device is being removed. This should prevent that. 355 - */ 356 - disable_irq(drproc->irq); 357 - 358 - rproc_del(rproc); 359 - rproc_free(rproc); 360 - if (dev->of_node) 361 - of_reserved_mem_device_release(dev); 362 332 } 363 333 364 334 static const struct of_device_id davinci_rproc_of_match[] __maybe_unused = { ··· 343 365 344 366 static struct platform_driver da8xx_rproc_driver = { 345 367 .probe = da8xx_rproc_probe, 346 - .remove = da8xx_rproc_remove, 347 368 .driver = { 348 369 .name = "davinci-rproc", 349 370 .of_match_table = of_match_ptr(davinci_rproc_of_match),
+29 -16
drivers/remoteproc/imx_dsp_rproc.c
··· 774 774 { 775 775 struct imx_dsp_rproc *priv = rproc->priv; 776 776 struct device *dev = rproc->dev.parent; 777 - struct rproc_mem_entry *carveout; 778 777 int ret; 779 778 780 779 ret = imx_dsp_rproc_add_carveout(priv); ··· 783 784 } 784 785 785 786 pm_runtime_get_sync(dev); 786 - 787 - /* 788 - * Clear buffers after pm rumtime for internal ocram is not 789 - * accessible if power and clock are not enabled. 790 - */ 791 - list_for_each_entry(carveout, &rproc->carveouts, node) { 792 - if (carveout->va) 793 - memset(carveout->va, 0, carveout->len); 794 - } 795 787 796 788 return 0; 797 789 } ··· 1012 1022 return 0; 1013 1023 } 1014 1024 1025 + static int imx_dsp_rproc_load(struct rproc *rproc, const struct firmware *fw) 1026 + { 1027 + struct imx_dsp_rproc *priv = rproc->priv; 1028 + const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg; 1029 + struct rproc_mem_entry *carveout; 1030 + int ret; 1031 + 1032 + /* Reset DSP if needed */ 1033 + if (dsp_dcfg->reset) 1034 + dsp_dcfg->reset(priv); 1035 + /* 1036 + * Clear buffers after pm rumtime for internal ocram is not 1037 + * accessible if power and clock are not enabled. 1038 + */ 1039 + list_for_each_entry(carveout, &rproc->carveouts, node) { 1040 + if (carveout->va) 1041 + memset(carveout->va, 0, carveout->len); 1042 + } 1043 + 1044 + ret = imx_dsp_rproc_elf_load_segments(rproc, fw); 1045 + if (ret) 1046 + return ret; 1047 + 1048 + return 0; 1049 + } 1050 + 1015 1051 static const struct rproc_ops imx_dsp_rproc_ops = { 1016 1052 .prepare = imx_dsp_rproc_prepare, 1017 1053 .unprepare = imx_dsp_rproc_unprepare, 1018 1054 .start = imx_dsp_rproc_start, 1019 1055 .stop = imx_dsp_rproc_stop, 1020 1056 .kick = imx_dsp_rproc_kick, 1021 - .load = imx_dsp_rproc_elf_load_segments, 1057 + .load = imx_dsp_rproc_load, 1022 1058 .parse_fw = imx_dsp_rproc_parse_fw, 1023 1059 .handle_rsc = imx_dsp_rproc_handle_rsc, 1024 1060 .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table, ··· 1205 1189 goto err_detach_domains; 1206 1190 } 1207 1191 1192 + rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_XTENSA); 1193 + 1208 1194 pm_runtime_enable(dev); 1209 1195 1210 1196 return 0; ··· 1232 1214 { 1233 1215 struct rproc *rproc = dev_get_drvdata(dev); 1234 1216 struct imx_dsp_rproc *priv = rproc->priv; 1235 - const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg; 1236 1217 int ret; 1237 1218 1238 1219 /* ··· 1251 1234 dev_err(dev, "failed on clk_bulk_prepare_enable\n"); 1252 1235 return ret; 1253 1236 } 1254 - 1255 - /* Reset DSP if needed */ 1256 - if (dsp_dcfg->reset) 1257 - dsp_dcfg->reset(priv); 1258 1237 1259 1238 return 0; 1260 1239 }
+259 -192
drivers/remoteproc/imx_rproc.c
··· 285 285 { 0x80000000, 0x80000000, 0x60000000, 0 }, 286 286 }; 287 287 288 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = { 289 - .src_reg = IMX7D_SRC_SCR, 290 - .src_mask = IMX7D_M4_RST_MASK, 291 - .src_start = IMX7D_M4_START, 292 - .src_stop = IMX8M_M7_STOP, 293 - .gpr_reg = IMX8M_GPR22, 294 - .gpr_wait = IMX8M_GPR22_CM7_CPUWAIT, 295 - .att = imx_rproc_att_imx8mn, 296 - .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn), 297 - .method = IMX_RPROC_MMIO, 298 - }; 288 + static int imx_rproc_arm_smc_start(struct rproc *rproc) 289 + { 290 + struct arm_smccc_res res; 299 291 300 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = { 301 - .att = imx_rproc_att_imx8mn, 302 - .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn), 303 - .method = IMX_RPROC_SMC, 304 - }; 292 + arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res); 305 293 306 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = { 307 - .src_reg = IMX7D_SRC_SCR, 308 - .src_mask = IMX7D_M4_RST_MASK, 309 - .src_start = IMX7D_M4_START, 310 - .src_stop = IMX7D_M4_STOP, 311 - .att = imx_rproc_att_imx8mq, 312 - .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq), 313 - .method = IMX_RPROC_MMIO, 314 - }; 294 + return res.a0; 295 + } 315 296 316 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = { 317 - .att = imx_rproc_att_imx8qm, 318 - .att_size = ARRAY_SIZE(imx_rproc_att_imx8qm), 319 - .method = IMX_RPROC_SCU_API, 320 - }; 297 + static int imx_rproc_mmio_start(struct rproc *rproc) 298 + { 299 + struct imx_rproc *priv = rproc->priv; 300 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 321 301 322 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = { 323 - .att = imx_rproc_att_imx8qxp, 324 - .att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp), 325 - .method = IMX_RPROC_SCU_API, 326 - }; 302 + if (priv->gpr) 303 + return regmap_clear_bits(priv->gpr, dcfg->gpr_reg, dcfg->gpr_wait); 327 304 328 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = { 329 - .att = imx_rproc_att_imx8ulp, 330 - .att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp), 331 - .method = IMX_RPROC_NONE, 332 - }; 305 + return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_start); 306 + } 333 307 334 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = { 335 - .att = imx_rproc_att_imx7ulp, 336 - .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp), 337 - .method = IMX_RPROC_NONE, 338 - .flags = IMX_RPROC_NEED_SYSTEM_OFF, 339 - }; 308 + static int imx_rproc_scu_api_start(struct rproc *rproc) 309 + { 310 + struct imx_rproc *priv = rproc->priv; 340 311 341 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = { 342 - .src_reg = IMX7D_SRC_SCR, 343 - .src_mask = IMX7D_M4_RST_MASK, 344 - .src_start = IMX7D_M4_START, 345 - .src_stop = IMX7D_M4_STOP, 346 - .att = imx_rproc_att_imx7d, 347 - .att_size = ARRAY_SIZE(imx_rproc_att_imx7d), 348 - .method = IMX_RPROC_MMIO, 349 - }; 350 - 351 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = { 352 - .src_reg = IMX6SX_SRC_SCR, 353 - .src_mask = IMX6SX_M4_RST_MASK, 354 - .src_start = IMX6SX_M4_START, 355 - .src_stop = IMX6SX_M4_STOP, 356 - .att = imx_rproc_att_imx6sx, 357 - .att_size = ARRAY_SIZE(imx_rproc_att_imx6sx), 358 - .method = IMX_RPROC_MMIO, 359 - }; 360 - 361 - static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = { 362 - .att = imx_rproc_att_imx93, 363 - .att_size = ARRAY_SIZE(imx_rproc_att_imx93), 364 - .method = IMX_RPROC_SMC, 365 - }; 312 + return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry); 313 + } 366 314 367 315 static int imx_rproc_start(struct rproc *rproc) 368 316 { 369 317 struct imx_rproc *priv = rproc->priv; 370 318 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 371 319 struct device *dev = priv->dev; 372 - struct arm_smccc_res res; 373 320 int ret; 374 321 375 322 ret = imx_rproc_xtr_mbox_init(rproc, true); 376 323 if (ret) 377 324 return ret; 378 325 379 - switch (dcfg->method) { 380 - case IMX_RPROC_MMIO: 381 - if (priv->gpr) { 382 - ret = regmap_clear_bits(priv->gpr, dcfg->gpr_reg, 383 - dcfg->gpr_wait); 384 - } else { 385 - ret = regmap_update_bits(priv->regmap, dcfg->src_reg, 386 - dcfg->src_mask, 387 - dcfg->src_start); 388 - } 389 - break; 390 - case IMX_RPROC_SMC: 391 - arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res); 392 - ret = res.a0; 393 - break; 394 - case IMX_RPROC_SCU_API: 395 - ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry); 396 - break; 397 - default: 326 + if (!dcfg->ops || !dcfg->ops->start) 398 327 return -EOPNOTSUPP; 399 - } 400 328 329 + ret = dcfg->ops->start(rproc); 401 330 if (ret) 402 331 dev_err(dev, "Failed to enable remote core!\n"); 403 332 404 333 return ret; 334 + } 335 + 336 + static int imx_rproc_arm_smc_stop(struct rproc *rproc) 337 + { 338 + struct imx_rproc *priv = rproc->priv; 339 + struct arm_smccc_res res; 340 + 341 + arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res); 342 + if (res.a1) 343 + dev_info(priv->dev, "Not in wfi, force stopped\n"); 344 + 345 + return res.a0; 346 + } 347 + 348 + static int imx_rproc_mmio_stop(struct rproc *rproc) 349 + { 350 + struct imx_rproc *priv = rproc->priv; 351 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 352 + int ret; 353 + 354 + if (priv->gpr) { 355 + ret = regmap_set_bits(priv->gpr, dcfg->gpr_reg, dcfg->gpr_wait); 356 + if (ret) { 357 + dev_err(priv->dev, "Failed to quiescence M4 platform!\n"); 358 + return ret; 359 + } 360 + } 361 + 362 + return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_stop); 363 + } 364 + 365 + static int imx_rproc_scu_api_stop(struct rproc *rproc) 366 + { 367 + struct imx_rproc *priv = rproc->priv; 368 + 369 + return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry); 405 370 } 406 371 407 372 static int imx_rproc_stop(struct rproc *rproc) ··· 374 409 struct imx_rproc *priv = rproc->priv; 375 410 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 376 411 struct device *dev = priv->dev; 377 - struct arm_smccc_res res; 378 412 int ret; 379 413 380 - switch (dcfg->method) { 381 - case IMX_RPROC_MMIO: 382 - if (priv->gpr) { 383 - ret = regmap_set_bits(priv->gpr, dcfg->gpr_reg, 384 - dcfg->gpr_wait); 385 - if (ret) { 386 - dev_err(priv->dev, 387 - "Failed to quiescence M4 platform!\n"); 388 - return ret; 389 - } 390 - } 391 - 392 - ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, 393 - dcfg->src_stop); 394 - break; 395 - case IMX_RPROC_SMC: 396 - arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res); 397 - ret = res.a0; 398 - if (res.a1) 399 - dev_info(dev, "Not in wfi, force stopped\n"); 400 - break; 401 - case IMX_RPROC_SCU_API: 402 - ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry); 403 - break; 404 - default: 414 + if (!dcfg->ops || !dcfg->ops->stop) 405 415 return -EOPNOTSUPP; 406 - } 407 416 417 + ret = dcfg->ops->stop(rproc); 408 418 if (ret) 409 419 dev_err(dev, "Failed to stop remote core\n"); 410 420 else ··· 862 922 return 0; 863 923 } 864 924 865 - static int imx_rproc_detect_mode(struct imx_rproc *priv) 925 + static int imx_rproc_arm_smc_detect_mode(struct rproc *rproc) 866 926 { 867 - struct regmap_config config = { .name = "imx-rproc" }; 927 + struct imx_rproc *priv = rproc->priv; 928 + struct arm_smccc_res res; 929 + 930 + arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res); 931 + if (res.a0) 932 + priv->rproc->state = RPROC_DETACHED; 933 + 934 + return 0; 935 + } 936 + 937 + static int imx_rproc_mmio_detect_mode(struct rproc *rproc) 938 + { 939 + const struct regmap_config config = { .name = "imx-rproc" }; 940 + struct imx_rproc *priv = rproc->priv; 868 941 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 869 942 struct device *dev = priv->dev; 870 943 struct regmap *regmap; 871 - struct arm_smccc_res res; 872 - int ret; 873 944 u32 val; 874 - u8 pt; 875 - 876 - switch (dcfg->method) { 877 - case IMX_RPROC_NONE: 878 - priv->rproc->state = RPROC_DETACHED; 879 - return 0; 880 - case IMX_RPROC_SMC: 881 - arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res); 882 - if (res.a0) 883 - priv->rproc->state = RPROC_DETACHED; 884 - return 0; 885 - case IMX_RPROC_SCU_API: 886 - ret = imx_scu_get_handle(&priv->ipc_handle); 887 - if (ret) 888 - return ret; 889 - ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id); 890 - if (ret) { 891 - dev_err(dev, "No fsl,resource-id property\n"); 892 - return ret; 893 - } 894 - 895 - if (priv->rsrc_id == IMX_SC_R_M4_1_PID0) 896 - priv->core_index = 1; 897 - else 898 - priv->core_index = 0; 899 - 900 - /* 901 - * If Mcore resource is not owned by Acore partition, It is kicked by ROM, 902 - * and Linux could only do IPC with Mcore and nothing else. 903 - */ 904 - if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) { 905 - if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry)) 906 - return -EINVAL; 907 - 908 - return imx_rproc_attach_pd(priv); 909 - } 910 - 911 - priv->rproc->state = RPROC_DETACHED; 912 - priv->rproc->recovery_disabled = false; 913 - rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY); 914 - 915 - /* Get partition id and enable irq in SCFW */ 916 - ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt); 917 - if (ret) { 918 - dev_err(dev, "not able to get resource owner\n"); 919 - return ret; 920 - } 921 - 922 - priv->rproc_pt = pt; 923 - priv->rproc_nb.notifier_call = imx_rproc_partition_notify; 924 - 925 - ret = imx_scu_irq_register_notifier(&priv->rproc_nb); 926 - if (ret) { 927 - dev_err(dev, "register scu notifier failed, %d\n", ret); 928 - return ret; 929 - } 930 - 931 - ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), 932 - true); 933 - if (ret) { 934 - imx_scu_irq_unregister_notifier(&priv->rproc_nb); 935 - dev_err(dev, "Enable irq failed, %d\n", ret); 936 - return ret; 937 - } 938 - 939 - return 0; 940 - default: 941 - break; 942 - } 945 + int ret; 943 946 944 947 priv->gpr = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,iomuxc-gpr"); 945 948 if (IS_ERR(priv->gpr)) ··· 920 1037 priv->rproc->state = RPROC_DETACHED; 921 1038 922 1039 return 0; 1040 + } 1041 + 1042 + static int imx_rproc_scu_api_detect_mode(struct rproc *rproc) 1043 + { 1044 + struct imx_rproc *priv = rproc->priv; 1045 + struct device *dev = priv->dev; 1046 + int ret; 1047 + u8 pt; 1048 + 1049 + ret = imx_scu_get_handle(&priv->ipc_handle); 1050 + if (ret) 1051 + return ret; 1052 + ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id); 1053 + if (ret) { 1054 + dev_err(dev, "No fsl,resource-id property\n"); 1055 + return ret; 1056 + } 1057 + 1058 + if (priv->rsrc_id == IMX_SC_R_M4_1_PID0) 1059 + priv->core_index = 1; 1060 + else 1061 + priv->core_index = 0; 1062 + 1063 + /* 1064 + * If Mcore resource is not owned by Acore partition, It is kicked by ROM, 1065 + * and Linux could only do IPC with Mcore and nothing else. 1066 + */ 1067 + if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) { 1068 + if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry)) 1069 + return -EINVAL; 1070 + 1071 + return imx_rproc_attach_pd(priv); 1072 + } 1073 + 1074 + priv->rproc->state = RPROC_DETACHED; 1075 + priv->rproc->recovery_disabled = false; 1076 + rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY); 1077 + 1078 + /* Get partition id and enable irq in SCFW */ 1079 + ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt); 1080 + if (ret) { 1081 + dev_err(dev, "not able to get resource owner\n"); 1082 + return ret; 1083 + } 1084 + 1085 + priv->rproc_pt = pt; 1086 + priv->rproc_nb.notifier_call = imx_rproc_partition_notify; 1087 + 1088 + ret = imx_scu_irq_register_notifier(&priv->rproc_nb); 1089 + if (ret) { 1090 + dev_err(dev, "register scu notifier failed, %d\n", ret); 1091 + return ret; 1092 + } 1093 + 1094 + ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), 1095 + true); 1096 + if (ret) { 1097 + imx_scu_irq_unregister_notifier(&priv->rproc_nb); 1098 + dev_err(dev, "Enable irq failed, %d\n", ret); 1099 + return ret; 1100 + } 1101 + 1102 + return 0; 1103 + } 1104 + 1105 + static int imx_rproc_detect_mode(struct imx_rproc *priv) 1106 + { 1107 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 1108 + 1109 + /* 1110 + * To i.MX{7,8} ULP, Linux is under control of RTOS, no need 1111 + * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED. 1112 + */ 1113 + if (!dcfg->ops || !dcfg->ops->detect_mode) { 1114 + priv->rproc->state = RPROC_DETACHED; 1115 + return 0; 1116 + } 1117 + 1118 + return dcfg->ops->detect_mode(priv->rproc); 923 1119 } 924 1120 925 1121 static int imx_rproc_clk_enable(struct imx_rproc *priv) ··· 1168 1206 imx_rproc_free_mbox(rproc); 1169 1207 destroy_workqueue(priv->workqueue); 1170 1208 } 1209 + 1210 + static const struct imx_rproc_plat_ops imx_rproc_ops_arm_smc = { 1211 + .start = imx_rproc_arm_smc_start, 1212 + .stop = imx_rproc_arm_smc_stop, 1213 + .detect_mode = imx_rproc_arm_smc_detect_mode, 1214 + }; 1215 + 1216 + static const struct imx_rproc_plat_ops imx_rproc_ops_mmio = { 1217 + .start = imx_rproc_mmio_start, 1218 + .stop = imx_rproc_mmio_stop, 1219 + .detect_mode = imx_rproc_mmio_detect_mode, 1220 + }; 1221 + 1222 + static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = { 1223 + .start = imx_rproc_scu_api_start, 1224 + .stop = imx_rproc_scu_api_stop, 1225 + .detect_mode = imx_rproc_scu_api_detect_mode, 1226 + }; 1227 + 1228 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = { 1229 + .src_reg = IMX7D_SRC_SCR, 1230 + .src_mask = IMX7D_M4_RST_MASK, 1231 + .src_start = IMX7D_M4_START, 1232 + .src_stop = IMX8M_M7_STOP, 1233 + .gpr_reg = IMX8M_GPR22, 1234 + .gpr_wait = IMX8M_GPR22_CM7_CPUWAIT, 1235 + .att = imx_rproc_att_imx8mn, 1236 + .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn), 1237 + .method = IMX_RPROC_MMIO, 1238 + .ops = &imx_rproc_ops_mmio, 1239 + }; 1240 + 1241 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = { 1242 + .att = imx_rproc_att_imx8mn, 1243 + .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn), 1244 + .method = IMX_RPROC_SMC, 1245 + .ops = &imx_rproc_ops_arm_smc, 1246 + }; 1247 + 1248 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = { 1249 + .src_reg = IMX7D_SRC_SCR, 1250 + .src_mask = IMX7D_M4_RST_MASK, 1251 + .src_start = IMX7D_M4_START, 1252 + .src_stop = IMX7D_M4_STOP, 1253 + .att = imx_rproc_att_imx8mq, 1254 + .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq), 1255 + .method = IMX_RPROC_MMIO, 1256 + .ops = &imx_rproc_ops_mmio, 1257 + }; 1258 + 1259 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = { 1260 + .att = imx_rproc_att_imx8qm, 1261 + .att_size = ARRAY_SIZE(imx_rproc_att_imx8qm), 1262 + .method = IMX_RPROC_SCU_API, 1263 + .ops = &imx_rproc_ops_scu_api, 1264 + }; 1265 + 1266 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = { 1267 + .att = imx_rproc_att_imx8qxp, 1268 + .att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp), 1269 + .method = IMX_RPROC_SCU_API, 1270 + .ops = &imx_rproc_ops_scu_api, 1271 + }; 1272 + 1273 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = { 1274 + .att = imx_rproc_att_imx8ulp, 1275 + .att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp), 1276 + .method = IMX_RPROC_NONE, 1277 + }; 1278 + 1279 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = { 1280 + .att = imx_rproc_att_imx7ulp, 1281 + .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp), 1282 + .method = IMX_RPROC_NONE, 1283 + .flags = IMX_RPROC_NEED_SYSTEM_OFF, 1284 + }; 1285 + 1286 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = { 1287 + .src_reg = IMX7D_SRC_SCR, 1288 + .src_mask = IMX7D_M4_RST_MASK, 1289 + .src_start = IMX7D_M4_START, 1290 + .src_stop = IMX7D_M4_STOP, 1291 + .att = imx_rproc_att_imx7d, 1292 + .att_size = ARRAY_SIZE(imx_rproc_att_imx7d), 1293 + .method = IMX_RPROC_MMIO, 1294 + .ops = &imx_rproc_ops_mmio, 1295 + }; 1296 + 1297 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = { 1298 + .src_reg = IMX6SX_SRC_SCR, 1299 + .src_mask = IMX6SX_M4_RST_MASK, 1300 + .src_start = IMX6SX_M4_START, 1301 + .src_stop = IMX6SX_M4_STOP, 1302 + .att = imx_rproc_att_imx6sx, 1303 + .att_size = ARRAY_SIZE(imx_rproc_att_imx6sx), 1304 + .method = IMX_RPROC_MMIO, 1305 + .ops = &imx_rproc_ops_mmio, 1306 + }; 1307 + 1308 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = { 1309 + .att = imx_rproc_att_imx93, 1310 + .att_size = ARRAY_SIZE(imx_rproc_att_imx93), 1311 + .method = IMX_RPROC_SMC, 1312 + .ops = &imx_rproc_ops_arm_smc, 1313 + }; 1171 1314 1172 1315 static const struct of_device_id imx_rproc_of_match[] = { 1173 1316 { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
+7
drivers/remoteproc/imx_rproc.h
··· 31 31 /* dcfg flags */ 32 32 #define IMX_RPROC_NEED_SYSTEM_OFF BIT(0) 33 33 34 + struct imx_rproc_plat_ops { 35 + int (*start)(struct rproc *rproc); 36 + int (*stop)(struct rproc *rproc); 37 + int (*detect_mode)(struct rproc *rproc); 38 + }; 39 + 34 40 struct imx_rproc_dcfg { 35 41 u32 src_reg; 36 42 u32 src_mask; ··· 48 42 size_t att_size; 49 43 enum imx_rproc_method method; 50 44 u32 flags; 45 + const struct imx_rproc_plat_ops *ops; 51 46 }; 52 47 53 48 #endif /* _IMX_RPROC_H */
+43 -52
drivers/remoteproc/keystone_remoteproc.c
··· 349 349 return 0; 350 350 } 351 351 352 + static void keystone_rproc_mem_release(void *data) 353 + { 354 + struct device *dev = data; 355 + 356 + of_reserved_mem_device_release(dev); 357 + } 358 + 359 + static void keystone_rproc_pm_runtime_put(void *data) 360 + { 361 + struct device *dev = data; 362 + 363 + pm_runtime_put_sync(dev); 364 + } 365 + 352 366 static int keystone_rproc_probe(struct platform_device *pdev) 353 367 { 354 368 struct device *dev = &pdev->dev; ··· 408 394 return PTR_ERR(ksproc->reset); 409 395 410 396 /* enable clock for accessing DSP internal memories */ 411 - pm_runtime_enable(dev); 397 + ret = devm_pm_runtime_enable(dev); 398 + if (ret < 0) 399 + return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); 400 + 412 401 ret = pm_runtime_resume_and_get(dev); 413 - if (ret < 0) { 414 - dev_err(dev, "failed to enable clock, status = %d\n", ret); 415 - goto disable_rpm; 416 - } 402 + if (ret < 0) 403 + return dev_err_probe(dev, ret, "failed to enable clock\n"); 404 + 405 + ret = devm_add_action_or_reset(dev, keystone_rproc_pm_runtime_put, dev); 406 + if (ret) 407 + return dev_err_probe(dev, ret, "failed to add disable pm devm action\n"); 417 408 418 409 ret = keystone_rproc_of_get_memories(pdev, ksproc); 419 410 if (ret) 420 - goto disable_clk; 411 + return ret; 421 412 422 413 ksproc->irq_ring = platform_get_irq_byname(pdev, "vring"); 423 - if (ksproc->irq_ring < 0) { 424 - ret = ksproc->irq_ring; 425 - goto disable_clk; 426 - } 414 + if (ksproc->irq_ring < 0) 415 + return ksproc->irq_ring; 427 416 428 417 ksproc->irq_fault = platform_get_irq_byname(pdev, "exception"); 429 - if (ksproc->irq_fault < 0) { 430 - ret = ksproc->irq_fault; 431 - goto disable_clk; 432 - } 418 + if (ksproc->irq_fault < 0) 419 + return ksproc->irq_fault; 433 420 434 - ksproc->kick_gpio = gpiod_get(dev, "kick", GPIOD_ASIS); 421 + ksproc->kick_gpio = devm_gpiod_get(dev, "kick", GPIOD_ASIS); 435 422 ret = PTR_ERR_OR_ZERO(ksproc->kick_gpio); 436 - if (ret) { 437 - dev_err(dev, "failed to get gpio for virtio kicks, status = %d\n", 438 - ret); 439 - goto disable_clk; 440 - } 423 + if (ret) 424 + return dev_err_probe(dev, ret, "failed to get gpio for virtio kicks\n"); 441 425 442 - if (of_reserved_mem_device_init(dev)) 426 + ret = of_reserved_mem_device_init(dev); 427 + if (ret) { 443 428 dev_warn(dev, "device does not have specific CMA pool\n"); 429 + } else { 430 + ret = devm_add_action_or_reset(dev, keystone_rproc_mem_release, dev); 431 + if (ret) 432 + return ret; 433 + } 444 434 445 435 /* ensure the DSP is in reset before loading firmware */ 446 436 ret = reset_control_status(ksproc->reset); 447 437 if (ret < 0) { 448 - dev_err(dev, "failed to get reset status, status = %d\n", ret); 449 - goto release_mem; 438 + return dev_err_probe(dev, ret, "failed to get reset status\n"); 450 439 } else if (ret == 0) { 451 440 WARN(1, "device is not in reset\n"); 452 441 keystone_rproc_dsp_reset(ksproc); 453 442 } 454 443 455 - ret = rproc_add(rproc); 456 - if (ret) { 457 - dev_err(dev, "failed to add register device with remoteproc core, status = %d\n", 458 - ret); 459 - goto release_mem; 460 - } 461 - 462 - platform_set_drvdata(pdev, ksproc); 444 + ret = devm_rproc_add(dev, rproc); 445 + if (ret) 446 + return dev_err_probe(dev, ret, "failed to register device with remoteproc core\n"); 463 447 464 448 return 0; 465 - 466 - release_mem: 467 - of_reserved_mem_device_release(dev); 468 - gpiod_put(ksproc->kick_gpio); 469 - disable_clk: 470 - pm_runtime_put_sync(dev); 471 - disable_rpm: 472 - pm_runtime_disable(dev); 473 - return ret; 474 - } 475 - 476 - static void keystone_rproc_remove(struct platform_device *pdev) 477 - { 478 - struct keystone_rproc *ksproc = platform_get_drvdata(pdev); 479 - 480 - rproc_del(ksproc->rproc); 481 - gpiod_put(ksproc->kick_gpio); 482 - pm_runtime_put_sync(&pdev->dev); 483 - pm_runtime_disable(&pdev->dev); 484 - of_reserved_mem_device_release(&pdev->dev); 485 449 } 486 450 487 451 static const struct of_device_id keystone_rproc_of_match[] = { ··· 473 481 474 482 static struct platform_driver keystone_rproc_driver = { 475 483 .probe = keystone_rproc_probe, 476 - .remove = keystone_rproc_remove, 477 484 .driver = { 478 485 .name = "keystone-rproc", 479 486 .of_match_table = keystone_rproc_of_match,
+2 -1
drivers/remoteproc/pru_rproc.c
··· 340 340 */ 341 341 int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr) 342 342 { 343 - struct pru_rproc *pru = rproc->priv; 343 + struct pru_rproc *pru; 344 344 unsigned int reg; 345 345 u32 mask, set; 346 346 u16 idx; ··· 352 352 if (!rproc->dev.parent || !is_pru_rproc(rproc->dev.parent)) 353 353 return -ENODEV; 354 354 355 + pru = rproc->priv; 355 356 /* pointer is 16 bit and index is 8-bit so mask out the rest */ 356 357 idx_mask = (c >= PRU_C28) ? 0xFFFF : 0xFF; 357 358
+5 -3
drivers/remoteproc/qcom_q6v5.c
··· 156 156 int ret; 157 157 158 158 ret = wait_for_completion_timeout(&q6v5->start_done, timeout); 159 - if (!ret) 160 - disable_irq(q6v5->handover_irq); 161 - 162 159 return !ret ? -ETIMEDOUT : 0; 163 160 } 164 161 EXPORT_SYMBOL_GPL(qcom_q6v5_wait_for_start); ··· 163 166 static irqreturn_t q6v5_handover_interrupt(int irq, void *data) 164 167 { 165 168 struct qcom_q6v5 *q6v5 = data; 169 + 170 + if (q6v5->handover_issued) { 171 + dev_err(q6v5->dev, "Handover signaled, but it already happened\n"); 172 + return IRQ_HANDLED; 173 + } 166 174 167 175 if (q6v5->handover) 168 176 q6v5->handover(q6v5);
+10 -1
drivers/remoteproc/qcom_q6v5_mss.c
··· 498 498 release_firmware(dp_fw); 499 499 } 500 500 501 + #define MSM8974_B00_OFFSET 0x1000 502 + 501 503 static int q6v5_load(struct rproc *rproc, const struct firmware *fw) 502 504 { 503 505 struct q6v5 *qproc = rproc->priv; ··· 518 516 return -EBUSY; 519 517 } 520 518 521 - memcpy(mba_region, fw->data, fw->size); 519 + if ((qproc->version == MSS_MSM8974 || 520 + qproc->version == MSS_MSM8226 || 521 + qproc->version == MSS_MSM8926) && 522 + fw->size > MSM8974_B00_OFFSET && 523 + !memcmp(fw->data, ELFMAG, SELFMAG)) 524 + memcpy(mba_region, fw->data + MSM8974_B00_OFFSET, fw->size - MSM8974_B00_OFFSET); 525 + else 526 + memcpy(mba_region, fw->data, fw->size); 522 527 q6v5_debug_policy_load(qproc, mba_region); 523 528 memunmap(mba_region); 524 529
+31 -1
drivers/remoteproc/qcom_q6v5_pas.c
··· 42 42 int pas_id; 43 43 int dtb_pas_id; 44 44 int lite_pas_id; 45 + int lite_dtb_pas_id; 45 46 unsigned int minidump_id; 46 47 bool auto_boot; 47 48 bool decrypt_shutdown; ··· 81 80 int pas_id; 82 81 int dtb_pas_id; 83 82 int lite_pas_id; 83 + int lite_dtb_pas_id; 84 84 unsigned int minidump_id; 85 85 int crash_reason_smem; 86 86 unsigned int smem_host_id; ··· 227 225 pas->firmware = fw; 228 226 229 227 if (pas->lite_pas_id) 230 - ret = qcom_scm_pas_shutdown(pas->lite_pas_id); 228 + qcom_scm_pas_shutdown(pas->lite_pas_id); 229 + if (pas->lite_dtb_pas_id) 230 + qcom_scm_pas_shutdown(pas->lite_dtb_pas_id); 231 231 232 232 if (pas->dtb_pas_id) { 233 233 ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev); ··· 725 721 pas->minidump_id = desc->minidump_id; 726 722 pas->pas_id = desc->pas_id; 727 723 pas->lite_pas_id = desc->lite_pas_id; 724 + pas->lite_dtb_pas_id = desc->lite_dtb_pas_id; 728 725 pas->info_name = desc->sysmon_name; 729 726 pas->smem_host_id = desc->smem_host_id; 730 727 pas->decrypt_shutdown = desc->decrypt_shutdown; ··· 1089 1084 .pas_id = 1, 1090 1085 .dtb_pas_id = 0x24, 1091 1086 .lite_pas_id = 0x1f, 1087 + .lite_dtb_pas_id = 0x29, 1092 1088 .minidump_id = 5, 1093 1089 .auto_boot = true, 1094 1090 .proxy_pd_names = (char*[]){ ··· 1259 1253 .ssr_name = "mpss", 1260 1254 .sysmon_name = "modem", 1261 1255 .ssctl_id = 0x22, 1256 + }; 1257 + 1258 + static const struct qcom_pas_data milos_cdsp_resource = { 1259 + .crash_reason_smem = 601, 1260 + .firmware_name = "cdsp.mbn", 1261 + .dtb_firmware_name = "cdsp_dtb.mbn", 1262 + .pas_id = 18, 1263 + .dtb_pas_id = 0x25, 1264 + .minidump_id = 7, 1265 + .auto_boot = true, 1266 + .proxy_pd_names = (char*[]){ 1267 + "cx", 1268 + "mx", 1269 + NULL 1270 + }, 1271 + .load_state = "cdsp", 1272 + .ssr_name = "cdsp", 1273 + .sysmon_name = "cdsp", 1274 + .ssctl_id = 0x17, 1275 + .smem_host_id = 5, 1262 1276 }; 1263 1277 1264 1278 static const struct qcom_pas_data sm8450_mpss_resource = { ··· 1455 1429 }; 1456 1430 1457 1431 static const struct of_device_id qcom_pas_of_match[] = { 1432 + { .compatible = "qcom,milos-adsp-pas", .data = &sm8550_adsp_resource}, 1433 + { .compatible = "qcom,milos-cdsp-pas", .data = &milos_cdsp_resource}, 1434 + { .compatible = "qcom,milos-mpss-pas", .data = &sm8450_mpss_resource}, 1435 + { .compatible = "qcom,milos-wpss-pas", .data = &sc7280_wpss_resource}, 1458 1436 { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource}, 1459 1437 { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, 1460 1438 { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
+9 -12
drivers/remoteproc/ti_k3_common.c
··· 155 155 } 156 156 EXPORT_SYMBOL_GPL(k3_rproc_release); 157 157 158 + static void k3_rproc_free_channel(void *data) 159 + { 160 + struct k3_rproc *kproc = data; 161 + 162 + mbox_free_channel(kproc->mbox); 163 + } 164 + 158 165 int k3_rproc_request_mbox(struct rproc *rproc) 159 166 { 160 167 struct k3_rproc *kproc = rproc->priv; ··· 180 173 return dev_err_probe(dev, PTR_ERR(kproc->mbox), 181 174 "mbox_request_channel failed\n"); 182 175 183 - /* 184 - * Ping the remote processor, this is only for sanity-sake for now; 185 - * there is no functional effect whatsoever. 186 - * 187 - * Note that the reply will _not_ arrive immediately: this message 188 - * will wait in the mailbox fifo until the remote processor is booted. 189 - */ 190 - ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST); 191 - if (ret < 0) { 192 - dev_err(dev, "mbox_send_message failed (%pe)\n", ERR_PTR(ret)); 193 - mbox_free_channel(kproc->mbox); 176 + ret = devm_add_action_or_reset(dev, k3_rproc_free_channel, kproc); 177 + if (ret) 194 178 return ret; 195 - } 196 179 197 180 return 0; 198 181 }
-2
drivers/remoteproc/ti_k3_dsp_remoteproc.c
··· 175 175 if (ret) 176 176 dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret)); 177 177 } 178 - 179 - mbox_free_channel(kproc->mbox); 180 178 } 181 179 182 180 static const struct k3_rproc_mem_data c66_mems[] = {
-2
drivers/remoteproc/ti_k3_r5_remoteproc.c
··· 1206 1206 return; 1207 1207 } 1208 1208 } 1209 - 1210 - mbox_free_channel(kproc->mbox); 1211 1209 } 1212 1210 } 1213 1211
+26 -43
drivers/remoteproc/wkup_m3_rproc.c
··· 125 125 }; 126 126 MODULE_DEVICE_TABLE(of, wkup_m3_rproc_of_match); 127 127 128 + static void wkup_m3_rproc_pm_runtime_put(void *data) 129 + { 130 + struct device *dev = data; 131 + 132 + pm_runtime_put_sync(dev); 133 + } 134 + 128 135 static int wkup_m3_rproc_probe(struct platform_device *pdev) 129 136 { 130 137 struct device *dev = &pdev->dev; ··· 155 148 return -ENODEV; 156 149 } 157 150 158 - pm_runtime_enable(&pdev->dev); 151 + ret = devm_pm_runtime_enable(dev); 152 + if (ret < 0) 153 + return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); 159 154 ret = pm_runtime_get_sync(&pdev->dev); 160 - if (ret < 0) { 161 - dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); 162 - goto err; 163 - } 155 + if (ret < 0) 156 + return dev_err_probe(dev, ret, "pm_runtime_get_sync() failed\n"); 157 + ret = devm_add_action_or_reset(dev, wkup_m3_rproc_pm_runtime_put, dev); 158 + if (ret) 159 + return dev_err_probe(dev, ret, "failed to add disable pm devm action\n"); 164 160 165 - rproc = rproc_alloc(dev, "wkup_m3", &wkup_m3_rproc_ops, 166 - fw_name, sizeof(*wkupm3)); 167 - if (!rproc) { 168 - ret = -ENOMEM; 169 - goto err; 170 - } 161 + rproc = devm_rproc_alloc(dev, "wkup_m3", &wkup_m3_rproc_ops, 162 + fw_name, sizeof(*wkupm3)); 163 + if (!rproc) 164 + return -ENOMEM; 171 165 172 166 rproc->auto_boot = false; 173 167 rproc->sysfs_read_only = true; ··· 183 175 if (!wkupm3->rsts) { 184 176 if (!(pdata && pdata->deassert_reset && pdata->assert_reset && 185 177 pdata->reset_name)) { 186 - dev_err(dev, "Platform data missing!\n"); 187 - ret = -ENODEV; 188 - goto err_put_rproc; 178 + return dev_err_probe(dev, -ENODEV, "Platform data missing!\n"); 189 179 } 190 180 } 191 181 ··· 191 185 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 192 186 mem_names[i]); 193 187 wkupm3->mem[i].cpu_addr = devm_ioremap_resource(dev, res); 194 - if (IS_ERR(wkupm3->mem[i].cpu_addr)) { 195 - dev_err(&pdev->dev, "devm_ioremap_resource failed for resource %d\n", 196 - i); 197 - ret = PTR_ERR(wkupm3->mem[i].cpu_addr); 198 - goto err_put_rproc; 199 - } 188 + if (IS_ERR(wkupm3->mem[i].cpu_addr)) 189 + return dev_err_probe(dev, PTR_ERR(wkupm3->mem[i].cpu_addr), 190 + "devm_ioremap_resource failed for resource %d\n", i); 200 191 wkupm3->mem[i].bus_addr = res->start; 201 192 wkupm3->mem[i].size = resource_size(res); 202 193 addrp = of_get_address(dev->of_node, i, &size, NULL); ··· 210 207 211 208 dev_set_drvdata(dev, rproc); 212 209 213 - ret = rproc_add(rproc); 214 - if (ret) { 215 - dev_err(dev, "rproc_add failed\n"); 216 - goto err_put_rproc; 217 - } 210 + ret = devm_rproc_add(dev, rproc); 211 + if (ret) 212 + return dev_err_probe(dev, ret, "rproc_add failed\n"); 218 213 219 214 return 0; 220 - 221 - err_put_rproc: 222 - rproc_free(rproc); 223 - err: 224 - pm_runtime_put_noidle(dev); 225 - pm_runtime_disable(dev); 226 - return ret; 227 - } 228 - 229 - static void wkup_m3_rproc_remove(struct platform_device *pdev) 230 - { 231 - struct rproc *rproc = platform_get_drvdata(pdev); 232 - 233 - rproc_del(rproc); 234 - rproc_free(rproc); 235 - pm_runtime_put_sync(&pdev->dev); 236 - pm_runtime_disable(&pdev->dev); 237 215 } 238 216 239 217 #ifdef CONFIG_PM ··· 235 251 236 252 static struct platform_driver wkup_m3_rproc_driver = { 237 253 .probe = wkup_m3_rproc_probe, 238 - .remove = wkup_m3_rproc_remove, 239 254 .driver = { 240 255 .name = "wkup_m3_rproc", 241 256 .of_match_table = wkup_m3_rproc_of_match,