diff mbox series

mmc: spi: Fix card detection during probe

Message ID 20190210173109.12602-1-j.neuschaefer@gmx.net (mailing list archive)
State New, archived
Headers show
Series mmc: spi: Fix card detection during probe | expand

Commit Message

J. Neuschäfer Feb. 10, 2019, 5:31 p.m. UTC
When using the mmc_spi driver with a card-detect pin, I noticed that the
card was not detected immediately after probe, but only after it was
unplugged and plugged back in (and the CD IRQ fired).

The call tree looks something like this:

mmc_spi_probe
  mmc_add_host
    mmc_start_host
      _mmc_detect_change
        mmc_schedule_delayed_work(&host->detect, 0)
          mmc_rescan
            host->bus_ops->detect(host)
              mmc_detect
                _mmc_detect_card_removed
                  host->ops->get_cd(host)
                    mmc_gpio_get_cd -> -ENOSYS (ctx->cd_gpio not set)
  mmc_gpiod_request_cd
    ctx->cd_gpio = desc

To fix this issue, call mmc_detect_change after the card-detect GPIO/IRQ
is registered.

Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
---
 drivers/mmc/host/mmc_spi.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Linus Walleij Feb. 11, 2019, 8:27 a.m. UTC | #1
On Sun, Feb 10, 2019 at 6:31 PM Jonathan Neuschäfer
<j.neuschaefer@gmx.net> wrote:

> When using the mmc_spi driver with a card-detect pin, I noticed that the
> card was not detected immediately after probe, but only after it was
> unplugged and plugged back in (and the CD IRQ fired).
>
> The call tree looks something like this:
>
> mmc_spi_probe
>   mmc_add_host
>     mmc_start_host
>       _mmc_detect_change
>         mmc_schedule_delayed_work(&host->detect, 0)
>           mmc_rescan
>             host->bus_ops->detect(host)
>               mmc_detect
>                 _mmc_detect_card_removed
>                   host->ops->get_cd(host)
>                     mmc_gpio_get_cd -> -ENOSYS (ctx->cd_gpio not set)
>   mmc_gpiod_request_cd
>     ctx->cd_gpio = desc
>
> To fix this issue, call mmc_detect_change after the card-detect GPIO/IRQ
> is registered.
>
> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>

Seems correct!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
Ulf Hansson Feb. 26, 2019, 8:18 a.m. UTC | #2
On Sun, 10 Feb 2019 at 18:31, Jonathan Neuschäfer <j.neuschaefer@gmx.net> wrote:
>
> When using the mmc_spi driver with a card-detect pin, I noticed that the
> card was not detected immediately after probe, but only after it was
> unplugged and plugged back in (and the CD IRQ fired).
>
> The call tree looks something like this:
>
> mmc_spi_probe
>   mmc_add_host
>     mmc_start_host
>       _mmc_detect_change
>         mmc_schedule_delayed_work(&host->detect, 0)
>           mmc_rescan
>             host->bus_ops->detect(host)
>               mmc_detect
>                 _mmc_detect_card_removed
>                   host->ops->get_cd(host)
>                     mmc_gpio_get_cd -> -ENOSYS (ctx->cd_gpio not set)
>   mmc_gpiod_request_cd
>     ctx->cd_gpio = desc
>
> To fix this issue, call mmc_detect_change after the card-detect GPIO/IRQ
> is registered.
>
> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>

This works well as fix and for stable! However, we should probably
clean up the code in ->probe() to avoid this thing altogether. Anyway,
I send a patch for that - on top.

Applied for fixes and added a stable tag, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/mmc_spi.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
> index 10ba46b728e8..8ade14fb2148 100644
> --- a/drivers/mmc/host/mmc_spi.c
> +++ b/drivers/mmc/host/mmc_spi.c
> @@ -1450,6 +1450,7 @@ static int mmc_spi_probe(struct spi_device *spi)
>                 mmc->caps &= ~MMC_CAP_NEEDS_POLL;
>                 mmc_gpiod_request_cd_irq(mmc);
>         }
> +       mmc_detect_change(mmc, 0);
>
>         /* Index 1 is write protect/read only */
>         status = mmc_gpiod_request_ro(mmc, NULL, 1, false, 0, NULL);
> --
> 2.20.1
>
J. Neuschäfer Feb. 26, 2019, 11:29 a.m. UTC | #3
On Tue, Feb 26, 2019 at 09:18:06AM +0100, Ulf Hansson wrote:
> On Sun, 10 Feb 2019 at 18:31, Jonathan Neuschäfer <j.neuschaefer@gmx.net> wrote:
> >
> > When using the mmc_spi driver with a card-detect pin, I noticed that the
> > card was not detected immediately after probe, but only after it was
> > unplugged and plugged back in (and the CD IRQ fired).
> >
> > The call tree looks something like this:
> >
> > mmc_spi_probe
> >   mmc_add_host
> >     mmc_start_host
> >       _mmc_detect_change
> >         mmc_schedule_delayed_work(&host->detect, 0)
> >           mmc_rescan
> >             host->bus_ops->detect(host)
> >               mmc_detect
> >                 _mmc_detect_card_removed
> >                   host->ops->get_cd(host)
> >                     mmc_gpio_get_cd -> -ENOSYS (ctx->cd_gpio not set)
> >   mmc_gpiod_request_cd
> >     ctx->cd_gpio = desc
> >
> > To fix this issue, call mmc_detect_change after the card-detect GPIO/IRQ
> > is registered.
> >
> > Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
> 
> This works well as fix and for stable! However, we should probably
> clean up the code in ->probe() to avoid this thing altogether.

I figured that calling mmc_gpiod_request_cd before mmc_add_host *should*
avoid the 'return -ENOSYS' in mmc_gpio_get_cd. However it turned out to
be not as simple as swapping around a few lines in mmc_spi_probe, when I
wrote/tested this patch.

> Anyway, I send a patch for that - on top.

Thanks!

> Applied for fixes and added a stable tag, thanks!

Great.


Thanks,
Jonathan Neuschäfer
diff mbox series

Patch

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 10ba46b728e8..8ade14fb2148 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1450,6 +1450,7 @@  static int mmc_spi_probe(struct spi_device *spi)
 		mmc->caps &= ~MMC_CAP_NEEDS_POLL;
 		mmc_gpiod_request_cd_irq(mmc);
 	}
+	mmc_detect_change(mmc, 0);
 
 	/* Index 1 is write protect/read only */
 	status = mmc_gpiod_request_ro(mmc, NULL, 1, false, 0, NULL);