summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-03-21 10:37:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-03-21 10:37:39 -0700
commit0e875ee5e897db13104faab93bb1ab2b95da9ab9 (patch)
tree2b869ada9730cd5a3584ef9d7f3f8bf22e0e9c70 /drivers
parentebc9bee8814d12ec247de117aa2f7fd39ff11127 (diff)
parent62210f7509e13a2caa7b080722a45229b8f17a0a (diff)
downloadlinux-0e875ee5e897db13104faab93bb1ab2b95da9ab9.tar.gz
linux-0e875ee5e897db13104faab93bb1ab2b95da9ab9.tar.bz2
linux-0e875ee5e897db13104faab93bb1ab2b95da9ab9.zip
Merge tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux
Pull remoteproc updates from Bjorn Andersson: "Qualcomm SM8650 audio, compute and modem remoteproc are added. Qualcomm X1 Elite audio and compute remoteprocs are added, after support for shutting down the bootloader-loaded firmware loaded into the audio DSP.. A dozen drivers in the subsystem are transitioned to use devres helpers for remoteproc and memory allocations - this makes it possible to acquire in-kernel handle to individual remoteproc instances in a cluster. The release of DMA memory for remoteproc virtio is corrected to ensure that restarting due to a watchdog bite doesn't attempt to allocate the memory again without first freeing it. Last, but not least, a couple of DeviceTree binding cleanups" * tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (30 commits) remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & cDSP remoteproc: qcom_wcnss: Use devm_rproc_alloc() helper remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc() helper remoteproc: qcom_q6v5_pas: Use devm_rproc_alloc() helper remoteproc: qcom_q6v5_mss: Use devm_rproc_alloc() helper remoteproc: qcom_q6v5_adsp: Use devm_rproc_alloc() helper dt-bindings: remoteproc: do not override firmware-name $ref dt-bindings: remoteproc: qcom,glink-rpm-edge: drop redundant type from label remoteproc: qcom: pas: correct data indentation remoteproc: Make rproc_get_by_phandle() work for clusters remoteproc: qcom: pas: Add SM8650 remoteproc support remoteproc: qcom: pas: make region assign more generic dt-bindings: remoteproc: qcom,sm8550-pas: document the SM8650 PAS remoteproc: k3-dsp: Use devm_rproc_add() helper remoteproc: k3-dsp: Use devm_ioremap_wc() helper remoteproc: k3-dsp: Add devm action to release tsp remoteproc: k3-dsp: Use devm_kzalloc() helper remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/remoteproc/imx_dsp_rproc.c11
-rw-r--r--drivers/remoteproc/imx_rproc.c16
-rw-r--r--drivers/remoteproc/qcom_q6v5_adsp.c14
-rw-r--r--drivers/remoteproc/qcom_q6v5_mss.c28
-rw-r--r--drivers/remoteproc/qcom_q6v5_pas.c326
-rw-r--r--drivers/remoteproc/qcom_q6v5_wcss.c24
-rw-r--r--drivers/remoteproc/qcom_wcnss.c17
-rw-r--r--drivers/remoteproc/remoteproc_core.c29
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c6
-rw-r--r--drivers/remoteproc/st_remoteproc.c15
-rw-r--r--drivers/remoteproc/stm32_rproc.c10
-rw-r--r--drivers/remoteproc/ti_k3_dsp_remoteproc.c156
12 files changed, 357 insertions, 295 deletions
diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
index d73727a5828a..087506e21508 100644
--- a/drivers/remoteproc/imx_dsp_rproc.c
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -1040,8 +1040,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
return ret;
}
- rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
- sizeof(*priv));
+ rproc = devm_rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops,
+ fw_name, sizeof(*priv));
if (!rproc)
return -ENOMEM;
@@ -1061,14 +1061,14 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
ret = imx_dsp_rproc_detect_mode(priv);
if (ret) {
dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
- goto err_put_rproc;
+ return ret;
}
/* There are multiple power domains required by DSP on some platform */
ret = imx_dsp_attach_pm_domains(priv);
if (ret) {
dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
- goto err_put_rproc;
+ return ret;
}
/* Get clocks */
ret = imx_dsp_rproc_clk_get(priv);
@@ -1091,8 +1091,6 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
err_detach_domains:
dev_pm_domain_detach_list(priv->pd_list);
-err_put_rproc:
- rproc_free(rproc);
return ret;
}
@@ -1105,7 +1103,6 @@ static void imx_dsp_rproc_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
rproc_del(rproc);
dev_pm_domain_detach_list(priv->pd_list);
- rproc_free(rproc);
}
/* pm runtime functions */
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 3161f14442bc..5a3fb902acc9 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -1049,16 +1049,14 @@ static int imx_rproc_probe(struct platform_device *pdev)
int ret;
/* set some other name then imx */
- rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
- NULL, sizeof(*priv));
+ rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
+ NULL, sizeof(*priv));
if (!rproc)
return -ENOMEM;
dcfg = of_device_get_match_data(dev);
- if (!dcfg) {
- ret = -EINVAL;
- goto err_put_rproc;
- }
+ if (!dcfg)
+ return -EINVAL;
priv = rproc->priv;
priv->rproc = rproc;
@@ -1069,8 +1067,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
priv->workqueue = create_workqueue(dev_name(dev));
if (!priv->workqueue) {
dev_err(dev, "cannot create workqueue\n");
- ret = -ENOMEM;
- goto err_put_rproc;
+ return -ENOMEM;
}
ret = imx_rproc_xtr_mbox_init(rproc);
@@ -1112,8 +1109,6 @@ err_put_mbox:
imx_rproc_free_mbox(rproc);
err_put_wkq:
destroy_workqueue(priv->workqueue);
-err_put_rproc:
- rproc_free(rproc);
return ret;
}
@@ -1128,7 +1123,6 @@ static void imx_rproc_remove(struct platform_device *pdev)
imx_rproc_put_scu(rproc);
imx_rproc_free_mbox(rproc);
destroy_workqueue(priv->workqueue);
- rproc_free(rproc);
}
static const struct of_device_id imx_rproc_of_match[] = {
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index 93f9a1537ec6..1d24c9b656a8 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -674,8 +674,8 @@ static int adsp_probe(struct platform_device *pdev)
return ret;
}
- rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
- firmware_name, sizeof(*adsp));
+ rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
+ firmware_name, sizeof(*adsp));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
@@ -700,16 +700,16 @@ static int adsp_probe(struct platform_device *pdev)
ret = adsp_alloc_memory_region(adsp);
if (ret)
- goto free_rproc;
+ return ret;
ret = adsp_init_clock(adsp, desc->clk_ids);
if (ret)
- goto free_rproc;
+ return ret;
ret = qcom_rproc_pds_attach(adsp, desc->pd_names, desc->num_pds);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
- goto free_rproc;
+ return ret;
}
ret = adsp_init_reset(adsp);
@@ -744,9 +744,6 @@ static int adsp_probe(struct platform_device *pdev)
disable_pm:
qcom_rproc_pds_detach(adsp);
-free_rproc:
- rproc_free(rproc);
-
return ret;
}
@@ -761,7 +758,6 @@ static void adsp_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(adsp->sysmon);
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
qcom_rproc_pds_detach(adsp);
- rproc_free(adsp->rproc);
}
static const struct adsp_pil_data adsp_resource_init = {
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index 394b2c1cb5e2..1779fc890e10 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev)
return ret;
}
- rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
- mba_image, sizeof(*qproc));
+ rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
+ mba_image, sizeof(*qproc));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev)
1, &qproc->hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "unable to read mpss firmware-name\n");
- goto free_rproc;
+ return ret;
}
platform_set_drvdata(pdev, qproc);
@@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev)
qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
- goto free_rproc;
+ return ret;
ret = q6v5_alloc_memory_region(qproc);
if (ret)
- goto free_rproc;
+ return ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
desc->proxy_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
- goto free_rproc;
+ return ret;
}
qproc->proxy_clk_count = ret;
@@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->reset_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n");
- goto free_rproc;
+ return ret;
}
qproc->reset_clk_count = ret;
@@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active clocks.\n");
- goto free_rproc;
+ return ret;
}
qproc->active_clk_count = ret;
@@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
- goto free_rproc;
+ return ret;
}
qproc->proxy_reg_count = ret;
@@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active regulators.\n");
- goto free_rproc;
+ return ret;
}
qproc->active_reg_count = ret;
@@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev)
desc->fallback_proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n");
- goto free_rproc;
+ return ret;
}
qproc->fallback_proxy_reg_count = ret;
} else if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n");
- goto free_rproc;
+ return ret;
} else {
qproc->proxy_pd_count = ret;
}
@@ -2127,8 +2127,6 @@ remove_subdevs:
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
detach_proxy_pds:
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
-free_rproc:
- rproc_free(rproc);
return ret;
}
@@ -2149,8 +2147,6 @@ static void q6v5_remove(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
-
- rproc_free(rproc);
}
static const struct rproc_hexagon_res sc7180_mss = {
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index a9dd58608052..54d8005d40a3 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -33,12 +33,15 @@
#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100
+#define MAX_ASSIGN_COUNT 3
+
struct adsp_data {
int crash_reason_smem;
const char *firmware_name;
const char *dtb_firmware_name;
int pas_id;
int dtb_pas_id;
+ int lite_pas_id;
unsigned int minidump_id;
bool auto_boot;
bool decrypt_shutdown;
@@ -51,6 +54,9 @@ struct adsp_data {
int ssctl_id;
int region_assign_idx;
+ int region_assign_count;
+ bool region_assign_shared;
+ int region_assign_vmid;
};
struct qcom_adsp {
@@ -72,6 +78,7 @@ struct qcom_adsp {
const char *dtb_firmware_name;
int pas_id;
int dtb_pas_id;
+ int lite_pas_id;
unsigned int minidump_id;
int crash_reason_smem;
bool decrypt_shutdown;
@@ -87,15 +94,18 @@ struct qcom_adsp {
phys_addr_t dtb_mem_phys;
phys_addr_t mem_reloc;
phys_addr_t dtb_mem_reloc;
- phys_addr_t region_assign_phys;
+ phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT];
void *mem_region;
void *dtb_mem_region;
size_t mem_size;
size_t dtb_mem_size;
- size_t region_assign_size;
+ size_t region_assign_size[MAX_ASSIGN_COUNT];
int region_assign_idx;
- u64 region_assign_perms;
+ int region_assign_count;
+ bool region_assign_shared;
+ int region_assign_vmid;
+ u64 region_assign_owners[MAX_ASSIGN_COUNT];
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_subdev smd_subdev;
@@ -210,6 +220,9 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
/* Store firmware handle to be used in adsp_start() */
adsp->firmware = fw;
+ if (adsp->lite_pas_id)
+ ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
+
if (adsp->dtb_pas_id) {
ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
if (ret) {
@@ -590,37 +603,53 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
static int adsp_assign_memory_region(struct qcom_adsp *adsp)
{
- struct reserved_mem *rmem = NULL;
- struct qcom_scm_vmperm perm;
+ struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
struct device_node *node;
+ unsigned int perm_size;
+ int offset;
int ret;
if (!adsp->region_assign_idx)
return 0;
- node = of_parse_phandle(adsp->dev->of_node, "memory-region", adsp->region_assign_idx);
- if (node)
- rmem = of_reserved_mem_lookup(node);
- of_node_put(node);
- if (!rmem) {
- dev_err(adsp->dev, "unable to resolve shareable memory-region\n");
- return -EINVAL;
- }
+ for (offset = 0; offset < adsp->region_assign_count; ++offset) {
+ struct reserved_mem *rmem = NULL;
+
+ node = of_parse_phandle(adsp->dev->of_node, "memory-region",
+ adsp->region_assign_idx + offset);
+ if (node)
+ rmem = of_reserved_mem_lookup(node);
+ of_node_put(node);
+ if (!rmem) {
+ dev_err(adsp->dev, "unable to resolve shareable memory-region index %d\n",
+ offset);
+ return -EINVAL;
+ }
- perm.vmid = QCOM_SCM_VMID_MSS_MSA;
- perm.perm = QCOM_SCM_PERM_RW;
+ if (adsp->region_assign_shared) {
+ perm[0].vmid = QCOM_SCM_VMID_HLOS;
+ perm[0].perm = QCOM_SCM_PERM_RW;
+ perm[1].vmid = adsp->region_assign_vmid;
+ perm[1].perm = QCOM_SCM_PERM_RW;
+ perm_size = 2;
+ } else {
+ perm[0].vmid = adsp->region_assign_vmid;
+ perm[0].perm = QCOM_SCM_PERM_RW;
+ perm_size = 1;
+ }
- adsp->region_assign_phys = rmem->base;
- adsp->region_assign_size = rmem->size;
- adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS);
+ adsp->region_assign_phys[offset] = rmem->base;
+ adsp->region_assign_size[offset] = rmem->size;
+ adsp->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
- ret = qcom_scm_assign_mem(adsp->region_assign_phys,
- adsp->region_assign_size,
- &adsp->region_assign_perms,
- &perm, 1);
- if (ret < 0) {
- dev_err(adsp->dev, "assign memory failed\n");
- return ret;
+ ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
+ adsp->region_assign_size[offset],
+ &adsp->region_assign_owners[offset],
+ perm, perm_size);
+ if (ret < 0) {
+ dev_err(adsp->dev, "assign memory %d failed\n", offset);
+ return ret;
+ }
}
return 0;
@@ -629,20 +658,23 @@ static int adsp_assign_memory_region(struct qcom_adsp *adsp)
static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
{
struct qcom_scm_vmperm perm;
+ int offset;
int ret;
- if (!adsp->region_assign_idx)
+ if (!adsp->region_assign_idx || adsp->region_assign_shared)
return;
- perm.vmid = QCOM_SCM_VMID_HLOS;
- perm.perm = QCOM_SCM_PERM_RW;
+ for (offset = 0; offset < adsp->region_assign_count; ++offset) {
+ perm.vmid = QCOM_SCM_VMID_HLOS;
+ perm.perm = QCOM_SCM_PERM_RW;
- ret = qcom_scm_assign_mem(adsp->region_assign_phys,
- adsp->region_assign_size,
- &adsp->region_assign_perms,
- &perm, 1);
- if (ret < 0)
- dev_err(adsp->dev, "unassign memory failed\n");
+ ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
+ adsp->region_assign_size[offset],
+ &adsp->region_assign_owners[offset],
+ &perm, 1);
+ if (ret < 0)
+ dev_err(adsp->dev, "unassign memory %d failed\n", offset);
+ }
}
static int adsp_probe(struct platform_device *pdev)
@@ -678,7 +710,7 @@ static int adsp_probe(struct platform_device *pdev)
if (desc->minidump_id)
ops = &adsp_minidump_ops;
- rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
+ rproc = devm_rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
@@ -693,9 +725,13 @@ static int adsp_probe(struct platform_device *pdev)
adsp->rproc = rproc;
adsp->minidump_id = desc->minidump_id;
adsp->pas_id = desc->pas_id;
+ adsp->lite_pas_id = desc->lite_pas_id;
adsp->info_name = desc->sysmon_name;
adsp->decrypt_shutdown = desc->decrypt_shutdown;
adsp->region_assign_idx = desc->region_assign_idx;
+ adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count);
+ adsp->region_assign_vmid = desc->region_assign_vmid;
+ adsp->region_assign_shared = desc->region_assign_shared;
if (dtb_fw_name) {
adsp->dtb_firmware_name = dtb_fw_name;
adsp->dtb_pas_id = desc->dtb_pas_id;
@@ -754,7 +790,6 @@ detach_proxy_pds:
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
free_rproc:
device_init_wakeup(adsp->dev, false);
- rproc_free(rproc);
return ret;
}
@@ -773,28 +808,27 @@ static void adsp_remove(struct platform_device *pdev)
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
device_init_wakeup(adsp->dev, false);
- rproc_free(adsp->rproc);
}
static const struct adsp_data adsp_resource_init = {
- .crash_reason_smem = 423,
- .firmware_name = "adsp.mdt",
- .pas_id = 1,
- .auto_boot = true,
- .ssr_name = "lpass",
- .sysmon_name = "adsp",
- .ssctl_id = 0x14,
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .pas_id = 1,
+ .auto_boot = true,
+ .ssr_name = "lpass",
+ .sysmon_name = "adsp",
+ .ssctl_id = 0x14,
};
static const struct adsp_data sdm845_adsp_resource_init = {
- .crash_reason_smem = 423,
- .firmware_name = "adsp.mdt",
- .pas_id = 1,
- .auto_boot = true,
- .load_state = "adsp",
- .ssr_name = "lpass",
- .sysmon_name = "adsp",
- .ssctl_id = 0x14,
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .pas_id = 1,
+ .auto_boot = true,
+ .load_state = "adsp",
+ .ssr_name = "lpass",
+ .sysmon_name = "adsp",
+ .ssctl_id = 0x14,
};
static const struct adsp_data sm6350_adsp_resource = {
@@ -829,18 +863,18 @@ static const struct adsp_data sm6375_mpss_resource = {
};
static const struct adsp_data sm8150_adsp_resource = {
- .crash_reason_smem = 423,
- .firmware_name = "adsp.mdt",
- .pas_id = 1,
- .auto_boot = true,
- .proxy_pd_names = (char*[]){
- "cx",
- NULL
- },
- .load_state = "adsp",
- .ssr_name = "lpass",
- .sysmon_name = "adsp",
- .ssctl_id = 0x14,
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .pas_id = 1,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "cx",
+ NULL
+ },
+ .load_state = "adsp",
+ .ssr_name = "lpass",
+ .sysmon_name = "adsp",
+ .ssctl_id = 0x14,
};
static const struct adsp_data sm8250_adsp_resource = {
@@ -876,17 +910,17 @@ static const struct adsp_data sm8350_adsp_resource = {
};
static const struct adsp_data msm8996_adsp_resource = {
- .crash_reason_smem = 423,
- .firmware_name = "adsp.mdt",
- .pas_id = 1,
- .auto_boot = true,
- .proxy_pd_names = (char*[]){
- "cx",
- NULL
- },
- .ssr_name = "lpass",
- .sysmon_name = "adsp",
- .ssctl_id = 0x14,
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .pas_id = 1,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "cx",
+ NULL
+ },
+ .ssr_name = "lpass",
+ .sysmon_name = "adsp",
+ .ssctl_id = 0x14,
};
static const struct adsp_data cdsp_resource_init = {
@@ -984,6 +1018,46 @@ static const struct adsp_data sc8280xp_nsp1_resource = {
.ssctl_id = 0x20,
};
+static const struct adsp_data x1e80100_adsp_resource = {
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .dtb_firmware_name = "adsp_dtb.mdt",
+ .pas_id = 1,
+ .dtb_pas_id = 0x24,
+ .lite_pas_id = 0x1f,
+ .minidump_id = 5,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "lcx",
+ "lmx",
+ NULL
+ },
+ .load_state = "adsp",
+ .ssr_name = "lpass",
+ .sysmon_name = "adsp",
+ .ssctl_id = 0x14,
+};
+
+static const struct adsp_data x1e80100_cdsp_resource = {
+ .crash_reason_smem = 601,
+ .firmware_name = "cdsp.mdt",
+ .dtb_firmware_name = "cdsp_dtb.mdt",
+ .pas_id = 18,
+ .dtb_pas_id = 0x25,
+ .minidump_id = 7,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "cx",
+ "mxc",
+ "nsp",
+ NULL
+ },
+ .load_state = "cdsp",
+ .ssr_name = "cdsp",
+ .sysmon_name = "cdsp",
+ .ssctl_id = 0x17,
+};
+
static const struct adsp_data sm8350_cdsp_resource = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
@@ -1033,33 +1107,33 @@ static const struct adsp_data sc8180x_mpss_resource = {
};
static const struct adsp_data msm8996_slpi_resource_init = {
- .crash_reason_smem = 424,
- .firmware_name = "slpi.mdt",
- .pas_id = 12,
- .auto_boot = true,
- .proxy_pd_names = (char*[]){
- "ssc_cx",
- NULL
- },
- .ssr_name = "dsps",
- .sysmon_name = "slpi",
- .ssctl_id = 0x16,
+ .crash_reason_smem = 424,
+ .firmware_name = "slpi.mdt",
+ .pas_id = 12,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "ssc_cx",
+ NULL
+ },
+ .ssr_name = "dsps",
+ .sysmon_name = "slpi",
+ .ssctl_id = 0x16,
};
static const struct adsp_data sdm845_slpi_resource_init = {
- .crash_reason_smem = 424,
- .firmware_name = "slpi.mdt",
- .pas_id = 12,
- .auto_boot = true,
- .proxy_pd_names = (char*[]){
- "lcx",
- "lmx",
- NULL
- },
- .load_state = "slpi",
- .ssr_name = "dsps",
- .sysmon_name = "slpi",
- .ssctl_id = 0x16,
+ .crash_reason_smem = 424,
+ .firmware_name = "slpi.mdt",
+ .pas_id = 12,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "lcx",
+ "lmx",
+ NULL
+ },
+ .load_state = "slpi",
+ .ssr_name = "dsps",
+ .sysmon_name = "slpi",
+ .ssctl_id = 0x16,
};
static const struct adsp_data wcss_resource_init = {
@@ -1163,6 +1237,8 @@ static const struct adsp_data sm8550_mpss_resource = {
.sysmon_name = "modem",
.ssctl_id = 0x12,
.region_assign_idx = 2,
+ .region_assign_count = 1,
+ .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
};
static const struct adsp_data sc7280_wpss_resource = {
@@ -1181,6 +1257,53 @@ static const struct adsp_data sc7280_wpss_resource = {
.ssctl_id = 0x19,
};
+static const struct adsp_data sm8650_cdsp_resource = {
+ .crash_reason_smem = 601,
+ .firmware_name = "cdsp.mdt",
+ .dtb_firmware_name = "cdsp_dtb.mdt",
+ .pas_id = 18,
+ .dtb_pas_id = 0x25,
+ .minidump_id = 7,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "cx",
+ "mxc",
+ "nsp",
+ NULL
+ },
+ .load_state = "cdsp",
+ .ssr_name = "cdsp",
+ .sysmon_name = "cdsp",
+ .ssctl_id = 0x17,
+ .region_assign_idx = 2,
+ .region_assign_count = 1,
+ .region_assign_shared = true,
+ .region_assign_vmid = QCOM_SCM_VMID_CDSP,
+};
+
+static const struct adsp_data sm8650_mpss_resource = {
+ .crash_reason_smem = 421,
+ .firmware_name = "modem.mdt",
+ .dtb_firmware_name = "modem_dtb.mdt",
+ .pas_id = 4,
+ .dtb_pas_id = 0x26,
+ .minidump_id = 3,
+ .auto_boot = false,
+ .decrypt_shutdown = true,
+ .proxy_pd_names = (char*[]){
+ "cx",
+ "mss",
+ NULL
+ },
+ .load_state = "modem",
+ .ssr_name = "mpss",
+ .sysmon_name = "modem",
+ .ssctl_id = 0x12,
+ .region_assign_idx = 2,
+ .region_assign_count = 3,
+ .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
+};
+
static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
{ .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
@@ -1236,6 +1359,11 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
{ .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
{ .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
+ { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource},
+ { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource},
+ { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource},
+ { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource},
+ { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource},
{ },
};
MODULE_DEVICE_TABLE(of, adsp_of_match);
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index cff1fa07d1de..94f68c919ee6 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
- rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
- desc->firmware_name, sizeof(*wcss));
+ rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
+ desc->firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
- goto free_rproc;
+ return ret;
ret = q6v5_alloc_memory_region(wcss);
if (ret)
- goto free_rproc;
+ return ret;
if (wcss->version == WCSS_QCS404) {
ret = q6v5_wcss_init_clock(wcss);
if (ret)
- goto free_rproc;
+ return ret;
ret = q6v5_wcss_init_regulator(wcss);
if (ret)
- goto free_rproc;
+ return ret;
}
ret = q6v5_wcss_init_reset(wcss, desc);
if (ret)
- goto free_rproc;
+ return ret;
ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
if (ret)
- goto free_rproc;
+ return ret;
qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
@@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = rproc_add(rproc);
if (ret)
- goto free_rproc;
+ return ret;
platform_set_drvdata(pdev, rproc);
return 0;
-
-free_rproc:
- rproc_free(rproc);
-
- return ret;
}
static void q6v5_wcss_remove(struct platform_device *pdev)
@@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
qcom_q6v5_deinit(&wcss->q6v5);
rproc_del(rproc);
- rproc_free(rproc);
}
static const struct wcss_data wcss_ipq8074_res_init = {
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
index 90de22c81da9..a7bb9da27029 100644
--- a/drivers/remoteproc/qcom_wcnss.c
+++ b/drivers/remoteproc/qcom_wcnss.c
@@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev)
if (ret < 0 && ret != -EINVAL)
return ret;
- rproc = rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
- fw_name, sizeof(*wcnss));
+ rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
+ fw_name, sizeof(*wcnss));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
@@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev)
mutex_init(&wcnss->iris_lock);
mmio = devm_platform_ioremap_resource_byname(pdev, "pmu");
- if (IS_ERR(mmio)) {
- ret = PTR_ERR(mmio);
- goto free_rproc;
- }
+ if (IS_ERR(mmio))
+ return PTR_ERR(mmio);
ret = wcnss_alloc_memory_region(wcnss);
if (ret)
- goto free_rproc;
+ return ret;
wcnss->pmu_cfg = mmio + data->pmu_offset;
wcnss->spare_out = mmio + data->spare_offset;
@@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev)
*/
ret = wcnss_init_pds(wcnss, data->pd_names);
if (ret && (ret != -ENODATA || !data->num_pd_vregs))
- goto free_rproc;
+ return ret;
ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
data->num_pd_vregs);
@@ -656,8 +654,6 @@ remove_iris:
qcom_iris_remove(wcnss->iris);
detach_pds:
wcnss_release_pds(wcnss);
-free_rproc:
- rproc_free(rproc);
return ret;
}
@@ -673,7 +669,6 @@ static void wcnss_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(wcnss->sysmon);
qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev);
wcnss_release_pds(wcnss);
- rproc_free(wcnss->rproc);
}
static const struct of_device_id wcnss_of_match[] = {
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 695cce218e8c..f276956f2c5c 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -33,6 +33,7 @@
#include <linux/idr.h>
#include <linux/elf.h>
#include <linux/crc32.h>
+#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_ring.h>
@@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach);
struct rproc *rproc_get_by_phandle(phandle phandle)
{
struct rproc *rproc = NULL, *r;
+ struct device_driver *driver;
struct device_node *np;
np = of_find_node_by_phandle(phandle);
@@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
list_for_each_entry_rcu(r, &rproc_list, node) {
if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
/* prevent underlying implementation from being removed */
- if (!try_module_get(r->dev.parent->driver->owner)) {
+
+ /*
+ * If the remoteproc's parent has a driver, the
+ * remoteproc is not part of a cluster and we can use
+ * that driver.
+ */
+ driver = r->dev.parent->driver;
+
+ /*
+ * If the remoteproc's parent does not have a driver,
+ * look for the driver associated with the cluster.
+ */
+ if (!driver) {
+ if (r->dev.parent->parent)
+ driver = r->dev.parent->parent->driver;
+ if (!driver)
+ break;
+ }
+
+ if (!try_module_get(driver->owner)) {
dev_err(&r->dev, "can't get owner\n");
break;
}
@@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free);
*/
void rproc_put(struct rproc *rproc)
{
- module_put(rproc->dev.parent->driver->owner);
+ if (rproc->dev.parent->driver)<