aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mxs-mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mxs-mmc.c')
-rw-r--r--drivers/mmc/host/mxs-mmc.c60
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
79static int mxs_mmc_get_ro(struct mmc_host *mmc) 75static 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
95static 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
105static int mxs_mmc_reset(struct mxs_mmc_host *host) 94static 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
550static const struct mmc_host_ops mxs_mmc_ops = { 539static 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;