]> git.sur5r.net Git - u-boot/blob - drivers/mmc/mmc-uclass.c
dm: mmc: Implement the MMC functions for block devices
[u-boot] / drivers / mmc / mmc-uclass.c
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 };