Re: [PATCH v4 8/9] bus: mhi: Expose DDR training data via controller sysfs
Kishore Batta <[email protected]> Tue, 14 Apr 2026 15:26:47 +0530
| 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 4/13/2026 5:28 PM, Manivannan Sadhasivam wrote: > On Thu, Mar 19, 2026 at 12:01:48PM +0530, Kishore Batta wrote: >> DDR training data captured during Sahara command mode needs to be >> accessible to userspace so it can be persisted and reused on subsequent >> boots. Currently, the training data is stored internally in the driver >> but has no external visibility once the sahara channel is torn down. >> > Maybe share some steps on how the userspace is expected to use this calibration > data. Sure. will update the commit message with the required details in the next version. >> Expose the captured DDR training data via a read-only binary sysfs >> attribute on the MHI controller device. The sysfs file is created under >> the controller node, allowing userspace to read the training data even >> after the sahara channel device has been removed. >> > So once the calibration data is read, how it can be used further? The userspace will store the calibration data in "mdmddr_0x<serial_no>.mbn format. In the next boot, Sahara driver loads the real DDR calibration data and training data will be restored. No repeated DDR training is performed at target end. > >> The sysfs attribute reads directly from controller-scoped storage and >> relies on device managed resources for cleanup when the controller >> device is destroyed. No explicit sysfs removal is required, avoiding >> lifetime dependencies on the Sahara channel device. >> > Missing ABI documentation. > > - Mani Currently i have added in a separate patch(9/9). I will squash it with this patch in the next version. >> Signed-off-by: Kishore Batta <[email protected]> >> --- >> drivers/bus/mhi/sahara/sahara.c | 69 +++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 69 insertions(+) >> >> diff --git a/drivers/bus/mhi/sahara/sahara.c b/drivers/bus/mhi/sahara/sahara.c >> index c88f1220199ac4373d3552167870c19a0d5f23b9..b7208738df10fc3c3895acd46873412818dc1730 100644 >> --- a/drivers/bus/mhi/sahara/sahara.c >> +++ b/drivers/bus/mhi/sahara/sahara.c >> @@ -415,6 +415,73 @@ static struct sahara_ctrl_trng_data *sahara_ctrl_trng_get(struct device *dev) >> return ct; >> } >> >> +static ssize_t ddr_training_data_read(struct file *filp, struct kobject *kobj, >> + const struct bin_attribute *attr, char *buf, >> + loff_t offset, size_t count) >> +{ >> + struct device *dev = kobj_to_dev(kobj); >> + struct sahara_ctrl_trng_data *ct; >> + size_t available; >> + >> + ct = sahara_ctrl_trng_get(dev); >> + if (!ct) >> + return -ENODEV; >> + >> + mutex_lock(&ct->lock); >> + >> + /* No data yet or offset past end */ >> + if (!ct->data || offset >= ct->size) { >> + mutex_unlock(&ct->lock); >> + return 0; >> + } >> + >> + available = ct->size - offset; >> + count = min(count, available); >> + memcpy(buf, (u8 *)ct->data + offset, count); >> + >> + mutex_unlock(&ct->lock); >> + >> + return count; >> +} >> + >> +static const struct bin_attribute ddr_training_data_attr = { >> + .attr = { >> + .name = "ddr_training_data", >> + .mode = 0444, >> + }, >> + .read = ddr_training_data_read, >> +}; >> + >> +static void sahara_sysfs_devres_release(struct device *dev, void *res) >> +{ >> + device_remove_bin_file(dev, &ddr_training_data_attr); >> +} >> + >> +static void sahara_sysfs_create(struct mhi_device *mhi_dev) >> +{ >> + struct device *dev = &mhi_dev->mhi_cntrl->mhi_dev->dev; >> + void *cookie; >> + int ret; >> + >> + if (devres_find(dev, sahara_sysfs_devres_release, NULL, NULL)) >> + return; >> + >> + ret = device_create_bin_file(dev, &ddr_training_data_attr); >> + if (ret) { >> + dev_warn(&mhi_dev->dev, >> + "Failed to create DDR training sysfs node (%d)\n", ret); >> + return; >> + } >> + >> + cookie = devres_alloc(sahara_sysfs_devres_release, 1, GFP_KERNEL); >> + if (!cookie) { >> + device_remove_bin_file(dev, &ddr_training_data_attr); >> + return; >> + } >> + >> + devres_add(dev, cookie); >> +} >> + >> static int sahara_find_image(struct sahara_context *context, u32 image_id) >> { >> char *fw_path; >> @@ -1272,6 +1339,8 @@ static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_ >> return ret; >> } >> >> + sahara_sysfs_create(mhi_dev); >> + >> return 0; >> } >> >> >> -- >> 2.34.1 >>