Currently, remoteproc and non-remoteproc subsystems use different
variants of the MDT loader helper API, primarily due to the handling of
the metadata context. Remoteproc subsystems retain this context until
authentication and reset, while non-remoteproc subsystems (e.g., video,
graphics) do not require it.
Add context aware qcom_mdt_pas_load() function which uses context
returned from qcom_scm_pas_ctx_init() and use it till subsystems
is out of set. This will also help in unifying the API used by
remoteproc and non-remoteproc subsystems drivers.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
If this approach is preferred, will convert all subsystem drivers to use the
same set of API's using context and completely get away with qcom_mdt_load()
-Mukesh
drivers/remoteproc/qcom_q6v5_pas.c | 53 ++++++++++++++---------------
drivers/soc/qcom/mdt_loader.c | 26 ++++++++++----
include/linux/soc/qcom/mdt_loader.h | 22 ++++++------
3 files changed, 56 insertions(+), 45 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 55a7da801183..e376c0338576 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -115,8 +115,8 @@ struct qcom_pas {
struct qcom_rproc_ssr ssr_subdev;
struct qcom_sysmon *sysmon;
- struct qcom_scm_pas_metadata pas_metadata;
- struct qcom_scm_pas_metadata dtb_pas_metadata;
+ struct qcom_scm_pas_ctx *pas_ctx;
+ struct qcom_scm_pas_ctx *dtb_pas_ctx;
};
static void qcom_pas_segment_dump(struct rproc *rproc,
@@ -209,9 +209,9 @@ static int qcom_pas_unprepare(struct rproc *rproc)
* auth_and_reset() was successful, but in other cases clean it up
* here.
*/
- qcom_scm_pas_metadata_release(&pas->pas_metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
return 0;
}
@@ -235,15 +235,8 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
return ret;
}
- ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
- pas->dtb_pas_id, pas->dtb_mem_phys,
- &pas->dtb_pas_metadata);
- if (ret)
- goto release_dtb_firmware;
-
- ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
- pas->dtb_mem_region, pas->dtb_mem_phys,
- pas->dtb_mem_size, &pas->dtb_mem_reloc);
+ ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, pas->dtb_firmware_name,
+ pas->dtb_mem_region, &pas->dtb_mem_reloc);
if (ret)
goto release_dtb_metadata;
}
@@ -251,9 +244,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
return 0;
release_dtb_metadata:
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
-
-release_dtb_firmware:
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
release_firmware(pas->dtb_firmware);
return ret;
@@ -301,14 +292,8 @@ static int qcom_pas_start(struct rproc *rproc)
}
}
- ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
- pas->mem_phys, &pas->pas_metadata);
- if (ret)
- goto disable_px_supply;
-
- ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware,
- pas->mem_region, pas->mem_phys, pas->mem_size,
- &pas->mem_reloc);
+ ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware,
+ pas->mem_region, &pas->dtb_mem_reloc);
if (ret)
goto release_pas_metadata;
@@ -328,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc)
goto release_pas_metadata;
}
- qcom_scm_pas_metadata_release(&pas->pas_metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
/* firmware is used to pass reference from qcom_pas_start(), drop it now */
pas->firmware = NULL;
@@ -338,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc)
return 0;
release_pas_metadata:
- qcom_scm_pas_metadata_release(&pas->pas_metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
disable_px_supply:
if (pas->px_supply)
regulator_disable(pas->px_supply);
@@ -774,6 +759,18 @@ static int qcom_pas_probe(struct platform_device *pdev)
}
qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name);
+
+ pas->pas_ctx = qcom_scm_pas_ctx_init(pas->dev, pas->pas_id, pas->mem_phys,
+ pas->mem_size, true);
+ if (!pas->pas_ctx)
+ goto remove_ssr_sysmon;
+
+ pas->dtb_pas_ctx = qcom_scm_pas_ctx_init(pas->dev, pas->dtb_pas_id,
+ pas->dtb_mem_phys, pas->dtb_mem_size,
+ true);
+ if (!pas->dtb_pas_ctx)
+ goto remove_ssr_sysmon;
+
ret = rproc_add(rproc);
if (ret)
goto remove_ssr_sysmon;
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index a5c80d4fcc36..509ff85d9bf6 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -228,7 +228,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
/**
- * qcom_mdt_pas_init() - initialize PAS region for firmware loading
+ * __qcom_mdt_pas_init() - initialize PAS region for firmware loading
* @dev: device handle to associate resources with
* @fw: firmware object for the mdt file
* @fw_name: name of the firmware, for construction of segment file names
@@ -238,9 +238,9 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
*
* Returns 0 on success, negative errno otherwise.
*/
-int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
- const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *ctx)
+static int __qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
+ const char *fw_name, int pas_id, phys_addr_t mem_phys,
+ struct qcom_scm_pas_metadata *ctx)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
@@ -302,7 +302,6 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
out:
return ret;
}
-EXPORT_SYMBOL_GPL(qcom_mdt_pas_init);
static bool qcom_mdt_bins_are_split(const struct firmware *fw)
{
@@ -456,7 +455,7 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
{
int ret;
- ret = qcom_mdt_pas_init(dev, fw, firmware, pas_id, mem_phys, NULL);
+ ret = __qcom_mdt_pas_init(dev, fw, firmware, pas_id, mem_phys, NULL);
if (ret)
return ret;
@@ -486,5 +485,20 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
}
EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init);
+int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
+ const char *firmware, void *mem_region, phys_addr_t *reloc_base)
+{
+ int ret;
+
+ ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral,
+ ctx->mem_phys, ctx->metadata);
+ if (ret)
+ return ret;
+
+ return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx->mem_phys,
+ ctx->mem_size, reloc_base);
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_pas_load);
+
MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format");
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
index 8ea8230579a2..450fa0be2af0 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -10,19 +10,20 @@
struct device;
struct firmware;
-struct qcom_scm_pas_metadata;
+struct qcom_scm_pas_ctx;
#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
ssize_t qcom_mdt_get_size(const struct firmware *fw);
-int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
- const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *pas_metadata_ctx);
+
int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, void *mem_region,
phys_addr_t mem_phys, size_t mem_size,
phys_addr_t *reloc_base);
+int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
+ const char *firmware, void *mem_region, phys_addr_t *reloc_base);
+
int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
const char *fw_name, void *mem_region,
phys_addr_t mem_phys, size_t mem_size,
@@ -37,13 +38,6 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw)
return -ENODEV;
}
-static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
- const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *pas_metadata_ctx)
-{
- return -ENODEV;
-}
-
static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id,
void *mem_region, phys_addr_t mem_phys,
@@ -52,6 +46,12 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
return -ENODEV;
}
+int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
+ const char *firmware, void *mem_region, phys_addr_t *reloc_base)
+{
+ return -ENODEV;
+}
+
static inline int qcom_mdt_load_no_init(struct device *dev,
const struct firmware *fw,
const char *fw_name, void *mem_region,
--
2.50.1
On 19/08/2025 17:54, Mukesh Ojha wrote: > Currently, remoteproc and non-remoteproc subsystems use different > variants of the MDT loader helper API, primarily due to the handling of > the metadata context. Remoteproc subsystems retain this context until > authentication and reset, while non-remoteproc subsystems (e.g., video, > graphics) do not require it. > > Add context aware qcom_mdt_pas_load() function which uses context > returned from qcom_scm_pas_ctx_init() and use it till subsystems > is out of set. This will also help in unifying the API used by > remoteproc and non-remoteproc subsystems drivers. > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> > --- I'm struggling with the logic here a little bit. You take this function which calls qcom_mtd_load_no_init(); > > - ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > - pas->dtb_pas_id, pas->dtb_mem_phys, > - &pas->dtb_pas_metadata); > - if (ret) > - goto release_dtb_firmware; > - > - ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > - pas->dtb_mem_region, pas->dtb_mem_phys, > - pas->dtb_mem_size, &pas->dtb_mem_reloc); > + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, pas->dtb_firmware_name, > + pas->dtb_mem_region, &pas->dtb_mem_reloc); and then turn it into > +int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw, > + const char *firmware, void *mem_region, phys_addr_t *reloc_base) > +{ > + int ret; > + > + ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral, > + ctx->mem_phys, ctx->metadata); > + if (ret) > + return ret; > + > + return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx->mem_phys, > + ctx->mem_size, reloc_base); Surely you want to qcom_mdt_load_no_init ? On current kernel return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx, mem_phys, ctx->mem_size, reloc_base, true); but that's a functional change > +} > +EXPORT_SYMBOL_GPL(qcom_mdt_pas_load); the no_init version of this looks like this: int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, const char *firmware, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size, phys_addr_t *reloc_base) { return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys, mem_size, reloc_base, false); } EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); So is it really the intention of this patch to change the callsites where qcom_mdt_pas_load() away from the init version to the no_init version ? Maybe its a symptom of patch collision but hmm, having a hard time cherry-picking this to test. --- bod
On Wed, Sep 03, 2025 at 04:03:05PM +0100, Bryan O'Donoghue wrote: > On 19/08/2025 17:54, Mukesh Ojha wrote: > > Currently, remoteproc and non-remoteproc subsystems use different > > variants of the MDT loader helper API, primarily due to the handling of > > the metadata context. Remoteproc subsystems retain this context until > > authentication and reset, while non-remoteproc subsystems (e.g., video, > > graphics) do not require it. > > > > Add context aware qcom_mdt_pas_load() function which uses context > > returned from qcom_scm_pas_ctx_init() and use it till subsystems > > is out of set. This will also help in unifying the API used by > > remoteproc and non-remoteproc subsystems drivers. > > > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> > > --- > > I'm struggling with the logic here a little bit. > > You take this function which calls qcom_mtd_load_no_init(); > > > - ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > > - pas->dtb_pas_id, pas->dtb_mem_phys, > > - &pas->dtb_pas_metadata); > > - if (ret) > > - goto release_dtb_firmware; > > - > > - ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > > - pas->dtb_mem_region, pas->dtb_mem_phys, > > - pas->dtb_mem_size, &pas->dtb_mem_reloc); > > + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, pas->dtb_firmware_name, > > + pas->dtb_mem_region, &pas->dtb_mem_reloc); > > and then turn it into > > > +int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw, > > + const char *firmware, void *mem_region, phys_addr_t *reloc_base) > > +{ > > + int ret; > > + > > + ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral, > > + ctx->mem_phys, ctx->metadata); > > + if (ret) > > + return ret; > > + > > + return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx->mem_phys, > > + ctx->mem_size, reloc_base); > > Surely you want to qcom_mdt_load_no_init ? > > On current kernel > return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx, > mem_phys, ctx->mem_size, > reloc_base, true); > > but that's a functional change > > > +} > > +EXPORT_SYMBOL_GPL(qcom_mdt_pas_load); > the no_init version of this looks like this: > > int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, > const char *firmware, int pas_id, > void *mem_region, phys_addr_t mem_phys, > size_t mem_size, phys_addr_t *reloc_base) > { > return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, > mem_phys, mem_size, reloc_base, false); > } > EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); > > So is it really the intention of this patch to change the callsites where > qcom_mdt_pas_load() away from the init version to the no_init version ? > > Maybe its a symptom of patch collision but hmm, having a hard time > cherry-picking this to test. My intention is to unify all subsystems whether it's remoteproc, video, or others using Secure PIL, so that they all use the same set of APIs via context (cxt). Like, we first initialize the context, and then use it for other PIL-related SMC calls such as pas_init, mem_setup, auth_and_reset, or even for the new rsc_table SMC call. This way, everything is connected, and it becomes clear which functions need to be called and it will also be extensible via a small handling for SHMbridge on gunyah absence. Similar changes would also apply to the MDT loader APIs. That's why I asked here after "---" in this patch if this approach is preferred, I will apply it consistently and eliminate redundant APIs. Let me know your thought. > > --- > bod > -- -Mukesh Ojha
On 04/09/2025 10:52, Mukesh Ojha wrote: >> So is it really the intention of this patch to change the callsites where >> qcom_mdt_pas_load() away from the init version to the no_init version ? >> >> Maybe its a symptom of patch collision but hmm, having a hard time >> cherry-picking this to test. > My intention is to unify all subsystems whether it's remoteproc, video, > or others using Secure PIL, so that they all use the same set of APIs > via context (cxt). > > Like, we first initialize the context, and then use it for other PIL-related > SMC calls such as pas_init, mem_setup, auth_and_reset, or even for the > new rsc_table SMC call. This way, everything is connected, and it > becomes clear which functions need to be called and it will also be > extensible via a small handling for SHMbridge on gunyah absence. Similar > changes would also apply to the MDT loader APIs. > > That's why I asked here after "---" in this patch if this approach is > preferred, I will apply it consistently and eliminate redundant APIs. > > Let me know your thought. For me its a question of digesting the change. Your series says "Add context aware qcom_mdt_pas_load()" but, it does more than add - it changes logic. At a minimum I'd suggest splitting the addition of the function from the changing of the existing logic so that the two could be disambiguated. The other comment I have is, is this change really required to enable pil loading @ EL2 ? You could for example structure this series to implement the changes you need for EL2 - and then have a last patch at the end to make the code "more beautiful" or even a second series to do that. So I'd suggest one of 1. Splitting the addition of the new helper and its use into separate patches in the same series. or 2. Doing the full EL2 conversion and then applying the "make the code look nice" patch last. So that we could for example take 11 of 13 patches or 3. Making the EL2 conversion and the posting a second series with your proposed tidy up Either way for me splicing both the addition and the usage here is a bit hard to parse, especially since I can't seem to find a public SHA where this series cleanly applies. --- bod
On Thu, Sep 04, 2025 at 11:15:29AM +0100, Bryan O'Donoghue wrote: > On 04/09/2025 10:52, Mukesh Ojha wrote: > > > So is it really the intention of this patch to change the callsites where > > > qcom_mdt_pas_load() away from the init version to the no_init version ? > > > > > > Maybe its a symptom of patch collision but hmm, having a hard time > > > cherry-picking this to test. > > My intention is to unify all subsystems whether it's remoteproc, video, > > or others using Secure PIL, so that they all use the same set of APIs > > via context (cxt). > > > > Like, we first initialize the context, and then use it for other PIL-related > > SMC calls such as pas_init, mem_setup, auth_and_reset, or even for the > > new rsc_table SMC call. This way, everything is connected, and it > > becomes clear which functions need to be called and it will also be > > extensible via a small handling for SHMbridge on gunyah absence. Similar > > changes would also apply to the MDT loader APIs. > > > > That's why I asked here after "---" in this patch if this approach is > > preferred, I will apply it consistently and eliminate redundant APIs. > > > > Let me know your thought. > > For me its a question of digesting the change. > > Your series says "Add context aware qcom_mdt_pas_load()" but, it does more > than add - it changes logic. > > At a minimum I'd suggest splitting the addition of the function from the > changing of the existing logic so that the two could be disambiguated. I agree, I did more than just add even used in current patch itself. Will split it. > > The other comment I have is, is this change really required to enable pil > loading @ EL2 ? Not exactly, but to looks things cleaner.. As the other way was carry extra boolean "rproc->has_iommu" in qcom_mdt_pas_init() for rproc and qcom_mdt_load() for video and other smc function to tell what needs to be done extra when Linux at EL2. > > You could for example structure this series to implement the changes you > need for EL2 - and then have a last patch at the end to make the code "more > beautiful" or even a second series to do that. > > So I'd suggest one of > > 1. Splitting the addition of the new helper and its use into > separate patches in the same series. > > or > > 2. Doing the full EL2 conversion and then applying the > "make the code look nice" patch last. > So that we could for example take 11 of 13 patches > > or > > 3. Making the EL2 conversion and the posting a second series > with your proposed tidy up > > Either way for me splicing both the addition and the usage here is a bit > hard to parse, especially since I can't seem to find a public SHA where this > series cleanly applies. I'm fine with 2 and 3 as well only if non-cleaner way with EL2 enablement gets accepted which may look ugly with lots of if's in the code or just do 1 for now. > > --- > bod -- -Mukesh Ojha
On 19/08/2025 17:54, Mukesh Ojha wrote: > Currently, remoteproc and non-remoteproc subsystems use different > variants of the MDT loader helper API, primarily due to the handling of > the metadata context. Remoteproc subsystems retain this context until > authentication and reset, while non-remoteproc subsystems (e.g., video, > graphics) do not require it. > > Add context aware qcom_mdt_pas_load() function which uses context > returned from qcom_scm_pas_ctx_init() and use it till subsystems > is out of set. This will also help in unifying the API used by > remoteproc and non-remoteproc subsystems drivers. > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> > --- > If this approach is preferred, will convert all subsystem drivers to use the > same set of API's using context and completely get away with qcom_mdt_load() > > -Mukesh > > drivers/remoteproc/qcom_q6v5_pas.c | 53 ++++++++++++++--------------- > drivers/soc/qcom/mdt_loader.c | 26 ++++++++++---- > include/linux/soc/qcom/mdt_loader.h | 22 ++++++------ > 3 files changed, 56 insertions(+), 45 deletions(-) > > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c > index 55a7da801183..e376c0338576 100644 > --- a/drivers/remoteproc/qcom_q6v5_pas.c > +++ b/drivers/remoteproc/qcom_q6v5_pas.c > @@ -115,8 +115,8 @@ struct qcom_pas { > struct qcom_rproc_ssr ssr_subdev; > struct qcom_sysmon *sysmon; > > - struct qcom_scm_pas_metadata pas_metadata; > - struct qcom_scm_pas_metadata dtb_pas_metadata; > + struct qcom_scm_pas_ctx *pas_ctx; > + struct qcom_scm_pas_ctx *dtb_pas_ctx; > }; > > static void qcom_pas_segment_dump(struct rproc *rproc, > @@ -209,9 +209,9 @@ static int qcom_pas_unprepare(struct rproc *rproc) > * auth_and_reset() was successful, but in other cases clean it up > * here. > */ > - qcom_scm_pas_metadata_release(&pas->pas_metadata); > + qcom_scm_pas_metadata_release(pas->pas_ctx->metadata); > if (pas->dtb_pas_id) > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > > return 0; > } > @@ -235,15 +235,8 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) > return ret; > } > > - ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > - pas->dtb_pas_id, pas->dtb_mem_phys, > - &pas->dtb_pas_metadata); > - if (ret) > - goto release_dtb_firmware; > - > - ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > - pas->dtb_mem_region, pas->dtb_mem_phys, > - pas->dtb_mem_size, &pas->dtb_mem_reloc); > + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, pas->dtb_firmware_name, > + pas->dtb_mem_region, &pas->dtb_mem_reloc); > if (ret) > goto release_dtb_metadata; > } > @@ -251,9 +244,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) > return 0; > > release_dtb_metadata: > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > - > -release_dtb_firmware: > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > release_firmware(pas->dtb_firmware); > > return ret; > @@ -301,14 +292,8 @@ static int qcom_pas_start(struct rproc *rproc) > } > } > > - ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, > - pas->mem_phys, &pas->pas_metadata); > - if (ret) > - goto disable_px_supply; > - > - ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, > - pas->mem_region, pas->mem_phys, pas->mem_size, > - &pas->mem_reloc); > + ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware, > + pas->mem_region, &pas->dtb_mem_reloc); > if (ret) > goto release_pas_metadata; > > @@ -328,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc) > goto release_pas_metadata; > } > > - qcom_scm_pas_metadata_release(&pas->pas_metadata); > + qcom_scm_pas_metadata_release(pas->pas_ctx->metadata); > if (pas->dtb_pas_id) > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > > /* firmware is used to pass reference from qcom_pas_start(), drop it now */ > pas->firmware = NULL; > @@ -338,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc) > return 0; > > release_pas_metadata: > - qcom_scm_pas_metadata_release(&pas->pas_metadata); > + qcom_scm_pas_metadata_release(pas->pas_ctx->metadata); > if (pas->dtb_pas_id) > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > disable_px_supply: > if (pas->px_supply) > regulator_disable(pas->px_supply); > @@ -774,6 +759,18 @@ static int qcom_pas_probe(struct platform_device *pdev) > } > > qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); > + > + pas->pas_ctx = qcom_scm_pas_ctx_init(pas->dev, pas->pas_id, pas->mem_phys, > + pas->mem_size, true); > + if (!pas->pas_ctx) > + goto remove_ssr_sysmon; this function already returns -ENOMEM you don't set ret to any particular value so if qcom_scm_pas_ctx_init() returned NULL, you would exit your probe function here "error out" with returning ret = 0 Please ERR_PTR() in qcom_scm_pas_ctx_init() and return the error up the call stack via your remove_ssr_sysmon jump label. --- bod
On Wed, Aug 20, 2025 at 12:48:55PM +0100, Bryan O'Donoghue wrote: > On 19/08/2025 17:54, Mukesh Ojha wrote: > > Currently, remoteproc and non-remoteproc subsystems use different > > variants of the MDT loader helper API, primarily due to the handling of > > the metadata context. Remoteproc subsystems retain this context until > > authentication and reset, while non-remoteproc subsystems (e.g., video, > > graphics) do not require it. > > > > Add context aware qcom_mdt_pas_load() function which uses context > > returned from qcom_scm_pas_ctx_init() and use it till subsystems > > is out of set. This will also help in unifying the API used by > > remoteproc and non-remoteproc subsystems drivers. > > > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> > > --- > > If this approach is preferred, will convert all subsystem drivers to use the > > same set of API's using context and completely get away with qcom_mdt_load() > > > > -Mukesh > > > > drivers/remoteproc/qcom_q6v5_pas.c | 53 ++++++++++++++--------------- > > drivers/soc/qcom/mdt_loader.c | 26 ++++++++++---- > > include/linux/soc/qcom/mdt_loader.h | 22 ++++++------ > > 3 files changed, 56 insertions(+), 45 deletions(-) > > > > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c > > index 55a7da801183..e376c0338576 100644 > > --- a/drivers/remoteproc/qcom_q6v5_pas.c > > +++ b/drivers/remoteproc/qcom_q6v5_pas.c > > @@ -115,8 +115,8 @@ struct qcom_pas { > > struct qcom_rproc_ssr ssr_subdev; > > struct qcom_sysmon *sysmon; > > - struct qcom_scm_pas_metadata pas_metadata; > > - struct qcom_scm_pas_metadata dtb_pas_metadata; > > + struct qcom_scm_pas_ctx *pas_ctx; > > + struct qcom_scm_pas_ctx *dtb_pas_ctx; > > }; > > static void qcom_pas_segment_dump(struct rproc *rproc, > > @@ -209,9 +209,9 @@ static int qcom_pas_unprepare(struct rproc *rproc) > > * auth_and_reset() was successful, but in other cases clean it up > > * here. > > */ > > - qcom_scm_pas_metadata_release(&pas->pas_metadata); > > + qcom_scm_pas_metadata_release(pas->pas_ctx->metadata); > > if (pas->dtb_pas_id) > > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > > return 0; > > } > > @@ -235,15 +235,8 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) > > return ret; > > } > > - ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > > - pas->dtb_pas_id, pas->dtb_mem_phys, > > - &pas->dtb_pas_metadata); > > - if (ret) > > - goto release_dtb_firmware; > > - > > - ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, > > - pas->dtb_mem_region, pas->dtb_mem_phys, > > - pas->dtb_mem_size, &pas->dtb_mem_reloc); > > + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, pas->dtb_firmware_name, > > + pas->dtb_mem_region, &pas->dtb_mem_reloc); > > if (ret) > > goto release_dtb_metadata; > > } > > @@ -251,9 +244,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) > > return 0; > > release_dtb_metadata: > > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > > - > > -release_dtb_firmware: > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > > release_firmware(pas->dtb_firmware); > > return ret; > > @@ -301,14 +292,8 @@ static int qcom_pas_start(struct rproc *rproc) > > } > > } > > - ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, > > - pas->mem_phys, &pas->pas_metadata); > > - if (ret) > > - goto disable_px_supply; > > - > > - ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, > > - pas->mem_region, pas->mem_phys, pas->mem_size, > > - &pas->mem_reloc); > > + ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware, > > + pas->mem_region, &pas->dtb_mem_reloc); > > if (ret) > > goto release_pas_metadata; > > @@ -328,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc) > > goto release_pas_metadata; > > } > > - qcom_scm_pas_metadata_release(&pas->pas_metadata); > > + qcom_scm_pas_metadata_release(pas->pas_ctx->metadata); > > if (pas->dtb_pas_id) > > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > > /* firmware is used to pass reference from qcom_pas_start(), drop it now */ > > pas->firmware = NULL; > > @@ -338,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc) > > return 0; > > release_pas_metadata: > > - qcom_scm_pas_metadata_release(&pas->pas_metadata); > > + qcom_scm_pas_metadata_release(pas->pas_ctx->metadata); > > if (pas->dtb_pas_id) > > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata); > > disable_px_supply: > > if (pas->px_supply) > > regulator_disable(pas->px_supply); > > @@ -774,6 +759,18 @@ static int qcom_pas_probe(struct platform_device *pdev) > > } > > qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); > > + > > + pas->pas_ctx = qcom_scm_pas_ctx_init(pas->dev, pas->pas_id, pas->mem_phys, > > + pas->mem_size, true); > > + if (!pas->pas_ctx) > > + goto remove_ssr_sysmon; > > this function already returns -ENOMEM you don't set ret to any particular > value so if qcom_scm_pas_ctx_init() returned NULL, you would exit your probe > function here "error out" with returning ret = 0 Ack. > > Please ERR_PTR() in qcom_scm_pas_ctx_init() and return the error up the call > stack via your remove_ssr_sysmon jump label. Sure. > > --- > bod -- -Mukesh Ojha
© 2016 - 2025 Red Hat, Inc.