[RFC PATCH] mmc: host: sdhci-iproc: implement the .hw_reset callback
Meagan Lloyd
meaganlloyd at linux.microsoft.com
Mon Apr 13 10:38:15 PDT 2026
On 3/27/2026 3:21 PM, Meagan Lloyd wrote:
> Implement the .hw_reset callback so that the eMMC can be reset as needed
> given cap-mmc-hw-reset is set in the devicetree and the functionality is
> enabled on the eMMC.
>
> Signed-off-by: Meagan Lloyd <meaganlloyd at linux.microsoft.com>
> ---
>
> SDHCI_POWER_CONTROL[4] (SD Host Controller Standard) has been repurposed
> on my Broadcomm processor to be eMMC hardware reset
> (SDIO*_eMMCSDXC_CTRL[12], HRESET).
>
> Can you confirm this repurposed bit is consistent across the Broadcomm
> iProc processors and thus the .hw_reset callback can be uniformly
> applied in this driver?
Hi Ray & Scott,
I hope you're doing well. This bit looks to have been repurposed from
the SD Host Controller Standard's VDD2 Power Control to being used for
toggling the hardware reset signal to eMMCs. Can you verify that it
applies across the iProc processors so that I may finalize this patch?
Thank you,
Meagan
>
> ---
> drivers/mmc/host/sdhci-iproc.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> index 35ef5c5f51467..9018ed7fe2e66 100644
> --- a/drivers/mmc/host/sdhci-iproc.c
> +++ b/drivers/mmc/host/sdhci-iproc.c
> @@ -181,12 +181,26 @@ static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
> return 200000;
> }
>
> +static void sdhci_iproc_hw_reset(struct sdhci_host *host)
> +{
> + u8 val = sdhci_readb(host, SDHCI_POWER_CONTROL);
> +
> + /* Trigger reset and hold for at least 1us (eMMC spec requirement) */
> + sdhci_writeb(host, val | BIT(4), SDHCI_POWER_CONTROL);
> + usleep_range(2, 10);
> +
> + /* Release from reset and wait for at least 200us (eMMC spec requirement) */
> + sdhci_writeb(host, val & ~BIT(4), SDHCI_POWER_CONTROL);
> + usleep_range(250, 300);
> +}
> +
> static const struct sdhci_ops sdhci_iproc_ops = {
> .set_clock = sdhci_set_clock,
> .get_max_clock = sdhci_iproc_get_max_clock,
> .set_bus_width = sdhci_set_bus_width,
> .reset = sdhci_reset,
> .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .hw_reset = sdhci_iproc_hw_reset,
> };
>
> static const struct sdhci_ops sdhci_iproc_32only_ops = {
> @@ -201,6 +215,7 @@ static const struct sdhci_ops sdhci_iproc_32only_ops = {
> .set_bus_width = sdhci_set_bus_width,
> .reset = sdhci_reset,
> .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .hw_reset = sdhci_iproc_hw_reset,
> };
>
> static const struct sdhci_pltfm_data sdhci_iproc_cygnus_pltfm_data = {
> @@ -283,6 +298,7 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
> .set_bus_width = sdhci_set_bus_width,
> .reset = sdhci_reset,
> .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .hw_reset = sdhci_iproc_hw_reset,
> };
>
> static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
More information about the linux-arm-kernel
mailing list