Skip to contentSkip to conversation

sdhci: runtime suspend/resume on card insert/removal

PATCH Vaibhav Hiremath 3 participants 17 messages Sep 10, 2015 – Sep 14, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

sdhci_irq() -->
-> sdhci_thread_irq(): host->thread_isr - 0x80

      -> sdhci_card_event()
      -> mmc_detect_change()
         --> _mmc_detect_change()
             --->  mmc_sd_detect()
                   mmc_sd_remove()
                   mmc_remove_card()
                   mmc_bus_remove()
                   mmc_power_off()
                   mmc_set_initial_state()
                   sdhci_set_ios()
                   ...
        sdhci_pxav3_runtime_suspend()
        sdhci_runtime_suspend_host()

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

But what I am observing here is, no interrupt is generated, as it is not enabled at all. And the reason being sdhci_runtime_suspend_host()

int sdhci_runtime_suspend_host(struct sdhci_host *host)

{
     ....
     spin_lock_irqsave(&host->lock, flags);
     host->ier &= SDHCI_INT_CARD_INT;
     sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
     sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
     spin_unlock_irqrestore(&host->lock, flags);
     ...
}

In my case, I see SDHCI_INT_CARD_INT is not ON and with above step we are not ensuring that it is enabled either.
Also we are not enabling card insertion and removal interrupts.

I have done following change to the code -

drivers/mmc/host/sdhci.c +0 -0
index 418f381..3129292 100644
@@ -2783,9 +2783,12 @@ int sdhci_runtime_suspend_host(struct sdhci_host 

*host)

         mmc_retune_needed(host->mmc);

         spin_lock_irqsave(&host->lock, flags);
-       host->ier &= SDHCI_INT_CARD_INT;
+
+       host->flags |= SDHCI_SDIO_IRQ_ENABLED;
+       host->ier |= SDHCI_INT_CARD_INT;
         sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
         sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+
         spin_unlock_irqrestore(&host->lock, flags);

         synchronize_hardirq(host->irq);

And things started working as expected.
The execution sequence of irq and sdhci_runtime_resume both looks ok to me.

Card insertion event =

sdhci_irq() -->
-> sdhci_thread_irq: host->thread_isr - 40

      --> sdhci_card_event()
      -->  mmc_detect_change()
           ---> _mmc_detect_change()
       ...
  -> sdhci_pxav3_runtime_resume()
     --> sdhci_do_set_ios:1438

I see card getting enumerated as expected -

[   15.116098] mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hz
[   15.356473] mmc1: new high speed SDHC card at address 1234
[   15.363962] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[   15.371043] sdhci_thread_irq:2642 host->thread_isr - 100
[   15.376492]  mmcblk1: p1

I believe (based on my understanding) the change I have done is right. I am not sure how other platforms using sdhci.c working so far, probably no runtime_pm support? Not sure though

Please let me know if I am missing something here.
And not, and everyone is ok with this, I will submit the patch fixing this issue.

Thanks,
Vaibhav

#1 lore raw

Hi Vaibhav,

Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

sdhci_irq() -->
-> sdhci_thread_irq(): host->thread_isr - 0x80

      -> sdhci_card_event()
      -> mmc_detect_change()
         --> _mmc_detect_change()
             --->  mmc_sd_detect()
                   mmc_sd_remove()
                   mmc_remove_card()
                   mmc_bus_remove()
                   mmc_power_off()
                   mmc_set_initial_state()
                   sdhci_set_ios()
                   ...
        sdhci_pxav3_runtime_suspend()
        sdhci_runtime_suspend_host()
Quoted 5 lines

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI controller itself because SDHCI controller is runtime suspended, clk gated or power gated. So the wakeup irq should come from other always on components. Take Marvell berlin SoC as an example:

there's gpio for sdcard detect, card insertion => trigger cd gpio interrupt =>resume sdhci host etc.

If your changes work, the I guess your SDHCI host are not clk gated or power gated during runtime suspended.

