blob: 1b967d982bc74946ccd61fe1c74ae5826662cb6f [file] [log] [blame]
Simon Glasse7ecf7c2015-06-23 15:38:48 -06001/*
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
14struct 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
Simon Glass8ef761e2016-05-01 13:52:39 -060024#ifdef CONFIG_BLK
25struct 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
44int get_mmc_num(void)
45{
46 return max(blk_find_max_devnum(IF_TYPE_MMC), 0);
47}
48
49int 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
60struct 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
73void 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)
96void 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
126void print_mmc_devices(char separator) { }
127#endif
128#endif /* CONFIG_BLK */
129
Simon Glasse7ecf7c2015-06-23 15:38:48 -0600130U_BOOT_DRIVER(mmc) = {
131 .name = "mmc",
132 .id = UCLASS_MMC,
133};
134
135UCLASS_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};