linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andreas Fenkart <afenkart@gmail.com>
To: Tony Lindgren <tony@atomide.com>
Cc: Chris Ball <cjb@laptop.org>,
	linux-omap <linux-omap@vger.kernel.org>,
	linux-mmc <linux-mmc@vger.kernel.org>,
	Balaji T K <balajitk@ti.com>
Subject: Re: [PATCH 2/2] mmc: omap_hsmmc: Enable SDIO interrupt
Date: Fri, 27 Sep 2013 08:38:59 +0200	[thread overview]
Message-ID: <CALtMJEDKxTcaNHmrVqMv7tznxB0uqYxuOix+ks+Bs_huiOCL4A@mail.gmail.com> (raw)
In-Reply-To: <20130926141936.GE8949@atomide.com>

2013/9/26 Tony Lindgren <tony@atomide.com>:
> Hi,
>
> * Andreas Fenkart <afenkart@gmail.com> [130926 01:34]:
>> 2013/9/26 Tony Lindgren <tony@atomide.com>:
>> > @@ -463,27 +469,34 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host)
>> >  static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
>> >                                   struct mmc_command *cmd)
>> >  {
>> > -       unsigned int irq_mask;
>> > +       u32 irq_mask = INT_EN_MASK;
>> > +       unsigned long flags;
>> >
>> >         if (host->use_dma)
>> > -               irq_mask = INT_EN_MASK & ~(BRR_EN | BWR_EN);
>> > -       else
>> > -               irq_mask = INT_EN_MASK;
>> > +               irq_mask &= ~(BRR_EN | BWR_EN);
>> >
>> >         /* Disable timeout for erases */
>> >         if (cmd->opcode == MMC_ERASE)
>> >                 irq_mask &= ~DTO_EN;
>> >
>> > +       spin_lock_irqsave(&host->irq_lock, flags);
>> >         OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
>> >         OMAP_HSMMC_WRITE(host->base, ISE, irq_mask);
>> > +       if (host->flags & HSMMC_SDIO_IRQ_ENABLED)
>> > +               irq_mask |= CIRQ_EN;
>> >         OMAP_HSMMC_WRITE(host->base, IE, irq_mask);
>> > +       spin_unlock_irqrestore(&host->irq_lock, flags);
>> >  }
>> >
>> >  static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
>> >  {
>> > +       unsigned long flags;
>> > +
>> > +       spin_lock_irqsave(&host->irq_lock, flags);
>> >         OMAP_HSMMC_WRITE(host->base, ISE, 0);
>> >         OMAP_HSMMC_WRITE(host->base, IE, 0);
>> >         OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
>>
>> This is wrong. SDIO IRQ must not be disabled upon host initiated transfer.
>> see omap_hsmmc_request_done

It's what Balaji already pointed out.

+   /* no transfer running, need to signal cirq if */
+   if (host->sdio_irq_en)
+       irq_mask |= CIRQ_EN;


omap_hsmmc_request_done calls omap_hsmmc_disable_irq

imagine this case:
1. host issues transfer from host->card (e.g. get RSSI)
2. at end of this transfer, SDIO IRQ are being masked
3. card wants to reply, raises an SDIO IRQ
4. nothing happens, since in 2. SDIO IRQ are masked

I verified this with my 88W8787 card. It is a problem

>
>> > +       spin_unlock_irqrestore(&host->irq_lock, flags);
>> >  }
>> >
>> >  /* Calculate divisor for the given clock frequency */
>> > @@ -1040,8 +1053,12 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
>> >         int status;
>> >
>> >         status = OMAP_HSMMC_READ(host->base, STAT);
>> > -       while (status & INT_EN_MASK && host->req_in_progress) {
>> > -               omap_hsmmc_do_irq(host, status);
>> > +       while (status & (INT_EN_MASK | CIRQ_EN)) {
>> > +               if (host->req_in_progress)
>> > +                       omap_hsmmc_do_irq(host, status);
>> > +
>> > +               if (status & CIRQ_EN)
>> > +                       mmc_signal_sdio_irq(host->mmc);
>> >
>> >                 /* Flush posted write */
>> >                 status = OMAP_HSMMC_READ(host->base, STAT);
>> > @@ -1556,6 +1573,43 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
>> >                 mmc_slot(host).init_card(card);
>> >  }
>> >
>> > +static void omap_hsmmc_enable_sdio_irq_nolock(struct omap_hsmmc_host *host,
>> > +                                        int enable)
>> > +{
>> > +       u32 irq_mask;
>> > +
>> > +       if (enable)
>> > +               host->flags |= HSMMC_SDIO_IRQ_ENABLED;
>> > +       else
>> > +               host->flags &= ~HSMMC_SDIO_IRQ_ENABLED;
>> > +
>> > +       /* SDIO IRQ will be enabled as appropriate in runtime resume */
>> > +       if (host->flags & HSMMC_RUNTIME_SUSPENDED)
>> > +               goto out;
>>
>> Not sure here, will the module still come out of suspend even with
>> SDIO IRQ disabled?
>> Otherwise nak, sdio irq must enabled independent of pm runtime state. In the
>> worst case need pm_runtime_get().
>
> Well this handling is similar to what's done in sdhci.c and
> seems to work for me for off-idle on 3730. In that case the
> whole MMC block is powered off and the wake up follows the
> dedicated io chain path. For the am33xx off-idle case, the
> wake-up path would be remuxed to the GPIO in the first GPIO
> bank that's always on, so again the whole MMC block is off.

Something like this but shorter as a comment:

/*
 * Must not touch registers while fclk if off, otherwise SIGBUS.
 * Card will still wake up upon SDIO IRQ, and we'll complete
 * the request in pm_runtime_resume
 */

Another interpretation of your code could be:

/* Sorry I'm having Siesta right now, try later */

>
> Maybe try to test this with your case with some additional
> patches?
>
>> >  static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
>> >  {
>> >         u32 hctl, capa, value;
>> > @@ -1608,7 +1662,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = {
>> >         .get_cd = omap_hsmmc_get_cd,
>> >         .get_ro = omap_hsmmc_get_ro,
>> >         .init_card = omap_hsmmc_init_card,
>> > -       /* NYET -- enable_sdio_irq */
>> > +       .enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
>>
>> What about am335x, if this patch goes in, it will break that platform.
>> quirk flag via device tree?
>
> I think it should still work, except the wake-up won't work for
> the off-idle case unless the SDIO interrupt is remux to the
> GPIO input?
>
> If there are other issues then yes, we can use the compatible
> flags.

Compatible section you mean, that sounds to good to me.
But do we know platform have the deficiency?

There used to be an if statement like this in one of your previous
patches.

+   if (match) {
+       mmc->caps |= MMC_CAP_SDIO_IRQ;
+       if (of_find_property(host->dev->of_node,
+                    "ti,quirk-swakeup-missing", NULL)) {
+           /* no wakeup from deeper power states, use polling */
+           mmc->caps &= ~MMC_CAP_SDIO_IRQ;
+       }
+   }

Either or is needed, otherwise existing platforms will break, and will have
to apply patches on top of yours to reenable polling (e.g. beaglebone)

>
> Thanks for the review and comments,
>
> Tony
>

  parent reply	other threads:[~2013-09-27  6:39 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-25 23:47 [PATCH 0/2] patches to enable SDIO interrupt support for omap_hsmmc for v3.13 Tony Lindgren
2013-09-25 23:47 ` [PATCH 1/2] mmc: omap_hsmmc: Fix context save and restore for DT Tony Lindgren
2013-09-25 23:47 ` [PATCH 2/2] mmc: omap_hsmmc: Enable SDIO interrupt Tony Lindgren
2013-09-26  8:26   ` Andreas Fenkart
2013-09-26 14:19     ` Tony Lindgren
2013-09-26 14:31       ` Balaji T K
2013-09-27  6:38       ` Andreas Fenkart [this message]
2013-09-27 21:10         ` Tony Lindgren

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=CALtMJEDKxTcaNHmrVqMv7tznxB0uqYxuOix+ks+Bs_huiOCL4A@mail.gmail.com \
    --to=afenkart@gmail.com \
    --cc=balajitk@ti.com \
    --cc=cjb@laptop.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=tony@atomide.com \
    /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;
as well as URLs for NNTP newsgroup(s).