Thanks,
Jisheng

Quoted 87 lines

But what I am observing here is, no interrupt is generated, as it is not enabled at all. And the reason being sdhci_runtime_suspend_host()

int sdhci_runtime_suspend_host(struct sdhci_host *host)

{
     ....
     spin_lock_irqsave(&host->lock, flags);
     host->ier &= SDHCI_INT_CARD_INT;
     sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
     sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
     spin_unlock_irqrestore(&host->lock, flags);
     ...
}

In my case, I see SDHCI_INT_CARD_INT is not ON and with above step we are not ensuring that it is enabled either.
Also we are not enabling card insertion and removal interrupts.

I have done following change to the code -

drivers/mmc/host/sdhci.c +4 -1
index 418f381..3129292 100644
@@ -2783,9 +2783,12 @@ int sdhci_runtime_suspend_host(struct sdhci_host 
 *host)
         mmc_retune_needed(host->mmc);
 
         spin_lock_irqsave(&host->lock, flags);
-       host->ier &= SDHCI_INT_CARD_INT;
+
+       host->flags |= SDHCI_SDIO_IRQ_ENABLED;
+       host->ier |= SDHCI_INT_CARD_INT;
         sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
         sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+
         spin_unlock_irqrestore(&host->lock, flags);
 
         synchronize_hardirq(host->irq);

And things started working as expected.
The execution sequence of irq and sdhci_runtime_resume both looks ok to me.

Card insertion event =

sdhci_irq() -->
-> sdhci_thread_irq: host->thread_isr - 40

      --> sdhci_card_event()
      -->  mmc_detect_change()
           ---> _mmc_detect_change()
       ...
  -> sdhci_pxav3_runtime_resume()
     --> sdhci_do_set_ios:1438

I see card getting enumerated as expected -

[   15.116098] mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hz
[   15.356473] mmc1: new high speed SDHC card at address 1234
[   15.363962] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[   15.371043] sdhci_thread_irq:2642 host->thread_isr - 100
[   15.376492]  mmcblk1: p1

I believe (based on my understanding) the change I have done is right. I am not sure how other platforms using sdhci.c working so far, probably no runtime_pm support? Not sure though

Please let me know if I am missing something here.
And not, and everyone is ok with this, I will submit the patch fixing this issue.

Thanks,
Vaibhav

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#2 lore raw
Quoted 48 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

   sdhci_irq() -->
    -> sdhci_thread_irq(): host->thread_isr - 0x80
       -> sdhci_card_event()
       -> mmc_detect_change()
          --> _mmc_detect_change()
              --->  mmc_sd_detect()
                    mmc_sd_remove()
                    mmc_remove_card()
                    mmc_bus_remove()
                    mmc_power_off()
                    mmc_set_initial_state()
                    sdhci_set_ios()
                    ...
         sdhci_pxav3_runtime_suspend()
         sdhci_runtime_suspend_host()
Quoted 5 lines

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

Quoted 7 lines

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI controller itself because SDHCI controller is runtime suspended, clk gated or power gated. So the wakeup irq should come from other always on components. Take Marvell berlin SoC as an example:

there's gpio for sdcard detect, card insertion => trigger cd gpio interrupt =>resume sdhci host etc.

Not always.

In my case SDHCI controller is generating card insert and remove event/interrupts. Just to add here, I am not configuring any pins to GPIO mode. My pin configuration for card-detect is in MMC_CD mode.

The card insertion and removal interrupt is mapped to SDHCI interrupt line, which is interrupt number 12 in my case.

# cat /proc/interrupts
            CPU0
  11:         55       GIC 105 Level     mmc0
  12:        220       GIC 101 Level     mmc1
Quoted 4 lines

If your changes work, the I guess your SDHCI host are not clk gated or power gated during runtime suspended.

This is what I suspected initially, but it doesn't look that way.

Without this change, if I just disable/remove

    pm_runtime_put_autosuspend(&pdev->dev);

