summaryrefslogtreecommitdiff
path: root/drivers/bus
diff options
context:
space:
mode:
authorQiang Yu <quic_qianyu@quicinc.com>2024-04-24 11:21:53 +0800
committerManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>2024-04-25 20:16:42 +0530
commit17553ba8e19dee8770b3dcc597d49dcc3418f3b0 (patch)
tree5b8725ed7a2cc33ab7395598fb80560b4542b12e /drivers/bus
parent813e0ae613d6ee1b3e11f1c41f8b9e9df8ef0493 (diff)
bus: mhi: host: Add sysfs entry to force device to enter EDL
Add sysfs entry to allow users of MHI bus to force device to enter EDL (Emergency Download) mode to download the device firmware. Since there is no guarantee that all the devices will support EDL mode, the sysfs entry is kept as an optional one and will appear only for the supported devices. Controllers supporting the EDL mode are expected to provide edl_trigger() callback that puts the device into EDL mode. Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Link: https://lore.kernel.org/r/1713928915-18229-2-git-send-email-quic_qianyu@quicinc.com [mani: fixed the kernel version and reworded the commit message] Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Diffstat (limited to 'drivers/bus')
-rw-r--r--drivers/bus/mhi/host/init.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index 44f934981de8..7104c1856987 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -127,6 +127,30 @@ static ssize_t soc_reset_store(struct device *dev,
}
static DEVICE_ATTR_WO(soc_reset);
+static ssize_t trigger_edl_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct mhi_device *mhi_dev = to_mhi_device(dev);
+ struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ if (!val)
+ return -EINVAL;
+
+ ret = mhi_cntrl->edl_trigger(mhi_cntrl);
+ if (ret)
+ return ret;
+
+ return count;
+}
+static DEVICE_ATTR_WO(trigger_edl);
+
static struct attribute *mhi_dev_attrs[] = {
&dev_attr_serial_number.attr,
&dev_attr_oem_pk_hash.attr,
@@ -1018,6 +1042,12 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
if (ret)
goto err_release_dev;
+ if (mhi_cntrl->edl_trigger) {
+ ret = sysfs_create_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr);
+ if (ret)
+ goto err_release_dev;
+ }
+
mhi_cntrl->mhi_dev = mhi_dev;
mhi_create_debugfs(mhi_cntrl);
@@ -1051,6 +1081,9 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
mhi_deinit_free_irq(mhi_cntrl);
mhi_destroy_debugfs(mhi_cntrl);
+ if (mhi_cntrl->edl_trigger)
+ sysfs_remove_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr);
+
destroy_workqueue(mhi_cntrl->hiprio_wq);
kfree(mhi_cntrl->mhi_cmd);
kfree(mhi_cntrl->mhi_event);