Updates to MHI channel handling
Subsystems (2)
cover Updates to MHI channel handling
MHI specification shows a state machine with support for STOP channel command and the validity of certain state transitions. MHI host currently does not provide any mechanism to stop a channel and restart it without resetting it. There are also times when the device moves on to a different execution environment while client drivers on the host are unaware of it and still attempt to reset the channels facing unnecessary timeouts.
This series addresses the above areas to provide support for stopping an MHI channel, resuming it back, and improving upon channel state machine handling in general.
This set of patches was tested on arm64 architecture.
Bhaumik Bhatt (4):
bus: mhi: core: Allow receiving a STOP channel command response
bus: mhi: core: Improvements to the channel handling state machine
bus: mhi: core: Add support to pause or resume channel data transfers
bus: mhi: core: Check execution environment for channel before issuing
reset
drivers/bus/mhi/core/init.c | 11 +- drivers/bus/mhi/core/internal.h | 12 +++ drivers/bus/mhi/core/main.c | 218 ++++++++++++++++++++++++++++------------ include/linux/mhi.h | 16 +++ 4 files changed, 192 insertions(+), 65 deletions(-)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 1/4 bus: mhi: core: Allow receiving a STOP channel command response
Add support to receive the response to a STOP channel command to the MHI bus. If a client would like to STOP a channel instead of issuing a RESET to it, this would provide support for it.
--- drivers/bus/mhi/core/init.c | 5 +++-- drivers/bus/mhi/core/main.c | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-)
drivers/bus/mhi/core/init.c +3 -2
@@ -1267,8 +1267,9 @@ static int mhi_driver_remove(struct device *dev)mutex_lock (&mhi_chan->mutex); -if (ch_state[dir] ==MHI_CH_STATE_ENABLED && - !mhi_chan->offload_ch) +if ((ch_state[dir] ==MHI_CH_STATE_ENABLED || + ch_state[dir] ==MHI_CH_STATE_STOP ) && + !mhi_chan->offload_ch)mhi_deinit_chan_ctxt (mhi_cntrl, mhi_chan); mhi_chan->ch_state =MHI_CH_STATE_DISABLED ;
drivers/bus/mhi/core/main.c +5 -0
@@ -1194,6 +1194,11 @@ int mhi_send_cmd(struct mhi_controller *mhi_cntrl, cmd_tre->dword[0 ] =MHI_TRE_CMD_RESET_DWORD0 ; cmd_tre->dword[1 ] =MHI_TRE_CMD_RESET_DWORD1 (chan);break ; +case MHI_CMD_STOP_CHAN : + cmd_tre->ptr =MHI_TRE_CMD_STOP_PTR ; + cmd_tre->dword[0 ] =MHI_TRE_CMD_STOP_DWORD0 ; + cmd_tre->dword[1 ] =MHI_TRE_CMD_STOP_DWORD1 (chan); +break ;case MHI_CMD_START_CHAN : cmd_tre->ptr =MHI_TRE_CMD_START_PTR ; cmd_tre->dword[0 ] =MHI_TRE_CMD_START_DWORD0 ;
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 2/4 bus: mhi: core: Improvements to the channel handling state machine
In reply to Bhaumik BhattAdd support to enable sending the stop channel command and improve the channel handling state machine such that all commands go through a common function. This can help ensure that the state machine is not violated in any way and adheres to the MHI specification.
--- drivers/bus/mhi/core/init.c | 6 ++ drivers/bus/mhi/core/internal.h | 12 +++ drivers/bus/mhi/core/main.c | 163 ++++++++++++++++++++++++---------------- 3 files changed, 116 insertions(+), 65 deletions(-)
drivers/bus/mhi/core/init.c +6 -0
@@ -51,6 +51,12 @@ const char * const mhi_state_str[MHI_STATE_MAX] = { [MHI_STATE_SYS_ERR] = "SYS_ERR", }; +const char *const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX ] = { + [MHI_CH_STATE_TYPE_RESET ] ="RESET" , + [MHI_CH_STATE_TYPE_STOP ] ="STOP" , + [MHI_CH_STATE_TYPE_START ] ="START" , +}; +static const char *const mhi_pm_state_str[] = { [MHI_PM_STATE_DISABLE ] ="DISABLE" , [MHI_PM_STATE_POR ] ="POR" ,
drivers/bus/mhi/core/internal.h +12 -0
@@ -369,6 +369,18 @@ enum mhi_ch_state { MHI_CH_STATE_ERROR = 0x5, }; +enum mhi_ch_state_type { +MHI_CH_STATE_TYPE_RESET , +MHI_CH_STATE_TYPE_STOP , +MHI_CH_STATE_TYPE_START , +MHI_CH_STATE_TYPE_MAX , +}; + +extern const char *const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX ]; +#define TO_CH_STATE_TYPE_STR (state) (((state) >= MHI_CH_STATE_TYPE_MAX) ? \ + "INVALID_STATE" : \ + mhi_ch_state_type_str[state]) +#define MHI_INVALID_BRSTMODE (mode) (mode != MHI_DB_BRST_DISABLE && \ mode != MHI_DB_BRST_ENABLE)
drivers/bus/mhi/core/main.c +98 -65
202 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 3/4 bus: mhi: core: Add support to pause or resume channel data transfers
In reply to Bhaumik BhattSome MHI clients may want to request for pausing or resuming of the data transfers for their channels. Enable them to do so using the new APIs provided for the same.
--- drivers/bus/mhi/core/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/mhi.h | 16 ++++++++++++++++ 2 files changed, 57 insertions(+)
drivers/bus/mhi/core/main.c +41 -0
@@ -1560,6 +1560,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) }EXPORT_SYMBOL_GPL (mhi_unprepare_from_transfer); +static int mhi_update_transfer_state (struct mhi_device *mhi_dev, +enum mhi_ch_state_type to_state) +{ +struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; +struct mhi_chan *mhi_chan; +int dir, ret; + +for (dir =0 ; dir <2 ; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + +if (!mhi_chan) +continue ; + +/* +* Bail out if one of the channels fail as client will reset +* both upon failure +*/ +mutex_lock (&mhi_chan->mutex); + ret =mhi_update_channel_state (mhi_cntrl, mhi_chan, to_state); +if (ret) { +mutex_unlock (&mhi_chan->mutex); +return ret; + } +mutex_unlock (&mhi_chan->mutex); + } + +return 0 ; +} + +int mhi_pause_transfer (struct mhi_device *mhi_dev) +{ +return mhi_update_transfer_state (mhi_dev,MHI_CH_STATE_TYPE_STOP ); +} +EXPORT_SYMBOL_GPL (mhi_pause_transfer); + +int mhi_resume_transfer (struct mhi_device *mhi_dev) +{ +return mhi_update_transfer_state (mhi_dev,MHI_CH_STATE_TYPE_START ); +} +EXPORT_SYMBOL_GPL (mhi_resume_transfer); +int mhi_poll (struct mhi_device *mhi_dev,u32 budget) {struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
include/linux/mhi.h +16 -0
@@ -702,6 +702,22 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev);void mhi_unprepare_from_transfer (struct mhi_device *mhi_dev);/** +* mhi_pause_transfer - Pause ongoing channel activity +* Moves both UL and DL channels to STOP state to halt +* pending transfers. +* @mhi_dev: Device associated with the channels +*/ +int mhi_pause_transfer (struct mhi_device *mhi_dev); + +/** +* mhi_resume_transfer - Resume channel activity +* Moves both UL and DL channels to START state to +* resume transfers. +* @mhi_dev: Device associated with the channels +*/ +int mhi_resume_transfer (struct mhi_device *mhi_dev); + +/** * mhi_poll - Poll for any available data in DL direction * @mhi_dev: Device associated with the channels * @budget: # of events to process
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1 3/4] bus: mhi: core: Add support to pause or resume channel data transfers
Hi Bhaumik,
Quoted 49 lines · Bhaumik Bhatt
Some MHI clients may want to request for pausing or resuming of the data transfers for their channels. Enable them to do so using the new APIs provided for the same.
Signed-off-by Bhaumik Bhatt <[email protected]>--- drivers/bus/mhi/core/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/mhi.h | 16 ++++++++++++++++ 2 files changed, 57 insertions(+)drivers/bus/mhi/core/main.c +30
-0@@ -1560,6 +1560,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) }EXPORT_SYMBOL_GPL (mhi_unprepare_from_transfer); +static int mhi_update_transfer_state (struct mhi_device *mhi_dev, +enum mhi_ch_state_type to_state) +{ +struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; +struct mhi_chan *mhi_chan; +int dir, ret; + +for (dir =0 ; dir <2 ; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + +if (!mhi_chan) +continue ; + +/* +* Bail out if one of the channels fail as client will reset +* both upon failure +*/ +mutex_lock (&mhi_chan->mutex); + ret =mhi_update_channel_state (mhi_cntrl, mhi_chan, to_state); +if (ret) { +mutex_unlock (&mhi_chan->mutex); +return ret; + } +mutex_unlock (&mhi_chan->mutex); + } + +return 0 ; +} + +int mhi_pause_transfer (struct mhi_device *mhi_dev)
drivers/bus/mhi/core/main.c void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) · line 1602
Quoted 10 lines
drivers/bus/mhi/core/main.c +10
-0+{ +return mhi_update_transfer_state (mhi_dev,MHI_CH_STATE_TYPE_STOP ); +} +EXPORT_SYMBOL_GPL (mhi_pause_transfer); + +int mhi_resume_transfer (struct mhi_device *mhi_dev) +{ +return mhi_update_transfer_state (mhi_dev,MHI_CH_STATE_TYPE_START ); +} +EXPORT_SYMBOL_GPL (mhi_resume_transfer);
Look like it is stop and start, not pause and resume?
TBH maybe we should rework/clarify MHI core and having well-defined states, maybe something like that:
1. When MHI core detects device for a driver, MHI core resets and initializes the channel(s), then call client driver probe function
=> channel UNKNOWN->DISABLED state
=> channel DISABLED->ENABLED state
2. When driver is ready for sending data, drivers calls mhi_start_transfer
=> Channel is ENABLED->RUNNING state
3. Driver performs normal data transfers
4. The driver can suspend/resume transfer, it stops (suspend) the channel, can
=> Channel is RUNNING->STOP
=> Channel is STOP->RUNNING
...
5. When device is removed, MHI core reset the channel
=> channel is (RUNNING|STOP) -> DISABLEDToday mhi_prepare_for_transfer performs both ENABLE and RUNNING transition, the idea would be to keep channel enabling/disabling in the MHI core (before/after driver probe/remove) and channel start/stop managed by the client driver.
Regards,
Loic
Re: [PATCH v1 3/4] bus: mhi: core: Add support to pause or resume channel data transfers
Hi Loic,
Quoted 62 lines · Loic Poulain
Hi Bhaumik,
Quoted 59 lines · Bhaumik Bhatt
Some MHI clients may want to request for pausing or resuming of the data transfers for their channels. Enable them to do so using the new APIs provided for the same.
Signed-off-by Bhaumik Bhatt <[email protected]>--- drivers/bus/mhi/core/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/mhi.h | 16 ++++++++++++++++ 2 files changed, 57 insertions(+)drivers/bus/mhi/core/main.c +15
-0@@ -1560,6 +1560,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) }EXPORT_SYMBOL_GPL (mhi_unprepare_from_transfer); +static int mhi_update_transfer_state (struct mhi_device *mhi_dev, +enum mhi_ch_state_type to_state) +{ +struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; +struct mhi_chan *mhi_chan; +int dir, ret; + +for (dir =0 ; dir <2 ; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + +if (!mhi_chan) +continue ; + +/* +* Bail out if one of the channels fail as client will reset
drivers/bus/mhi/core/main.c +4
-0+* both upon failure +*/ +mutex_lock (&mhi_chan->mutex); + ret = mhi_update_channel_state(mhi_cntrl, mhi_chan,
to_state);drivers/bus/mhi/core/main.c +13
-0+if (ret) { +mutex_unlock (&mhi_chan->mutex); +return ret; + } +mutex_unlock (&mhi_chan->mutex); + } + +return 0 ; +} + +int mhi_pause_transfer (struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev,
MHI_CH_STATE_TYPE_STOP);drivers/bus/mhi/core/main.c +3
-0+} +EXPORT_SYMBOL_GPL (mhi_pause_transfer); +
Quoted 8 lines
drivers/bus/mhi/core/main.c
Quoted 6 lines
drivers/bus/mhi/core/main.c +3
-0+int mhi_resume_transfer (struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev,
MHI_CH_STATE_TYPE_START);drivers/bus/mhi/core/main.c +2
-0+} +EXPORT_SYMBOL_GPL (mhi_resume_transfer);Look like it is stop and start, not pause and resume?
I wanted to keep it pause and resume because it could get confusing for someone looking at this pair of APIs, that a client driver would also need to "start" channels after "preparing" them. Since that is not that case, and the mhi_prepare_for_transfer() API itself is supposed to also start the channels, it would be better to keep these as "pause" and "resume" instead IMO.
Any comments in favor or "stop" and "start"?
Quoted 18 lines
TBH maybe we should rework/clarify MHI core and having well-defined states, maybe something like that:
1. When MHI core detects device for a driver, MHI core resets and initializes the channel(s), then call client driver probe function
=> channel UNKNOWN->DISABLED state => channel DISABLED->ENABLED state 2. When driver is ready for sending data, drivers calls mhi_start_transfer => Channel is ENABLED->RUNNING state 3. Driver performs normal data transfers 4. The driver can suspend/resume transfer, it stops (suspend) the channel, can => Channel is RUNNING->STOP => Channel is STOP->RUNNING ... 5. When device is removed, MHI core reset the channel => channel is (RUNNING|STOP) -> DISABLED
Quoted 7 lines
Today
mhi_prepare_for_transferperforms both ENABLE and RUNNING transition, the idea would be to keep channel enabling/disabling in the MHI core (before/after driver probe/remove) and channel start/stop managed by the client driver.Regards,
Loic
Your idea is good but it would not have much additional benefits and would involve MHI core "enabling" channels and allocating memory for each channel context when they are only declared as supported by the controller but are not actually being put to use.
mhi_prepare_for_transfer() does both channel context initialization and starts the channels, which is good because it allocates memory when needed. So, this benefits system memory if a controller with support for many channels exists but only a few channels are used.
Regarding the states to track from host:
-> DISABLED (We know channels are not active: in reset state or not probed yet) -> ENABLED (Active and running when needed for data transfers)
-> STOP (Paused: leaves the channel context as is since channels are not reset) -> SUSPENDED (Unload in progress: Entered before resetting channels/remove())
BTW, we have the debugfs entry for "channels" that dumps the context to show exactly what the channel states are from device perspective. We can rely on it if needed.
If there are some comments I can add to make things clear, please let me know.
Thanks,
Bhaumik
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1 3/4] bus: mhi: core: Add support to pause or resume channel data transfers
Hi Bhaumik,
Quoted 75 lines · Bhaumik Bhatt
Hi Loic,
Quoted 63 lines · Loic Poulain
Hi Bhaumik,
Quoted 59 lines · Bhaumik Bhatt
Some MHI clients may want to request for pausing or resuming of the data transfers for their channels. Enable them to do so using the new APIs provided for the same.
Signed-off-by Bhaumik Bhatt <[email protected]>--- drivers/bus/mhi/core/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/mhi.h | 16 ++++++++++++++++ 2 files changed, 57 insertions(+)drivers/bus/mhi/core/main.c +15
-0@@ -1560,6 +1560,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) }EXPORT_SYMBOL_GPL (mhi_unprepare_from_transfer); +static int mhi_update_transfer_state (struct mhi_device *mhi_dev, +enum mhi_ch_state_type to_state) +{ +struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; +struct mhi_chan *mhi_chan; +int dir, ret; + +for (dir =0 ; dir <2 ; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + +if (!mhi_chan) +continue ; + +/* +* Bail out if one of the channels fail as client will reset
drivers/bus/mhi/core/main.c +4
-0+* both upon failure +*/ +mutex_lock (&mhi_chan->mutex); + ret = mhi_update_channel_state(mhi_cntrl, mhi_chan,
to_state);drivers/bus/mhi/core/main.c +13
-0+if (ret) { +mutex_unlock (&mhi_chan->mutex); +return ret; + } +mutex_unlock (&mhi_chan->mutex); + } + +return 0 ; +} + +int mhi_pause_transfer (struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev,
MHI_CH_STATE_TYPE_STOP);drivers/bus/mhi/core/main.c +3
-0+} +EXPORT_SYMBOL_GPL (mhi_pause_transfer); +Quoted 8 lines
drivers/bus/mhi/core/main.c
Quoted 6 lines
drivers/bus/mhi/core/main.c +3
-0+int mhi_resume_transfer (struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev,
MHI_CH_STATE_TYPE_START);drivers/bus/mhi/core/main.c +2
-0+} +EXPORT_SYMBOL_GPL (mhi_resume_transfer);Look like it is stop and start, not pause and resume?
Quoted 7 lines
I wanted to keep it pause and resume because it could get confusing for someone
looking at this pair of APIs, that a client driver would also need to "start"
channels after "preparing" them. Since that is not that case, and themhi_prepare_for_transfer()API itself is supposed to also start the channels, it
Yes, because prepare_for_transfer is actually init_and_start. I'm not in favor of hiding what is really done at mhi_core level, start is start and stop is stop, if it's correctly documented that should not be confusing. just saying (stop moves channels in stop state, start in enabled state), but other opinions are welcome.
Quoted 31 lines
would be better to keep these as "pause" and "resume" instead IMO.
Any comments in favor or "stop" and "start"?
Quoted 20 lines
TBH maybe we should rework/clarify MHI core and having well-defined states, maybe something like that:
1. When MHI core detects device for a driver, MHI core resets and initializes the channel(s), then call client driver probe function
=> channel UNKNOWN->DISABLED state => channel DISABLED->ENABLED state 2. When driver is ready for sending data, drivers calls mhi_start_transfer => Channel is ENABLED->RUNNING state 3. Driver performs normal data transfers 4. The driver can suspend/resume transfer, it stops (suspend) the channel, can => Channel is RUNNING->STOP => Channel is STOP->RUNNING ... 5. When device is removed, MHI core reset the channel => channel is (RUNNING|STOP) -> DISABLEDQuoted 7 lines
Today
mhi_prepare_for_transferperforms both ENABLE and RUNNING transition, the idea would be to keep channel enabling/disabling in the MHI core (before/after driver probe/remove) and channel start/stop managed by the client driver.Regards,
Loic
Quoted 7 lines
Your idea is good but it would not have much additional benefits and would
involve MHI core "enabling" channels and allocating memory for each channel
context when they are only declared as supported by the controller but are not
actually being put to use.
Ok, your point is valid.
Quoted 33 lines
mhi_prepare_for_transfer()does both channel context initialization and starts
the channels, which is good because it allocates memory when needed. So, this
benefits system memory if a controller with support for many channels exists but
only a few channels are used.Regarding the states to track from host:
-> DISABLED (We know channels are not active: in reset state or not probed yet)
-> ENABLED (Active and running when needed for data transfers) -> STOP (Paused: leaves the channel context as is since channels are not reset)
-> SUSPENDED (Unload in progress: Entered before resetting channels/remove())BTW, we have the debugfs entry for "channels" that dumps the context to show
exactly what the channel states are from device perspective. We can rely on it
if needed.If there are some comments I can add to make things clear, please let me know.
Thanks,
Bhaumik
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Re: [PATCH v1 3/4] bus: mhi: core: Add support to pause or resume channel data transfers
Hi Loic,
Quoted 86 lines · Loic Poulain
Hi Bhaumik,
Quoted 75 lines · Bhaumik Bhatt
Hi Loic,
Quoted 63 lines · Loic Poulain
Hi Bhaumik,
Quoted 59 lines · Bhaumik Bhatt
Some MHI clients may want to request for pausing or resuming of the data transfers for their channels. Enable them to do so using the new APIs provided for the same.
Signed-off-by Bhaumik Bhatt <[email protected]>--- drivers/bus/mhi/core/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/mhi.h | 16 ++++++++++++++++ 2 files changed, 57 insertions(+)drivers/bus/mhi/core/main.c +15
-0@@ -1560,6 +1560,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) }EXPORT_SYMBOL_GPL (mhi_unprepare_from_transfer); +static int mhi_update_transfer_state (struct mhi_device *mhi_dev, +enum mhi_ch_state_type to_state) +{ +struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; +struct mhi_chan *mhi_chan; +int dir, ret; + +for (dir =0 ; dir <2 ; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + +if (!mhi_chan) +continue ; + +/* +* Bail out if one of the channels fail as client will reset
drivers/bus/mhi/core/main.c +4
-0+* both upon failure +*/ +mutex_lock (&mhi_chan->mutex); + ret = mhi_update_channel_state(mhi_cntrl, mhi_chan,
to_state);drivers/bus/mhi/core/main.c +13
-0+if (ret) { +mutex_unlock (&mhi_chan->mutex); +return ret; + } +mutex_unlock (&mhi_chan->mutex); + } + +return 0 ; +} + +int mhi_pause_transfer (struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev,
MHI_CH_STATE_TYPE_STOP);drivers/bus/mhi/core/main.c +3
-0+} +EXPORT_SYMBOL_GPL (mhi_pause_transfer); +Quoted 8 lines
drivers/bus/mhi/core/main.c
Quoted 6 lines
drivers/bus/mhi/core/main.c +3
-0+int mhi_resume_transfer (struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev,
MHI_CH_STATE_TYPE_START);drivers/bus/mhi/core/main.c +2
-0+} +EXPORT_SYMBOL_GPL (mhi_resume_transfer);Look like it is stop and start, not pause and resume?
Quoted 7 lines
I wanted to keep it pause and resume because it could get confusing for someone
looking at this pair of APIs, that a client driver would also need to "start"
channels after "preparing" them. Since that is not that case, and themhi_prepare_for_transfer()API itself is supposed to also start the channels, it
Quoted 6 lines
Yes, because
prepare_for_transferis actuallyinit_and_start. I'm not in favor of hiding what is really done atmhi_corelevel, start is start and stop is stop, if it's correctly documented that should not be confusing. just saying (stop moves channels in stop state, start in enabled state), but other opinions are welcome.
I can rename it and have it documented in the mhi_prepare_for_transfer() API that we actually already start the channel, so it is not required to be used at first. I can improve this documentation in mhi.h as a separate patch.
Later, if a client driver wants to issue stop and start commands, it can do so. I'm not too picky with the name. Maybe Mani or someone else may have more comments.
Thanks for looking in to this.
Quoted 39 lines
Quoted 31 lines
would be better to keep these as "pause" and "resume" instead IMO.
Any comments in favor or "stop" and "start"?
Quoted 20 lines
TBH maybe we should rework/clarify MHI core and having well-defined states, maybe something like that:
1. When MHI core detects device for a driver, MHI core resets and initializes the channel(s), then call client driver probe function
=> channel UNKNOWN->DISABLED state => channel DISABLED->ENABLED state 2. When driver is ready for sending data, drivers calls mhi_start_transfer => Channel is ENABLED->RUNNING state 3. Driver performs normal data transfers 4. The driver can suspend/resume transfer, it stops (suspend) the channel, can => Channel is RUNNING->STOP => Channel is STOP->RUNNING ... 5. When device is removed, MHI core reset the channel => channel is (RUNNING|STOP) -> DISABLEDQuoted 7 lines
Today
mhi_prepare_for_transferperforms both ENABLE and RUNNING transition, the idea would be to keep channel enabling/disabling in the MHI core (before/after driver probe/remove) and channel start/stop managed by the client driver.Regards,
LoicQuoted 7 lines
Your idea is good but it would not have much additional benefits and would
involve MHI core "enabling" channels and allocating memory for each channel
context when they are only declared as supported by the controller but are not
actually being put to use.
Quoted 36 lines
Ok, your point is valid.
Quoted 34 lines
mhi_prepare_for_transfer()does both channel context initialization and starts
the channels, which is good because it allocates memory when needed. So, this
benefits system memory if a controller with support for many channels exists but
only a few channels are used.Regarding the states to track from host:
-> DISABLED (We know channels are not active: in reset state or not probed yet)
-> ENABLED (Active and running when needed for data transfers) -> STOP (Paused: leaves the channel context as is since channels are not
reset)
-> SUSPENDED (Unload in progress: Entered before resetting channels/remove())BTW, we have the debugfs entry for "channels" that dumps the context to show
exactly what the channel states are from device perspective. We can rely on it
if needed.If there are some comments I can add to make things clear, please let me know.
Thanks,
Bhaumik
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Thanks,
Bhaumik
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1 3/4] bus: mhi: core: Add support to pause or resume channel data transfers
Quoted 2 lines · Bhaumik Bhatt
Hi Loic,
[...]
Quoted 16 lines
Quoted 10 lines
Quoted 9 lines
Quoted 1 line
Look like it is stop and start, not pause and resume?
I wanted to keep it pause and resume because it could get confusing for
someone
looking at this pair of APIs, that a client driver would also need to "start"
channels after "preparing" them. Since that is not that case, and themhi_prepare_for_transfer()API itself is supposed to also start the channels, itQuoted 6 lines
Yes, because
prepare_for_transferis actuallyinit_and_start. I'm not in favor of hiding what is really done atmhi_corelevel, start is start and stop is stop, if it's correctly documented that should not be confusing. just saying (stop moves channels in stop state, start in enabled state), but other opinions are welcome.
Quoted 9 lines
I can rename it and have it documented in the
mhi_prepare_for_transfer()API that we actually already start the channel, so it is not required to be used at first. I can improve this documentation inmhi.has a separate patch.Later, if a client driver wants to issue stop and start commands, it can do so.
I'm not too picky with the name. Maybe Mani or someone else may have more comments.
Please use start and stop to match what the function is doing. We should always name the APIs with respect to their function.
Thanks,
Mani
PATCH 4/4 bus: mhi: core: Check execution environment for channel before issuing reset
In reply to Bhaumik BhattA client can attempt to unprepare certain channels for transfer even after the execution environment they are supposed to run in has changed. In the event that happens, the device need not be notified of the reset and the host can proceed with clean up for the channel context and memory allocated for it on the host.
--- drivers/bus/mhi/core/main.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/bus/mhi/core/main.c +13 -0
@@ -1323,11 +1323,24 @@ static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl,/* no more processing events for this channel */ mutex_lock (&mhi_chan->mutex); +if (!(BIT (mhi_cntrl->ee) & mhi_chan->ee_mask)) { +dev_err (dev, +"Current EE: %s Required EE Mask: 0x%x for chan: %s\n" , +TO_MHI_EXEC_STR (mhi_cntrl->ee), mhi_chan->ee_mask, + mhi_chan->name); + goto exit_unprepare_channel; + } + ret =mhi_update_channel_state (mhi_cntrl, mhi_chan,MHI_CH_STATE_TYPE_RESET );if (ret)dev_err (dev,"Failed to reset channel, still resetting\n" ); +exit_unprepare_channel: +write_lock_irq (&mhi_chan->lock); + mhi_chan->ch_state =MHI_CH_STATE_DISABLED ; +write_unlock_irq (&mhi_chan->lock); +if (!mhi_chan->offload_ch) {mhi_reset_chan (mhi_cntrl, mhi_chan);mhi_deinit_chan_ctxt (mhi_cntrl, mhi_chan);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project