then also it works for me. What it tells me that, if I disable runtime_pm then it works.

I can cross-check register values to make sure that it is really turned off. Let me do that as well.

Thanks,
Vaibhav

#3 lore raw
Quoted 56 lines · On Thu, 10 Sep 2015 13:21:12 +0530 Vaibhav Hiremath…
Quoted 53 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

   sdhci_irq() -->
    -> sdhci_thread_irq(): host->thread_isr - 0x80
       -> sdhci_card_event()
       -> mmc_detect_change()
          --> _mmc_detect_change()
              --->  mmc_sd_detect()
                    mmc_sd_remove()
                    mmc_remove_card()
                    mmc_bus_remove()
                    mmc_power_off()
                    mmc_set_initial_state()
                    sdhci_set_ios()
                    ...
         sdhci_pxav3_runtime_suspend()
         sdhci_runtime_suspend_host()
Quoted 5 lines

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI controller itself because SDHCI controller is runtime suspended, clk gated or power gated. So the wakeup irq should come from other always on components. Take Marvell berlin SoC as an example:

Quoted 7 lines
Quoted 2 lines

there's gpio for sdcard detect, card insertion => trigger cd gpio interrupt =>resume sdhci host etc.

Not always.

In my case SDHCI controller is generating card insert and remove event/interrupts. Just to add here, I am not configuring any pins

How could sdhci controller generate card insert/remove interrupts if it's clk gated or power gated? We should have another wake up mechanism for runtime pm.

Quoted 1 line

to GPIO mode. My pin configuration for card-detect is in MMC_CD mode.

I guess the pin is muxed between SD_CD pin and gpio.

Quoted 29 lines

The card insertion and removal interrupt is mapped to SDHCI interrupt line, which is interrupt number 12 in my case.

# cat /proc/interrupts
            CPU0
  11:         55       GIC 105 Level     mmc0
  12:        220       GIC 101 Level     mmc1
Quoted 4 lines

If your changes work, the I guess your SDHCI host are not clk gated or power gated during runtime suspended.

This is what I suspected initially, but it doesn't look that way.

Without this change, if I just disable/remove

    pm_runtime_put_autosuspend(&pdev->dev);

then also it works for me. What it tells me that, if I disable runtime_pm then it works.

I can cross-check register values to make sure that it is really turned off. Let me do that as well.

Thanks,
Vaibhav

#4 lore raw
In reply to Jisheng Zhang
Quoted 42 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

sdhci_irq() -->
-> sdhci_thread_irq(): host->thread_isr - 0x80

      -> sdhci_card_event()
      -> mmc_detect_change()
         --> _mmc_detect_change()
             --->  mmc_sd_detect()
                   mmc_sd_remove()
                   mmc_remove_card()
                   mmc_bus_remove()
                   mmc_power_off()
                   mmc_set_initial_state()
                   sdhci_set_ios()
                   ...
        sdhci_pxav3_runtime_suspend()
        sdhci_runtime_suspend_host()
Quoted 7 lines
Quoted 5 lines

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#5 lore raw

Hi Russell,

Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

sdhci_irq() -->
-> sdhci_thread_irq(): host->thread_isr - 0x80

      -> sdhci_card_event()
      -> mmc_detect_change()
         --> _mmc_detect_change()
             --->  mmc_sd_detect()
                   mmc_sd_remove()
                   mmc_remove_card()
                   mmc_bus_remove()
                   mmc_power_off()
                   mmc_set_initial_state()
                   sdhci_set_ios()
                   ...
        sdhci_pxav3_runtime_suspend()
        sdhci_runtime_suspend_host()

Till here everything looks perfect :) (if I got it right)

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.

Thanks for clarification,
Jisheng

#6 lore raw
Quoted 54 lines · Jisheng Zhang

Hi Russell,

