Re: [PATCH] mmc: sdio: avoid spurious calls to interrupt handlers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 15 Apr 2012, Sujit Reddy Thumma wrote:

> Hi Nicolas,
> 
> >
> > Commit 06e8935feb "optimized SDIO IRQ handling for single irq"
> > introduced some spurious calls to SDIO function interrupt handlers,
> > such as when the SDIO IRQ thread is started, or the safety check
> > performed upon a system resume.  Let's add a flag to perform the
> > optimization only when a real interrupt is signaled by the host
> > driver and we know there is no point confirming it.
> >
> 
> Thanks for putting up formal patch.
> 
> > Reported-by: Sujit Reddy Thumma <sthumma@xxxxxxxxxxxxxx>
> > Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxx>
> > Cc: stable@xxxxxxxxxx
> >
> > diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
> > index f573e7f9f7..3d8ceb4084 100644
> > --- a/drivers/mmc/core/sdio_irq.c
> > +++ b/drivers/mmc/core/sdio_irq.c
> > @@ -28,18 +28,20 @@
> >
> >  #include "sdio_ops.h"
> >
> > -static int process_sdio_pending_irqs(struct mmc_card *card)
> > +static int process_sdio_pending_irqs(struct mmc_host *host)
> >  {
> > +	struct mmc_card *card = host->card;
> >  	int i, ret, count;
> >  	unsigned char pending;
> >  	struct sdio_func *func;
> >
> >  	/*
> >  	 * Optimization, if there is only 1 function interrupt registered
> > -	 * call irq handler directly
> > +	 * and we know an IRQ was signaled then call irq handler directly.
> > +	 * Otherwise do the full probe.
> >  	 */
> >  	func = card->sdio_single_irq;
> > -	if (func) {
> > +	if (func && host->sdio_irq_pending) {
> >  		func->irq_handler(func);
> >  		return 1;
> >  	}
> > @@ -116,7 +118,8 @@ static int sdio_irq_thread(void *_host)
> >  		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
> >  		if (ret)
> >  			break;
> > -		ret = process_sdio_pending_irqs(host->card);
> > +		ret = process_sdio_pending_irqs(host);
> > +		host->sdio_irq_pending = false;
> >  		mmc_release_host(host);
> >
> >  		/*
> > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> > index ee2b0363c0..557aa4cd66 100644
> > --- a/include/linux/mmc/host.h
> > +++ b/include/linux/mmc/host.h
> > @@ -323,6 +323,7 @@ struct mmc_host {
> >
> >  	unsigned int		sdio_irqs;
> >  	struct task_struct	*sdio_irq_thread;
> > +	bool			sdio_irq_pending;
> >  	atomic_t		sdio_irq_thread_abort;
> >
> >  	mmc_pm_flag_t		pm_flags;	/* requested pm features */
> > @@ -378,6 +379,7 @@ extern int mmc_cache_ctrl(struct mmc_host *, u8);
> >  static inline void mmc_signal_sdio_irq(struct mmc_host *host)
> >  {
> >  	host->ops->enable_sdio_irq(host, 0);
> > +	host->sdio_irq_pending = true;
> >  	wake_up_process(host->sdio_irq_thread);
> >  }
> 
> In this case probably we need to add the following:
> @@ -946,8 +946,11 @@ static int mmc_sdio_resume(struct mmc_host *host)
>                 }
>         }
> 
> -       if (!err && host->sdio_irqs)
> -               mmc_signal_sdio_irq(host);
> +       if (!err && host->sdio_irqs) {
> +               host->ops->enable_sdio_irq(host, 0);
> +               wake_up_process(host->sdio_irq_thread);
> +       }

The call to enable_sdio_irq() is probably redundant.  Only 
wake_up_process() should be sufficient.


Nicolas
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux