sdmmc_host: implement sd_enable()

This is mainly useful for bootloaders that want to safely
disable the SD/MMC controller before booting. Disabling a
controller will reset and power down the bus; all attempts
to read or write to a disabled controller will fail.

Change-Id: I4a7ec4287f2b8510a35d964cc806c74be8c86406
This commit is contained in:
Aidan MacDonald 2026-01-13 16:06:34 +00:00 committed by Solomon Peachy
parent 80fec463df
commit 72dd8bc4d0
2 changed files with 35 additions and 0 deletions

View file

@ -114,6 +114,7 @@ void sdmmc_host_init(struct sdmmc_host *host,
host->ops = ops;
host->controller = controller;
host->present = !config->is_removable;
host->enabled = true;
mutex_init(&host->lock);
array[i] = host;
@ -188,6 +189,26 @@ static void sdmmc_host_bus_reset(struct sdmmc_host *host)
memset(&host->cardinfo, 0, sizeof(host->cardinfo));
}
/*
* Call to enable/disable the host controller. If disabled then the
* controller and device are powered off and no access to the storage
* device is allowed.
*/
static void sdmmc_host_set_enabled(struct sdmmc_host *host, bool enabled)
{
mutex_lock(&host->lock);
if (enabled != host->enabled)
{
if (host->enabled)
sdmmc_host_bus_reset(host);
host->enabled = enabled;
}
mutex_unlock(&host->lock);
}
#ifdef HAVE_HOTSWAP
static void sdmmc_host_hotswap_event(struct sdmmc_host *host, bool is_present)
{
@ -629,6 +650,9 @@ static int sdmmc_host_transfer(struct sdmmc_host *host,
mutex_lock(&host->lock);
if (!host->enabled)
goto out;
if (!sdmmc_host_medium_present(host))
goto out;
@ -721,6 +745,16 @@ tCardInfo *card_get_info_target(int drive)
return &sdmmc_sd_hosts[drive]->cardinfo;
}
void sd_enable(bool enabled)
{
for (size_t i = 0; i < ARRAYLEN(sdmmc_sd_hosts); ++i)
{
struct sdmmc_host *host = sdmmc_sd_hosts[i];
sdmmc_host_set_enabled(host, enabled);
}
}
long sd_last_disk_activity(void)
{
return sdmmc_sd_last_activity;