Hi James, > > > May 26 07:44:33 xo-96-6d-f4 kernel: [ 198.341764] mmc0: Timeout waiting for hardware interrupt. > > > May 26 07:44:33 xo-96-6d-f4 kernel: [ 198.341784] mwifiex_sdio mmc0:0001:1: read mp_regs failed > > > > I was expecting that mwifiex_sdio_resume handler is called before > > the SDIO interrupt function is called. > > This does not happen. The SDIO interrupt function is always called > before the mwifiex_sdio_resume handler. I see. > > Method to test: > > --- a/drivers/net/wireless/mwifiex/sdio.c > +++ b/drivers/net/wireless/mwifiex/sdio.c > @@ -712,6 +712,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) > u32 sdio_ireg; > unsigned long flags; > > + if (adapter->is_suspended) > + dev_warn(adapter->dev, "interrupt while adapter is suspended\n"); > + > if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, > REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, > 0)) { > > # grep -c "after resume" /var/log/messages > 630 > # grep -c "interrupt while adapter" /var/log/messages > 630 > > Also, sometimes mwifiex_sdio_suspend runs while an SDIO register > operation is in progress, because of an interrupt. I can reduce the > frequency of the "mmc0: Timeout..." if I delay suspend until the > register option is completed. > > This occurs roughly 3 out of 630 suspends. > > The platform is not SMP, even though it is mmp3. So I made an > unpleasant hack: > > --- a/drivers/net/wireless/mwifiex/sdio.c > +++ b/drivers/net/wireless/mwifiex/sdio.c > @@ -54,6 +54,8 @@ static DEFINE_RATELIMIT_STATE(noskb_rs, > 120 * HZ, > 1); > > +volatile static bool in_progress; > + > /* > * SDIO probe. > * > @@ -206,6 +208,22 @@ static int mwifiex_sdio_suspend(struct device *dev) > struct mwifiex_adapter *adapter; > mmc_pm_flag_t pm_flag = 0; > int ret = 0; > + int i; > + > + /* an attempt to avoid suspend for a short time while sdio i/o is in progress */ > + if (in_progress) { > + pr_err("suspend: sdio i/o is in_progress, delaying\n"); > + WARN_ON_ONCE(1); > + > + i = 50; > + while (in_progress && i-- > 0) msleep(10); > + > + if (in_progress) { > + pr_err("suspend: sdio i/o was in_progress\n"); > + WARN_ON_ONCE(1); > + return -EFAULT; > + } > + } I think MMC has better knowledge about the host being claimed or not. If a register read/write is in progress, host->claimed and host->claim_cnt should have non-zero values. So, the delay logic is better to be done in MMC before calling driver's suspend handler. Regards, Bing -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html