Quoted 49 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 48 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 42 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

   sdhci_irq() -->
    -> sdhci_thread_irq(): host->thread_isr - 0x80
       -> sdhci_card_event()
       -> mmc_detect_change()
          --> _mmc_detect_change()
              --->  mmc_sd_detect()
                    mmc_sd_remove()
                    mmc_remove_card()
                    mmc_bus_remove()
                    mmc_power_off()
                    mmc_set_initial_state()
                    sdhci_set_ios()
                    ...
         sdhci_pxav3_runtime_suspend()
         sdhci_runtime_suspend_host()

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

Quoted 9 lines
Quoted 4 lines
Quoted 1 line

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.

So Jisheng,

You are ok with above change, right?

Thanks,
Vaibhav

#7 lore raw
Quoted 62 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 59 lines · Jisheng Zhang

Hi Russell,

Quoted 53 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 42 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

   sdhci_irq() -->
    -> sdhci_thread_irq(): host->thread_isr - 0x80
       -> sdhci_card_event()
       -> mmc_detect_change()
          --> _mmc_detect_change()
              --->  mmc_sd_detect()
                    mmc_sd_remove()
                    mmc_remove_card()
                    mmc_bus_remove()
                    mmc_power_off()
                    mmc_set_initial_state()
                    sdhci_set_ios()
                    ...
         sdhci_pxav3_runtime_suspend()
         sdhci_runtime_suspend_host()
Quoted 7 lines
Quoted 5 lines

Till here everything looks perfect :) (if I got it right)

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Quoted 8 lines
Quoted 4 lines

Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.

So Jisheng,

You are ok with above change, right?

Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.

IMHO, your patch is still not necessary and perhaps wrong.

Thanks,
Jisheng

#8 lore raw
Quoted 70 lines · Jisheng Zhang
Quoted 67 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 63 lines · Jisheng Zhang

Hi Russell,

Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

    sdhci_irq() -->
     -> sdhci_thread_irq(): host->thread_isr - 0x80
        -> sdhci_card_event()
        -> mmc_detect_change()
           --> _mmc_detect_change()
               --->  mmc_sd_detect()
                     mmc_sd_remove()
                     mmc_remove_card()
                     mmc_bus_remove()
                     mmc_power_off()
                     mmc_set_initial_state()
                     sdhci_set_ios()
                     ...
          sdhci_pxav3_runtime_suspend()
          sdhci_runtime_suspend_host()

Till here everything looks perfect :) (if I got it right)

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.

Quoted 9 lines
Quoted 3 lines

So Jisheng,

You are ok with above change, right?

Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.

IMHO, your patch is still not necessary and perhaps wrong.

Don't be in hurry to conclude,
Let's understand the technical aspect fist.

Let me clarify once again here,

The card detect interrupt is coming from SDHCI controller itself, I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.

Clock Gating:
=============
#

# devmem 0xd4282854
0x0000181B
# [ 1318.948460] mmc1: card 1234 removed

#

# devmem 0xd4282854
0x00001800
#

Power from the regulator -
==========================

Only "vqmmc" stays on, and it is required for the card detection. I have confirmed it.

So my patch still makes sense.

Thanks,
Vaibhav

#9 lore raw
Quoted 83 lines · On Mon, 14 Sep 2015 13:43:32 +0530 Vaibhav Hiremath…
Quoted 70 lines · Jisheng Zhang
Quoted 67 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 63 lines · Jisheng Zhang

Hi Russell,

Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

    sdhci_irq() -->
     -> sdhci_thread_irq(): host->thread_isr - 0x80
        -> sdhci_card_event()
        -> mmc_detect_change()
           --> _mmc_detect_change()
               --->  mmc_sd_detect()
                     mmc_sd_remove()
                     mmc_remove_card()
                     mmc_bus_remove()
                     mmc_power_off()
                     mmc_set_initial_state()
                     sdhci_set_ios()
                     ...
          sdhci_pxav3_runtime_suspend()
          sdhci_runtime_suspend_host()

Till here everything looks perfect :) (if I got it right)

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.

