Loading drivers/bus/mhi/controllers/mhi_arch_qcom.c +38 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ struct arch_info { struct dma_iommu_mapping *mapping; async_cookie_t cookie; void *boot_ipc_log; void *tsync_ipc_log; struct mhi_device *boot_dev; struct mhi_link_info current_link_info; struct work_struct bw_scale_work; Loading @@ -50,6 +51,8 @@ struct arch_info { #define DLOG "Dev->Host: " #define HLOG "Host: " #define MHI_TSYNC_LOG_PAGES (10) #ifdef CONFIG_MHI_DEBUG #define MHI_IPC_LOG_PAGES (100) Loading Loading @@ -81,6 +84,19 @@ static int mhi_arch_pm_notifier(struct notifier_block *nb, return NOTIFY_DONE; } static void mhi_arch_timesync_log(struct mhi_controller *mhi_cntrl, u64 remote_time) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct arch_info *arch_info = mhi_dev->arch_info; if (remote_time != U64_MAX) ipc_log_string(arch_info->tsync_ipc_log, "%6u.%06lu 0x%llx", REMOTE_TICKS_TO_SEC(remote_time), REMOTE_TIME_REMAINDER_US(remote_time), remote_time); } static int mhi_arch_set_bus_request(struct mhi_controller *mhi_cntrl, int index) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); Loading Loading @@ -228,6 +244,18 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) pm_relax(&mhi_cntrl->mhi_dev->dev); } static void mhi_arch_esoc_ops_mdm_error(void *priv) { struct mhi_controller *mhi_cntrl = priv; MHI_LOG("Enter: mdm asserted\n"); /* transition MHI state into error state */ mhi_control_error(mhi_cntrl); MHI_LOG("Exit\n"); } static void mhi_bl_dl_cb(struct mhi_device *mhi_device, struct mhi_result *mhi_result) { Loading Loading @@ -431,6 +459,14 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) node, 0); mhi_cntrl->log_lvl = mhi_ipc_log_lvl; snprintf(node, sizeof(node), "mhi_tsync_%04x_%02u.%02u.%02u", mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus, mhi_cntrl->slot); arch_info->tsync_ipc_log = ipc_log_context_create( MHI_TSYNC_LOG_PAGES, node, 0); if (arch_info->tsync_ipc_log) mhi_cntrl->tsync_log = mhi_arch_timesync_log; /* register for bus scale if defined */ arch_info->msm_bus_pdata = msm_bus_cl_get_pdata_from_dev( &mhi_dev->pci_dev->dev); Loading Loading @@ -481,6 +517,8 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) mhi_arch_esoc_ops_power_on; esoc_ops->esoc_link_power_off = mhi_arch_esoc_ops_power_off; esoc_ops->esoc_link_mdm_crash = mhi_arch_esoc_ops_mdm_error; ret = esoc_register_client_hook(arch_info->esoc_client, esoc_ops); Loading drivers/bus/mhi/controllers/mhi_qcom.h +8 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,14 @@ #define MHI_RPM_SUSPEND_TMR_MS (250) #define MHI_PCI_BAR_NUM (0) /* timesync time calculations */ #define REMOTE_TICKS_TO_US(x) (div_u64((x) * 100ULL, \ div_u64(mhi_cntrl->remote_timer_freq, 10000ULL))) #define REMOTE_TICKS_TO_SEC(x) (div_u64((x), \ mhi_cntrl->remote_timer_freq)) #define REMOTE_TIME_REMAINDER_US(x) (REMOTE_TICKS_TO_US((x)) % \ (REMOTE_TICKS_TO_SEC((x)) * 1000000ULL)) extern const char * const mhi_ee_str[MHI_EE_MAX]; #define TO_MHI_EXEC_STR(ee) (ee >= MHI_EE_MAX ? "INVALID_EE" : mhi_ee_str[ee]) Loading drivers/bus/mhi/core/mhi_internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -761,6 +761,7 @@ int mhi_create_timesync_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl); int mhi_create_vote_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_vote_sysfs(struct mhi_controller *mhi_cntrl); int mhi_early_notify_device(struct device *dev, void *data); /* timesync log support */ static inline void mhi_timesync_log(struct mhi_controller *mhi_cntrl) Loading drivers/bus/mhi/core/mhi_main.c +23 −0 Original line number Diff line number Diff line Loading @@ -646,6 +646,22 @@ int mhi_destroy_device(struct device *dev, void *data) return 0; } int mhi_early_notify_device(struct device *dev, void *data) { struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; /* skip early notification */ if (!mhi_dev->early_notif) return 0; MHI_LOG("Early notification for dev:%s\n", mhi_dev->chan_name); mhi_notify(mhi_dev, MHI_CB_FATAL_ERROR); return 0; } void mhi_notify(struct mhi_device *mhi_dev, enum MHI_CB cb_reason) { struct mhi_driver *mhi_drv; Loading Loading @@ -856,6 +872,13 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) /* add if there is a matching DT node */ mhi_assign_of_node(mhi_cntrl, mhi_dev); /* * if set, these device should get a early notification during * early notification state */ mhi_dev->early_notif = of_property_read_bool(mhi_dev->dev.of_node, "mhi,early-notify"); /* init wake source */ if (mhi_dev->dl_chan && mhi_dev->dl_chan->wake_capable) device_init_wakeup(&mhi_dev->dev, true); Loading drivers/bus/mhi/core/mhi_pm.c +30 −0 Original line number Diff line number Diff line Loading @@ -893,6 +893,36 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) } EXPORT_SYMBOL(mhi_async_power_up); /* Transition MHI into error state and notify critical clients */ void mhi_control_error(struct mhi_controller *mhi_cntrl) { enum MHI_PM_STATE cur_state; MHI_LOG("Enter with pm_state:%s MHI_STATE:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state)); write_lock_irq(&mhi_cntrl->pm_lock); cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_LD_ERR_FATAL_DETECT); write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT) { MHI_ERR("Failed to transition to state:%s from:%s\n", to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT), to_mhi_pm_state_str(cur_state)); goto exit_control_error; } /* start notifying all clients who request early notification */ device_for_each_child(mhi_cntrl->dev, NULL, mhi_early_notify_device); exit_control_error: MHI_LOG("Exit with pm_state:%s MHI_STATE:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state)); } EXPORT_SYMBOL(mhi_control_error); void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) { enum MHI_PM_STATE cur_state; Loading Loading
drivers/bus/mhi/controllers/mhi_arch_qcom.c +38 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ struct arch_info { struct dma_iommu_mapping *mapping; async_cookie_t cookie; void *boot_ipc_log; void *tsync_ipc_log; struct mhi_device *boot_dev; struct mhi_link_info current_link_info; struct work_struct bw_scale_work; Loading @@ -50,6 +51,8 @@ struct arch_info { #define DLOG "Dev->Host: " #define HLOG "Host: " #define MHI_TSYNC_LOG_PAGES (10) #ifdef CONFIG_MHI_DEBUG #define MHI_IPC_LOG_PAGES (100) Loading Loading @@ -81,6 +84,19 @@ static int mhi_arch_pm_notifier(struct notifier_block *nb, return NOTIFY_DONE; } static void mhi_arch_timesync_log(struct mhi_controller *mhi_cntrl, u64 remote_time) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); struct arch_info *arch_info = mhi_dev->arch_info; if (remote_time != U64_MAX) ipc_log_string(arch_info->tsync_ipc_log, "%6u.%06lu 0x%llx", REMOTE_TICKS_TO_SEC(remote_time), REMOTE_TIME_REMAINDER_US(remote_time), remote_time); } static int mhi_arch_set_bus_request(struct mhi_controller *mhi_cntrl, int index) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); Loading Loading @@ -228,6 +244,18 @@ static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags) pm_relax(&mhi_cntrl->mhi_dev->dev); } static void mhi_arch_esoc_ops_mdm_error(void *priv) { struct mhi_controller *mhi_cntrl = priv; MHI_LOG("Enter: mdm asserted\n"); /* transition MHI state into error state */ mhi_control_error(mhi_cntrl); MHI_LOG("Exit\n"); } static void mhi_bl_dl_cb(struct mhi_device *mhi_device, struct mhi_result *mhi_result) { Loading Loading @@ -431,6 +459,14 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) node, 0); mhi_cntrl->log_lvl = mhi_ipc_log_lvl; snprintf(node, sizeof(node), "mhi_tsync_%04x_%02u.%02u.%02u", mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus, mhi_cntrl->slot); arch_info->tsync_ipc_log = ipc_log_context_create( MHI_TSYNC_LOG_PAGES, node, 0); if (arch_info->tsync_ipc_log) mhi_cntrl->tsync_log = mhi_arch_timesync_log; /* register for bus scale if defined */ arch_info->msm_bus_pdata = msm_bus_cl_get_pdata_from_dev( &mhi_dev->pci_dev->dev); Loading Loading @@ -481,6 +517,8 @@ int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl) mhi_arch_esoc_ops_power_on; esoc_ops->esoc_link_power_off = mhi_arch_esoc_ops_power_off; esoc_ops->esoc_link_mdm_crash = mhi_arch_esoc_ops_mdm_error; ret = esoc_register_client_hook(arch_info->esoc_client, esoc_ops); Loading
drivers/bus/mhi/controllers/mhi_qcom.h +8 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,14 @@ #define MHI_RPM_SUSPEND_TMR_MS (250) #define MHI_PCI_BAR_NUM (0) /* timesync time calculations */ #define REMOTE_TICKS_TO_US(x) (div_u64((x) * 100ULL, \ div_u64(mhi_cntrl->remote_timer_freq, 10000ULL))) #define REMOTE_TICKS_TO_SEC(x) (div_u64((x), \ mhi_cntrl->remote_timer_freq)) #define REMOTE_TIME_REMAINDER_US(x) (REMOTE_TICKS_TO_US((x)) % \ (REMOTE_TICKS_TO_SEC((x)) * 1000000ULL)) extern const char * const mhi_ee_str[MHI_EE_MAX]; #define TO_MHI_EXEC_STR(ee) (ee >= MHI_EE_MAX ? "INVALID_EE" : mhi_ee_str[ee]) Loading
drivers/bus/mhi/core/mhi_internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -761,6 +761,7 @@ int mhi_create_timesync_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl); int mhi_create_vote_sysfs(struct mhi_controller *mhi_cntrl); void mhi_destroy_vote_sysfs(struct mhi_controller *mhi_cntrl); int mhi_early_notify_device(struct device *dev, void *data); /* timesync log support */ static inline void mhi_timesync_log(struct mhi_controller *mhi_cntrl) Loading
drivers/bus/mhi/core/mhi_main.c +23 −0 Original line number Diff line number Diff line Loading @@ -646,6 +646,22 @@ int mhi_destroy_device(struct device *dev, void *data) return 0; } int mhi_early_notify_device(struct device *dev, void *data) { struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; /* skip early notification */ if (!mhi_dev->early_notif) return 0; MHI_LOG("Early notification for dev:%s\n", mhi_dev->chan_name); mhi_notify(mhi_dev, MHI_CB_FATAL_ERROR); return 0; } void mhi_notify(struct mhi_device *mhi_dev, enum MHI_CB cb_reason) { struct mhi_driver *mhi_drv; Loading Loading @@ -856,6 +872,13 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) /* add if there is a matching DT node */ mhi_assign_of_node(mhi_cntrl, mhi_dev); /* * if set, these device should get a early notification during * early notification state */ mhi_dev->early_notif = of_property_read_bool(mhi_dev->dev.of_node, "mhi,early-notify"); /* init wake source */ if (mhi_dev->dl_chan && mhi_dev->dl_chan->wake_capable) device_init_wakeup(&mhi_dev->dev, true); Loading
drivers/bus/mhi/core/mhi_pm.c +30 −0 Original line number Diff line number Diff line Loading @@ -893,6 +893,36 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) } EXPORT_SYMBOL(mhi_async_power_up); /* Transition MHI into error state and notify critical clients */ void mhi_control_error(struct mhi_controller *mhi_cntrl) { enum MHI_PM_STATE cur_state; MHI_LOG("Enter with pm_state:%s MHI_STATE:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state)); write_lock_irq(&mhi_cntrl->pm_lock); cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_LD_ERR_FATAL_DETECT); write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT) { MHI_ERR("Failed to transition to state:%s from:%s\n", to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT), to_mhi_pm_state_str(cur_state)); goto exit_control_error; } /* start notifying all clients who request early notification */ device_for_each_child(mhi_cntrl->dev, NULL, mhi_early_notify_device); exit_control_error: MHI_LOG("Exit with pm_state:%s MHI_STATE:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state)); } EXPORT_SYMBOL(mhi_control_error); void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) { enum MHI_PM_STATE cur_state; Loading