• Linus Walleij's avatar
    mmc: mmci: Make busy complete state machine explicit · 7be5ac5f
    Linus Walleij authored
    This refactors the ->busy_complete() callback currently
    only used by Ux500 and STM32 to handle busy detection on
    hardware where one and the same IRQ is fired whether we get
    a start or an end signal on busy detect.
    
    The code is currently using the cached status from the
    command IRQ in ->busy_status as a state to select what to
    do next: if this state is non-zero we are waiting for
    IRQs and if it is zero we treat the state as the starting
    point for a busy detect wait cycle.
    
    Make this explicit by creating a state machine where the
    ->busy_complete callback moves between three states.
    
    The Ux500 busy detect code currently assumes this order:
    we enable the busy detect IRQ, get a busy start IRQ, then a
    busy end IRQ, and then we clear and mask this IRQ and
    proceed.
    
    We insert debug prints for unexpected states.
    
    This works as before on most cards, however on a
    problematic card that is not working with busy detect, and
    which I have been debugging, the following happens a lot:
    
    [    3.380554] mmci-pl18x 80005000.mmc: no busy signalling in time
    [    3.387420] mmci-pl18x 80005000.mmc: no busy signalling in time
    [    3.394561] mmci-pl18x 80005000.mmc: lost busy status
         when waiting for busy start IRQ
    
    This probably means that the busy detect start IRQ has
    already occurred when we start executing the
    ->busy_complete() callbacks, and the busy detect end IRQ
    is counted as the start IRQ, and this is what is causing
    the card to not be detected properly.
    Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    Link: https://lore.kernel.org/r/20230405-pl180-busydetect-fix-v7-5-69a7164f2a61@linaro.orgSigned-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
    7be5ac5f
mmci.c 63.2 KB