Messages in this thread | | | Date | Mon, 28 Feb 2022 10:10:49 -0600 | Subject | Re: [PATCH v4 12/27] bus: mhi: ep: Add support for creating and destroying MHI EP devices | From | Alex Elder <> |
| |
On 2/28/22 6:43 AM, Manivannan Sadhasivam wrote: > This commit adds support for creating and destroying MHI endpoint devices. > The MHI endpoint devices binds to the MHI endpoint channels and are used > to transfer data between MHI host and endpoint device. > > There is a single MHI EP device for each channel pair. The devices will be > created when the corresponding channels has been started by the host and > will be destroyed during MHI EP power down and reset. > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Looks good.
Reviewed-by: Alex Elder <elder@linaro.org>
> --- > drivers/bus/mhi/ep/main.c | 83 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 83 insertions(+) > > diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c > index 2bdcf1657479..3afae0bfd83c 100644 > --- a/drivers/bus/mhi/ep/main.c > +++ b/drivers/bus/mhi/ep/main.c > @@ -68,6 +68,89 @@ static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl, > return mhi_dev; > } > > +/* > + * MHI channels are always defined in pairs with UL as the even numbered > + * channel and DL as odd numbered one. This function gets UL channel (primary) > + * as the ch_id and always looks after the next entry in channel list for > + * the corresponding DL channel (secondary). > + */ > +static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) > +{ > + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ch_id]; > + struct device *dev = mhi_cntrl->cntrl_dev; > + struct mhi_ep_device *mhi_dev; > + int ret; > + > + /* Check if the channel name is same for both UL and DL */ > + if (strcmp(mhi_chan->name, mhi_chan[1].name)) { > + dev_err(dev, "UL and DL channel names are not same: (%s) != (%s)\n", > + mhi_chan->name, mhi_chan[1].name); > + return -EINVAL; > + } > + > + mhi_dev = mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_XFER); > + if (IS_ERR(mhi_dev)) > + return PTR_ERR(mhi_dev); > + > + /* Configure primary channel */ > + mhi_dev->ul_chan = mhi_chan; > + get_device(&mhi_dev->dev); > + mhi_chan->mhi_dev = mhi_dev; > + > + /* Configure secondary channel as well */ > + mhi_chan++; > + mhi_dev->dl_chan = mhi_chan; > + get_device(&mhi_dev->dev); > + mhi_chan->mhi_dev = mhi_dev; > + > + /* Channel name is same for both UL and DL */ > + mhi_dev->name = mhi_chan->name; > + dev_set_name(&mhi_dev->dev, "%s_%s", > + dev_name(&mhi_cntrl->mhi_dev->dev), > + mhi_dev->name); > + > + ret = device_add(&mhi_dev->dev); > + if (ret) > + put_device(&mhi_dev->dev); > + > + return ret; > +} > + > +static int mhi_ep_destroy_device(struct device *dev, void *data) > +{ > + struct mhi_ep_device *mhi_dev; > + struct mhi_ep_cntrl *mhi_cntrl; > + struct mhi_ep_chan *ul_chan, *dl_chan; > + > + if (dev->bus != &mhi_ep_bus_type) > + return 0; > + > + mhi_dev = to_mhi_ep_device(dev); > + mhi_cntrl = mhi_dev->mhi_cntrl; > + > + /* Only destroy devices created for channels */ > + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) > + return 0; > + > + ul_chan = mhi_dev->ul_chan; > + dl_chan = mhi_dev->dl_chan; > + > + if (ul_chan) > + put_device(&ul_chan->mhi_dev->dev); > + > + if (dl_chan) > + put_device(&dl_chan->mhi_dev->dev); > + > + dev_dbg(&mhi_cntrl->mhi_dev->dev, "Destroying device for chan:%s\n", > + mhi_dev->name); > + > + /* Notify the client and remove the device from MHI bus */ > + device_del(dev); > + put_device(dev); > + > + return 0; > +} > + > static int mhi_ep_chan_init(struct mhi_ep_cntrl *mhi_cntrl, > const struct mhi_ep_cntrl_config *config) > {
| |