Loading drivers/bus/mhi/core/mhi_internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -757,6 +757,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 @@ -637,6 +637,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 @@ -847,6 +863,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 @@ -884,6 +884,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 include/linux/mhi.h +11 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,8 @@ struct mhi_controller { * @ul_chan_id: MHI channel id for UL transfer * @dl_chan_id: MHI channel id for DL transfer * @tiocm: Device current terminal settings * @early_notif: This device needs an early notification in case of error * with external modem. * @dev_vote: Keep external device in active state * @bus_vote: Keep physical bus (pci, spi) in active state * @priv: Driver private data Loading @@ -347,6 +349,7 @@ struct mhi_device { int ul_event_id; int dl_event_id; u32 tiocm; bool early_notif; const struct mhi_device_id *id; const char *chan_name; struct mhi_controller *mhi_cntrl; Loading Loading @@ -699,6 +702,14 @@ static inline bool mhi_is_active(struct mhi_device *mhi_dev) mhi_cntrl->dev_state <= MHI_STATE_M3_FAST); } /** * mhi_control_error - MHI controller went into unrecoverable error state. * Will transition MHI into Linkdown state. Do not call from atomic * context. * @mhi_cntrl: MHI controller */ void mhi_control_error(struct mhi_controller *mhi_cntrl); /** * mhi_debug_reg_dump - dump MHI registers for debug purpose * @mhi_cntrl: MHI controller Loading Loading
drivers/bus/mhi/core/mhi_internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -757,6 +757,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 @@ -637,6 +637,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 @@ -847,6 +863,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 @@ -884,6 +884,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
include/linux/mhi.h +11 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,8 @@ struct mhi_controller { * @ul_chan_id: MHI channel id for UL transfer * @dl_chan_id: MHI channel id for DL transfer * @tiocm: Device current terminal settings * @early_notif: This device needs an early notification in case of error * with external modem. * @dev_vote: Keep external device in active state * @bus_vote: Keep physical bus (pci, spi) in active state * @priv: Driver private data Loading @@ -347,6 +349,7 @@ struct mhi_device { int ul_event_id; int dl_event_id; u32 tiocm; bool early_notif; const struct mhi_device_id *id; const char *chan_name; struct mhi_controller *mhi_cntrl; Loading Loading @@ -699,6 +702,14 @@ static inline bool mhi_is_active(struct mhi_device *mhi_dev) mhi_cntrl->dev_state <= MHI_STATE_M3_FAST); } /** * mhi_control_error - MHI controller went into unrecoverable error state. * Will transition MHI into Linkdown state. Do not call from atomic * context. * @mhi_cntrl: MHI controller */ void mhi_control_error(struct mhi_controller *mhi_cntrl); /** * mhi_debug_reg_dump - dump MHI registers for debug purpose * @mhi_cntrl: MHI controller Loading