Quoted 9 lines
Quoted 3 lines

So Jisheng,

You are ok with above change, right?

Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.

IMHO, your patch is still not necessary and perhaps wrong.

Quoted 8 lines

Don't be in hurry to conclude,
Let's understand the technical aspect fist.

Let me clarify once again here,

The card detect interrupt is coming from SDHCI controller itself,

But how the SDHCI controller generate CD interrupt when it's in runtime suspended state, i.e clock gated or power gated?

Quoted 2 lines

I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.

But seems we still didn't know the sdhci host is clock gated or power gated.

Quoted 5 lines

Clock Gating:
=============
#

Quoted 8 lines
# devmem 0xd4282854
0x0000181B
# [ 1318.948460] mmc1: card 1234 removed

#

# devmem 0xd4282854
0x00001800
#

Can you plz read the SDHCI host registers after this step? If the host is clock gated, we should get "asynchronous external abort" in theory.

Thanks

#10 lore raw
Quoted 90 lines · Jisheng Zhang
Quoted 87 lines · On Mon, 14 Sep 2015 13:43:32 +0530 Vaibhav Hiremath…
Quoted 70 lines · Jisheng Zhang
Quoted 67 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 63 lines · Jisheng Zhang

Hi Russell,

Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.

Let me try to explain it using execution sequence -

During boot:

MMC SD card gets detected as expected.

[    2.431012] mmc1: new high speed SDHC card at address 1234
[    2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB
[    2.444841]  mmcblk1: p1

Now after coming to the linux prompt, if card removal event occurs then the call sequence is -

     sdhci_irq() -->
      -> sdhci_thread_irq(): host->thread_isr - 0x80
         -> sdhci_card_event()
         -> mmc_detect_change()
            --> _mmc_detect_change()
                --->  mmc_sd_detect()
                      mmc_sd_remove()
                      mmc_remove_card()
                      mmc_bus_remove()
                      mmc_power_off()
                      mmc_set_initial_state()
                      sdhci_set_ios()
                      ...
           sdhci_pxav3_runtime_suspend()
           sdhci_runtime_suspend_host()

Till here everything looks perfect :) (if I got it right)

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.

AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI

Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.

Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.

Quoted 9 lines
Quoted 3 lines

So Jisheng,

You are ok with above change, right?

Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.

IMHO, your patch is still not necessary and perhaps wrong.

Don't be in hurry to conclude,
Let's understand the technical aspect fist.

Quoted 8 lines
Quoted 4 lines

Let me clarify once again here,

The card detect interrupt is coming from SDHCI controller itself,

But how the SDHCI controller generate CD interrupt when it's in runtime suspended state, i.e clock gated or power gated?

Due to lack of detailed Documentation its difficult to conclude here

Quoted 5 lines
Quoted 2 lines

I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.

But seems we still didn't know the sdhci host is clock gated or power gated.

Register above is
SDIO Host 1 Clock/Reset Control Register

And bit 3 & 4 says

BIT 3:

SD Host 1 Peripheral Clock Enable
0x1: Peripheral clock enabled
0x0: Peripheral clock disabled

BIT4:

SD Host 1 AXI Clock Enable
0x1: AXI clock enabled
0x0: AXI clock disabled

Quoted 9 lines
Quoted 9 lines

Clock Gating:
=============
#

# devmem 0xd4282854
0x0000181B
# [ 1318.948460] mmc1: card 1234 removed
Quoted 8 lines
Quoted 4 lines

#

# devmem 0xd4282854
0x00001800
#

Can you plz read the SDHCI host registers after this step? If the host is clock gated, we should get "asynchronous external abort" in theory.

Ok, that's another way. I can cross check on this.

Thanks,
Vaibhav

#11 lore raw
Quoted 28 lines · Vaibhav Hiremath
Quoted 25 lines · Jisheng Zhang
Quoted 22 lines · On Mon, 14 Sep 2015 13:43:32 +0530 Vaibhav Hiremath…
Quoted 19 lines · Jisheng Zhang
Quoted 16 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 13 lines · Jisheng Zhang

