Re: [PATCH v4 5/9] bus: mhi: Add QDU100 variant and image_id firmware fallback
Jeff Hugo <[email protected]> Thu, 9 Apr 2026 15:14:10 -0600
| Newsgroups | dev.linux.lists.mhi,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 3/19/2026 12:31 AM, Kishore Batta wrote: > The Sahara driver currently selects a firmware image table based on the > attached device, but it does not recognize QDU100 devices that expose the > protocol on the SAHARA MHI channel. As a result, the host cannot associate > QDU100 devices with the correct firmware namespace during image transfer. > > Extend the probe-time variant selection to match the SAHARA MHI channel > and associate it with the QDU100 firmware folder. Add an image_id based > firmware lookup fallback for cases where an image does not have an explicit > table entry. This allows required images to be provisioned by the platform > without requiring device specific client drivers or additional registration > mechanisms. > > This change only affects devices matched on the SAHARA channel and does not > change behavior for existing AIC100 and AIC200 devices. > > Signed-off-by: Kishore Batta <[email protected]> > --- > drivers/bus/mhi/sahara/sahara.c | 77 ++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 72 insertions(+), 5 deletions(-) > > diff --git a/drivers/bus/mhi/sahara/sahara.c b/drivers/bus/mhi/sahara/sahara.c > index 8f1c0d72066c0cf80c09d78bfc51df2e482133b9..4ea14c57774f51a778289d7409372a6ab21fea60 100644 > --- a/drivers/bus/mhi/sahara/sahara.c > +++ b/drivers/bus/mhi/sahara/sahara.c > @@ -234,6 +234,36 @@ static const char * const aic200_image_table[] = { > [78] = "qcom/aic200/pvs.bin", > }; > > +static const char * const qdu100_image_table[] = { > + [5] = "qcom/qdu100/uefi.elf", > + [8] = "qcom/qdu100/qdsp6sw.mbn", > + [16] = "qcom/qdu100/efs1.bin", > + [17] = "qcom/qdu100/efs2.bin", > + [20] = "qcom/qdu100/efs3.bin", > + [23] = "qcom/qdu100/aop.mbn", > + [25] = "qcom/qdu100/tz.mbn", > + [29] = "qcom/qdu100/zeros_1sector.bin", > + [33] = "qcom/qdu100/hypvm.mbn", > + [34] = "qcom/qdu100/mdmddr.mbn", > + [36] = "qcom/qdu100/multi_image_qti.mbn", > + [37] = "qcom/qdu100/multi_image.mbn", > + [38] = "qcom/qdu100/xbl_config.elf", > + [39] = "qcom/qdu100/abl_userdebug.elf", > + [40] = "qcom/qdu100/zeros_1sector.bin", > + [41] = "qcom/qdu100/devcfg.mbn", > + [42] = "qcom/qdu100/zeros_1sector.bin", > + [45] = "qcom/qdu100/tools_l.elf", > + [46] = "qcom/qdu100/Quantum.elf", > + [47] = "qcom/qdu100/quest.elf", > + [48] = "qcom/qdu100/xbl_ramdump.elf", > + [49] = "qcom/qdu100/shrm.elf", > + [50] = "qcom/qdu100/cpucp.elf", > + [51] = "qcom/qdu100/aop_devcfg.mbn", > + [52] = "qcom/qdu100/fw_csm_gsi_3.0.elf", > + [53] = "qcom/qdu100/qdsp6sw_dtbs.elf", > + [54] = "qcom/qdu100/qupv3fw.elf", > +}; > + > static const struct sahara_variant sahara_variants[] = { > { > .match = "AIC100", > @@ -250,6 +280,14 @@ static const struct sahara_variant sahara_variants[] = { > .table_size = ARRAY_SIZE(aic200_image_table), > .fw_folder = "aic200", > .non_streaming = false, > + }, > + { > + .match = "SAHARA", > + .match_is_chan = true, Theres a half dozen non-QDU100 devices in pci_generic.c which expose "SAHARA" channels. Considering those as valid usecases, I don't see this mechanism working. Everything non-AIC is now going to be treated as QDU100. > + .image_table = qdu100_image_table, > + .table_size = ARRAY_SIZE(qdu100_image_table), > + .fw_folder = "qdu100", > + .non_streaming = false, > } > }; > > @@ -278,8 +316,21 @@ static const struct sahara_variant *sahara_select_variant(struct mhi_device *mhi > return NULL; > } > > +static int sahara_request_fw(struct sahara_context *context, const char *path) > +{ > + int ret; > + > + ret = firmware_request_nowarn(&context->firmware, path, > + &context->mhi_dev->dev); > + if (ret) > + dev_dbg(&context->mhi_dev->dev, > + "Request for file %s failed %d\n", path, ret); > + return ret; > +} This is a pointless change. Drop it. > + > static int sahara_find_image(struct sahara_context *context, u32 image_id) > { > + char *fw_path; > int ret; > > if (image_id == context->active_image_id) > @@ -292,8 +343,26 @@ static int sahara_find_image(struct sahara_context *context, u32 image_id) > } > > if (image_id >= context->table_size || !context->image_table[image_id]) { > - dev_err(&context->mhi_dev->dev, "request for unknown image: %d\n", image_id); > - return -EINVAL; > + if (!context->fw_folder) { > + dev_err(&context->mhi_dev->dev, > + "Request for unknown image: %u (no fw folder)\n", image_id); > + return -EINVAL; > + } > + > + fw_path = kasprintf(GFP_KERNEL, "qcom/%s/image_%u.elf", > + context->fw_folder, image_id); > + if (!fw_path) > + return -ENOMEM; > + > + ret = sahara_request_fw(context, fw_path); > + kfree(fw_path); > + if (ret) { > + dev_err(&context->mhi_dev->dev, > + "request for unknown image: %d\n", image_id); > + return -EINVAL; > + } > + context->active_image_id = image_id; > + return 0; I don't see a usecase for this fw path search functionality, and I think it breaks the documented firmware loading guidelines. > } > > /* > @@ -301,9 +370,7 @@ static int sahara_find_image(struct sahara_context *context, u32 image_id) > * Only the device knows. Suppress error messages that could suggest an > * a problem when we were actually able to continue. > */ > - ret = firmware_request_nowarn(&context->firmware, > - context->image_table[image_id], > - &context->mhi_dev->dev); > + ret = sahara_request_fw(context, context->image_table[image_id]); > if (ret) { > dev_dbg(&context->mhi_dev->dev, "request for image id %d / file %s failed %d\n", > image_id, context->image_table[image_id], ret); >