Skip to content

Commit fa2d0aa

Browse files
tq-schiffermstorulf
authored andcommitted
mmc: core: Allow setting slot index via device tree alias
As with GPIO, UART and others, allow specifying the device index via the aliases node in the device tree. On embedded devices, there is often a combination of removable (e.g. SD card) and non-removable MMC devices (e.g. eMMC). Therefore the index might change depending on * host of removable device * removable card present or not This makes it difficult to hardcode the root device, if it is on the non-removable device. E.g. if SD card is present eMMC will be mmcblk1, if SD card is not present at boot, eMMC will be mmcblk0. Alternative solutions like PARTUUIDs do not cover the case where multiple mmcblk devices contain the same image. This is a common issue on devices that can boot both from eMMC (for regular boot) and SD cards (as a temporary boot medium for development). When a firmware image is installed to eMMC after a test boot via SD card, there will be no reliable way to refer to a specific device using (PART)UUIDs oder LABELs. The demand for this feature has led to multiple attempts to implement it, dating back at least to 2012 (see https://www.spinics.net/lists/linux-mmc/msg26586.html for a previous discussion from 2014). All indices defined in the aliases node will be reserved for use by the respective MMC device, moving the indices of devices that don't have an alias up into the non-reserved range. If the aliases node is not found, the driver will act as before. This is a rebased and cleaned up version of https://www.spinics.net/lists/linux-mmc/msg26588.html . Based-on-patch-by: Sascha Hauer <[email protected]> Link: https://lkml.org/lkml/2020/8/5/194 Signed-off-by: Matthias Schiffer <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent 1796164 commit fa2d0aa

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

drivers/mmc/core/host.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,20 @@ int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
376376
}
377377
EXPORT_SYMBOL(mmc_of_parse_voltage);
378378

379+
/**
380+
* mmc_first_nonreserved_index() - get the first index that is not reserved
381+
*/
382+
static int mmc_first_nonreserved_index(void)
383+
{
384+
int max;
385+
386+
max = of_alias_get_highest_id("mmc");
387+
if (max < 0)
388+
return 0;
389+
390+
return max + 1;
391+
}
392+
379393
/**
380394
* mmc_alloc_host - initialise the per-host structure.
381395
* @extra: sizeof private data structure
@@ -387,6 +401,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
387401
{
388402
int err;
389403
struct mmc_host *host;
404+
int alias_id, min_idx, max_idx;
390405

391406
host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
392407
if (!host)
@@ -395,7 +410,16 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
395410
/* scanning will be enabled when we're ready */
396411
host->rescan_disable = 1;
397412

398-
err = ida_simple_get(&mmc_host_ida, 0, 0, GFP_KERNEL);
413+
alias_id = of_alias_get_id(dev->of_node, "mmc");
414+
if (alias_id >= 0) {
415+
min_idx = alias_id;
416+
max_idx = alias_id + 1;
417+
} else {
418+
min_idx = mmc_first_nonreserved_index();
419+
max_idx = 0;
420+
}
421+
422+
err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
399423
if (err < 0) {
400424
kfree(host);
401425
return NULL;

0 commit comments

Comments
 (0)