Loading drivers/bus/mhi/core/mhi_init.c +3 −0 Original line number Diff line number Diff line Loading @@ -356,6 +356,9 @@ void mhi_destroy_sysfs(struct mhi_controller *mhi_cntrl) } spin_unlock(&mhi_tsync->lock); if (mhi_tsync->db_response_pending) complete(&mhi_tsync->db_completion); kfree(mhi_cntrl->mhi_tsync); mhi_cntrl->mhi_tsync = NULL; mutex_unlock(&mhi_cntrl->tsync_mutex); Loading drivers/bus/mhi/core/mhi_internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -728,8 +728,10 @@ struct mhi_timesync { void __iomem *time_reg; u32 int_sequence; u64 local_time; u64 remote_time; bool db_support; bool db_response_pending; struct completion db_completion; spinlock_t lock; /* list protection */ struct list_head head; }; Loading drivers/bus/mhi/core/mhi_main.c +48 −16 Original line number Diff line number Diff line Loading @@ -1396,6 +1396,10 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl, if (unlikely(mhi_tsync->int_sequence != sequence)) { MHI_ASSERT(1, "Unexpected response:0x%llx Expected:0x%llx\n", sequence, mhi_tsync->int_sequence); mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); mutex_unlock(&mhi_cntrl->tsync_mutex); goto exit_tsync_process; } Loading @@ -1421,6 +1425,11 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl, } while (true); mhi_tsync->db_response_pending = false; mhi_tsync->remote_time = remote_time; complete(&mhi_tsync->db_completion); mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); mutex_unlock(&mhi_cntrl->tsync_mutex); exit_tsync_process: Loading Loading @@ -2549,13 +2558,37 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync; u64 local_time; int ret; mutex_lock(&mhi_cntrl->tsync_mutex); /* not all devices support time features */ if (!mhi_tsync) { ret = -EIO; goto err_unlock; if (!mhi_tsync) return -EINVAL; if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) { MHI_ERR("MHI is not in active state, pm_state:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state)); return -EIO; } mutex_lock(&mhi_cntrl->tsync_mutex); /* return times from last async request completion */ if (mhi_tsync->db_response_pending) { local_time = mhi_tsync->local_time; mutex_unlock(&mhi_cntrl->tsync_mutex); ret = wait_for_completion_timeout(&mhi_tsync->db_completion, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || !ret) { MHI_ERR("Pending DB request did not complete, abort\n"); return -EAGAIN; } *t_host = local_time; *t_dev = mhi_tsync->remote_time; return 0; } /* bring to M0 state */ Loading Loading @@ -2624,14 +2657,13 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, int ret = 0; /* not all devices support all time features */ if (!mhi_tsync || !mhi_tsync->db_support) return -EINVAL; mutex_lock(&mhi_cntrl->tsync_mutex); if (!mhi_tsync || !mhi_tsync->db_support) { ret = -EIO; goto error_unlock; } /* tsync db can only be rung in M0 state */ ret = __mhi_device_get_sync(mhi_cntrl); ret = mhi_device_get_sync(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); if (ret) goto error_unlock; Loading Loading @@ -2699,21 +2731,21 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, MHI_VERB("time DB request with seq:0x%llx\n", mhi_tsync->int_sequence); mhi_tsync->db_response_pending = true; init_completion(&mhi_tsync->db_completion); skip_tsync_db: spin_lock(&mhi_tsync->lock); list_add_tail(&tsync_node->node, &mhi_tsync->head); spin_unlock(&mhi_tsync->lock); ret = 0; mutex_unlock(&mhi_cntrl->tsync_mutex); return 0; error_invalid_state: if (ret) kfree(tsync_node); error_no_mem: read_lock_bh(&mhi_cntrl->pm_lock); mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); error_unlock: mutex_unlock(&mhi_cntrl->tsync_mutex); return ret; Loading Loading
drivers/bus/mhi/core/mhi_init.c +3 −0 Original line number Diff line number Diff line Loading @@ -356,6 +356,9 @@ void mhi_destroy_sysfs(struct mhi_controller *mhi_cntrl) } spin_unlock(&mhi_tsync->lock); if (mhi_tsync->db_response_pending) complete(&mhi_tsync->db_completion); kfree(mhi_cntrl->mhi_tsync); mhi_cntrl->mhi_tsync = NULL; mutex_unlock(&mhi_cntrl->tsync_mutex); Loading
drivers/bus/mhi/core/mhi_internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -728,8 +728,10 @@ struct mhi_timesync { void __iomem *time_reg; u32 int_sequence; u64 local_time; u64 remote_time; bool db_support; bool db_response_pending; struct completion db_completion; spinlock_t lock; /* list protection */ struct list_head head; }; Loading
drivers/bus/mhi/core/mhi_main.c +48 −16 Original line number Diff line number Diff line Loading @@ -1396,6 +1396,10 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl, if (unlikely(mhi_tsync->int_sequence != sequence)) { MHI_ASSERT(1, "Unexpected response:0x%llx Expected:0x%llx\n", sequence, mhi_tsync->int_sequence); mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); mutex_unlock(&mhi_cntrl->tsync_mutex); goto exit_tsync_process; } Loading @@ -1421,6 +1425,11 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl, } while (true); mhi_tsync->db_response_pending = false; mhi_tsync->remote_time = remote_time; complete(&mhi_tsync->db_completion); mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); mutex_unlock(&mhi_cntrl->tsync_mutex); exit_tsync_process: Loading Loading @@ -2549,13 +2558,37 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync; u64 local_time; int ret; mutex_lock(&mhi_cntrl->tsync_mutex); /* not all devices support time features */ if (!mhi_tsync) { ret = -EIO; goto err_unlock; if (!mhi_tsync) return -EINVAL; if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) { MHI_ERR("MHI is not in active state, pm_state:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state)); return -EIO; } mutex_lock(&mhi_cntrl->tsync_mutex); /* return times from last async request completion */ if (mhi_tsync->db_response_pending) { local_time = mhi_tsync->local_time; mutex_unlock(&mhi_cntrl->tsync_mutex); ret = wait_for_completion_timeout(&mhi_tsync->db_completion, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || !ret) { MHI_ERR("Pending DB request did not complete, abort\n"); return -EAGAIN; } *t_host = local_time; *t_dev = mhi_tsync->remote_time; return 0; } /* bring to M0 state */ Loading Loading @@ -2624,14 +2657,13 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, int ret = 0; /* not all devices support all time features */ if (!mhi_tsync || !mhi_tsync->db_support) return -EINVAL; mutex_lock(&mhi_cntrl->tsync_mutex); if (!mhi_tsync || !mhi_tsync->db_support) { ret = -EIO; goto error_unlock; } /* tsync db can only be rung in M0 state */ ret = __mhi_device_get_sync(mhi_cntrl); ret = mhi_device_get_sync(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); if (ret) goto error_unlock; Loading Loading @@ -2699,21 +2731,21 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, MHI_VERB("time DB request with seq:0x%llx\n", mhi_tsync->int_sequence); mhi_tsync->db_response_pending = true; init_completion(&mhi_tsync->db_completion); skip_tsync_db: spin_lock(&mhi_tsync->lock); list_add_tail(&tsync_node->node, &mhi_tsync->head); spin_unlock(&mhi_tsync->lock); ret = 0; mutex_unlock(&mhi_cntrl->tsync_mutex); return 0; error_invalid_state: if (ret) kfree(tsync_node); error_no_mem: read_lock_bh(&mhi_cntrl->pm_lock); mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS); error_unlock: mutex_unlock(&mhi_cntrl->tsync_mutex); return ret; Loading