diff options
Diffstat (limited to 'drivers/mmc/core/host.c')
-rw-r--r-- | drivers/mmc/core/host.c | 65 |
1 files changed, 25 insertions, 40 deletions
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 270d58a4c43d..8be0df758e68 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -29,13 +29,20 @@ | |||
29 | 29 | ||
30 | #include "core.h" | 30 | #include "core.h" |
31 | #include "host.h" | 31 | #include "host.h" |
32 | #include "slot-gpio.h" | ||
33 | #include "pwrseq.h" | ||
32 | 34 | ||
33 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) | 35 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) |
34 | 36 | ||
37 | static DEFINE_IDR(mmc_host_idr); | ||
38 | static DEFINE_SPINLOCK(mmc_host_lock); | ||
39 | |||
35 | static void mmc_host_classdev_release(struct device *dev) | 40 | static void mmc_host_classdev_release(struct device *dev) |
36 | { | 41 | { |
37 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | 42 | struct mmc_host *host = cls_dev_to_mmc_host(dev); |
38 | mutex_destroy(&host->slot.lock); | 43 | spin_lock(&mmc_host_lock); |
44 | idr_remove(&mmc_host_idr, host->index); | ||
45 | spin_unlock(&mmc_host_lock); | ||
39 | kfree(host); | 46 | kfree(host); |
40 | } | 47 | } |
41 | 48 | ||
@@ -54,9 +61,6 @@ void mmc_unregister_host_class(void) | |||
54 | class_unregister(&mmc_host_class); | 61 | class_unregister(&mmc_host_class); |
55 | } | 62 | } |
56 | 63 | ||
57 | static DEFINE_IDR(mmc_host_idr); | ||
58 | static DEFINE_SPINLOCK(mmc_host_lock); | ||
59 | |||
60 | #ifdef CONFIG_MMC_CLKGATE | 64 | #ifdef CONFIG_MMC_CLKGATE |
61 | static ssize_t clkgate_delay_show(struct device *dev, | 65 | static ssize_t clkgate_delay_show(struct device *dev, |
62 | struct device_attribute *attr, char *buf) | 66 | struct device_attribute *attr, char *buf) |
@@ -367,16 +371,10 @@ int mmc_of_parse(struct mmc_host *host) | |||
367 | 371 | ||
368 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, | 372 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, |
369 | 0, &cd_gpio_invert); | 373 | 0, &cd_gpio_invert); |
370 | if (ret) { | 374 | if (!ret) |
371 | if (ret == -EPROBE_DEFER) | ||
372 | return ret; | ||
373 | if (ret != -ENOENT) { | ||
374 | dev_err(host->parent, | ||
375 | "Failed to request CD GPIO: %d\n", | ||
376 | ret); | ||
377 | } | ||
378 | } else | ||
379 | dev_info(host->parent, "Got CD GPIO\n"); | 375 | dev_info(host->parent, "Got CD GPIO\n"); |
376 | else if (ret != -ENOENT) | ||
377 | return ret; | ||
380 | 378 | ||
381 | /* | 379 | /* |
382 | * There are two ways to flag that the CD line is inverted: | 380 | * There are two ways to flag that the CD line is inverted: |
@@ -397,16 +395,10 @@ int mmc_of_parse(struct mmc_host *host) | |||
397 | ro_cap_invert = of_property_read_bool(np, "wp-inverted"); | 395 | ro_cap_invert = of_property_read_bool(np, "wp-inverted"); |
398 | 396 | ||
399 | ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert); | 397 | ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert); |
400 | if (ret) { | 398 | if (!ret) |
401 | if (ret == -EPROBE_DEFER) | ||
402 | goto out; | ||
403 | if (ret != -ENOENT) { | ||
404 | dev_err(host->parent, | ||
405 | "Failed to request WP GPIO: %d\n", | ||
406 | ret); | ||
407 | } | ||
408 | } else | ||
409 | dev_info(host->parent, "Got WP GPIO\n"); | 399 | dev_info(host->parent, "Got WP GPIO\n"); |
400 | else if (ret != -ENOENT) | ||
401 | return ret; | ||
410 | 402 | ||
411 | /* See the comment on CD inversion above */ | 403 | /* See the comment on CD inversion above */ |
412 | if (ro_cap_invert ^ ro_gpio_invert) | 404 | if (ro_cap_invert ^ ro_gpio_invert) |
@@ -457,11 +449,7 @@ int mmc_of_parse(struct mmc_host *host) | |||
457 | host->dsr_req = 0; | 449 | host->dsr_req = 0; |
458 | } | 450 | } |
459 | 451 | ||
460 | return 0; | 452 | return mmc_pwrseq_alloc(host); |
461 | |||
462 | out: | ||
463 | mmc_gpio_free_cd(host); | ||
464 | return ret; | ||
465 | } | 453 | } |
466 | 454 | ||
467 | EXPORT_SYMBOL(mmc_of_parse); | 455 | EXPORT_SYMBOL(mmc_of_parse); |
@@ -491,8 +479,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
491 | host->index = err; | 479 | host->index = err; |
492 | spin_unlock(&mmc_host_lock); | 480 | spin_unlock(&mmc_host_lock); |
493 | idr_preload_end(); | 481 | idr_preload_end(); |
494 | if (err < 0) | 482 | if (err < 0) { |
495 | goto free; | 483 | kfree(host); |
484 | return NULL; | ||
485 | } | ||
496 | 486 | ||
497 | dev_set_name(&host->class_dev, "mmc%d", host->index); | 487 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
498 | 488 | ||
@@ -501,10 +491,12 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
501 | host->class_dev.class = &mmc_host_class; | 491 | host->class_dev.class = &mmc_host_class; |
502 | device_initialize(&host->class_dev); | 492 | device_initialize(&host->class_dev); |
503 | 493 | ||
504 | mmc_host_clk_init(host); | 494 | if (mmc_gpio_alloc(host)) { |
495 | put_device(&host->class_dev); | ||
496 | return NULL; | ||
497 | } | ||
505 | 498 | ||
506 | mutex_init(&host->slot.lock); | 499 | mmc_host_clk_init(host); |
507 | host->slot.cd_irq = -EINVAL; | ||
508 | 500 | ||
509 | spin_lock_init(&host->lock); | 501 | spin_lock_init(&host->lock); |
510 | init_waitqueue_head(&host->wq); | 502 | init_waitqueue_head(&host->wq); |
@@ -525,10 +517,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
525 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | 517 | host->max_blk_count = PAGE_CACHE_SIZE / 512; |
526 | 518 | ||
527 | return host; | 519 | return host; |
528 | |||
529 | free: | ||
530 | kfree(host); | ||
531 | return NULL; | ||
532 | } | 520 | } |
533 | 521 | ||
534 | EXPORT_SYMBOL(mmc_alloc_host); | 522 | EXPORT_SYMBOL(mmc_alloc_host); |
@@ -601,10 +589,7 @@ EXPORT_SYMBOL(mmc_remove_host); | |||
601 | */ | 589 | */ |
602 | void mmc_free_host(struct mmc_host *host) | 590 | void mmc_free_host(struct mmc_host *host) |
603 | { | 591 | { |
604 | spin_lock(&mmc_host_lock); | 592 | mmc_pwrseq_free(host); |
605 | idr_remove(&mmc_host_idr, host->index); | ||
606 | spin_unlock(&mmc_host_lock); | ||
607 | |||
608 | put_device(&host->class_dev); | 593 | put_device(&host->class_dev); |
609 | } | 594 | } |
610 | 595 | ||