aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 20:00:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 20:00:09 -0400
commitd880e5ad0df3c2e1d69bb356737a46abb5087d42 (patch)
treec90c8800de28c1a9cc8b59fe314a86ff80aa1eeb
parent4c1fad64eff481982349f5795b9c198c532b0f13 (diff)
parentfbb6aacb078285f88e4a4a20399c6af8d61e0000 (diff)
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 ...
-rw-r--r--Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt132
-rw-r--r--Documentation/remoteproc.txt6
-rw-r--r--drivers/remoteproc/Kconfig16
-rw-r--r--drivers/remoteproc/Makefile2
-rw-r--r--drivers/remoteproc/da8xx_remoteproc.c6
-rw-r--r--drivers/remoteproc/omap_remoteproc.c9
-rw-r--r--drivers/remoteproc/qcom_q6v5_pil.c8
-rw-r--r--drivers/remoteproc/qcom_wcnss.c624
-rw-r--r--drivers/remoteproc/qcom_wcnss.h22
-rw-r--r--drivers/remoteproc/qcom_wcnss_iris.c188
-rw-r--r--drivers/remoteproc/remoteproc_core.c248
-rw-r--r--drivers/remoteproc/remoteproc_debugfs.c20
-rw-r--r--drivers/remoteproc/remoteproc_elf_loader.c6
-rw-r--r--drivers/remoteproc/remoteproc_internal.h15
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c35
-rw-r--r--drivers/remoteproc/st_remoteproc.c4
-rw-r--r--drivers/remoteproc/ste_modem_rproc.c4
-rw-r--r--drivers/remoteproc/wkup_m3_rproc.c6
-rw-r--r--include/linux/platform_data/remoteproc-omap.h6
-rw-r--r--include/linux/remoteproc.h16
20 files changed, 1168 insertions, 205 deletions
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt
new file mode 100644
index 000000000000..0d2361ebe3d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt
@@ -0,0 +1,132 @@
1Qualcomm WCNSS Peripheral Image Loader
2
3This document defines the binding for a component that loads and boots firmware
4on 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
63A single subnode of the WCNSS PIL describes the attached rf module and its
64resource 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
94The following example describes the resources needed to boot control the WCNSS,
95with attached WCN3680, as it is commonly found on MSM8974 boards.
96
97pronto@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};
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt
index ef0219fa4bb4..f07597482351 100644
--- a/Documentation/remoteproc.txt
+++ b/Documentation/remoteproc.txt
@@ -101,9 +101,9 @@ int dummy_rproc_example(struct rproc *my_rproc)
101 On success, the new rproc is returned, and on failure, NULL. 101 On success, the new rproc is returned, and on failure, NULL.
102 102
103 Note: _never_ directly deallocate @rproc, even if it was not registered 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 - Free an rproc handle that was allocated by rproc_alloc. 107 - Free an rproc handle that was allocated by rproc_alloc.
108 This function essentially unrolls rproc_alloc(), by decrementing the 108 This function essentially unrolls rproc_alloc(), by decrementing the
109 rproc's refcount. It doesn't directly free rproc; that would happen 109 rproc's refcount. It doesn't directly free rproc; that would happen
@@ -131,7 +131,7 @@ int dummy_rproc_example(struct rproc *my_rproc)
131 has completed successfully. 131 has completed successfully.
132 132
133 After rproc_del() returns, @rproc is still valid, and its 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 Returns 0 on success and -EINVAL if @rproc isn't valid. 136 Returns 0 on success and -EINVAL if @rproc isn't valid.
137 137
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 1a8bf76a925f..f76b3b1dca1a 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -91,6 +91,22 @@ config QCOM_Q6V5_PIL
91 Say y here to support the Qualcomm Peripherial Image Loader for the 91 Say y here to support the Qualcomm Peripherial Image Loader for the
92 Hexagon V5 based remote processors. 92 Hexagon V5 based remote processors.
93 93
94config QCOM_WCNSS_IRIS
95 tristate
96 depends on OF && ARCH_QCOM
97
98config 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
94config ST_REMOTEPROC 110config ST_REMOTEPROC
95 tristate "ST remoteproc support" 111 tristate "ST remoteproc support"
96 depends on ARCH_STI 112 depends on ARCH_STI
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 92d3758bd15c..6dfb62ed643f 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -13,4 +13,6 @@ obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o
13obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o 13obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
14obj-$(CONFIG_QCOM_MDT_LOADER) += qcom_mdt_loader.o 14obj-$(CONFIG_QCOM_MDT_LOADER) += qcom_mdt_loader.o
15obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o 15obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o
16obj-$(CONFIG_QCOM_WCNSS_IRIS) += qcom_wcnss_iris.o
17obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss.o
16obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o 18obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o
diff --git a/drivers/remoteproc/da8xx_remoteproc.c b/drivers/remoteproc/da8xx_remoteproc.c
index 009e56f67de2..1afac8f31be0 100644
--- a/drivers/remoteproc/da8xx_remoteproc.c
+++ b/drivers/remoteproc/da8xx_remoteproc.c
@@ -147,7 +147,7 @@ static void da8xx_rproc_kick(struct rproc *rproc, int vqid)
147{ 147{
148 struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv; 148 struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv;
149 149
150 /* Interupt remote proc */ 150 /* Interrupt remote proc */
151 writel(SYSCFG_CHIPSIG2, drproc->chipsig); 151 writel(SYSCFG_CHIPSIG2, drproc->chipsig);
152} 152}
153 153
@@ -261,7 +261,7 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
261 return 0; 261 return 0;
262 262
263free_rproc: 263free_rproc:
264 rproc_put(rproc); 264 rproc_free(rproc);
265 265
266 return ret; 266 return ret;
267} 267}
@@ -290,7 +290,7 @@ static int da8xx_rproc_remove(struct platform_device *pdev)
290 disable_irq(drproc->irq); 290 disable_irq(drproc->irq);
291 291
292 rproc_del(rproc); 292 rproc_del(rproc);
293 rproc_put(rproc); 293 rproc_free(rproc);
294 294
295 return 0; 295 return 0;
296} 296}
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index b74368a91235..fa63bf2eb885 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -96,7 +96,8 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
96 /* send the index of the triggered virtqueue in the mailbox payload */ 96 /* send the index of the triggered virtqueue in the mailbox payload */
97 ret = mbox_send_message(oproc->mbox, (void *)vqid); 97 ret = mbox_send_message(oproc->mbox, (void *)vqid);
98 if (ret < 0) 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/*
@@ -196,7 +197,7 @@ static int omap_rproc_probe(struct platform_device *pdev)
196 } 197 }
197 198
198 rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops, 199 rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops,
199 pdata->firmware, sizeof(*oproc)); 200 pdata->firmware, sizeof(*oproc));
200 if (!rproc) 201 if (!rproc)
201 return -ENOMEM; 202 return -ENOMEM;
202 203
@@ -214,7 +215,7 @@ static int omap_rproc_probe(struct platform_device *pdev)
214 return 0; 215 return 0;
215 216
216free_rproc: 217free_rproc:
217 rproc_put(rproc); 218 rproc_free(rproc);
218 return ret; 219 return ret;
219} 220}
220 221
@@ -223,7 +224,7 @@ static int omap_rproc_remove(struct platform_device *pdev)
223 struct rproc *rproc = platform_get_drvdata(pdev); 224 struct rproc *rproc = platform_get_drvdata(pdev);
224 225
225 rproc_del(rproc); 226 rproc_del(rproc);
226 rproc_put(rproc); 227 rproc_free(rproc);
227 228
228 return 0; 229 return 0;
229} 230}
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
index 2a1b2c7d8f2c..2e0caaaa766a 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -863,8 +863,10 @@ static int q6v5_probe(struct platform_device *pdev)
863 goto free_rproc; 863 goto free_rproc;
864 864
865 qproc->state = qcom_smem_state_get(&pdev->dev, "stop", &qproc->stop_bit); 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 goto free_rproc; 868 goto free_rproc;
869 }
868 870
869 ret = rproc_add(rproc); 871 ret = rproc_add(rproc);
870 if (ret) 872 if (ret)
@@ -873,7 +875,7 @@ static int q6v5_probe(struct platform_device *pdev)
873 return 0; 875 return 0;
874 876
875free_rproc: 877free_rproc:
876 rproc_put(rproc); 878 rproc_free(rproc);
877 879
878 return ret; 880 return ret;
879} 881}
@@ -883,7 +885,7 @@ static int q6v5_remove(struct platform_device *pdev)
883 struct q6v5 *qproc = platform_get_drvdata(pdev); 885 struct q6v5 *qproc = platform_get_drvdata(pdev);
884 886
885 rproc_del(qproc->rproc); 887 rproc_del(qproc->rproc);
886 rproc_put(qproc->rproc); 888 rproc_free(qproc->rproc);
887 889
888 return 0; 890 return 0;
889} 891}
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
new file mode 100644
index 000000000000..f5cedeaafba1
--- /dev/null
+++ b/drivers/remoteproc/qcom_wcnss.c
@@ -0,0 +1,624 @@
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
58struct 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
66struct 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
99static 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
111static 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
123static 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
135void 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}
146EXPORT_SYMBOL_GPL(qcom_wcnss_assign_iris);
147
148static 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
181static const struct rproc_fw_ops wcnss_fw_ops = {
182 .find_rsc_table = qcom_mdt_find_rsc_table,
183 .load = wcnss_load,
184};
185
186static 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
196static 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
243static 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
285disable_iris:
286 qcom_iris_disable(wcnss->iris);
287disable_regulators:
288 regulator_bulk_disable(wcnss->num_vregs, wcnss->vregs);
289release_iris_lock:
290 mutex_unlock(&wcnss->iris_lock);
291
292 return ret;
293}
294
295static 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
322static 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
334static const struct rproc_ops wcnss_ops = {
335 .start = wcnss_start,
336 .stop = wcnss_stop,
337 .da_to_va = wcnss_da_to_va,
338};
339
340static 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
349static 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
367static 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
376static 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
390static 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
399static 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
436static 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
463static 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
491static 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
587free_rproc:
588 rproc_free(rproc);
589
590 return ret;
591}
592
593static 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
606static 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
613static 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
622module_platform_driver(wcnss_driver);
623MODULE_DESCRIPTION("Qualcomm Peripherial Image Loader for Wireless Subsystem");
624MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/qcom_wcnss.h b/drivers/remoteproc/qcom_wcnss.h
new file mode 100644
index 000000000000..9dc4a9fe41e1
--- /dev/null
+++ b/drivers/remoteproc/qcom_wcnss.h
@@ -0,0 +1,22 @@
1#ifndef __QCOM_WNCSS_H__
2#define __QCOM_WNCSS_H__
3
4struct qcom_iris;
5struct qcom_wcnss;
6
7struct 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
17int qcom_iris_enable(struct qcom_iris *iris);
18void qcom_iris_disable(struct qcom_iris *iris);
19
20void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, struct qcom_iris *iris, bool use_48mhz_xo);
21
22#endif
diff --git a/drivers/remoteproc/qcom_wcnss_iris.c b/drivers/remoteproc/qcom_wcnss_iris.c
new file mode 100644
index 000000000000..f0ca24a8dd0b
--- /dev/null
+++ b/drivers/remoteproc/qcom_wcnss_iris.c
@@ -0,0 +1,188 @@
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
27struct 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
36struct iris_data {
37 const struct wcnss_vreg_info *vregs;
38 size_t num_vregs;
39
40 bool use_48mhz_xo;
41};
42
43static 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
54static 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
65static 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
76int 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
92disable_regulators:
93 regulator_bulk_disable(iris->num_vregs, iris->vregs);
94
95 return ret;
96}
97EXPORT_SYMBOL_GPL(qcom_iris_enable);
98
99void 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}
104EXPORT_SYMBOL_GPL(qcom_iris_disable);
105
106static 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
161static 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
170static 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
177static 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
186module_platform_driver(wcnss_driver);
187MODULE_DESCRIPTION("Qualcomm Wireless Subsystem Iris driver");
188MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index fe0539ed9cb5..c6bfb3496684 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -78,7 +78,7 @@ static const char *rproc_crash_to_string(enum rproc_crash_type type)
78 * will try to access an unmapped device address. 78 * will try to access an unmapped device address.
79 */ 79 */
80static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, 80static 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 struct rproc *rproc = token; 83 struct rproc *rproc = token;
84 84
@@ -236,8 +236,8 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
236 } 236 }
237 notifyid = ret; 237 notifyid = ret;
238 238
239 dev_dbg(dev, "vring%d: va %p dma %llx size %x idr %d\n", i, va, 239 dev_dbg(dev, "vring%d: va %p dma %pad size 0x%x idr %d\n",
240 (unsigned long long)dma, size, notifyid); 240 i, va, &dma, size, notifyid);
241 241
242 rvring->va = va; 242 rvring->va = va;
243 rvring->dma = dma; 243 rvring->dma = dma;
@@ -263,19 +263,13 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
263 struct fw_rsc_vdev_vring *vring = &rsc->vring[i]; 263 struct fw_rsc_vdev_vring *vring = &rsc->vring[i];
264 struct rproc_vring *rvring = &rvdev->vring[i]; 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", 266 dev_dbg(dev, "vdev rsc: vring%d: da 0x%x, qsz %d, align %d\n",
267 i, vring->da, vring->num, vring->align); 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 }
274 268
275 /* verify queue size and vring alignment are sane */ 269 /* verify queue size and vring alignment are sane */
276 if (!vring->num || !vring->align) { 270 if (!vring->num || !vring->align) {
277 dev_err(dev, "invalid qsz (%d) or alignment (%d)\n", 271 dev_err(dev, "invalid qsz (%d) or alignment (%d)\n",
278 vring->num, vring->align); 272 vring->num, vring->align);
279 return -EINVAL; 273 return -EINVAL;
280 } 274 }
281 275
@@ -330,7 +324,7 @@ void rproc_free_vring(struct rproc_vring *rvring)
330 * Returns 0 on success, or an appropriate error code otherwise 324 * Returns 0 on success, or an appropriate error code otherwise
331 */ 325 */
332static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, 326static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
333 int offset, int avail) 327 int offset, int avail)
334{ 328{
335 struct device *dev = &rproc->dev; 329 struct device *dev = &rproc->dev;
336 struct rproc_vdev *rvdev; 330 struct rproc_vdev *rvdev;
@@ -349,7 +343,7 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
349 return -EINVAL; 343 return -EINVAL;
350 } 344 }
351 345
352 dev_dbg(dev, "vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n", 346 dev_dbg(dev, "vdev rsc: id %d, dfeatures 0x%x, cfg len %d, %d vrings\n",
353 rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings); 347 rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings);
354 348
355 /* we currently support only two vrings per rvdev */ 349 /* we currently support only two vrings per rvdev */
@@ -358,7 +352,7 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
358 return -EINVAL; 352 return -EINVAL;
359 } 353 }
360 354
361 rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL); 355 rvdev = kzalloc(sizeof(*rvdev), GFP_KERNEL);
362 if (!rvdev) 356 if (!rvdev)
363 return -ENOMEM; 357 return -ENOMEM;
364 358
@@ -407,7 +401,7 @@ free_rvdev:
407 * Returns 0 on success, or an appropriate error code otherwise 401 * Returns 0 on success, or an appropriate error code otherwise
408 */ 402 */
409static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, 403static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
410 int offset, int avail) 404 int offset, int avail)
411{ 405{
412 struct rproc_mem_entry *trace; 406 struct rproc_mem_entry *trace;
413 struct device *dev = &rproc->dev; 407 struct device *dev = &rproc->dev;
@@ -455,8 +449,8 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
455 449
456 rproc->num_traces++; 450 rproc->num_traces++;
457 451
458 dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", name, ptr, 452 dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n",
459 rsc->da, rsc->len); 453 name, ptr, rsc->da, rsc->len);
460 454
461 return 0; 455 return 0;
462} 456}
@@ -487,7 +481,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
487 * are outside those ranges. 481 * are outside those ranges.
488 */ 482 */
489static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc, 483static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
490 int offset, int avail) 484 int offset, int avail)
491{ 485{
492 struct rproc_mem_entry *mapping; 486 struct rproc_mem_entry *mapping;
493 struct device *dev = &rproc->dev; 487 struct device *dev = &rproc->dev;
@@ -530,7 +524,7 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
530 list_add_tail(&mapping->node, &rproc->mappings); 524 list_add_tail(&mapping->node, &rproc->mappings);
531 525
532 dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n", 526 dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
533 rsc->pa, rsc->da, rsc->len); 527 rsc->pa, rsc->da, rsc->len);
534 528
535 return 0; 529 return 0;
536 530
@@ -558,9 +552,8 @@ out:
558 * pressure is important; it may have a substantial impact on performance. 552 * pressure is important; it may have a substantial impact on performance.
559 */ 553 */
560static int rproc_handle_carveout(struct rproc *rproc, 554static int rproc_handle_carveout(struct rproc *rproc,
561 struct fw_rsc_carveout *rsc, 555 struct fw_rsc_carveout *rsc,
562 int offset, int avail) 556 int offset, int avail)
563
564{ 557{
565 struct rproc_mem_entry *carveout, *mapping; 558 struct rproc_mem_entry *carveout, *mapping;
566 struct device *dev = &rproc->dev; 559 struct device *dev = &rproc->dev;
@@ -579,8 +572,8 @@ static int rproc_handle_carveout(struct rproc *rproc,
579 return -EINVAL; 572 return -EINVAL;
580 } 573 }
581 574
582 dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n", 575 dev_dbg(dev, "carveout rsc: name: %s, da 0x%x, pa 0x%x, len 0x%x, flags 0x%x\n",
583 rsc->da, rsc->pa, rsc->len, rsc->flags); 576 rsc->name, rsc->da, rsc->pa, rsc->len, rsc->flags);
584 577
585 carveout = kzalloc(sizeof(*carveout), GFP_KERNEL); 578 carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
586 if (!carveout) 579 if (!carveout)
@@ -588,13 +581,14 @@ static int rproc_handle_carveout(struct rproc *rproc,
588 581
589 va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL); 582 va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
590 if (!va) { 583 if (!va) {
591 dev_err(dev->parent, "dma_alloc_coherent err: %d\n", rsc->len); 584 dev_err(dev->parent,
585 "failed to allocate dma memory: len 0x%x\n", rsc->len);
592 ret = -ENOMEM; 586 ret = -ENOMEM;
593 goto free_carv; 587 goto free_carv;
594 } 588 }
595 589
596 dev_dbg(dev, "carveout va %p, dma %llx, len 0x%x\n", va, 590 dev_dbg(dev, "carveout va %p, dma %pad, len 0x%x\n",
597 (unsigned long long)dma, rsc->len); 591 va, &dma, rsc->len);
598 592
599 /* 593 /*
600 * Ok, this is non-standard. 594 * Ok, this is non-standard.
@@ -616,13 +610,12 @@ static int rproc_handle_carveout(struct rproc *rproc,
616 if (rproc->domain) { 610 if (rproc->domain) {
617 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 611 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
618 if (!mapping) { 612 if (!mapping) {
619 dev_err(dev, "kzalloc mapping failed\n");
620 ret = -ENOMEM; 613 ret = -ENOMEM;
621 goto dma_free; 614 goto dma_free;
622 } 615 }
623 616
624 ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len, 617 ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
625 rsc->flags); 618 rsc->flags);
626 if (ret) { 619 if (ret) {
627 dev_err(dev, "iommu_map failed: %d\n", ret); 620 dev_err(dev, "iommu_map failed: %d\n", ret);
628 goto free_mapping; 621 goto free_mapping;
@@ -639,8 +632,8 @@ static int rproc_handle_carveout(struct rproc *rproc,
639 mapping->len = rsc->len; 632 mapping->len = rsc->len;
640 list_add_tail(&mapping->node, &rproc->mappings); 633 list_add_tail(&mapping->node, &rproc->mappings);
641 634
642 dev_dbg(dev, "carveout mapped 0x%x to 0x%llx\n", 635 dev_dbg(dev, "carveout mapped 0x%x to %pad\n",
643 rsc->da, (unsigned long long)dma); 636 rsc->da, &dma);
644 } 637 }
645 638
646 /* 639 /*
@@ -697,17 +690,13 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = {
697 [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout, 690 [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
698 [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem, 691 [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
699 [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace, 692 [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
700 [RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */ 693 [RSC_VDEV] = (rproc_handle_resource_t)rproc_count_vrings,
701}; 694};
702 695
703static rproc_handle_resource_t rproc_vdev_handler[RSC_LAST] = { 696static rproc_handle_resource_t rproc_vdev_handler[RSC_LAST] = {
704 [RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev, 697 [RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev,
705}; 698};
706 699
707static rproc_handle_resource_t rproc_count_vrings_handler[RSC_LAST] = {
708 [RSC_VDEV] = (rproc_handle_resource_t)rproc_count_vrings,
709};
710
711/* handle firmware resource entries before booting the remote processor */ 700/* handle firmware resource entries before booting the remote processor */
712static int rproc_handle_resources(struct rproc *rproc, int len, 701static int rproc_handle_resources(struct rproc *rproc, int len,
713 rproc_handle_resource_t handlers[RSC_LAST]) 702 rproc_handle_resource_t handlers[RSC_LAST])
@@ -757,6 +746,7 @@ static int rproc_handle_resources(struct rproc *rproc, int len,
757static void rproc_resource_cleanup(struct rproc *rproc) 746static void rproc_resource_cleanup(struct rproc *rproc)
758{ 747{
759 struct rproc_mem_entry *entry, *tmp; 748 struct rproc_mem_entry *entry, *tmp;
749 struct rproc_vdev *rvdev, *rvtmp;
760 struct device *dev = &rproc->dev; 750 struct device *dev = &rproc->dev;
761 751
762 /* clean up debugfs trace entries */ 752 /* clean up debugfs trace entries */
@@ -775,7 +765,7 @@ static void rproc_resource_cleanup(struct rproc *rproc)
775 if (unmapped != entry->len) { 765 if (unmapped != entry->len) {
776 /* nothing much to do besides complaining */ 766 /* nothing much to do besides complaining */
777 dev_err(dev, "failed to unmap %u/%zu\n", entry->len, 767 dev_err(dev, "failed to unmap %u/%zu\n", entry->len,
778 unmapped); 768 unmapped);
779 } 769 }
780 770
781 list_del(&entry->node); 771 list_del(&entry->node);
@@ -789,6 +779,10 @@ static void rproc_resource_cleanup(struct rproc *rproc)
789 list_del(&entry->node); 779 list_del(&entry->node);
790 kfree(entry); 780 kfree(entry);
791 } 781 }
782
783 /* clean up remote vdev entries */
784 list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node)
785 rproc_remove_virtio_dev(rvdev);
792} 786}
793 787
794/* 788/*
@@ -801,9 +795,6 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
801 struct resource_table *table, *loaded_table; 795 struct resource_table *table, *loaded_table;
802 int ret, tablesz; 796 int ret, tablesz;
803 797
804 if (!rproc->table_ptr)
805 return -ENOMEM;
806
807 ret = rproc_fw_sanity_check(rproc, fw); 798 ret = rproc_fw_sanity_check(rproc, fw);
808 if (ret) 799 if (ret)
809 return ret; 800 return ret;
@@ -830,9 +821,25 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
830 goto clean_up; 821 goto clean_up;
831 } 822 }
832 823
833 /* Verify that resource table in loaded fw is unchanged */ 824 /*
834 if (rproc->table_csum != crc32(0, table, tablesz)) { 825 * Create a copy of the resource table. When a virtio device starts
835 dev_err(dev, "resource checksum failed, fw changed?\n"); 826 * and calls vring_new_virtqueue() the address of the allocated vring
827 * will be stored in the cached_table. Before the device is started,
828 * cached_table will be copied into device memory.
829 */
830 rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL);
831 if (!rproc->cached_table)
832 goto clean_up;
833
834 rproc->table_ptr = rproc->cached_table;
835
836 /* reset max_notifyid */
837 rproc->max_notifyid = -1;
838
839 /* look for virtio devices and register them */
840 ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler);
841 if (ret) {
842 dev_err(dev, "Failed to handle vdev resources: %d\n", ret);
836 goto clean_up; 843 goto clean_up;
837 } 844 }
838 845
@@ -840,49 +847,50 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
840 ret = rproc_handle_resources(rproc, tablesz, rproc_loading_handlers); 847 ret = rproc_handle_resources(rproc, tablesz, rproc_loading_handlers);
841 if (ret) { 848 if (ret) {
842 dev_err(dev, "Failed to process resources: %d\n", ret); 849 dev_err(dev, "Failed to process resources: %d\n", ret);
843 goto clean_up; 850 goto clean_up_resources;
844 } 851 }
845 852
846 /* load the ELF segments to memory */ 853 /* load the ELF segments to memory */
847 ret = rproc_load_segments(rproc, fw); 854 ret = rproc_load_segments(rproc, fw);
848 if (ret) { 855 if (ret) {
849 dev_err(dev, "Failed to load program segments: %d\n", ret); 856 dev_err(dev, "Failed to load program segments: %d\n", ret);
850 goto clean_up; 857 goto clean_up_resources;
851 } 858 }
852 859
853 /* 860 /*
854 * The starting device has been given the rproc->cached_table as the 861 * The starting device has been given the rproc->cached_table as the
855 * resource table. The address of the vring along with the other 862 * resource table. The address of the vring along with the other
856 * allocated resources (carveouts etc) is stored in cached_table. 863 * allocated resources (carveouts etc) is stored in cached_table.
857 * In order to pass this information to the remote device we must 864 * In order to pass this information to the remote device we must copy
858 * copy this information to device memory. 865 * this information to device memory. We also update the table_ptr so
866 * that any subsequent changes will be applied to the loaded version.
859 */ 867 */
860 loaded_table = rproc_find_loaded_rsc_table(rproc, fw); 868 loaded_table = rproc_find_loaded_rsc_table(rproc, fw);
861 if (loaded_table) 869 if (loaded_table) {
862 memcpy(loaded_table, rproc->cached_table, tablesz); 870 memcpy(loaded_table, rproc->cached_table, tablesz);
871 rproc->table_ptr = loaded_table;
872 }
863 873
864 /* power up the remote processor */ 874 /* power up the remote processor */
865 ret = rproc->ops->start(rproc); 875 ret = rproc->ops->start(rproc);
866 if (ret) { 876 if (ret) {
867 dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret); 877 dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret);
868 goto clean_up; 878 goto clean_up_resources;
869 } 879 }
870 880
871 /*
872 * Update table_ptr so that all subsequent vring allocations and
873 * virtio fields manipulation update the actual loaded resource table
874 * in device memory.
875 */
876 rproc->table_ptr = loaded_table;
877
878 rproc->state = RPROC_RUNNING; 881 rproc->state = RPROC_RUNNING;
879 882
880 dev_info(dev, "remote processor %s is now up\n", rproc->name); 883 dev_info(dev, "remote processor %s is now up\n", rproc->name);
881 884
882 return 0; 885 return 0;
883 886
884clean_up: 887clean_up_resources:
885 rproc_resource_cleanup(rproc); 888 rproc_resource_cleanup(rproc);
889clean_up:
890 kfree(rproc->cached_table);
891 rproc->cached_table = NULL;
892 rproc->table_ptr = NULL;
893
886 rproc_disable_iommu(rproc); 894 rproc_disable_iommu(rproc);
887 return ret; 895 return ret;
888} 896}
@@ -898,42 +906,11 @@ clean_up:
898static void rproc_fw_config_virtio(const struct firmware *fw, void *context) 906static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
899{ 907{
900 struct rproc *rproc = context; 908 struct rproc *rproc = context;
901 struct resource_table *table;
902 int ret, tablesz;
903
904 if (rproc_fw_sanity_check(rproc, fw) < 0)
905 goto out;
906
907 /* look for the resource table */
908 table = rproc_find_rsc_table(rproc, fw, &tablesz);
909 if (!table)
910 goto out;
911
912 rproc->table_csum = crc32(0, table, tablesz);
913
914 /*
915 * Create a copy of the resource table. When a virtio device starts
916 * and calls vring_new_virtqueue() the address of the allocated vring
917 * will be stored in the cached_table. Before the device is started,
918 * cached_table will be copied into devic memory.
919 */
920 rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL);
921 if (!rproc->cached_table)
922 goto out;
923
924 rproc->table_ptr = rproc->cached_table;
925 909
926 /* count the number of notify-ids */ 910 /* if rproc is marked always-on, request it to boot */
927 rproc->max_notifyid = -1; 911 if (rproc->auto_boot)
928 ret = rproc_handle_resources(rproc, tablesz, 912 rproc_boot_nowait(rproc);
929 rproc_count_vrings_handler);
930 if (ret)
931 goto out;
932
933 /* look for virtio devices and register them */
934 ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler);
935 913
936out:
937 release_firmware(fw); 914 release_firmware(fw);
938 /* allow rproc_del() contexts, if any, to proceed */ 915 /* allow rproc_del() contexts, if any, to proceed */
939 complete_all(&rproc->firmware_loading_complete); 916 complete_all(&rproc->firmware_loading_complete);
@@ -969,7 +946,7 @@ static int rproc_add_virtio_devices(struct rproc *rproc)
969 * rproc_trigger_recovery() - recover a remoteproc 946 * rproc_trigger_recovery() - recover a remoteproc
970 * @rproc: the remote processor 947 * @rproc: the remote processor
971 * 948 *
972 * The recovery is done by reseting all the virtio devices, that way all the 949 * The recovery is done by resetting all the virtio devices, that way all the
973 * rpmsg drivers will be reseted along with the remote processor making the 950 * rpmsg drivers will be reseted along with the remote processor making the
974 * remoteproc functional again. 951 * remoteproc functional again.
975 * 952 *
@@ -977,23 +954,23 @@ static int rproc_add_virtio_devices(struct rproc *rproc)
977 */ 954 */
978int rproc_trigger_recovery(struct rproc *rproc) 955int rproc_trigger_recovery(struct rproc *rproc)
979{ 956{
980 struct rproc_vdev *rvdev, *rvtmp;
981
982 dev_err(&rproc->dev, "recovering %s\n", rproc->name); 957 dev_err(&rproc->dev, "recovering %s\n", rproc->name);
983 958
984 init_completion(&rproc->crash_comp); 959 init_completion(&rproc->crash_comp);
985 960
986 /* clean up remote vdev entries */ 961 /* shut down the remote */
987 list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) 962 /* TODO: make sure this works with rproc->power > 1 */
988 rproc_remove_virtio_dev(rvdev); 963 rproc_shutdown(rproc);
989 964
990 /* wait until there is no more rproc users */ 965 /* wait until there is no more rproc users */
991 wait_for_completion(&rproc->crash_comp); 966 wait_for_completion(&rproc->crash_comp);
992 967
993 /* Free the copy of the resource table */ 968 /*
994 kfree(rproc->cached_table); 969 * boot the remote processor up again
970 */
971 rproc_boot(rproc);
995 972
996 return rproc_add_virtio_devices(rproc); 973 return 0;
997} 974}
998 975
999/** 976/**
@@ -1058,20 +1035,6 @@ static int __rproc_boot(struct rproc *rproc, bool wait)
1058 return ret; 1035 return ret;
1059 } 1036 }
1060 1037
1061 /* loading a firmware is required */
1062 if (!rproc->firmware) {
1063 dev_err(dev, "%s: no firmware to load\n", __func__);
1064 ret = -EINVAL;
1065 goto unlock_mutex;
1066 }
1067
1068 /* prevent underlying implementation from being removed */
1069 if (!try_module_get(dev->parent->driver->owner)) {
1070 dev_err(dev, "%s: can't get owner\n", __func__);
1071 ret = -EINVAL;
1072 goto unlock_mutex;
1073 }
1074
1075 /* skip the boot process if rproc is already powered up */ 1038 /* skip the boot process if rproc is already powered up */
1076 if (atomic_inc_return(&rproc->power) > 1) { 1039 if (atomic_inc_return(&rproc->power) > 1) {
1077 ret = 0; 1040 ret = 0;
@@ -1096,10 +1059,8 @@ static int __rproc_boot(struct rproc *rproc, bool wait)
1096 release_firmware(firmware_p); 1059 release_firmware(firmware_p);
1097 1060
1098downref_rproc: 1061downref_rproc:
1099 if (ret) { 1062 if (ret)
1100 module_put(dev->parent->driver->owner);
1101 atomic_dec(&rproc->power); 1063 atomic_dec(&rproc->power);
1102 }
1103unlock_mutex: 1064unlock_mutex:
1104 mutex_unlock(&rproc->lock); 1065 mutex_unlock(&rproc->lock);
1105 return ret; 1066 return ret;
@@ -1173,8 +1134,10 @@ void rproc_shutdown(struct rproc *rproc)
1173 1134
1174 rproc_disable_iommu(rproc); 1135 rproc_disable_iommu(rproc);
1175 1136
1176 /* Give the next start a clean resource table */ 1137 /* Free the copy of the resource table */
1177 rproc->table_ptr = rproc->cached_table; 1138 kfree(rproc->cached_table);
1139 rproc->cached_table = NULL;
1140 rproc->table_ptr = NULL;
1178 1141
1179 /* if in crash state, unlock crash handler */ 1142 /* if in crash state, unlock crash handler */
1180 if (rproc->state == RPROC_CRASHED) 1143 if (rproc->state == RPROC_CRASHED)
@@ -1186,8 +1149,6 @@ void rproc_shutdown(struct rproc *rproc)
1186 1149
1187out: 1150out:
1188 mutex_unlock(&rproc->lock); 1151 mutex_unlock(&rproc->lock);
1189 if (!ret)
1190 module_put(dev->parent->driver->owner);
1191} 1152}
1192EXPORT_SYMBOL(rproc_shutdown); 1153EXPORT_SYMBOL(rproc_shutdown);
1193 1154
@@ -1216,6 +1177,12 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
1216 mutex_lock(&rproc_list_mutex); 1177 mutex_lock(&rproc_list_mutex);
1217 list_for_each_entry(r, &rproc_list, node) { 1178 list_for_each_entry(r, &rproc_list, node) {
1218 if (r->dev.parent && r->dev.parent->of_node == np) { 1179 if (r->dev.parent && r->dev.parent->of_node == np) {
1180 /* prevent underlying implementation from being removed */
1181 if (!try_module_get(r->dev.parent->driver->owner)) {
1182 dev_err(&r->dev, "can't get owner\n");
1183 break;
1184 }
1185
1219 rproc = r; 1186 rproc = r;
1220 get_device(&rproc->dev); 1187 get_device(&rproc->dev);
1221 break; 1188 break;
@@ -1335,11 +1302,11 @@ static struct device_type rproc_type = {
1335 * On success the new rproc is returned, and on failure, NULL. 1302 * On success the new rproc is returned, and on failure, NULL.
1336 * 1303 *
1337 * Note: _never_ directly deallocate @rproc, even if it was not registered 1304 * Note: _never_ directly deallocate @rproc, even if it was not registered
1338 * yet. Instead, when you need to unroll rproc_alloc(), use rproc_put(). 1305 * yet. Instead, when you need to unroll rproc_alloc(), use rproc_free().
1339 */ 1306 */
1340struct rproc *rproc_alloc(struct device *dev, const char *name, 1307struct rproc *rproc_alloc(struct device *dev, const char *name,
1341 const struct rproc_ops *ops, 1308 const struct rproc_ops *ops,
1342 const char *firmware, int len) 1309 const char *firmware, int len)
1343{ 1310{
1344 struct rproc *rproc; 1311 struct rproc *rproc;
1345 char *p, *template = "rproc-%s-fw"; 1312 char *p, *template = "rproc-%s-fw";
@@ -1359,7 +1326,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
1359 */ 1326 */
1360 name_len = strlen(name) + strlen(template) - 2 + 1; 1327 name_len = strlen(name) + strlen(template) - 2 + 1;
1361 1328
1362 rproc = kzalloc(sizeof(struct rproc) + len + name_len, GFP_KERNEL); 1329 rproc = kzalloc(sizeof(*rproc) + len + name_len, GFP_KERNEL);
1363 if (!rproc) 1330 if (!rproc)
1364 return NULL; 1331 return NULL;
1365 1332
@@ -1374,6 +1341,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
1374 rproc->name = name; 1341 rproc->name = name;
1375 rproc->ops = ops; 1342 rproc->ops = ops;
1376 rproc->priv = &rproc[1]; 1343 rproc->priv = &rproc[1];
1344 rproc->auto_boot = true;
1377 1345
1378 device_initialize(&rproc->dev); 1346 device_initialize(&rproc->dev);
1379 rproc->dev.parent = dev; 1347 rproc->dev.parent = dev;
@@ -1413,7 +1381,22 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
1413EXPORT_SYMBOL(rproc_alloc); 1381EXPORT_SYMBOL(rproc_alloc);
1414 1382
1415/** 1383/**
1416 * rproc_put() - unroll rproc_alloc() 1384 * rproc_free() - unroll rproc_alloc()
1385 * @rproc: the remote processor handle
1386 *
1387 * This function decrements the rproc dev refcount.
1388 *
1389 * If no one holds any reference to rproc anymore, then its refcount would
1390 * now drop to zero, and it would be freed.
1391 */
1392void rproc_free(struct rproc *rproc)
1393{
1394 put_device(&rproc->dev);
1395}
1396EXPORT_SYMBOL(rproc_free);
1397
1398/**
1399 * rproc_put() - release rproc reference
1417 * @rproc: the remote processor handle 1400 * @rproc: the remote processor handle
1418 * 1401 *
1419 * This function decrements the rproc dev refcount. 1402 * This function decrements the rproc dev refcount.
@@ -1423,6 +1406,7 @@ EXPORT_SYMBOL(rproc_alloc);
1423 */ 1406 */
1424void rproc_put(struct rproc *rproc) 1407void rproc_put(struct rproc *rproc)
1425{ 1408{
1409 module_put(rproc->dev.parent->driver->owner);
1426 put_device(&rproc->dev); 1410 put_device(&rproc->dev);
1427} 1411}
1428EXPORT_SYMBOL(rproc_put); 1412EXPORT_SYMBOL(rproc_put);
@@ -1438,7 +1422,7 @@ EXPORT_SYMBOL(rproc_put);
1438 * 1422 *
1439 * After rproc_del() returns, @rproc isn't freed yet, because 1423 * After rproc_del() returns, @rproc isn't freed yet, because
1440 * of the outstanding reference created by rproc_alloc. To decrement that 1424 * of the outstanding reference created by rproc_alloc. To decrement that
1441 * one last refcount, one still needs to call rproc_put(). 1425 * one last refcount, one still needs to call rproc_free().
1442 * 1426 *
1443 * Returns 0 on success and -EINVAL if @rproc isn't valid. 1427 * Returns 0 on success and -EINVAL if @rproc isn't valid.
1444 */ 1428 */
@@ -1452,13 +1436,15 @@ int rproc_del(struct rproc *rproc)
1452 /* if rproc is just being registered, wait */ 1436 /* if rproc is just being registered, wait */
1453 wait_for_completion(&rproc->firmware_loading_complete); 1437 wait_for_completion(&rproc->firmware_loading_complete);
1454 1438
1439 /* if rproc is marked always-on, rproc_add() booted it */
1440 /* TODO: make sure this works with rproc->power > 1 */
1441 if (rproc->auto_boot)
1442 rproc_shutdown(rproc);
1443
1455 /* clean up remote vdev entries */ 1444 /* clean up remote vdev entries */
1456 list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) 1445 list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node)
1457 rproc_remove_virtio_dev(rvdev); 1446 rproc_remove_virtio_dev(rvdev);
1458 1447
1459 /* Free the copy of the resource table */
1460 kfree(rproc->cached_table);
1461
1462 /* the rproc is downref'ed as soon as it's removed from the klist */ 1448 /* the rproc is downref'ed as soon as it's removed from the klist */
1463 mutex_lock(&rproc_list_mutex); 1449 mutex_lock(&rproc_list_mutex);
1464 list_del(&rproc->node); 1450 list_del(&rproc->node);
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 74a120b6e206..374797206c79 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -45,7 +45,7 @@ static struct dentry *rproc_dbg;
45 * as it provides very early tracing with little to no dependencies at all. 45 * as it provides very early tracing with little to no dependencies at all.
46 */ 46 */
47static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, 47static 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 struct rproc_mem_entry *trace = filp->private_data; 50 struct rproc_mem_entry *trace = filp->private_data;
51 int len = strnlen(trace->va, trace->len); 51 int len = strnlen(trace->va, trace->len);
@@ -73,7 +73,7 @@ static const char * const rproc_state_string[] = {
73 73
74/* expose the state of the remote processor via debugfs */ 74/* expose the state of the remote processor via debugfs */
75static ssize_t rproc_state_read(struct file *filp, char __user *userbuf, 75static 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 struct rproc *rproc = filp->private_data; 78 struct rproc *rproc = filp->private_data;
79 unsigned int state; 79 unsigned int state;
@@ -83,7 +83,7 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
83 state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state; 83 state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state;
84 84
85 i = scnprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state], 85 i = scnprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state],
86 rproc->state); 86 rproc->state);
87 87
88 return simple_read_from_buffer(userbuf, count, ppos, buf, i); 88 return simple_read_from_buffer(userbuf, count, ppos, buf, i);
89} 89}
@@ -130,7 +130,7 @@ static const struct file_operations rproc_state_ops = {
130 130
131/* expose the name of the remote processor via debugfs */ 131/* expose the name of the remote processor via debugfs */
132static ssize_t rproc_name_read(struct file *filp, char __user *userbuf, 132static 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 struct rproc *rproc = filp->private_data; 135 struct rproc *rproc = filp->private_data;
136 /* need room for the name, a newline and a terminating null */ 136 /* need room for the name, a newline and a terminating null */
@@ -230,12 +230,12 @@ void rproc_remove_trace_file(struct dentry *tfile)
230} 230}
231 231
232struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, 232struct 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 struct dentry *tfile; 235 struct dentry *tfile;
236 236
237 tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, 237 tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, trace,
238 trace, &trace_rproc_ops); 238 &trace_rproc_ops);
239 if (!tfile) { 239 if (!tfile) {
240 dev_err(&rproc->dev, "failed to create debugfs trace entry\n"); 240 dev_err(&rproc->dev, "failed to create debugfs trace entry\n");
241 return NULL; 241 return NULL;
@@ -264,11 +264,11 @@ void rproc_create_debug_dir(struct rproc *rproc)
264 return; 264 return;
265 265
266 debugfs_create_file("name", 0400, rproc->dbg_dir, 266 debugfs_create_file("name", 0400, rproc->dbg_dir,
267 rproc, &rproc_name_ops); 267 rproc, &rproc_name_ops);
268 debugfs_create_file("state", 0400, rproc->dbg_dir, 268 debugfs_create_file("state", 0400, rproc->dbg_dir,
269 rproc, &rproc_state_ops); 269 rproc, &rproc_state_ops);
270 debugfs_create_file("recovery", 0400, rproc->dbg_dir, 270 debugfs_create_file("recovery", 0400, rproc->dbg_dir,
271 rproc, &rproc_recovery_ops); 271 rproc, &rproc_recovery_ops);
272} 272}
273 273
274void __init rproc_init_debugfs(void) 274void __init rproc_init_debugfs(void)
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index ce283a5b42a1..c523983a4aec 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -166,18 +166,18 @@ rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
166 continue; 166 continue;
167 167
168 dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", 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 if (filesz > memsz) { 171 if (filesz > memsz) {
172 dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", 172 dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n",
173 filesz, memsz); 173 filesz, memsz);
174 ret = -EINVAL; 174 ret = -EINVAL;
175 break; 175 break;
176 } 176 }
177 177
178 if (offset + filesz > fw->size) { 178 if (offset + filesz > fw->size) {
179 dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", 179 dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n",
180 offset + filesz, fw->size); 180 offset + filesz, fw->size);
181 ret = -EINVAL; 181 ret = -EINVAL;
182 break; 182 break;
183 } 183 }
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 57e1de59bec8..4cf93ca2816e 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -36,10 +36,10 @@ struct rproc;
36 */ 36 */
37struct rproc_fw_ops { 37struct rproc_fw_ops {
38 struct resource_table *(*find_rsc_table)(struct rproc *rproc, 38 struct resource_table *(*find_rsc_table)(struct rproc *rproc,
39 const struct firmware *fw, 39 const struct firmware *fw,
40 int *tablesz); 40 int *tablesz);
41 struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc, 41 struct resource_table *(*find_loaded_rsc_table)(
42 const struct firmware *fw); 42 struct rproc *rproc, const struct firmware *fw);
43 int (*load)(struct rproc *rproc, const struct firmware *fw); 43 int (*load)(struct rproc *rproc, const struct firmware *fw);
44 int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); 44 int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
45 u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); 45 u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
@@ -57,7 +57,7 @@ void rproc_remove_virtio_dev(struct rproc_vdev *rvdev);
57/* from remoteproc_debugfs.c */ 57/* from remoteproc_debugfs.c */
58void rproc_remove_trace_file(struct dentry *tfile); 58void rproc_remove_trace_file(struct dentry *tfile);
59struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, 59struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
60 struct rproc_mem_entry *trace); 60 struct rproc_mem_entry *trace);
61void rproc_delete_debug_dir(struct rproc *rproc); 61void rproc_delete_debug_dir(struct rproc *rproc);
62void rproc_create_debug_dir(struct rproc *rproc); 62void rproc_create_debug_dir(struct rproc *rproc);
63void rproc_init_debugfs(void); 63void rproc_init_debugfs(void);
@@ -98,7 +98,8 @@ int rproc_load_segments(struct rproc *rproc, const struct firmware *fw)
98 98
99static inline 99static inline
100struct resource_table *rproc_find_rsc_table(struct rproc *rproc, 100struct 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 if (rproc->fw_ops->find_rsc_table) 104 if (rproc->fw_ops->find_rsc_table)
104 return rproc->fw_ops->find_rsc_table(rproc, fw, tablesz); 105 return rproc->fw_ops->find_rsc_table(rproc, fw, tablesz);
@@ -108,7 +109,7 @@ struct resource_table *rproc_find_rsc_table(struct rproc *rproc,
108 109
109static inline 110static inline
110struct resource_table *rproc_find_loaded_rsc_table(struct rproc *rproc, 111struct resource_table *rproc_find_loaded_rsc_table(struct rproc *rproc,
111 const struct firmware *fw) 112 const struct firmware *fw)
112{ 113{
113 if (rproc->fw_ops->find_loaded_rsc_table) 114 if (rproc->fw_ops->find_loaded_rsc_table)
114 return rproc->fw_ops->find_loaded_rsc_table(rproc, fw); 115 return rproc->fw_ops->find_loaded_rsc_table(rproc, fw);
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index cc91556313e1..01870a16d6d2 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -69,7 +69,7 @@ irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
69EXPORT_SYMBOL(rproc_vq_interrupt); 69EXPORT_SYMBOL(rproc_vq_interrupt);
70 70
71static struct virtqueue *rp_find_vq(struct virtio_device *vdev, 71static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
72 unsigned id, 72 unsigned int id,
73 void (*callback)(struct virtqueue *vq), 73 void (*callback)(struct virtqueue *vq),
74 const char *name) 74 const char *name)
75{ 75{
@@ -101,14 +101,14 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
101 memset(addr, 0, size); 101 memset(addr, 0, size);
102 102
103 dev_dbg(dev, "vring%d: va %p qsz %d notifyid %d\n", 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 * Create the new vq, and tell virtio we're not interested in 107 * Create the new vq, and tell virtio we're not interested in
108 * the 'weak' smp barriers, since we're talking with a real device. 108 * the 'weak' smp barriers, since we're talking with a real device.
109 */ 109 */
110 vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, addr, 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 if (!vq) { 112 if (!vq) {
113 dev_err(dev, "vring_new_virtqueue %s failed\n", name); 113 dev_err(dev, "vring_new_virtqueue %s failed\n", name);
114 rproc_free_vring(rvring); 114 rproc_free_vring(rvring);
@@ -136,20 +136,14 @@ static void __rproc_virtio_del_vqs(struct virtio_device *vdev)
136 136
137static void rproc_virtio_del_vqs(struct virtio_device *vdev) 137static 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 __rproc_virtio_del_vqs(vdev); 139 __rproc_virtio_del_vqs(vdev);
145} 140}
146 141
147static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, 142static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
148 struct virtqueue *vqs[], 143 struct virtqueue *vqs[],
149 vq_callback_t *callbacks[], 144 vq_callback_t *callbacks[],
150 const char * const names[]) 145 const char * const names[])
151{ 146{
152 struct rproc *rproc = vdev_to_rproc(vdev);
153 int i, ret; 147 int i, ret;
154 148
155 for (i = 0; i < nvqs; ++i) { 149 for (i = 0; i < nvqs; ++i) {
@@ -160,13 +154,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
160 } 154 }
161 } 155 }
162 156
163 /* now that the vqs are all set, boot the remote processor */
164 ret = rproc_boot_nowait(rproc);
165 if (ret) {
166 dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret);
167 goto error;
168 }
169
170 return 0; 157 return 0;
171 158
172error: 159error:
@@ -239,8 +226,8 @@ static int rproc_virtio_finalize_features(struct virtio_device *vdev)
239 return 0; 226 return 0;
240} 227}
241 228
242static void rproc_virtio_get(struct virtio_device *vdev, unsigned offset, 229static void rproc_virtio_get(struct virtio_device *vdev, unsigned int offset,
243 void *buf, unsigned len) 230 void *buf, unsigned int len)
244{ 231{
245 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); 232 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
246 struct fw_rsc_vdev *rsc; 233 struct fw_rsc_vdev *rsc;
@@ -257,8 +244,8 @@ static void rproc_virtio_get(struct virtio_device *vdev, unsigned offset,
257 memcpy(buf, cfg + offset, len); 244 memcpy(buf, cfg + offset, len);
258} 245}
259 246
260static void rproc_virtio_set(struct virtio_device *vdev, unsigned offset, 247static void rproc_virtio_set(struct virtio_device *vdev, unsigned int offset,
261 const void *buf, unsigned len) 248 const void *buf, unsigned int len)
262{ 249{
263 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); 250 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
264 struct fw_rsc_vdev *rsc; 251 struct fw_rsc_vdev *rsc;
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
index 6f056caa8a56..ae8963fcc8c8 100644
--- a/drivers/remoteproc/st_remoteproc.c
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -262,7 +262,7 @@ static int st_rproc_probe(struct platform_device *pdev)
262 return 0; 262 return 0;
263 263
264free_rproc: 264free_rproc:
265 rproc_put(rproc); 265 rproc_free(rproc);
266 return ret; 266 return ret;
267} 267}
268 268
@@ -277,7 +277,7 @@ static int st_rproc_remove(struct platform_device *pdev)
277 277
278 of_reserved_mem_device_release(&pdev->dev); 278 of_reserved_mem_device_release(&pdev->dev);
279 279
280 rproc_put(rproc); 280 rproc_free(rproc);
281 281
282 return 0; 282 return 0;
283} 283}
diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c
index 53dc17bdd54e..03d69a9a3c5b 100644
--- a/drivers/remoteproc/ste_modem_rproc.c
+++ b/drivers/remoteproc/ste_modem_rproc.c
@@ -257,7 +257,7 @@ static int sproc_drv_remove(struct platform_device *pdev)
257 rproc_del(sproc->rproc); 257 rproc_del(sproc->rproc);
258 dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE, 258 dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE,
259 sproc->fw_addr, sproc->fw_dma_addr); 259 sproc->fw_addr, sproc->fw_dma_addr);
260 rproc_put(sproc->rproc); 260 rproc_free(sproc->rproc);
261 261
262 mdev->drv_data = NULL; 262 mdev->drv_data = NULL;
263 263
@@ -325,7 +325,7 @@ free_mem:
325free_rproc: 325free_rproc:
326 /* Reset device data upon error */ 326 /* Reset device data upon error */
327 mdev->drv_data = NULL; 327 mdev->drv_data = NULL;
328 rproc_put(rproc); 328 rproc_free(rproc);
329 return err; 329 return err;
330} 330}
331 331
diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c
index 02d271d101b4..18175d0331fd 100644
--- a/drivers/remoteproc/wkup_m3_rproc.c
+++ b/drivers/remoteproc/wkup_m3_rproc.c
@@ -167,6 +167,8 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
167 goto err; 167 goto err;
168 } 168 }
169 169
170 rproc->auto_boot = false;
171
170 wkupm3 = rproc->priv; 172 wkupm3 = rproc->priv;
171 wkupm3->rproc = rproc; 173 wkupm3->rproc = rproc;
172 wkupm3->pdev = pdev; 174 wkupm3->pdev = pdev;
@@ -206,7 +208,7 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
206 return 0; 208 return 0;
207 209
208err_put_rproc: 210err_put_rproc:
209 rproc_put(rproc); 211 rproc_free(rproc);
210err: 212err:
211 pm_runtime_put_noidle(dev); 213 pm_runtime_put_noidle(dev);
212 pm_runtime_disable(dev); 214 pm_runtime_disable(dev);
@@ -218,7 +220,7 @@ static int wkup_m3_rproc_remove(struct platform_device *pdev)
218 struct rproc *rproc = platform_get_drvdata(pdev); 220 struct rproc *rproc = platform_get_drvdata(pdev);
219 221
220 rproc_del(rproc); 222 rproc_del(rproc);
221 rproc_put(rproc); 223 rproc_free(rproc);
222 pm_runtime_put_sync(&pdev->dev); 224 pm_runtime_put_sync(&pdev->dev);
223 pm_runtime_disable(&pdev->dev); 225 pm_runtime_disable(&pdev->dev);
224 226
diff --git a/include/linux/platform_data/remoteproc-omap.h b/include/linux/platform_data/remoteproc-omap.h
index bfbd12b41162..71a1b2399c48 100644
--- a/include/linux/platform_data/remoteproc-omap.h
+++ b/include/linux/platform_data/remoteproc-omap.h
@@ -39,9 +39,9 @@ struct omap_rproc_pdata {
39 const char *firmware; 39 const char *firmware;
40 const char *mbox_name; 40 const char *mbox_name;
41 const struct rproc_ops *ops; 41 const struct rproc_ops *ops;
42 int (*device_enable) (struct platform_device *pdev); 42 int (*device_enable)(struct platform_device *pdev);
43 int (*device_shutdown) (struct platform_device *pdev); 43 int (*device_shutdown)(struct platform_device *pdev);
44 void(*set_bootaddr)(u32); 44 void (*set_bootaddr)(u32);
45}; 45};
46 46
47#if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE) 47#if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE)
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 1c457a8dd5a6..930023b7c825 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -118,7 +118,7 @@ enum fw_resource_type {
118 RSC_LAST = 4, 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 * struct fw_rsc_carveout - physically contiguous memory request 124 * struct fw_rsc_carveout - physically contiguous memory request
@@ -241,7 +241,7 @@ struct fw_rsc_trace {
241 * @notifyid is a unique rproc-wide notify index for this vring. This notify 241 * @notifyid is a unique rproc-wide notify index for this vring. This notify
242 * index is used when kicking a remote processor, to let it know that this 242 * index is used when kicking a remote processor, to let it know that this
243 * vring is triggered. 243 * vring is triggered.
244 * @reserved: reserved (must be zero) 244 * @pa: physical address
245 * 245 *
246 * This descriptor is not a resource entry by itself; it is part of the 246 * This descriptor is not a resource entry by itself; it is part of the
247 * vdev resource type (see below). 247 * vdev resource type (see below).
@@ -255,7 +255,7 @@ struct fw_rsc_vdev_vring {
255 u32 align; 255 u32 align;
256 u32 num; 256 u32 num;
257 u32 notifyid; 257 u32 notifyid;
258 u32 reserved; 258 u32 pa;
259} __packed; 259} __packed;
260 260
261/** 261/**
@@ -409,7 +409,6 @@ enum rproc_crash_type {
409 * @max_notifyid: largest allocated notify id. 409 * @max_notifyid: largest allocated notify id.
410 * @table_ptr: pointer to the resource table in effect 410 * @table_ptr: pointer to the resource table in effect
411 * @cached_table: copy of the resource table 411 * @cached_table: copy of the resource table
412 * @table_csum: checksum of the resource table
413 * @has_iommu: flag to indicate if remote processor is behind an MMU 412 * @has_iommu: flag to indicate if remote processor is behind an MMU
414 */ 413 */
415struct rproc { 414struct rproc {
@@ -435,14 +434,14 @@ struct rproc {
435 struct idr notifyids; 434 struct idr notifyids;
436 int index; 435 int index;
437 struct work_struct crash_handler; 436 struct work_struct crash_handler;
438 unsigned crash_cnt; 437 unsigned int crash_cnt;
439 struct completion crash_comp; 438 struct completion crash_comp;
440 bool recovery_disabled; 439 bool recovery_disabled;
441 int max_notifyid; 440 int max_notifyid;
442 struct resource_table *table_ptr; 441 struct resource_table *table_ptr;
443 struct resource_table *cached_table; 442 struct resource_table *cached_table;
444 u32 table_csum;
445 bool has_iommu; 443 bool has_iommu;
444 bool auto_boot;
446}; 445};
447 446
448/* we currently support only two vrings per rvdev */ 447/* we currently support only two vrings per rvdev */
@@ -489,11 +488,12 @@ struct rproc_vdev {
489 488
490struct rproc *rproc_get_by_phandle(phandle phandle); 489struct rproc *rproc_get_by_phandle(phandle phandle);
491struct rproc *rproc_alloc(struct device *dev, const char *name, 490struct rproc *rproc_alloc(struct device *dev, const char *name,
492 const struct rproc_ops *ops, 491 const struct rproc_ops *ops,
493 const char *firmware, int len); 492 const char *firmware, int len);
494void rproc_put(struct rproc *rproc); 493void rproc_put(struct rproc *rproc);
495int rproc_add(struct rproc *rproc); 494int rproc_add(struct rproc *rproc);
496int rproc_del(struct rproc *rproc); 495int rproc_del(struct rproc *rproc);
496void rproc_free(struct rproc *rproc);
497 497
498int rproc_boot(struct rproc *rproc); 498int rproc_boot(struct rproc *rproc);
499void rproc_shutdown(struct rproc *rproc); 499void rproc_shutdown(struct rproc *rproc);