Hi Russell,

Quoted 8 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 7 lines · Jisheng Zhang

Hi Vaibhav,

Quoted 2 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…

Hi,

<snip>

Quoted 39 lines
Quoted 6 lines
Quoted 2 lines

I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.

But seems we still didn't know the sdhci host is clock gated or power gated.

Register above is
SDIO Host 1 Clock/Reset Control Register

And bit 3 & 4 says

BIT 3:

SD Host 1 Peripheral Clock Enable
0x1: Peripheral clock enabled
0x0: Peripheral clock disabled

BIT4:

SD Host 1 AXI Clock Enable
0x1: AXI clock enabled
0x0: AXI clock disabled

Quoted 14 lines
Quoted 13 lines

Clock Gating:
=============
#

# devmem 0xd4282854
0x0000181B
# [ 1318.948460] mmc1: card 1234 removed

#

# devmem 0xd4282854
0x00001800
#
Quoted 6 lines
Quoted 3 lines

Can you plz read the SDHCI host registers after this step? If the host is clock gated, we should get "asynchronous external abort" in theory.

Ok, that's another way. I can cross check on this.

Came across below lines in the datasheet,

========= Copy-n-paste from datasheet============

All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled by
PMUA_SDH1_CLK_RES_CTRL.

==================================================

And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.

This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.

So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)

And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.

So Jisheng,
The change/patch which I was referring to now is more clear and I believe now you would realize that it is required for SDH to work on PXA1928 platform.

If you have access to internal documentation or someone who knows the design, please try to cross check.

Thanks,
Vaibhav

#12 lore raw
Quoted 22 lines · Vaibhav Hiremath

Came across below lines in the datasheet,

========= Copy-n-paste from datasheet============

All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled by
PMUA_SDH1_CLK_RES_CTRL.

==================================================

And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.

This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.

Quoted 7 lines

So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)

And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.

What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.

Yes, it means you don't get the same savings as you would by turning off that clock, but that's the choice between using the internal card detection and a GPIO for this. The code shouldn't force you to use a GPIO just because the Linux driver implementation dumbly disables the AXI clock.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#13 lore raw
Quoted 35 lines · Russell King - ARM Linux
Quoted 22 lines · Vaibhav Hiremath

Came across below lines in the datasheet,

========= Copy-n-paste from datasheet============

All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled by
PMUA_SDH1_CLK_RES_CTRL.

==================================================

And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.

This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.

Quoted 7 lines

So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)

And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.

What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.

Quoted 5 lines

Yes, it means you don't get the same savings as you would by turning off that clock, but that's the choice between using the internal card detection and a GPIO for this. The code shouldn't force you to use a GPIO just because the Linux driver implementation dumbly disables the AXI clock.

Note that should also happen if a SDIO card is inserted, and the SDIO IRQ is enabled - so the SDIO card can signal an interrupt back to the host.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#14 lore raw
In reply to Russell King - ARM Linux
Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Vaibhav Hiremath

Came across below lines in the datasheet,

========= Copy-n-paste from datasheet============

All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled by
PMUA_SDH1_CLK_RES_CTRL.

==================================================

And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.

This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.

So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)

Quoted 8 lines
Quoted 3 lines

And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.

What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.

Yes, exactly.
Its clock driver which is doing this.

static struct mmp_param_gate_clk apmu_gate_clks[] = {
         /* The gate clocks has mux parent. */
         {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT, 

PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, };

Here the mask and enable_val both are set to 0x1b, which means it shuts off both peripheral and AXI clock both.

Quoted 6 lines

Yes, it means you don't get the same savings as you would by turning off that clock, but that's the choice between using the internal card detection and a GPIO for this. The code shouldn't force you to use a GPIO just because the Linux driver implementation dumbly disables the AXI clock.

Exactly,

In my case, luckily I have eMMC on board, which keeps AXI clock ON all the time. Not sure why somebody would keep dependency like this, inspite having individual control for AXI clock.

Thanks,
Vaibhav

#15 lore raw
Quoted 40 lines · Vaibhav Hiremath
Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Vaibhav Hiremath

Came across below lines in the datasheet,

========= Copy-n-paste from datasheet============

All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled by
PMUA_SDH1_CLK_RES_CTRL.

==================================================

And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.

This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.

So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)

