Re: [PATCH v4 8/9] bus: mhi: Expose DDR training data via controller sysfs
Manivannan Sadhasivam <[email protected]> Mon, 13 Apr 2026 17:28:56 +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 | <tbwahssgudfeacfj3wcg32yw5fkqorswees4gv4geypjmmdcyu@tv6qkuhyw23l> |
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. > 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 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 > 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 > -- மணிவண்ணன் சதாசிவம்