• Andrea Merello's avatar
    mmc: core: make pwrseq_emmc (partially) support sleepy GPIO controllers · 002ee28e
    Andrea Merello authored
    pwrseq_emmc.c implements a HW reset procedure for eMMC chip by driving a
    GPIO line.
    
    It registers the .reset() cb on mmc_pwrseq_ops and it registers a system
    restart notification handler; both of them perform reset by unconditionally
    calling gpiod_set_value().
    
    If the eMMC reset line is tied to a GPIO controller whose driver can sleep
    (i.e. I2C GPIO controller), then the kernel would spit warnings when trying
    to reset the eMMC chip by means of .reset() mmc_pwrseq_ops cb (that is
    exactly what I'm seeing during boot).
    
    Furthermore, on system reset we would gets to the system restart
    notification handler with disabled interrupts - local_irq_disable() is
    called in machine_restart() at least on ARM/ARM64 - and we would be in
    trouble when the GPIO driver tries to sleep (which indeed doesn't happen
    here, likely because in my case the machine specific code doesn't call
    do_kernel_restart(), I guess..).
    
    This patch fixes the .reset() cb to make use of gpiod_set_value_cansleep(),
    so that the eMMC gets reset on boot without complaints, while, since there
    isn't that much we can do, we avoid register the restart handler if the
    GPIO controller has a sleepy driver (and we spit a dev_notice() message to
    let people know)..
    
    This had been tested on a downstream 4.9 kernel with backported
    commit 83f37ee7ba33 ("mmc: pwrseq: Add reset callback to the struct
    mmc_pwrseq_ops") and commit ae60fb031cf2 ("mmc: core: Don't do eMMC HW
    reset when resuming the eMMC card"), because I couldn't boot my board
    otherwise. Maybe worth to RFT.
    Signed-off-by: default avatarAndrea Merello <andrea.merello@gmail.com>
    Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
    002ee28e
pwrseq_emmc.c 3.1 KB