Quoted 8 lines
Quoted 3 lines

And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.

What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.

Yes, exactly.
Its clock driver which is doing this.

Quoted 8 lines
static struct mmp_param_gate_clk apmu_gate_clks[] = {
        /* The gate clocks has mux parent. */
        {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT,

PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, };

Here the mask and enable_val both are set to 0x1b, which means it shuts off both peripheral and AXI clock both.

*Sigh*.

So, rather than represent the hardware in DT by telling the SDHCI code that you have two independent clocks, you've chosen to do the brain dead thing, and combine the two clocks *which are logically different* to suit the Linux implementation, thereby leaking implementation details into DT, and creating a compatibility headache through doing so.

Stop doing this. Just stop it. It's broken, it's wrong, and it's down right idiotic.

DT should _always_ describe the bloody hardware, not the implementation.

I suggest that you have only one way to solve this on this platform.

1. Declare new clocks from your PXA clock driver which expose the AXI and peripheral clock separately.
2. Add code (if not already there) to the SDHCI crap-pile to claim and appropriately manage these two clocks, falling back to the existing but broken method with existing DT.
3. Change DT to provide the new clocks to SDHCI.

That's about the only way I can see to ensure that an old DT file would continue to work with a new kernel, given this fsckup.

Please. In future, be careful when describing stuff in DT. Don't take short cuts to suit the implementation. Always describe the hardware, don't describe the implementation. *Especially* when it comes to things like device resources.

It really doesn't matter if the driver doesn't cope with them - the important thing is that the DT always correctly describes the hardware.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#16 lore raw
Quoted 72 lines · Russell King - ARM Linux
Quoted 40 lines · Vaibhav Hiremath
Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Vaibhav Hiremath

Came across below lines in the datasheet,

========= Copy-n-paste from datasheet============

All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled by
PMUA_SDH1_CLK_RES_CTRL.

==================================================

And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.

This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.

So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)

Quoted 8 lines
Quoted 3 lines

And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.

What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.

Yes, exactly.
Its clock driver which is doing this.

Quoted 8 lines
static struct mmp_param_gate_clk apmu_gate_clks[] = {
         /* The gate clocks has mux parent. */
         {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT,

PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, };

Here the mask and enable_val both are set to 0x1b, which means it shuts off both peripheral and AXI clock both.

*Sigh*.

So, rather than represent the hardware in DT by telling the SDHCI code that you have two independent clocks, you've chosen to do the brain dead thing, and combine the two clocks *which are logically different* to suit the Linux implementation, thereby leaking implementation details into DT, and creating a compatibility headache through doing so.

Stop doing this. Just stop it. It's broken, it's wrong, and it's down right idiotic.

DT should _always_ describe the bloody hardware, not the implementation.

I suggest that you have only one way to solve this on this platform.

1. Declare new clocks from your PXA clock driver which expose the AXI and peripheral clock separately.
2. Add code (if not already there) to the SDHCI crap-pile to claim and appropriately manage these two clocks, falling back to the existing but broken method with existing DT.
3. Change DT to provide the new clocks to SDHCI.

Quoted 3 lines

That's about the only way I can see to ensure that an old DT file would continue to work with a new kernel, given this fsckup.

sdhci-pxav3 driver already handles both, in terms of 'core' and 'io' clock. And it does disable both the clocks in runtime_pm_suspend()

So I have to find a way not to disable AXI clock here.

And yes, both clocks should be defined separately.

Looping Rob here as well.
Rob please add if I am missing anything here.