xref: /openbmc/u-boot/drivers/mmc/mmc-uclass.c (revision ad5b5801)
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