aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/host.c')
-rw-r--r--drivers/mmc/core/host.c65
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
37static DEFINE_IDR(mmc_host_idr);
38static DEFINE_SPINLOCK(mmc_host_lock);
39
35static void mmc_host_classdev_release(struct device *dev) 40static 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
57static DEFINE_IDR(mmc_host_idr);
58static DEFINE_SPINLOCK(mmc_host_lock);
59
60#ifdef CONFIG_MMC_CLKGATE 64#ifdef CONFIG_MMC_CLKGATE
61static ssize_t clkgate_delay_show(struct device *dev, 65static 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
462out:
463 mmc_gpio_free_cd(host);
464 return ret;
465} 453}
466 454
467EXPORT_SYMBOL(mmc_of_parse); 455EXPORT_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
529free:
530 kfree(host);
531 return NULL;
532} 520}
533 521
534EXPORT_SYMBOL(mmc_alloc_host); 522EXPORT_SYMBOL(mmc_alloc_host);
@@ -601,10 +589,7 @@ EXPORT_SYMBOL(mmc_remove_host);
601 */ 589 */
602void mmc_free_host(struct mmc_host *host) 590void 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