From 34e46f48e9af18e55248b20f498434a3e709b9ef Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 20 Mar 2020 15:04:26 -0700 Subject: [PATCH 1/2] mhi: core: add asynchronous time request support in sysfs Add support to request time from device using the asynchronous method in ticks and microseconds using sysfs entries. Change-Id: Idb661ad6db9f1cc4cd594c96755986ece4961b03 Signed-off-by: Bhaumik Bhatt --- drivers/bus/mhi/core/mhi_init.c | 78 ++++++++++++++++++++++++++++- drivers/bus/mhi/core/mhi_internal.h | 1 + drivers/bus/mhi/core/mhi_main.c | 6 +-- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 24a5175b246f..a5284a1c25d3 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,25 @@ const char *to_mhi_pm_state_str(enum MHI_PM_STATE state) return mhi_pm_state_str[index]; } +static void mhi_time_async_cb(struct mhi_device *mhi_dev, u32 sequence, + u64 local_time, u64 remote_time) +{ + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + + MHI_LOG("Time response: seq:%llx local: %llu remote: %llu (ticks)\n", + sequence, local_time, remote_time); +} + +static void mhi_time_us_async_cb(struct mhi_device *mhi_dev, u32 sequence, + u64 local_time, u64 remote_time) +{ + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + + MHI_LOG("Time response: seq:%llx local: %llu remote: %llu (us)\n", + sequence, LOCAL_TICKS_TO_US(local_time), + REMOTE_TICKS_TO_US(remote_time)); +} + static ssize_t time_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -110,7 +130,8 @@ static ssize_t time_show(struct device *dev, ret = mhi_get_remote_time_sync(mhi_dev, &t_host, &t_device); if (ret) { MHI_ERR("Failed to obtain time, ret:%d\n", ret); - return ret; + return scnprintf(buf, PAGE_SIZE, + "Request failed or feature unsupported\n"); } return scnprintf(buf, PAGE_SIZE, "local: %llu remote: %llu (ticks)\n", @@ -130,7 +151,8 @@ static ssize_t time_us_show(struct device *dev, ret = mhi_get_remote_time_sync(mhi_dev, &t_host, &t_device); if (ret) { MHI_ERR("Failed to obtain time, ret:%d\n", ret); - return ret; + return scnprintf(buf, PAGE_SIZE, + "Request failed or feature unsupported\n"); } return scnprintf(buf, PAGE_SIZE, "local: %llu remote: %llu (us)\n", @@ -139,9 +161,59 @@ static ssize_t time_us_show(struct device *dev, } static DEVICE_ATTR_RO(time_us); +static ssize_t time_async_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + u32 seq = prandom_u32(); + int ret; + + if (!seq) + seq = 1; + + ret = mhi_get_remote_time(mhi_dev, seq, &mhi_time_async_cb); + if (ret) { + MHI_ERR("Failed to request time, seq:%llx, ret:%d\n", seq, ret); + return scnprintf(buf, PAGE_SIZE, + "Request failed or feature unsupported\n"); + } + + return scnprintf(buf, PAGE_SIZE, + "Requested time asynchronously with seq:%llx\n", seq); +} +static DEVICE_ATTR_RO(time_async); + +static ssize_t time_us_async_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + u32 seq = prandom_u32(); + int ret; + + if (!seq) + seq = 1; + + ret = mhi_get_remote_time(mhi_dev, seq, &mhi_time_us_async_cb); + if (ret) { + MHI_ERR("Failed to request time, seq:%llx, ret:%d\n", seq, ret); + return scnprintf(buf, PAGE_SIZE, + "Request failed or feature unsupported\n"); + } + + return scnprintf(buf, PAGE_SIZE, + "Requested time asynchronously with seq:%llx\n", seq); +} +static DEVICE_ATTR_RO(time_us_async); + static struct attribute *mhi_tsync_attrs[] = { &dev_attr_time.attr, &dev_attr_time_us.attr, + &dev_attr_time_async.attr, + &dev_attr_time_us_async.attr, NULL, }; @@ -725,6 +797,8 @@ static int mhi_init_timesync(struct mhi_controller *mhi_cntrl) return er_index; } + mhi_tsync->db_support = true; + time_cfg_offset = time_offset + TIMESYNC_CFG_OFFSET; /* advertise host support */ diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index cb45bcd3f216..34c518d73d16 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -727,6 +727,7 @@ struct tsync_node { struct mhi_timesync { void __iomem *time_reg; u32 int_sequence; + bool db_support; spinlock_t lock; /* list protection */ struct list_head head; }; diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 6fb804deb9b1..61aedea4a801 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -2545,7 +2545,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, int ret; mutex_lock(&mhi_cntrl->tsync_mutex); - /* not all devices support time feature */ + /* not all devices support time features */ if (!mhi_tsync) { ret = -EIO; goto error_unlock; @@ -2620,9 +2620,9 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, struct tsync_node *tsync_node; int ret; - /* not all devices support time feature */ + /* not all devices support all time features */ mutex_lock(&mhi_cntrl->tsync_mutex); - if (!mhi_tsync) { + if (!mhi_tsync || !mhi_tsync->db_support) { ret = -EIO; goto error_unlock; } From 9298cd363606c4e8cd5dd470dd50bf96d7748aca Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 20 Mar 2020 12:17:38 -0700 Subject: [PATCH 2/2] mhi: core: remove duplicate timesync sysfs functions Remove duplicate timesync sysfs functions as they have moved to a different file. Change-Id: Ia1988f32eb6bf16914564977d09ba7ee81022335 Signed-off-by: Bhaumik Bhatt --- drivers/bus/mhi/core/mhi_main.c | 69 --------------------------------- 1 file changed, 69 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 61aedea4a801..aa55ad065641 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -797,75 +797,6 @@ static void mhi_assign_of_node(struct mhi_controller *mhi_cntrl, } } -static ssize_t time_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct mhi_device *mhi_dev = to_mhi_device(dev); - struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; - u64 t_host, t_device; - int ret; - - ret = mhi_get_remote_time_sync(mhi_dev, &t_host, &t_device); - if (ret) { - MHI_ERR("Failed to obtain time, ret:%d\n", ret); - return ret; - } - - return scnprintf(buf, PAGE_SIZE, "local: %llu remote: %llu (ticks)\n", - t_host, t_device); -} -static DEVICE_ATTR_RO(time); - -static ssize_t time_us_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct mhi_device *mhi_dev = to_mhi_device(dev); - struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; - u64 t_host, t_device; - int ret; - - ret = mhi_get_remote_time_sync(mhi_dev, &t_host, &t_device); - if (ret) { - MHI_ERR("Failed to obtain time, ret:%d\n", ret); - return ret; - } - - return scnprintf(buf, PAGE_SIZE, "local: %llu remote: %llu (us)\n", - LOCAL_TICKS_TO_US(t_host), - REMOTE_TICKS_TO_US(t_device)); -} -static DEVICE_ATTR_RO(time_us); - -static struct attribute *mhi_tsync_attrs[] = { - &dev_attr_time.attr, - &dev_attr_time_us.attr, - NULL, -}; - -static const struct attribute_group mhi_tsync_group = { - .attrs = mhi_tsync_attrs, -}; - -void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl) -{ - if (mhi_cntrl->mhi_tsync) { - mutex_lock(&mhi_cntrl->tsync_mutex); - sysfs_remove_group(&mhi_cntrl->mhi_dev->dev.kobj, - &mhi_tsync_group); - kfree(mhi_cntrl->mhi_tsync); - mhi_cntrl->mhi_tsync = NULL; - mutex_unlock(&mhi_cntrl->tsync_mutex); - } -} - -int mhi_create_timesync_sysfs(struct mhi_controller *mhi_cntrl) -{ - return sysfs_create_group(&mhi_cntrl->mhi_dev->dev.kobj, - &mhi_tsync_group); -} - /* bind mhi channels into mhi devices */ void mhi_create_devices(struct mhi_controller *mhi_cntrl) {