Commit 51ec92e295d563dd5712d198a7e46c2ae5ccccb2
Committed by
Linus Torvalds
1 parent
03c086a747
Exists in
master
and in
7 other branches
mmc: use sysfs groups to handle conditional attributes
Suppressing uevents turned out to be a bad idea as it screws up the order of events, making user space very confused. Change the system to use sysfs groups instead. This is a regression that, for some odd reason, has gone unnoticed for some time. It confuses hal so that the block devices (which have the mmc device as a parent) are not registered. End result being that desktop magic when cards are inserted won't work. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 9 changed files with 96 additions and 198 deletions Side-by-side Diff
drivers/mmc/core/Makefile
drivers/mmc/core/bus.c
... | ... | @@ -17,7 +17,6 @@ |
17 | 17 | #include <linux/mmc/card.h> |
18 | 18 | #include <linux/mmc/host.h> |
19 | 19 | |
20 | -#include "sysfs.h" | |
21 | 20 | #include "core.h" |
22 | 21 | #include "sdio_cis.h" |
23 | 22 | #include "bus.h" |
... | ... | @@ -43,7 +42,7 @@ |
43 | 42 | } |
44 | 43 | |
45 | 44 | static struct device_attribute mmc_dev_attrs[] = { |
46 | - MMC_ATTR_RO(type), | |
45 | + __ATTR(type, S_IRUGO, mmc_type_show, NULL), | |
47 | 46 | __ATTR_NULL, |
48 | 47 | }; |
49 | 48 | |
... | ... | @@ -189,7 +188,7 @@ |
189 | 188 | /* |
190 | 189 | * Allocate and initialise a new MMC card structure. |
191 | 190 | */ |
192 | -struct mmc_card *mmc_alloc_card(struct mmc_host *host) | |
191 | +struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type) | |
193 | 192 | { |
194 | 193 | struct mmc_card *card; |
195 | 194 | |
... | ... | @@ -204,6 +203,7 @@ |
204 | 203 | card->dev.parent = mmc_classdev(host); |
205 | 204 | card->dev.bus = &mmc_bus_type; |
206 | 205 | card->dev.release = mmc_release_card; |
206 | + card->dev.type = type; | |
207 | 207 | |
208 | 208 | return card; |
209 | 209 | } |
210 | 210 | |
... | ... | @@ -248,24 +248,10 @@ |
248 | 248 | type, card->rca); |
249 | 249 | } |
250 | 250 | |
251 | - card->dev.uevent_suppress = 1; | |
252 | - | |
253 | 251 | ret = device_add(&card->dev); |
254 | 252 | if (ret) |
255 | 253 | return ret; |
256 | 254 | |
257 | - if (card->host->bus_ops->sysfs_add) { | |
258 | - ret = card->host->bus_ops->sysfs_add(card->host, card); | |
259 | - if (ret) { | |
260 | - device_del(&card->dev); | |
261 | - return ret; | |
262 | - } | |
263 | - } | |
264 | - | |
265 | - card->dev.uevent_suppress = 0; | |
266 | - | |
267 | - kobject_uevent(&card->dev.kobj, KOBJ_ADD); | |
268 | - | |
269 | 255 | mmc_card_set_present(card); |
270 | 256 | |
271 | 257 | return 0; |
... | ... | @@ -285,9 +271,6 @@ |
285 | 271 | printk(KERN_INFO "%s: card %04x removed\n", |
286 | 272 | mmc_hostname(card->host), card->rca); |
287 | 273 | } |
288 | - | |
289 | - if (card->host->bus_ops->sysfs_remove) | |
290 | - card->host->bus_ops->sysfs_remove(card->host, card); | |
291 | 274 | device_del(&card->dev); |
292 | 275 | } |
293 | 276 |
drivers/mmc/core/bus.h
... | ... | @@ -11,7 +11,16 @@ |
11 | 11 | #ifndef _MMC_CORE_BUS_H |
12 | 12 | #define _MMC_CORE_BUS_H |
13 | 13 | |
14 | -struct mmc_card *mmc_alloc_card(struct mmc_host *host); | |
14 | +#define MMC_DEV_ATTR(name, fmt, args...) \ | |
15 | +static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ | |
16 | +{ \ | |
17 | + struct mmc_card *card = container_of(dev, struct mmc_card, dev); \ | |
18 | + return sprintf(buf, fmt, args); \ | |
19 | +} \ | |
20 | +static DEVICE_ATTR(name, S_IRUGO, mmc_##name##_show, NULL) | |
21 | + | |
22 | +struct mmc_card *mmc_alloc_card(struct mmc_host *host, | |
23 | + struct device_type *type); | |
15 | 24 | int mmc_add_card(struct mmc_card *card); |
16 | 25 | void mmc_remove_card(struct mmc_card *card); |
17 | 26 |
drivers/mmc/core/core.h
... | ... | @@ -18,8 +18,6 @@ |
18 | 18 | struct mmc_bus_ops { |
19 | 19 | void (*remove)(struct mmc_host *); |
20 | 20 | void (*detect)(struct mmc_host *); |
21 | - int (*sysfs_add)(struct mmc_host *, struct mmc_card *card); | |
22 | - void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card); | |
23 | 21 | void (*suspend)(struct mmc_host *); |
24 | 22 | void (*resume)(struct mmc_host *); |
25 | 23 | }; |
drivers/mmc/core/mmc.c
... | ... | @@ -17,7 +17,6 @@ |
17 | 17 | #include <linux/mmc/mmc.h> |
18 | 18 | |
19 | 19 | #include "core.h" |
20 | -#include "sysfs.h" | |
21 | 20 | #include "bus.h" |
22 | 21 | #include "mmc_ops.h" |
23 | 22 | |
... | ... | @@ -248,6 +247,44 @@ |
248 | 247 | return err; |
249 | 248 | } |
250 | 249 | |
250 | +MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | |
251 | + card->raw_cid[2], card->raw_cid[3]); | |
252 | +MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |
253 | + card->raw_csd[2], card->raw_csd[3]); | |
254 | +MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | |
255 | +MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | |
256 | +MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | |
257 | +MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | |
258 | +MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); | |
259 | +MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); | |
260 | +MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); | |
261 | + | |
262 | +static struct attribute *mmc_std_attrs[] = { | |
263 | + &dev_attr_cid.attr, | |
264 | + &dev_attr_csd.attr, | |
265 | + &dev_attr_date.attr, | |
266 | + &dev_attr_fwrev.attr, | |
267 | + &dev_attr_hwrev.attr, | |
268 | + &dev_attr_manfid.attr, | |
269 | + &dev_attr_name.attr, | |
270 | + &dev_attr_oemid.attr, | |
271 | + &dev_attr_serial.attr, | |
272 | + NULL, | |
273 | +}; | |
274 | + | |
275 | +static struct attribute_group mmc_std_attr_group = { | |
276 | + .attrs = mmc_std_attrs, | |
277 | +}; | |
278 | + | |
279 | +static struct attribute_group *mmc_attr_groups[] = { | |
280 | + &mmc_std_attr_group, | |
281 | + NULL, | |
282 | +}; | |
283 | + | |
284 | +static struct device_type mmc_type = { | |
285 | + .groups = mmc_attr_groups, | |
286 | +}; | |
287 | + | |
251 | 288 | /* |
252 | 289 | * Handle the detection and initialisation of a card. |
253 | 290 | * |
... | ... | @@ -308,7 +345,7 @@ |
308 | 345 | /* |
309 | 346 | * Allocate card structure. |
310 | 347 | */ |
311 | - card = mmc_alloc_card(host); | |
348 | + card = mmc_alloc_card(host, &mmc_type); | |
312 | 349 | if (IS_ERR(card)) { |
313 | 350 | err = PTR_ERR(card); |
314 | 351 | goto err; |
... | ... | @@ -459,53 +496,6 @@ |
459 | 496 | } |
460 | 497 | } |
461 | 498 | |
462 | -MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | |
463 | - card->raw_cid[2], card->raw_cid[3]); | |
464 | -MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |
465 | - card->raw_csd[2], card->raw_csd[3]); | |
466 | -MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year); | |
467 | -MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev); | |
468 | -MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev); | |
469 | -MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid); | |
470 | -MMC_ATTR_FN(name, "%s\n", card->cid.prod_name); | |
471 | -MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid); | |
472 | -MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial); | |
473 | - | |
474 | -static struct device_attribute mmc_dev_attrs[] = { | |
475 | - MMC_ATTR_RO(cid), | |
476 | - MMC_ATTR_RO(csd), | |
477 | - MMC_ATTR_RO(date), | |
478 | - MMC_ATTR_RO(fwrev), | |
479 | - MMC_ATTR_RO(hwrev), | |
480 | - MMC_ATTR_RO(manfid), | |
481 | - MMC_ATTR_RO(name), | |
482 | - MMC_ATTR_RO(oemid), | |
483 | - MMC_ATTR_RO(serial), | |
484 | - __ATTR_NULL, | |
485 | -}; | |
486 | - | |
487 | -/* | |
488 | - * Adds sysfs entries as relevant. | |
489 | - */ | |
490 | -static int mmc_sysfs_add(struct mmc_host *host, struct mmc_card *card) | |
491 | -{ | |
492 | - int ret; | |
493 | - | |
494 | - ret = mmc_add_attrs(card, mmc_dev_attrs); | |
495 | - if (ret < 0) | |
496 | - return ret; | |
497 | - | |
498 | - return 0; | |
499 | -} | |
500 | - | |
501 | -/* | |
502 | - * Removes the sysfs entries added by mmc_sysfs_add(). | |
503 | - */ | |
504 | -static void mmc_sysfs_remove(struct mmc_host *host, struct mmc_card *card) | |
505 | -{ | |
506 | - mmc_remove_attrs(card, mmc_dev_attrs); | |
507 | -} | |
508 | - | |
509 | 499 | #ifdef CONFIG_MMC_UNSAFE_RESUME |
510 | 500 | |
511 | 501 | /* |
... | ... | @@ -560,8 +550,6 @@ |
560 | 550 | static const struct mmc_bus_ops mmc_ops = { |
561 | 551 | .remove = mmc_remove, |
562 | 552 | .detect = mmc_detect, |
563 | - .sysfs_add = mmc_sysfs_add, | |
564 | - .sysfs_remove = mmc_sysfs_remove, | |
565 | 553 | .suspend = mmc_suspend, |
566 | 554 | .resume = mmc_resume, |
567 | 555 | }; |
drivers/mmc/core/sd.c
... | ... | @@ -18,7 +18,6 @@ |
18 | 18 | #include <linux/mmc/sd.h> |
19 | 19 | |
20 | 20 | #include "core.h" |
21 | -#include "sysfs.h" | |
22 | 21 | #include "bus.h" |
23 | 22 | #include "mmc_ops.h" |
24 | 23 | #include "sd_ops.h" |
... | ... | @@ -283,6 +282,47 @@ |
283 | 282 | return err; |
284 | 283 | } |
285 | 284 | |
285 | +MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | |
286 | + card->raw_cid[2], card->raw_cid[3]); | |
287 | +MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |
288 | + card->raw_csd[2], card->raw_csd[3]); | |
289 | +MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); | |
290 | +MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | |
291 | +MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | |
292 | +MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | |
293 | +MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | |
294 | +MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); | |
295 | +MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); | |
296 | +MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); | |
297 | + | |
298 | + | |
299 | +static struct attribute *sd_std_attrs[] = { | |
300 | + &dev_attr_cid.attr, | |
301 | + &dev_attr_csd.attr, | |
302 | + &dev_attr_scr.attr, | |
303 | + &dev_attr_date.attr, | |
304 | + &dev_attr_fwrev.attr, | |
305 | + &dev_attr_hwrev.attr, | |
306 | + &dev_attr_manfid.attr, | |
307 | + &dev_attr_name.attr, | |
308 | + &dev_attr_oemid.attr, | |
309 | + &dev_attr_serial.attr, | |
310 | + NULL, | |
311 | +}; | |
312 | + | |
313 | +static struct attribute_group sd_std_attr_group = { | |
314 | + .attrs = sd_std_attrs, | |
315 | +}; | |
316 | + | |
317 | +static struct attribute_group *sd_attr_groups[] = { | |
318 | + &sd_std_attr_group, | |
319 | + NULL, | |
320 | +}; | |
321 | + | |
322 | +static struct device_type sd_type = { | |
323 | + .groups = sd_attr_groups, | |
324 | +}; | |
325 | + | |
286 | 326 | /* |
287 | 327 | * Handle the detection and initialisation of a card. |
288 | 328 | * |
... | ... | @@ -352,7 +392,7 @@ |
352 | 392 | /* |
353 | 393 | * Allocate card structure. |
354 | 394 | */ |
355 | - card = mmc_alloc_card(host); | |
395 | + card = mmc_alloc_card(host, &sd_type); | |
356 | 396 | if (IS_ERR(card)) { |
357 | 397 | err = PTR_ERR(card); |
358 | 398 | goto err; |
... | ... | @@ -518,55 +558,6 @@ |
518 | 558 | } |
519 | 559 | } |
520 | 560 | |
521 | -MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | |
522 | - card->raw_cid[2], card->raw_cid[3]); | |
523 | -MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | |
524 | - card->raw_csd[2], card->raw_csd[3]); | |
525 | -MMC_ATTR_FN(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); | |
526 | -MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year); | |
527 | -MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev); | |
528 | -MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev); | |
529 | -MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid); | |
530 | -MMC_ATTR_FN(name, "%s\n", card->cid.prod_name); | |
531 | -MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid); | |
532 | -MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial); | |
533 | - | |
534 | -static struct device_attribute mmc_sd_dev_attrs[] = { | |
535 | - MMC_ATTR_RO(cid), | |
536 | - MMC_ATTR_RO(csd), | |
537 | - MMC_ATTR_RO(scr), | |
538 | - MMC_ATTR_RO(date), | |
539 | - MMC_ATTR_RO(fwrev), | |
540 | - MMC_ATTR_RO(hwrev), | |
541 | - MMC_ATTR_RO(manfid), | |
542 | - MMC_ATTR_RO(name), | |
543 | - MMC_ATTR_RO(oemid), | |
544 | - MMC_ATTR_RO(serial), | |
545 | - __ATTR_NULL, | |
546 | -}; | |
547 | - | |
548 | -/* | |
549 | - * Adds sysfs entries as relevant. | |
550 | - */ | |
551 | -static int mmc_sd_sysfs_add(struct mmc_host *host, struct mmc_card *card) | |
552 | -{ | |
553 | - int ret; | |
554 | - | |
555 | - ret = mmc_add_attrs(card, mmc_sd_dev_attrs); | |
556 | - if (ret < 0) | |
557 | - return ret; | |
558 | - | |
559 | - return 0; | |
560 | -} | |
561 | - | |
562 | -/* | |
563 | - * Removes the sysfs entries added by mmc_sysfs_add(). | |
564 | - */ | |
565 | -static void mmc_sd_sysfs_remove(struct mmc_host *host, struct mmc_card *card) | |
566 | -{ | |
567 | - mmc_remove_attrs(card, mmc_sd_dev_attrs); | |
568 | -} | |
569 | - | |
570 | 561 | #ifdef CONFIG_MMC_UNSAFE_RESUME |
571 | 562 | |
572 | 563 | /* |
... | ... | @@ -621,8 +612,6 @@ |
621 | 612 | static const struct mmc_bus_ops mmc_sd_ops = { |
622 | 613 | .remove = mmc_sd_remove, |
623 | 614 | .detect = mmc_sd_detect, |
624 | - .sysfs_add = mmc_sd_sysfs_add, | |
625 | - .sysfs_remove = mmc_sd_sysfs_remove, | |
626 | 615 | .suspend = mmc_sd_suspend, |
627 | 616 | .resume = mmc_sd_resume, |
628 | 617 | }; |
drivers/mmc/core/sdio.c
drivers/mmc/core/sysfs.c
1 | -/* | |
2 | - * linux/drivers/mmc/core/sysfs.c | |
3 | - * | |
4 | - * Copyright (C) 2003 Russell King, All Rights Reserved. | |
5 | - * Copyright 2007 Pierre Ossman | |
6 | - * | |
7 | - * This program is free software; you can redistribute it and/or modify | |
8 | - * it under the terms of the GNU General Public License version 2 as | |
9 | - * published by the Free Software Foundation. | |
10 | - * | |
11 | - * MMC sysfs/driver model support. | |
12 | - */ | |
13 | -#include <linux/device.h> | |
14 | - | |
15 | -#include <linux/mmc/card.h> | |
16 | - | |
17 | -#include "sysfs.h" | |
18 | - | |
19 | -int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs) | |
20 | -{ | |
21 | - int error = 0; | |
22 | - int i; | |
23 | - | |
24 | - for (i = 0; attr_name(attrs[i]); i++) { | |
25 | - error = device_create_file(&card->dev, &attrs[i]); | |
26 | - if (error) { | |
27 | - while (--i >= 0) | |
28 | - device_remove_file(&card->dev, &attrs[i]); | |
29 | - break; | |
30 | - } | |
31 | - } | |
32 | - | |
33 | - return error; | |
34 | -} | |
35 | - | |
36 | -void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs) | |
37 | -{ | |
38 | - int i; | |
39 | - | |
40 | - for (i = 0; attr_name(attrs[i]); i++) | |
41 | - device_remove_file(&card->dev, &attrs[i]); | |
42 | -} |
drivers/mmc/core/sysfs.h
1 | -/* | |
2 | - * linux/drivers/mmc/core/sysfs.h | |
3 | - * | |
4 | - * Copyright (C) 2003 Russell King, All Rights Reserved. | |
5 | - * Copyright 2007 Pierre Ossman | |
6 | - * | |
7 | - * This program is free software; you can redistribute it and/or modify | |
8 | - * it under the terms of the GNU General Public License version 2 as | |
9 | - * published by the Free Software Foundation. | |
10 | - */ | |
11 | -#ifndef _MMC_CORE_SYSFS_H | |
12 | -#define _MMC_CORE_SYSFS_H | |
13 | - | |
14 | -#define MMC_ATTR_FN(name, fmt, args...) \ | |
15 | -static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ | |
16 | -{ \ | |
17 | - struct mmc_card *card = container_of(dev, struct mmc_card, dev);\ | |
18 | - return sprintf(buf, fmt, args); \ | |
19 | -} | |
20 | - | |
21 | -#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL) | |
22 | - | |
23 | -int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs); | |
24 | -void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs); | |
25 | - | |
26 | -#endif |