diff options
| -rw-r--r-- | drivers/mmc/card/block.c | 34 | ||||
| -rw-r--r-- | drivers/mmc/card/mmc_test.c | 18 | ||||
| -rw-r--r-- | drivers/mmc/core/bus.c | 41 | ||||
| -rw-r--r-- | include/linux/mmc/card.h | 14 |
4 files changed, 69 insertions, 38 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 2fc426926574..2c25271f8c41 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -2418,9 +2418,8 @@ static const struct mmc_fixup blk_fixups[] = | |||
| 2418 | END_FIXUP | 2418 | END_FIXUP |
| 2419 | }; | 2419 | }; |
| 2420 | 2420 | ||
| 2421 | static int mmc_blk_probe(struct device *dev) | 2421 | static int mmc_blk_probe(struct mmc_card *card) |
| 2422 | { | 2422 | { |
| 2423 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
| 2424 | struct mmc_blk_data *md, *part_md; | 2423 | struct mmc_blk_data *md, *part_md; |
| 2425 | char cap_str[10]; | 2424 | char cap_str[10]; |
| 2426 | 2425 | ||
| @@ -2445,7 +2444,7 @@ static int mmc_blk_probe(struct device *dev) | |||
| 2445 | if (mmc_blk_alloc_parts(card, md)) | 2444 | if (mmc_blk_alloc_parts(card, md)) |
| 2446 | goto out; | 2445 | goto out; |
| 2447 | 2446 | ||
| 2448 | dev_set_drvdata(dev, md); | 2447 | dev_set_drvdata(&card->dev, md); |
| 2449 | 2448 | ||
| 2450 | if (mmc_add_disk(md)) | 2449 | if (mmc_add_disk(md)) |
| 2451 | goto out; | 2450 | goto out; |
| @@ -2475,10 +2474,9 @@ static int mmc_blk_probe(struct device *dev) | |||
| 2475 | return 0; | 2474 | return 0; |
| 2476 | } | 2475 | } |
| 2477 | 2476 | ||
| 2478 | static int mmc_blk_remove(struct device *dev) | 2477 | static void mmc_blk_remove(struct mmc_card *card) |
| 2479 | { | 2478 | { |
| 2480 | struct mmc_card *card = mmc_dev_to_card(dev); | 2479 | struct mmc_blk_data *md = dev_get_drvdata(&card->dev); |
| 2481 | struct mmc_blk_data *md = dev_get_drvdata(dev); | ||
| 2482 | 2480 | ||
| 2483 | mmc_blk_remove_parts(card, md); | 2481 | mmc_blk_remove_parts(card, md); |
| 2484 | pm_runtime_get_sync(&card->dev); | 2482 | pm_runtime_get_sync(&card->dev); |
| @@ -2489,15 +2487,13 @@ static int mmc_blk_remove(struct device *dev) | |||
| 2489 | pm_runtime_disable(&card->dev); | 2487 | pm_runtime_disable(&card->dev); |
| 2490 | pm_runtime_put_noidle(&card->dev); | 2488 | pm_runtime_put_noidle(&card->dev); |
| 2491 | mmc_blk_remove_req(md); | 2489 | mmc_blk_remove_req(md); |
| 2492 | dev_set_drvdata(dev, NULL); | 2490 | dev_set_drvdata(&card->dev, NULL); |
| 2493 | |||
| 2494 | return 0; | ||
| 2495 | } | 2491 | } |
| 2496 | 2492 | ||
| 2497 | static int _mmc_blk_suspend(struct device *dev) | 2493 | static int _mmc_blk_suspend(struct mmc_card *card) |
| 2498 | { | 2494 | { |
| 2499 | struct mmc_blk_data *part_md; | 2495 | struct mmc_blk_data *part_md; |
| 2500 | struct mmc_blk_data *md = dev_get_drvdata(dev); | 2496 | struct mmc_blk_data *md = dev_get_drvdata(&card->dev); |
| 2501 | 2497 | ||
| 2502 | if (md) { | 2498 | if (md) { |
| 2503 | mmc_queue_suspend(&md->queue); | 2499 | mmc_queue_suspend(&md->queue); |
| @@ -2508,15 +2504,17 @@ static int _mmc_blk_suspend(struct device *dev) | |||
| 2508 | return 0; | 2504 | return 0; |
| 2509 | } | 2505 | } |
| 2510 | 2506 | ||
| 2511 | static void mmc_blk_shutdown(struct device *dev) | 2507 | static void mmc_blk_shutdown(struct mmc_card *card) |
| 2512 | { | 2508 | { |
| 2513 | _mmc_blk_suspend(dev); | 2509 | _mmc_blk_suspend(card); |
| 2514 | } | 2510 | } |
| 2515 | 2511 | ||
| 2516 | #ifdef CONFIG_PM_SLEEP | 2512 | #ifdef CONFIG_PM_SLEEP |
| 2517 | static int mmc_blk_suspend(struct device *dev) | 2513 | static int mmc_blk_suspend(struct device *dev) |
| 2518 | { | 2514 | { |
| 2519 | return _mmc_blk_suspend(dev); | 2515 | struct mmc_card *card = mmc_dev_to_card(dev); |
| 2516 | |||
| 2517 | return _mmc_blk_suspend(card); | ||
| 2520 | } | 2518 | } |
| 2521 | 2519 | ||
| 2522 | static int mmc_blk_resume(struct device *dev) | 2520 | static int mmc_blk_resume(struct device *dev) |
| @@ -2541,9 +2539,11 @@ static int mmc_blk_resume(struct device *dev) | |||
| 2541 | 2539 | ||
| 2542 | static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume); | 2540 | static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume); |
| 2543 | 2541 | ||
| 2544 | static struct device_driver mmc_driver = { | 2542 | static struct mmc_driver mmc_driver = { |
| 2545 | .name = "mmcblk", | 2543 | .drv = { |
| 2546 | .pm = &mmc_blk_pm_ops, | 2544 | .name = "mmcblk", |
| 2545 | .pm = &mmc_blk_pm_ops, | ||
| 2546 | }, | ||
| 2547 | .probe = mmc_blk_probe, | 2547 | .probe = mmc_blk_probe, |
| 2548 | .remove = mmc_blk_remove, | 2548 | .remove = mmc_blk_remove, |
| 2549 | .shutdown = mmc_blk_shutdown, | 2549 | .shutdown = mmc_blk_shutdown, |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 7dac4695163b..53b741398b93 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <linux/mmc/host.h> | 14 | #include <linux/mmc/host.h> |
| 15 | #include <linux/mmc/mmc.h> | 15 | #include <linux/mmc/mmc.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/device.h> | ||
| 18 | 17 | ||
| 19 | #include <linux/scatterlist.h> | 18 | #include <linux/scatterlist.h> |
| 20 | #include <linux/swap.h> /* For nr_free_buffer_pages() */ | 19 | #include <linux/swap.h> /* For nr_free_buffer_pages() */ |
| @@ -2996,9 +2995,8 @@ err: | |||
| 2996 | return ret; | 2995 | return ret; |
| 2997 | } | 2996 | } |
| 2998 | 2997 | ||
| 2999 | static int mmc_test_probe(struct device *dev) | 2998 | static int mmc_test_probe(struct mmc_card *card) |
| 3000 | { | 2999 | { |
| 3001 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
| 3002 | int ret; | 3000 | int ret; |
| 3003 | 3001 | ||
| 3004 | if (!mmc_card_mmc(card) && !mmc_card_sd(card)) | 3002 | if (!mmc_card_mmc(card) && !mmc_card_sd(card)) |
| @@ -3013,22 +3011,20 @@ static int mmc_test_probe(struct device *dev) | |||
| 3013 | return 0; | 3011 | return 0; |
| 3014 | } | 3012 | } |
| 3015 | 3013 | ||
| 3016 | static int mmc_test_remove(struct device *dev) | 3014 | static void mmc_test_remove(struct mmc_card *card) |
| 3017 | { | 3015 | { |
| 3018 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
| 3019 | |||
| 3020 | mmc_test_free_result(card); | 3016 | mmc_test_free_result(card); |
| 3021 | mmc_test_free_dbgfs_file(card); | 3017 | mmc_test_free_dbgfs_file(card); |
| 3022 | |||
| 3023 | return 0; | ||
| 3024 | } | 3018 | } |
| 3025 | 3019 | ||
| 3026 | static void mmc_test_shutdown(struct device *dev) | 3020 | static void mmc_test_shutdown(struct mmc_card *card) |
| 3027 | { | 3021 | { |
| 3028 | } | 3022 | } |
| 3029 | 3023 | ||
| 3030 | static struct device_driver mmc_driver = { | 3024 | static struct mmc_driver mmc_driver = { |
| 3031 | .name = "mmc_test", | 3025 | .drv = { |
| 3026 | .name = "mmc_test", | ||
| 3027 | }, | ||
| 3032 | .probe = mmc_test_probe, | 3028 | .probe = mmc_test_probe, |
| 3033 | .remove = mmc_test_remove, | 3029 | .remove = mmc_test_remove, |
| 3034 | .shutdown = mmc_test_shutdown, | 3030 | .shutdown = mmc_test_shutdown, |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index c5ef10065a4a..972ff844cf5a 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include "sdio_cis.h" | 26 | #include "sdio_cis.h" |
| 27 | #include "bus.h" | 27 | #include "bus.h" |
| 28 | 28 | ||
| 29 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) | ||
| 30 | |||
| 29 | static ssize_t type_show(struct device *dev, | 31 | static ssize_t type_show(struct device *dev, |
| 30 | struct device_attribute *attr, char *buf) | 32 | struct device_attribute *attr, char *buf) |
| 31 | { | 33 | { |
| @@ -105,14 +107,33 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 105 | return retval; | 107 | return retval; |
| 106 | } | 108 | } |
| 107 | 109 | ||
| 110 | static int mmc_bus_probe(struct device *dev) | ||
| 111 | { | ||
| 112 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
| 113 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
| 114 | |||
| 115 | return drv->probe(card); | ||
| 116 | } | ||
| 117 | |||
| 118 | static int mmc_bus_remove(struct device *dev) | ||
| 119 | { | ||
| 120 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
| 121 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
| 122 | |||
| 123 | drv->remove(card); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 108 | static void mmc_bus_shutdown(struct device *dev) | 128 | static void mmc_bus_shutdown(struct device *dev) |
| 109 | { | 129 | { |
| 130 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
| 110 | struct mmc_card *card = mmc_dev_to_card(dev); | 131 | struct mmc_card *card = mmc_dev_to_card(dev); |
| 111 | struct mmc_host *host = card->host; | 132 | struct mmc_host *host = card->host; |
| 112 | int ret; | 133 | int ret; |
| 113 | 134 | ||
| 114 | if (dev->driver && dev->driver->shutdown) | 135 | if (dev->driver && drv->shutdown) |
| 115 | dev->driver->shutdown(dev); | 136 | drv->shutdown(card); |
| 116 | 137 | ||
| 117 | if (host->bus_ops->shutdown) { | 138 | if (host->bus_ops->shutdown) { |
| 118 | ret = host->bus_ops->shutdown(host); | 139 | ret = host->bus_ops->shutdown(host); |
| @@ -181,6 +202,8 @@ static struct bus_type mmc_bus_type = { | |||
| 181 | .dev_groups = mmc_dev_groups, | 202 | .dev_groups = mmc_dev_groups, |
| 182 | .match = mmc_bus_match, | 203 | .match = mmc_bus_match, |
| 183 | .uevent = mmc_bus_uevent, | 204 | .uevent = mmc_bus_uevent, |
| 205 | .probe = mmc_bus_probe, | ||
| 206 | .remove = mmc_bus_remove, | ||
| 184 | .shutdown = mmc_bus_shutdown, | 207 | .shutdown = mmc_bus_shutdown, |
| 185 | .pm = &mmc_bus_pm_ops, | 208 | .pm = &mmc_bus_pm_ops, |
| 186 | }; | 209 | }; |
| @@ -199,22 +222,24 @@ void mmc_unregister_bus(void) | |||
| 199 | * mmc_register_driver - register a media driver | 222 | * mmc_register_driver - register a media driver |
| 200 | * @drv: MMC media driver | 223 | * @drv: MMC media driver |
| 201 | */ | 224 | */ |
| 202 | int mmc_register_driver(struct device_driver *drv) | 225 | int mmc_register_driver(struct mmc_driver *drv) |
| 203 | { | 226 | { |
| 204 | drv->bus = &mmc_bus_type; | 227 | drv->drv.bus = &mmc_bus_type; |
| 205 | return driver_register(drv); | 228 | return driver_register(&drv->drv); |
| 206 | } | 229 | } |
| 230 | |||
| 207 | EXPORT_SYMBOL(mmc_register_driver); | 231 | EXPORT_SYMBOL(mmc_register_driver); |
| 208 | 232 | ||
| 209 | /** | 233 | /** |
| 210 | * mmc_unregister_driver - unregister a media driver | 234 | * mmc_unregister_driver - unregister a media driver |
| 211 | * @drv: MMC media driver | 235 | * @drv: MMC media driver |
| 212 | */ | 236 | */ |
| 213 | void mmc_unregister_driver(struct device_driver *drv) | 237 | void mmc_unregister_driver(struct mmc_driver *drv) |
| 214 | { | 238 | { |
| 215 | drv->bus = &mmc_bus_type; | 239 | drv->drv.bus = &mmc_bus_type; |
| 216 | driver_unregister(drv); | 240 | driver_unregister(&drv->drv); |
| 217 | } | 241 | } |
| 242 | |||
| 218 | EXPORT_SYMBOL(mmc_unregister_driver); | 243 | EXPORT_SYMBOL(mmc_unregister_driver); |
| 219 | 244 | ||
| 220 | static void mmc_release_card(struct device *dev) | 245 | static void mmc_release_card(struct device *dev) |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index a6cf4c063e4e..19f0175c0afa 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
| @@ -512,8 +512,18 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) | |||
| 512 | 512 | ||
| 513 | #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) | 513 | #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) |
| 514 | 514 | ||
| 515 | extern int mmc_register_driver(struct device_driver *); | 515 | /* |
| 516 | extern void mmc_unregister_driver(struct device_driver *); | 516 | * MMC device driver (e.g., Flash card, I/O card...) |
| 517 | */ | ||
| 518 | struct mmc_driver { | ||
| 519 | struct device_driver drv; | ||
| 520 | int (*probe)(struct mmc_card *); | ||
| 521 | void (*remove)(struct mmc_card *); | ||
| 522 | void (*shutdown)(struct mmc_card *); | ||
| 523 | }; | ||
| 524 | |||
| 525 | extern int mmc_register_driver(struct mmc_driver *); | ||
| 526 | extern void mmc_unregister_driver(struct mmc_driver *); | ||
| 517 | 527 | ||
| 518 | extern void mmc_fixup_device(struct mmc_card *card, | 528 | extern void mmc_fixup_device(struct mmc_card *card, |
| 519 | const struct mmc_fixup *table); | 529 | const struct mmc_fixup *table); |
