diff options
Diffstat (limited to 'drivers/mmc/host/mxs-mmc.c')
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 60 |
1 files changed, 18 insertions, 42 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 50fc9df791b2..073e871a0fc8 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/mmc/host.h> | 38 | #include <linux/mmc/host.h> |
39 | #include <linux/mmc/mmc.h> | 39 | #include <linux/mmc/mmc.h> |
40 | #include <linux/mmc/sdio.h> | 40 | #include <linux/mmc/sdio.h> |
41 | #include <linux/mmc/slot-gpio.h> | ||
41 | #include <linux/gpio.h> | 42 | #include <linux/gpio.h> |
42 | #include <linux/regulator/consumer.h> | 43 | #include <linux/regulator/consumer.h> |
43 | #include <linux/module.h> | 44 | #include <linux/module.h> |
@@ -69,37 +70,25 @@ struct mxs_mmc_host { | |||
69 | unsigned char bus_width; | 70 | unsigned char bus_width; |
70 | spinlock_t lock; | 71 | spinlock_t lock; |
71 | int sdio_irq_en; | 72 | int sdio_irq_en; |
72 | int wp_gpio; | ||
73 | bool wp_inverted; | ||
74 | bool cd_inverted; | ||
75 | bool broken_cd; | ||
76 | bool non_removable; | ||
77 | }; | 73 | }; |
78 | 74 | ||
79 | static int mxs_mmc_get_ro(struct mmc_host *mmc) | 75 | static int mxs_mmc_get_cd(struct mmc_host *mmc) |
80 | { | 76 | { |
81 | struct mxs_mmc_host *host = mmc_priv(mmc); | 77 | struct mxs_mmc_host *host = mmc_priv(mmc); |
82 | int ret; | 78 | struct mxs_ssp *ssp = &host->ssp; |
83 | 79 | int present, ret; | |
84 | if (!gpio_is_valid(host->wp_gpio)) | ||
85 | return -EINVAL; | ||
86 | |||
87 | ret = gpio_get_value(host->wp_gpio); | ||
88 | 80 | ||
89 | if (host->wp_inverted) | 81 | ret = mmc_gpio_get_cd(mmc); |
90 | ret = !ret; | 82 | if (ret >= 0) |
83 | return ret; | ||
91 | 84 | ||
92 | return ret; | 85 | present = !(readl(ssp->base + HW_SSP_STATUS(ssp)) & |
93 | } | 86 | BM_SSP_STATUS_CARD_DETECT); |
94 | 87 | ||
95 | static int mxs_mmc_get_cd(struct mmc_host *mmc) | 88 | if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) |
96 | { | 89 | present = !present; |
97 | struct mxs_mmc_host *host = mmc_priv(mmc); | ||
98 | struct mxs_ssp *ssp = &host->ssp; | ||
99 | 90 | ||
100 | return host->non_removable || host->broken_cd || | 91 | return present; |
101 | !(readl(ssp->base + HW_SSP_STATUS(ssp)) & | ||
102 | BM_SSP_STATUS_CARD_DETECT) ^ host->cd_inverted; | ||
103 | } | 92 | } |
104 | 93 | ||
105 | static int mxs_mmc_reset(struct mxs_mmc_host *host) | 94 | static int mxs_mmc_reset(struct mxs_mmc_host *host) |
@@ -549,7 +538,7 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
549 | 538 | ||
550 | static const struct mmc_host_ops mxs_mmc_ops = { | 539 | static const struct mmc_host_ops mxs_mmc_ops = { |
551 | .request = mxs_mmc_request, | 540 | .request = mxs_mmc_request, |
552 | .get_ro = mxs_mmc_get_ro, | 541 | .get_ro = mmc_gpio_get_ro, |
553 | .get_cd = mxs_mmc_get_cd, | 542 | .get_cd = mxs_mmc_get_cd, |
554 | .set_ios = mxs_mmc_set_ios, | 543 | .set_ios = mxs_mmc_set_ios, |
555 | .enable_sdio_irq = mxs_mmc_enable_sdio_irq, | 544 | .enable_sdio_irq = mxs_mmc_enable_sdio_irq, |
@@ -579,15 +568,12 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
579 | { | 568 | { |
580 | const struct of_device_id *of_id = | 569 | const struct of_device_id *of_id = |
581 | of_match_device(mxs_mmc_dt_ids, &pdev->dev); | 570 | of_match_device(mxs_mmc_dt_ids, &pdev->dev); |
582 | struct device_node *np = pdev->dev.of_node; | ||
583 | struct mxs_mmc_host *host; | 571 | struct mxs_mmc_host *host; |
584 | struct mmc_host *mmc; | 572 | struct mmc_host *mmc; |
585 | struct resource *iores; | 573 | struct resource *iores; |
586 | int ret = 0, irq_err; | 574 | int ret = 0, irq_err; |
587 | struct regulator *reg_vmmc; | 575 | struct regulator *reg_vmmc; |
588 | enum of_gpio_flags flags; | ||
589 | struct mxs_ssp *ssp; | 576 | struct mxs_ssp *ssp; |
590 | u32 bus_width = 0; | ||
591 | 577 | ||
592 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 578 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
593 | irq_err = platform_get_irq(pdev, 0); | 579 | irq_err = platform_get_irq(pdev, 0); |
@@ -648,23 +634,13 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
648 | mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | | 634 | mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | |
649 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; | 635 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; |
650 | 636 | ||
651 | of_property_read_u32(np, "bus-width", &bus_width); | ||
652 | if (bus_width == 4) | ||
653 | mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
654 | else if (bus_width == 8) | ||
655 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; | ||
656 | host->broken_cd = of_property_read_bool(np, "broken-cd"); | ||
657 | host->non_removable = of_property_read_bool(np, "non-removable"); | ||
658 | if (host->non_removable) | ||
659 | mmc->caps |= MMC_CAP_NONREMOVABLE; | ||
660 | host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags); | ||
661 | if (flags & OF_GPIO_ACTIVE_LOW) | ||
662 | host->wp_inverted = 1; | ||
663 | |||
664 | host->cd_inverted = of_property_read_bool(np, "cd-inverted"); | ||
665 | |||
666 | mmc->f_min = 400000; | 637 | mmc->f_min = 400000; |
667 | mmc->f_max = 288000000; | 638 | mmc->f_max = 288000000; |
639 | |||
640 | ret = mmc_of_parse(mmc); | ||
641 | if (ret) | ||
642 | goto out_clk_disable; | ||
643 | |||
668 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 644 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
669 | 645 | ||
670 | mmc->max_segs = 52; | 646 | mmc->max_segs = 52; |