public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
To: Alex Elder <elder@linaro.org>
Cc: mhi@lists.linux.dev, quic_hemantk@quicinc.com,
	quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com,
	vinod.koul@linaro.org, bjorn.andersson@linaro.org,
	dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com,
	quic_cang@quicinc.com, quic_skananth@quicinc.com,
	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 17/27] bus: mhi: ep: Add support for processing MHI endpoint interrupts
Date: Tue, 1 Mar 2022 12:11:28 +0530	[thread overview]
Message-ID: <20220301064128.GD12451@workstation> (raw)
In-Reply-To: <3c611baf-1be9-4bf2-86c9-30a3b935a86b@linaro.org>

On Mon, Feb 28, 2022 at 10:45:15AM -0600, Alex Elder wrote:
> On 2/28/22 6:43 AM, Manivannan Sadhasivam wrote:
> > Add support for processing MHI endpoint interrupts such as control
> > interrupt, command interrupt and channel interrupt from the host.
> > 
> > The interrupts will be generated in the endpoint device whenever host
> > writes to the corresponding doorbell registers. The doorbell logic
> > is handled inside the hardware internally.
> > 
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> 
> One suggestion for future work, but otherwise this looks good.
> 
> Reviewed-by: Alex Elder <elder@linaro.org>
> 
> > ---
> >   drivers/bus/mhi/ep/main.c | 123 +++++++++++++++++++++++++++++++++++++-
> >   include/linux/mhi_ep.h    |   4 ++
> >   2 files changed, 125 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
> > index 7a29543586d0..ce690b1aeace 100644
> > --- a/drivers/bus/mhi/ep/main.c
> > +++ b/drivers/bus/mhi/ep/main.c
> > @@ -143,6 +143,112 @@ static void mhi_ep_state_worker(struct work_struct *work)
> >   	}
> >   }
> > +static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, unsigned long ch_int,
> > +				    u32 ch_idx)
> > +{
> > +	struct mhi_ep_ring_item *item;
> > +	struct mhi_ep_ring *ring;
> > +	bool work = !!ch_int;
> > +	LIST_HEAD(head);
> > +	u32 i;
> > +
> > +	/* First add the ring items to a local list */
> > +	for_each_set_bit(i, &ch_int, 32) {
> > +		/* Channel index varies for each register: 0, 32, 64, 96 */
> > +		u32 ch_id = ch_idx + i;
> > +
> > +		ring = &mhi_cntrl->mhi_chan[ch_id].ring;
> > +		item = kzalloc(sizeof(*item), GFP_ATOMIC);
> 
> It looks like this will be used a lot, so I suggest you
> consider creating a slab cache of ring items to allocate
> from.  I haven't suggested that elsewhere, but it's
> possible there are other frequently-allocated structures
> that would warrant that.
> 

Sure.

Thanks,
Mani

> > +		if (!item)
> > +			return;
> > +
> > +		item->ring = ring;
> > +		list_add_tail(&item->node, &head);
> > +	}
> > +
> > +	/* Now, splice the local list into ch_db_list and queue the work item */
> > +	if (work) {
> > +		spin_lock(&mhi_cntrl->list_lock);
> > +		list_splice_tail_init(&head, &mhi_cntrl->ch_db_list);
> > +		spin_unlock(&mhi_cntrl->list_lock);
> > +	}
> > +}
> > +
> > +/*
> > + * Channel interrupt statuses are contained in 4 registers each of 32bit length.
> > + * For checking all interrupts, we need to loop through each registers and then
> > + * check for bits set.
> > + */
> > +static void mhi_ep_check_channel_interrupt(struct mhi_ep_cntrl *mhi_cntrl)
> > +{
> > +	u32 ch_int, ch_idx, i;
> > +
> > +	/* Bail out if there is no channel doorbell interrupt */
> > +	if (!mhi_ep_mmio_read_chdb_status_interrupts(mhi_cntrl))
> > +		return;
> > +
> > +	for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) {
> > +		ch_idx = i * MHI_MASK_CH_EV_LEN;
> > +
> > +		/* Only process channel interrupt if the mask is enabled */
> > +		ch_int = mhi_cntrl->chdb[i].status & mhi_cntrl->chdb[i].mask;
> > +		if (ch_int) {
> > +			mhi_ep_queue_channel_db(mhi_cntrl, ch_int, ch_idx);
> > +			mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_n(i),
> > +							mhi_cntrl->chdb[i].status);
> > +		}
> > +	}
> > +}
> > +
> > +static void mhi_ep_process_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl,
> > +					 enum mhi_state state)
> > +{
> > +	struct mhi_ep_state_transition *item;
> > +
> > +	item = kzalloc(sizeof(*item), GFP_ATOMIC);
> > +	if (!item)
> > +		return;
> > +
> > +	item->state = state;
> > +	spin_lock(&mhi_cntrl->list_lock);
> > +	list_add_tail(&item->node, &mhi_cntrl->st_transition_list);
> > +	spin_unlock(&mhi_cntrl->list_lock);
> > +
> > +	queue_work(mhi_cntrl->wq, &mhi_cntrl->state_work);
> > +}
> > +
> > +/*
> > + * Interrupt handler that services interrupts raised by the host writing to
> > + * MHICTRL and Command ring doorbell (CRDB) registers for state change and
> > + * channel interrupts.
> > + */
> > +static irqreturn_t mhi_ep_irq(int irq, void *data)
> > +{
> > +	struct mhi_ep_cntrl *mhi_cntrl = data;
> > +	struct device *dev = &mhi_cntrl->mhi_dev->dev;
> > +	enum mhi_state state;
> > +	u32 int_value;
> > +
> > +	/* Acknowledge the ctrl interrupt */
> > +	int_value = mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS);
> > +	mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR, int_value);
> > +
> > +	/* Check for ctrl interrupt */
> > +	if (FIELD_GET(MHI_CTRL_INT_STATUS_MSK, int_value)) {
> > +		dev_dbg(dev, "Processing ctrl interrupt\n");
> > +		mhi_ep_process_ctrl_interrupt(mhi_cntrl, state);
> > +	}
> > +
> > +	/* Check for command doorbell interrupt */
> > +	if (FIELD_GET(MHI_CTRL_INT_STATUS_CRDB_MSK, int_value))
> > +		dev_dbg(dev, "Processing command doorbell interrupt\n");
> > +
> > +	/* Check for channel interrupts */
> > +	mhi_ep_check_channel_interrupt(mhi_cntrl);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> >   static void mhi_ep_release_device(struct device *dev)
> >   {
> >   	struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
> > @@ -339,7 +445,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
> >   	struct mhi_ep_device *mhi_dev;
> >   	int ret;
> > -	if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio)
> > +	if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio || !mhi_cntrl->irq)
> >   		return -EINVAL;
> >   	ret = mhi_ep_chan_init(mhi_cntrl, config);
> > @@ -361,6 +467,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
> >   	}
> >   	INIT_LIST_HEAD(&mhi_cntrl->st_transition_list);
> > +	INIT_LIST_HEAD(&mhi_cntrl->ch_db_list);
> >   	spin_lock_init(&mhi_cntrl->state_lock);
> >   	spin_lock_init(&mhi_cntrl->list_lock);
> >   	mutex_init(&mhi_cntrl->event_lock);
> > @@ -376,12 +483,20 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
> >   		goto err_destroy_wq;
> >   	}
> > +	irq_set_status_flags(mhi_cntrl->irq, IRQ_NOAUTOEN);
> > +	ret = request_irq(mhi_cntrl->irq, mhi_ep_irq, IRQF_TRIGGER_HIGH,
> > +			  "doorbell_irq", mhi_cntrl);
> > +	if (ret) {
> > +		dev_err(mhi_cntrl->cntrl_dev, "Failed to request Doorbell IRQ\n");
> > +		goto err_ida_free;
> > +	}
> > +
> >   	/* Allocate the controller device */
> >   	mhi_dev = mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_CONTROLLER);
> >   	if (IS_ERR(mhi_dev)) {
> >   		dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n");
> >   		ret = PTR_ERR(mhi_dev);
> > -		goto err_ida_free;
> > +		goto err_free_irq;
> >   	}
> >   	dev_set_name(&mhi_dev->dev, "mhi_ep%u", mhi_cntrl->index);
> > @@ -398,6 +513,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
> >   err_put_dev:
> >   	put_device(&mhi_dev->dev);
> > +err_free_irq:
> > +	free_irq(mhi_cntrl->irq, mhi_cntrl);
> >   err_ida_free:
> >   	ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index);
> >   err_destroy_wq:
> > @@ -417,6 +534,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl)
> >   	destroy_workqueue(mhi_cntrl->wq);
> > +	free_irq(mhi_cntrl->irq, mhi_cntrl);
> > +
> >   	kfree(mhi_cntrl->mhi_cmd);
> >   	kfree(mhi_cntrl->mhi_chan);
> > diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
> > index dc27a5de7d3c..43aa9b133db4 100644
> > --- a/include/linux/mhi_ep.h
> > +++ b/include/linux/mhi_ep.h
> > @@ -70,6 +70,7 @@ struct mhi_ep_db_info {
> >    * @list_lock: Lock for protecting state transition and channel doorbell lists
> >    * @state_lock: Lock for protecting state transitions
> >    * @st_transition_list: List of state transitions
> > + * @ch_db_list: List of queued channel doorbells
> >    * @wq: Dedicated workqueue for handling rings and state changes
> >    * @state_work: State transition worker
> >    * @raise_irq: CB function for raising IRQ to the host
> > @@ -87,6 +88,7 @@ struct mhi_ep_db_info {
> >    * @chdb_offset: Channel doorbell offset set by the host
> >    * @erdb_offset: Event ring doorbell offset set by the host
> >    * @index: MHI Endpoint controller index
> > + * @irq: IRQ used by the endpoint controller
> >    */
> >   struct mhi_ep_cntrl {
> >   	struct device *cntrl_dev;
> > @@ -111,6 +113,7 @@ struct mhi_ep_cntrl {
> >   	spinlock_t state_lock;
> >   	struct list_head st_transition_list;
> > +	struct list_head ch_db_list;
> >   	struct workqueue_struct *wq;
> >   	struct work_struct state_work;
> > @@ -137,6 +140,7 @@ struct mhi_ep_cntrl {
> >   	u32 chdb_offset;
> >   	u32 erdb_offset;
> >   	u32 index;
> > +	int irq;
> >   };
> >   /**
> 

  reply	other threads:[~2022-03-01  6:41 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-28 12:43 [PATCH v4 00/27] Add initial support for MHI endpoint stack Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 01/27] bus: mhi: Fix pm_state conversion to string Manivannan Sadhasivam
2022-02-28 15:30   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 02/27] bus: mhi: Fix MHI DMA structure endianness Manivannan Sadhasivam
2022-02-28 15:40   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 03/27] bus: mhi: Move host MHI code to "host" directory Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 04/27] bus: mhi: Use bitfield operations for register read and write Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 05/27] bus: mhi: Use bitfield operations for handling DWORDs of ring elements Manivannan Sadhasivam
2022-02-28 14:00   ` David Laight
2022-02-28 14:43     ` 'Manivannan Sadhasivam'
2022-02-28 15:11       ` Alex Elder
2022-02-28 15:40       ` David Laight
2022-02-28 15:51         ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 06/27] bus: mhi: Cleanup the register definitions used in headers Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 07/27] bus: mhi: host: Rename "struct mhi_tre" to "struct mhi_ring_element" Manivannan Sadhasivam
2022-02-28 15:52   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 08/27] bus: mhi: Move common MHI definitions out of host directory Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 09/27] bus: mhi: Make mhi_state_str[] array static inline and move to common.h Manivannan Sadhasivam
2022-02-28 15:56   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 10/27] bus: mhi: ep: Add support for registering MHI endpoint controllers Manivannan Sadhasivam
2022-02-28 16:06   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 11/27] bus: mhi: ep: Add support for registering MHI endpoint client drivers Manivannan Sadhasivam
2022-02-28 16:09   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 12/27] bus: mhi: ep: Add support for creating and destroying MHI EP devices Manivannan Sadhasivam
2022-02-28 16:10   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 13/27] bus: mhi: ep: Add support for managing MMIO registers Manivannan Sadhasivam
2022-02-28 16:23   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 14/27] bus: mhi: ep: Add support for ring management Manivannan Sadhasivam
2022-02-28 16:27   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 15/27] bus: mhi: ep: Add support for sending events to the host Manivannan Sadhasivam
2022-02-28 16:37   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 16/27] bus: mhi: ep: Add support for managing MHI state machine Manivannan Sadhasivam
2022-02-28 16:41   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 17/27] bus: mhi: ep: Add support for processing MHI endpoint interrupts Manivannan Sadhasivam
2022-02-28 16:45   ` Alex Elder
2022-03-01  6:41     ` Manivannan Sadhasivam [this message]
2022-02-28 12:43 ` [PATCH v4 18/27] bus: mhi: ep: Add support for powering up the MHI endpoint stack Manivannan Sadhasivam
2022-02-28 16:47   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 19/27] bus: mhi: ep: Add support for powering down " Manivannan Sadhasivam
2022-02-28 16:49   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 20/27] bus: mhi: ep: Add support for handling MHI_RESET Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 21/27] bus: mhi: ep: Add support for handling SYS_ERR condition Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 22/27] bus: mhi: ep: Add support for processing command rings Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 23/27] bus: mhi: ep: Add support for reading from the host Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 24/27] bus: mhi: ep: Add support for processing channel rings Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 25/27] bus: mhi: ep: Add support for queueing SKBs to the host Manivannan Sadhasivam
2022-02-28 16:51   ` Alex Elder
2022-02-28 12:43 ` [PATCH v4 26/27] bus: mhi: ep: Add support for suspending and resuming channels Manivannan Sadhasivam
2022-02-28 12:43 ` [PATCH v4 27/27] bus: mhi: ep: Add uevent support for module autoloading Manivannan Sadhasivam
2022-02-28 16:57 ` [PATCH v4 00/27] Add initial support for MHI endpoint stack Alex Elder
2022-03-01  6:15   ` Manivannan Sadhasivam
2022-03-01  8:50 ` Manivannan Sadhasivam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220301064128.GD12451@workstation \
    --to=manivannan.sadhasivam@linaro.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=elder@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhi@lists.linux.dev \
    --cc=quic_bbhatt@quicinc.com \
    --cc=quic_cang@quicinc.com \
    --cc=quic_hemantk@quicinc.com \
    --cc=quic_jhugo@quicinc.com \
    --cc=quic_skananth@quicinc.com \
    --cc=quic_vbadigan@quicinc.com \
    --cc=vinod.koul@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox