1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * linux/drivers/mmc/core/bus.c |
4 | * |
5 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
6 | * Copyright (C) 2007 Pierre Ossman |
7 | * |
8 | * MMC card bus driver model |
9 | */ |
10 | |
11 | #include <linux/export.h> |
12 | #include <linux/device.h> |
13 | #include <linux/err.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/stat.h> |
16 | #include <linux/of.h> |
17 | #include <linux/pm_runtime.h> |
18 | #include <linux/sysfs.h> |
19 | |
20 | #include <linux/mmc/card.h> |
21 | #include <linux/mmc/host.h> |
22 | |
23 | #include "core.h" |
24 | #include "card.h" |
25 | #include "host.h" |
26 | #include "sdio_cis.h" |
27 | #include "bus.h" |
28 | |
29 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) |
30 | |
31 | static ssize_t type_show(struct device *dev, |
32 | struct device_attribute *attr, char *buf) |
33 | { |
34 | struct mmc_card *card = mmc_dev_to_card(dev); |
35 | |
36 | switch (card->type) { |
37 | case MMC_TYPE_MMC: |
38 | return sysfs_emit(buf, fmt: "MMC\n" ); |
39 | case MMC_TYPE_SD: |
40 | return sysfs_emit(buf, fmt: "SD\n" ); |
41 | case MMC_TYPE_SDIO: |
42 | return sysfs_emit(buf, fmt: "SDIO\n" ); |
43 | case MMC_TYPE_SD_COMBO: |
44 | return sysfs_emit(buf, fmt: "SDcombo\n" ); |
45 | default: |
46 | return -EFAULT; |
47 | } |
48 | } |
49 | static DEVICE_ATTR_RO(type); |
50 | |
51 | static struct attribute *mmc_dev_attrs[] = { |
52 | &dev_attr_type.attr, |
53 | NULL, |
54 | }; |
55 | ATTRIBUTE_GROUPS(mmc_dev); |
56 | |
57 | static int |
58 | mmc_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) |
59 | { |
60 | const struct mmc_card *card = mmc_dev_to_card(dev); |
61 | const char *type; |
62 | unsigned int i; |
63 | int retval = 0; |
64 | |
65 | switch (card->type) { |
66 | case MMC_TYPE_MMC: |
67 | type = "MMC" ; |
68 | break; |
69 | case MMC_TYPE_SD: |
70 | type = "SD" ; |
71 | break; |
72 | case MMC_TYPE_SDIO: |
73 | type = "SDIO" ; |
74 | break; |
75 | case MMC_TYPE_SD_COMBO: |
76 | type = "SDcombo" ; |
77 | break; |
78 | default: |
79 | type = NULL; |
80 | } |
81 | |
82 | if (type) { |
83 | retval = add_uevent_var(env, format: "MMC_TYPE=%s" , type); |
84 | if (retval) |
85 | return retval; |
86 | } |
87 | |
88 | if (mmc_card_sdio(card) || mmc_card_sd_combo(card)) { |
89 | retval = add_uevent_var(env, format: "SDIO_ID=%04X:%04X" , |
90 | card->cis.vendor, card->cis.device); |
91 | if (retval) |
92 | return retval; |
93 | |
94 | retval = add_uevent_var(env, format: "SDIO_REVISION=%u.%u" , |
95 | card->major_rev, card->minor_rev); |
96 | if (retval) |
97 | return retval; |
98 | |
99 | for (i = 0; i < card->num_info; i++) { |
100 | retval = add_uevent_var(env, format: "SDIO_INFO%u=%s" , i+1, card->info[i]); |
101 | if (retval) |
102 | return retval; |
103 | } |
104 | } |
105 | |
106 | /* |
107 | * SDIO (non-combo) cards are not handled by mmc_block driver and do not |
108 | * have accessible CID register which used by mmc_card_name() function. |
109 | */ |
110 | if (mmc_card_sdio(card)) |
111 | return 0; |
112 | |
113 | retval = add_uevent_var(env, format: "MMC_NAME=%s" , mmc_card_name(card)); |
114 | if (retval) |
115 | return retval; |
116 | |
117 | /* |
118 | * Request the mmc_block device. Note: that this is a direct request |
119 | * for the module it carries no information as to what is inserted. |
120 | */ |
121 | retval = add_uevent_var(env, format: "MODALIAS=mmc:block" ); |
122 | |
123 | return retval; |
124 | } |
125 | |
126 | static int mmc_bus_probe(struct device *dev) |
127 | { |
128 | struct mmc_driver *drv = to_mmc_driver(dev->driver); |
129 | struct mmc_card *card = mmc_dev_to_card(dev); |
130 | |
131 | return drv->probe(card); |
132 | } |
133 | |
134 | static void mmc_bus_remove(struct device *dev) |
135 | { |
136 | struct mmc_driver *drv = to_mmc_driver(dev->driver); |
137 | struct mmc_card *card = mmc_dev_to_card(dev); |
138 | |
139 | drv->remove(card); |
140 | } |
141 | |
142 | static void mmc_bus_shutdown(struct device *dev) |
143 | { |
144 | struct mmc_driver *drv = to_mmc_driver(dev->driver); |
145 | struct mmc_card *card = mmc_dev_to_card(dev); |
146 | struct mmc_host *host = card->host; |
147 | int ret; |
148 | |
149 | if (dev->driver && drv->shutdown) |
150 | drv->shutdown(card); |
151 | |
152 | if (host->bus_ops->shutdown) { |
153 | ret = host->bus_ops->shutdown(host); |
154 | if (ret) |
155 | pr_warn("%s: error %d during shutdown\n" , |
156 | mmc_hostname(host), ret); |
157 | } |
158 | } |
159 | |
160 | #ifdef CONFIG_PM_SLEEP |
161 | static int mmc_bus_suspend(struct device *dev) |
162 | { |
163 | struct mmc_card *card = mmc_dev_to_card(dev); |
164 | struct mmc_host *host = card->host; |
165 | int ret; |
166 | |
167 | ret = pm_generic_suspend(dev); |
168 | if (ret) |
169 | return ret; |
170 | |
171 | ret = host->bus_ops->suspend(host); |
172 | if (ret) |
173 | pm_generic_resume(dev); |
174 | |
175 | return ret; |
176 | } |
177 | |
178 | static int mmc_bus_resume(struct device *dev) |
179 | { |
180 | struct mmc_card *card = mmc_dev_to_card(dev); |
181 | struct mmc_host *host = card->host; |
182 | int ret; |
183 | |
184 | ret = host->bus_ops->resume(host); |
185 | if (ret) |
186 | pr_warn("%s: error %d during resume (card was removed?)\n" , |
187 | mmc_hostname(host), ret); |
188 | |
189 | ret = pm_generic_resume(dev); |
190 | return ret; |
191 | } |
192 | #endif |
193 | |
194 | #ifdef CONFIG_PM |
195 | static int mmc_runtime_suspend(struct device *dev) |
196 | { |
197 | struct mmc_card *card = mmc_dev_to_card(dev); |
198 | struct mmc_host *host = card->host; |
199 | |
200 | return host->bus_ops->runtime_suspend(host); |
201 | } |
202 | |
203 | static int mmc_runtime_resume(struct device *dev) |
204 | { |
205 | struct mmc_card *card = mmc_dev_to_card(dev); |
206 | struct mmc_host *host = card->host; |
207 | |
208 | return host->bus_ops->runtime_resume(host); |
209 | } |
210 | #endif /* !CONFIG_PM */ |
211 | |
212 | static const struct dev_pm_ops mmc_bus_pm_ops = { |
213 | SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, NULL) |
214 | SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume) |
215 | }; |
216 | |
217 | static struct bus_type mmc_bus_type = { |
218 | .name = "mmc" , |
219 | .dev_groups = mmc_dev_groups, |
220 | .uevent = mmc_bus_uevent, |
221 | .probe = mmc_bus_probe, |
222 | .remove = mmc_bus_remove, |
223 | .shutdown = mmc_bus_shutdown, |
224 | .pm = &mmc_bus_pm_ops, |
225 | }; |
226 | |
227 | int mmc_register_bus(void) |
228 | { |
229 | return bus_register(bus: &mmc_bus_type); |
230 | } |
231 | |
232 | void mmc_unregister_bus(void) |
233 | { |
234 | bus_unregister(bus: &mmc_bus_type); |
235 | } |
236 | |
237 | /** |
238 | * mmc_register_driver - register a media driver |
239 | * @drv: MMC media driver |
240 | */ |
241 | int mmc_register_driver(struct mmc_driver *drv) |
242 | { |
243 | drv->drv.bus = &mmc_bus_type; |
244 | return driver_register(drv: &drv->drv); |
245 | } |
246 | |
247 | EXPORT_SYMBOL(mmc_register_driver); |
248 | |
249 | /** |
250 | * mmc_unregister_driver - unregister a media driver |
251 | * @drv: MMC media driver |
252 | */ |
253 | void mmc_unregister_driver(struct mmc_driver *drv) |
254 | { |
255 | drv->drv.bus = &mmc_bus_type; |
256 | driver_unregister(drv: &drv->drv); |
257 | } |
258 | |
259 | EXPORT_SYMBOL(mmc_unregister_driver); |
260 | |
261 | static void mmc_release_card(struct device *dev) |
262 | { |
263 | struct mmc_card *card = mmc_dev_to_card(dev); |
264 | |
265 | sdio_free_common_cis(card); |
266 | |
267 | kfree(objp: card->info); |
268 | |
269 | kfree(objp: card); |
270 | } |
271 | |
272 | /* |
273 | * Allocate and initialise a new MMC card structure. |
274 | */ |
275 | struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type) |
276 | { |
277 | struct mmc_card *card; |
278 | |
279 | card = kzalloc(size: sizeof(struct mmc_card), GFP_KERNEL); |
280 | if (!card) |
281 | return ERR_PTR(error: -ENOMEM); |
282 | |
283 | card->host = host; |
284 | |
285 | device_initialize(dev: &card->dev); |
286 | |
287 | card->dev.parent = mmc_classdev(host); |
288 | card->dev.bus = &mmc_bus_type; |
289 | card->dev.release = mmc_release_card; |
290 | card->dev.type = type; |
291 | |
292 | return card; |
293 | } |
294 | |
295 | /* |
296 | * Register a new MMC card with the driver model. |
297 | */ |
298 | int mmc_add_card(struct mmc_card *card) |
299 | { |
300 | int ret; |
301 | const char *type; |
302 | const char *uhs_bus_speed_mode = "" ; |
303 | static const char *const uhs_speeds[] = { |
304 | [UHS_SDR12_BUS_SPEED] = "SDR12 " , |
305 | [UHS_SDR25_BUS_SPEED] = "SDR25 " , |
306 | [UHS_SDR50_BUS_SPEED] = "SDR50 " , |
307 | [UHS_SDR104_BUS_SPEED] = "SDR104 " , |
308 | [UHS_DDR50_BUS_SPEED] = "DDR50 " , |
309 | }; |
310 | |
311 | |
312 | dev_set_name(dev: &card->dev, name: "%s:%04x" , mmc_hostname(card->host), card->rca); |
313 | dev_set_removable(dev: &card->dev, |
314 | removable: mmc_card_is_removable(host: card->host) ? |
315 | DEVICE_REMOVABLE : DEVICE_FIXED); |
316 | |
317 | switch (card->type) { |
318 | case MMC_TYPE_MMC: |
319 | type = "MMC" ; |
320 | break; |
321 | case MMC_TYPE_SD: |
322 | type = "SD" ; |
323 | if (mmc_card_blockaddr(card)) { |
324 | if (mmc_card_ext_capacity(card)) |
325 | type = "SDXC" ; |
326 | else |
327 | type = "SDHC" ; |
328 | } |
329 | break; |
330 | case MMC_TYPE_SDIO: |
331 | type = "SDIO" ; |
332 | break; |
333 | case MMC_TYPE_SD_COMBO: |
334 | type = "SD-combo" ; |
335 | if (mmc_card_blockaddr(card)) |
336 | type = "SDHC-combo" ; |
337 | break; |
338 | default: |
339 | type = "?" ; |
340 | break; |
341 | } |
342 | |
343 | if (mmc_card_uhs(card) && |
344 | (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds))) |
345 | uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed]; |
346 | |
347 | if (mmc_host_is_spi(card->host)) { |
348 | pr_info("%s: new %s%s%s card on SPI\n" , |
349 | mmc_hostname(card->host), |
350 | mmc_card_hs(card) ? "high speed " : "" , |
351 | mmc_card_ddr52(card) ? "DDR " : "" , |
352 | type); |
353 | } else { |
354 | pr_info("%s: new %s%s%s%s%s%s card at address %04x\n" , |
355 | mmc_hostname(card->host), |
356 | mmc_card_uhs(card) ? "ultra high speed " : |
357 | (mmc_card_hs(card) ? "high speed " : "" ), |
358 | mmc_card_hs400(card) ? "HS400 " : |
359 | (mmc_card_hs200(card) ? "HS200 " : "" ), |
360 | mmc_card_hs400es(card) ? "Enhanced strobe " : "" , |
361 | mmc_card_ddr52(card) ? "DDR " : "" , |
362 | uhs_bus_speed_mode, type, card->rca); |
363 | } |
364 | |
365 | mmc_add_card_debugfs(card); |
366 | card->dev.of_node = mmc_of_find_child_device(host: card->host, func_num: 0); |
367 | |
368 | device_enable_async_suspend(dev: &card->dev); |
369 | |
370 | ret = device_add(dev: &card->dev); |
371 | if (ret) |
372 | return ret; |
373 | |
374 | mmc_card_set_present(card); |
375 | |
376 | return 0; |
377 | } |
378 | |
379 | /* |
380 | * Unregister a new MMC card with the driver model, and |
381 | * (eventually) free it. |
382 | */ |
383 | void mmc_remove_card(struct mmc_card *card) |
384 | { |
385 | struct mmc_host *host = card->host; |
386 | |
387 | mmc_remove_card_debugfs(card); |
388 | |
389 | if (mmc_card_present(card)) { |
390 | if (mmc_host_is_spi(card->host)) { |
391 | pr_info("%s: SPI card removed\n" , |
392 | mmc_hostname(card->host)); |
393 | } else { |
394 | pr_info("%s: card %04x removed\n" , |
395 | mmc_hostname(card->host), card->rca); |
396 | } |
397 | device_del(dev: &card->dev); |
398 | of_node_put(node: card->dev.of_node); |
399 | } |
400 | |
401 | if (host->cqe_enabled) { |
402 | host->cqe_ops->cqe_disable(host); |
403 | host->cqe_enabled = false; |
404 | } |
405 | |
406 | put_device(dev: &card->dev); |
407 | } |
408 | |