1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <mmc.h> 10 #include <dm.h> 11 #include <dm/lists.h> 12 #include <dm/root.h> 13 14 struct mmc *mmc_get_mmc_dev(struct udevice *dev) 15 { 16 struct mmc_uclass_priv *upriv; 17 18 if (!device_active(dev)) 19 return NULL; 20 upriv = dev_get_uclass_priv(dev); 21 return upriv->mmc; 22 } 23 24 #ifdef CONFIG_BLK 25 struct mmc *find_mmc_device(int dev_num) 26 { 27 struct udevice *dev, *mmc_dev; 28 int ret; 29 30 ret = blk_get_device(IF_TYPE_MMC, dev_num, &dev); 31 32 if (ret) { 33 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 34 printf("MMC Device %d not found\n", dev_num); 35 #endif 36 return NULL; 37 } 38 39 mmc_dev = dev_get_parent(dev); 40 41 return mmc_get_mmc_dev(mmc_dev); 42 } 43 44 int get_mmc_num(void) 45 { 46 return max(blk_find_max_devnum(IF_TYPE_MMC), 0); 47 } 48 49 int mmc_get_next_devnum(void) 50 { 51 int ret; 52 53 ret = get_mmc_num(); 54 if (ret < 0) 55 return ret; 56 57 return ret + 1; 58 } 59 60 struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) 61 { 62 struct blk_desc *desc; 63 struct udevice *dev; 64 65 device_find_first_child(mmc->dev, &dev); 66 if (!dev) 67 return NULL; 68 desc = dev_get_uclass_platdata(dev); 69 70 return desc; 71 } 72 73 void mmc_do_preinit(void) 74 { 75 struct udevice *dev; 76 struct uclass *uc; 77 int ret; 78 79 ret = uclass_get(UCLASS_MMC, &uc); 80 if (ret) 81 return; 82 uclass_foreach_dev(dev, uc) { 83 struct mmc *m = mmc_get_mmc_dev(dev); 84 85 if (!m) 86 continue; 87 #ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT 88 mmc_set_preinit(m, 1); 89 #endif 90 if (m->preinit) 91 mmc_start_init(m); 92 } 93 } 94 95 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 96 void print_mmc_devices(char separator) 97 { 98 struct udevice *dev; 99 char *mmc_type; 100 bool first = true; 101 102 for (uclass_first_device(UCLASS_MMC, &dev); 103 dev; 104 uclass_next_device(&dev)) { 105 struct mmc *m = mmc_get_mmc_dev(dev); 106 107 if (!first) { 108 printf("%c", separator); 109 if (separator != '\n') 110 puts(" "); 111 } 112 if (m->has_init) 113 mmc_type = IS_SD(m) ? "SD" : "eMMC"; 114 else 115 mmc_type = NULL; 116 117 printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum); 118 if (mmc_type) 119 printf(" (%s)", mmc_type); 120 } 121 122 printf("\n"); 123 } 124 125 #else 126 void print_mmc_devices(char separator) { } 127 #endif 128 #endif /* CONFIG_BLK */ 129 130 U_BOOT_DRIVER(mmc) = { 131 .name = "mmc", 132 .id = UCLASS_MMC, 133 }; 134 135 UCLASS_DRIVER(mmc) = { 136 .id = UCLASS_MMC, 137 .name = "mmc", 138 .flags = DM_UC_FLAG_SEQ_ALIAS, 139 .per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv), 140 }; 141