aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Poulain <loic.poulain@linaro.org>2020-12-14 16:06:36 +0100
committerLoic Poulain <loic.poulain@linaro.org>2021-01-05 10:03:07 +0100
commit91f65d0eab25836345022491df5fbe6674605892 (patch)
tree0470578bc39e1154640bda6ca9afe55fb95665a9
parent6488c266484c9ca07df6f849f40eab51543fa39e (diff)
[DONOTUPSTREAM]mhi_uci: fix DIAG support
The current firmware is buggy an does not allow to close the DIAG without causing error on subsequent DIAG session (open). This patch simply prevents to close channel in case of DIAG chardev release. Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
-rw-r--r--drivers/bus/mhi/uci.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/bus/mhi/uci.c b/drivers/bus/mhi/uci.c
index 092321ac1232..b2423cd1e189 100644
--- a/drivers/bus/mhi/uci.c
+++ b/drivers/bus/mhi/uci.c
@@ -27,6 +27,8 @@ struct uci_dev {
unsigned int minor;
size_t mtu;
+ bool keep_channel_open;
+
struct mhi_device *mhi_dev;
struct mutex mhi_dev_lock;
@@ -42,6 +44,7 @@ struct uci_dev {
#define UCI_DEV_DL_CAP 0
#define UCI_DEV_UL_CAP 1
#define UCI_DEV_CONNECTED 2
+#define UCI_DEV_STARTED 3
struct kref ref_count;
};
@@ -118,6 +121,9 @@ static int mhi_uci_open(struct inode *inode, struct file *filp)
kref_get(&udev->ref_count);
mutex_unlock(&uci_drv_lock);
+ if (test_bit(UCI_DEV_STARTED, &udev->flags) && udev->keep_channel_open)
+ goto skip_open;
+
/* Start MHI channel(s) and fill RX queue */
mutex_lock(&udev->mhi_dev_lock);
ret = mhi_prepare_for_transfer(udev->mhi_dev, 0);
@@ -128,7 +134,9 @@ static int mhi_uci_open(struct inode *inode, struct file *filp)
if (ret)
return ret;
+skip_open:
filp->private_data = udev;
+ set_bit(UCI_DEV_STARTED, &udev->flags);
/* stream-like non-seekable file descriptor */
stream_open(inode, filp);
@@ -142,8 +150,10 @@ static int mhi_uci_release(struct inode *inode, struct file *file)
/* Stop the channels, if it is not already destroyed */
mutex_lock(&udev->mhi_dev_lock);
- if (udev->mhi_dev)
+ if (udev->mhi_dev && !udev->keep_channel_open) {
mhi_unprepare_from_transfer(udev->mhi_dev);
+ clear_bit(UCI_DEV_STARTED, &udev->flags);
+ }
mutex_unlock(&udev->mhi_dev_lock);
file->private_data = NULL;
@@ -426,6 +436,10 @@ static int mhi_uci_probe(struct mhi_device *mhi_dev,
if (mhi_dev->ul_chan)
set_bit(UCI_DEV_UL_CAP, &udev->flags);
+ /* FIXME */
+ if (!strcmp("DIAG", id->chan))
+ udev->keep_channel_open = true;
+
dev_set_drvdata(&mhi_dev->dev, udev);
/* Creates a new device and registers it with sysfs */