diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/card/block.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c | 79 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mxcmmc.c | 2 |
6 files changed, 76 insertions, 13 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index adc205c49fbf..85f0e8cd875b 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -130,7 +130,7 @@ mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | static struct block_device_operations mmc_bdops = { | 133 | static const struct block_device_operations mmc_bdops = { |
134 | .open = mmc_blk_open, | 134 | .open = mmc_blk_open, |
135 | .release = mmc_blk_release, | 135 | .release = mmc_blk_release, |
136 | .getgeo = mmc_blk_getgeo, | 136 | .getgeo = mmc_blk_getgeo, |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 06084dbf1277..2fb9d5f271ea 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -276,7 +276,7 @@ static struct attribute_group mmc_std_attr_group = { | |||
276 | .attrs = mmc_std_attrs, | 276 | .attrs = mmc_std_attrs, |
277 | }; | 277 | }; |
278 | 278 | ||
279 | static struct attribute_group *mmc_attr_groups[] = { | 279 | static const struct attribute_group *mmc_attr_groups[] = { |
280 | &mmc_std_attr_group, | 280 | &mmc_std_attr_group, |
281 | NULL, | 281 | NULL, |
282 | }; | 282 | }; |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index cd81c395e164..7ad646fe077e 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -314,7 +314,7 @@ static struct attribute_group sd_std_attr_group = { | |||
314 | .attrs = sd_std_attrs, | 314 | .attrs = sd_std_attrs, |
315 | }; | 315 | }; |
316 | 316 | ||
317 | static struct attribute_group *sd_attr_groups[] = { | 317 | static const struct attribute_group *sd_attr_groups[] = { |
318 | &sd_std_attr_group, | 318 | &sd_std_attr_group, |
319 | NULL, | 319 | NULL, |
320 | }; | 320 | }; |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index e1aa8471ab1c..8741d0f5146a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/amba/bus.h> | 21 | #include <linux/amba/bus.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
24 | #include <linux/gpio.h> | ||
24 | 25 | ||
25 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
26 | #include <asm/div64.h> | 27 | #include <asm/div64.h> |
@@ -430,7 +431,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
430 | clk = 255; | 431 | clk = 255; |
431 | host->cclk = host->mclk / (2 * (clk + 1)); | 432 | host->cclk = host->mclk / (2 * (clk + 1)); |
432 | } | 433 | } |
433 | if (host->hw_designer == 0x80) | 434 | if (host->hw_designer == AMBA_VENDOR_ST) |
434 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ | 435 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ |
435 | clk |= MCI_CLK_ENABLE; | 436 | clk |= MCI_CLK_ENABLE; |
436 | } | 437 | } |
@@ -443,7 +444,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
443 | break; | 444 | break; |
444 | case MMC_POWER_UP: | 445 | case MMC_POWER_UP: |
445 | /* The ST version does not have this, fall through to POWER_ON */ | 446 | /* The ST version does not have this, fall through to POWER_ON */ |
446 | if (host->hw_designer != 0x80) { | 447 | if (host->hw_designer != AMBA_VENDOR_ST) { |
447 | pwr |= MCI_PWR_UP; | 448 | pwr |= MCI_PWR_UP; |
448 | break; | 449 | break; |
449 | } | 450 | } |
@@ -453,7 +454,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
453 | } | 454 | } |
454 | 455 | ||
455 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { | 456 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { |
456 | if (host->hw_designer != 0x80) | 457 | if (host->hw_designer != AMBA_VENDOR_ST) |
457 | pwr |= MCI_ROD; | 458 | pwr |= MCI_ROD; |
458 | else { | 459 | else { |
459 | /* | 460 | /* |
@@ -472,17 +473,41 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
472 | } | 473 | } |
473 | } | 474 | } |
474 | 475 | ||
476 | static int mmci_get_ro(struct mmc_host *mmc) | ||
477 | { | ||
478 | struct mmci_host *host = mmc_priv(mmc); | ||
479 | |||
480 | if (host->gpio_wp == -ENOSYS) | ||
481 | return -ENOSYS; | ||
482 | |||
483 | return gpio_get_value(host->gpio_wp); | ||
484 | } | ||
485 | |||
486 | static int mmci_get_cd(struct mmc_host *mmc) | ||
487 | { | ||
488 | struct mmci_host *host = mmc_priv(mmc); | ||
489 | unsigned int status; | ||
490 | |||
491 | if (host->gpio_cd == -ENOSYS) | ||
492 | status = host->plat->status(mmc_dev(host->mmc)); | ||
493 | else | ||
494 | status = gpio_get_value(host->gpio_cd); | ||
495 | |||
496 | return !status; | ||
497 | } | ||
498 | |||
475 | static const struct mmc_host_ops mmci_ops = { | 499 | static const struct mmc_host_ops mmci_ops = { |
476 | .request = mmci_request, | 500 | .request = mmci_request, |
477 | .set_ios = mmci_set_ios, | 501 | .set_ios = mmci_set_ios, |
502 | .get_ro = mmci_get_ro, | ||
503 | .get_cd = mmci_get_cd, | ||
478 | }; | 504 | }; |
479 | 505 | ||
480 | static void mmci_check_status(unsigned long data) | 506 | static void mmci_check_status(unsigned long data) |
481 | { | 507 | { |
482 | struct mmci_host *host = (struct mmci_host *)data; | 508 | struct mmci_host *host = (struct mmci_host *)data; |
483 | unsigned int status; | 509 | unsigned int status = mmci_get_cd(host->mmc); |
484 | 510 | ||
485 | status = host->plat->status(mmc_dev(host->mmc)); | ||
486 | if (status ^ host->oldstat) | 511 | if (status ^ host->oldstat) |
487 | mmc_detect_change(host->mmc, 0); | 512 | mmc_detect_change(host->mmc, 0); |
488 | 513 | ||
@@ -515,12 +540,15 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
515 | 540 | ||
516 | host = mmc_priv(mmc); | 541 | host = mmc_priv(mmc); |
517 | host->mmc = mmc; | 542 | host->mmc = mmc; |
518 | /* Bits 12 thru 19 is the designer */ | 543 | |
519 | host->hw_designer = (dev->periphid >> 12) & 0xff; | 544 | host->gpio_wp = -ENOSYS; |
520 | /* Bits 20 thru 23 is the revison */ | 545 | host->gpio_cd = -ENOSYS; |
521 | host->hw_revision = (dev->periphid >> 20) & 0xf; | 546 | |
547 | host->hw_designer = amba_manf(dev); | ||
548 | host->hw_revision = amba_rev(dev); | ||
522 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); | 549 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); |
523 | DBG(host, "revision = 0x%01x\n", host->hw_revision); | 550 | DBG(host, "revision = 0x%01x\n", host->hw_revision); |
551 | |||
524 | host->clk = clk_get(&dev->dev, NULL); | 552 | host->clk = clk_get(&dev->dev, NULL); |
525 | if (IS_ERR(host->clk)) { | 553 | if (IS_ERR(host->clk)) { |
526 | ret = PTR_ERR(host->clk); | 554 | ret = PTR_ERR(host->clk); |
@@ -591,6 +619,27 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
591 | writel(0, host->base + MMCIMASK1); | 619 | writel(0, host->base + MMCIMASK1); |
592 | writel(0xfff, host->base + MMCICLEAR); | 620 | writel(0xfff, host->base + MMCICLEAR); |
593 | 621 | ||
622 | #ifdef CONFIG_GPIOLIB | ||
623 | if (gpio_is_valid(plat->gpio_cd)) { | ||
624 | ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); | ||
625 | if (ret == 0) | ||
626 | ret = gpio_direction_input(plat->gpio_cd); | ||
627 | if (ret == 0) | ||
628 | host->gpio_cd = plat->gpio_cd; | ||
629 | else if (ret != -ENOSYS) | ||
630 | goto err_gpio_cd; | ||
631 | } | ||
632 | if (gpio_is_valid(plat->gpio_wp)) { | ||
633 | ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); | ||
634 | if (ret == 0) | ||
635 | ret = gpio_direction_input(plat->gpio_wp); | ||
636 | if (ret == 0) | ||
637 | host->gpio_wp = plat->gpio_wp; | ||
638 | else if (ret != -ENOSYS) | ||
639 | goto err_gpio_wp; | ||
640 | } | ||
641 | #endif | ||
642 | |||
594 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); | 643 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); |
595 | if (ret) | 644 | if (ret) |
596 | goto unmap; | 645 | goto unmap; |
@@ -602,6 +651,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
602 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | 651 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); |
603 | 652 | ||
604 | amba_set_drvdata(dev, mmc); | 653 | amba_set_drvdata(dev, mmc); |
654 | host->oldstat = mmci_get_cd(host->mmc); | ||
605 | 655 | ||
606 | mmc_add_host(mmc); | 656 | mmc_add_host(mmc); |
607 | 657 | ||
@@ -620,6 +670,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
620 | irq0_free: | 670 | irq0_free: |
621 | free_irq(dev->irq[0], host); | 671 | free_irq(dev->irq[0], host); |
622 | unmap: | 672 | unmap: |
673 | if (host->gpio_wp != -ENOSYS) | ||
674 | gpio_free(host->gpio_wp); | ||
675 | err_gpio_wp: | ||
676 | if (host->gpio_cd != -ENOSYS) | ||
677 | gpio_free(host->gpio_cd); | ||
678 | err_gpio_cd: | ||
623 | iounmap(host->base); | 679 | iounmap(host->base); |
624 | clk_disable: | 680 | clk_disable: |
625 | clk_disable(host->clk); | 681 | clk_disable(host->clk); |
@@ -655,6 +711,11 @@ static int __devexit mmci_remove(struct amba_device *dev) | |||
655 | free_irq(dev->irq[0], host); | 711 | free_irq(dev->irq[0], host); |
656 | free_irq(dev->irq[1], host); | 712 | free_irq(dev->irq[1], host); |
657 | 713 | ||
714 | if (host->gpio_wp != -ENOSYS) | ||
715 | gpio_free(host->gpio_wp); | ||
716 | if (host->gpio_cd != -ENOSYS) | ||
717 | gpio_free(host->gpio_cd); | ||
718 | |||
658 | iounmap(host->base); | 719 | iounmap(host->base); |
659 | clk_disable(host->clk); | 720 | clk_disable(host->clk); |
660 | clk_put(host->clk); | 721 | clk_put(host->clk); |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 0441bac1c0ec..839f264c9725 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -151,6 +151,8 @@ struct mmci_host { | |||
151 | struct mmc_data *data; | 151 | struct mmc_data *data; |
152 | struct mmc_host *mmc; | 152 | struct mmc_host *mmc; |
153 | struct clk *clk; | 153 | struct clk *clk; |
154 | int gpio_cd; | ||
155 | int gpio_wp; | ||
154 | 156 | ||
155 | unsigned int data_xfered; | 157 | unsigned int data_xfered; |
156 | 158 | ||
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index bc14bb1b0579..88671529c45d 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -512,7 +512,7 @@ static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) | |||
512 | } | 512 | } |
513 | 513 | ||
514 | /* For the DMA case the DMA engine handles the data transfer | 514 | /* For the DMA case the DMA engine handles the data transfer |
515 | * automatically. For non DMA we have to to it ourselves. | 515 | * automatically. For non DMA we have to do it ourselves. |
516 | * Don't do it in interrupt context though. | 516 | * Don't do it in interrupt context though. |
517 | */ | 517 | */ |
518 | if (!mxcmci_use_dma(host) && host->data) | 518 | if (!mxcmci_use_dma(host) && host->data) |