On Mon, Jan 04, 2021 at 02:49:30PM +0100, Loic Poulain wrote: > The MHI specification allows to perform a hard reset of the device > when writing to the SOC_RESET register. It can be used to completely > restart the device (e.g. in case of unrecoverable MHI error). > > This is up to the MHI controller driver to determine when this hard > reset should be used, and in case of MHI errors, should be used as > a reset of last resort (after standard MHI stack reset). > > This function is a stateless function, the MHI layer do nothing except > triggering the reset by writing into the right register(s), this is up > to the caller to ensure right mhi_controller state (e.g. unregister the > controller if necessary). > > Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxx> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> Thanks, Mani > --- > drivers/bus/mhi/core/main.c | 13 +++++++++++++ > include/linux/mhi.h | 9 +++++++++ > 2 files changed, 22 insertions(+) > > diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c > index a353d1e..c181a85 100644 > --- a/drivers/bus/mhi/core/main.c > +++ b/drivers/bus/mhi/core/main.c > @@ -142,6 +142,19 @@ enum mhi_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl) > } > EXPORT_SYMBOL_GPL(mhi_get_mhi_state); > > +void mhi_soc_reset(struct mhi_controller *mhi_cntrl) > +{ > + if (mhi_cntrl->reset) { > + mhi_cntrl->reset(mhi_cntrl); > + return; > + } > + > + /* Generic MHI SoC reset */ > + mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, MHI_SOC_RESET_REQ_OFFSET, > + MHI_SOC_RESET_REQ); > +} > +EXPORT_SYMBOL_GPL(mhi_soc_reset); > + > int mhi_map_single_no_bb(struct mhi_controller *mhi_cntrl, > struct mhi_buf_info *buf_info) > { > diff --git a/include/linux/mhi.h b/include/linux/mhi.h > index 04cf7f3..7ddbcd7 100644 > --- a/include/linux/mhi.h > +++ b/include/linux/mhi.h > @@ -355,6 +355,7 @@ struct mhi_controller_config { > * @unmap_single: CB function to destroy TRE buffer > * @read_reg: Read a MHI register via the physical link (required) > * @write_reg: Write a MHI register via the physical link (required) > + * @reset: Controller specific reset function (optional) > * @buffer_len: Bounce buffer length > * @index: Index of the MHI controller instance > * @bounce_buf: Use of bounce buffer > @@ -445,6 +446,7 @@ struct mhi_controller { > u32 *out); > void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr, > u32 val); > + void (*reset)(struct mhi_controller *mhi_cntrl); > > size_t buffer_len; > int index; > @@ -681,6 +683,13 @@ enum mhi_ee_type mhi_get_exec_env(struct mhi_controller *mhi_cntrl); > enum mhi_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); > > /** > + * mhi_soc_reset - Trigger a device reset. This can be used as a last resort > + * to reset and recover a device. > + * @mhi_cntrl: MHI controller > + */ > +void mhi_soc_reset(struct mhi_controller *mhi_cntrl); > + > +/** > * mhi_device_get - Disable device low power mode > * @mhi_dev: Device associated with the channel > */ > -- > 2.7.4 >