aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-07-09 10:16:07 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-07-09 10:16:07 -0400
commit89001446925d6da8785c3265a71316e34c6d15de (patch)
tree467acdeafd056c93456d4db33ada112ae804eabe /drivers/mmc
parent7fb2bbf4d9e7e62057184f1e061566459eef6c79 (diff)
MMC: MMCI: use gpiolib for card detect/write protect
Use gpiolib where available (and when valid GPIOs are provided) for write protect/card detect status reporting. We fall back to the old 'status' method where gpiolib support is not available. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmci.c63
-rw-r--r--drivers/mmc/host/mmci.h2
2 files changed, 63 insertions, 2 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index ac43f395eec0..5eb86a8c943b 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>
@@ -472,17 +473,41 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
472 } 473 }
473} 474}
474 475
476static 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
486static 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
475static const struct mmc_host_ops mmci_ops = { 499static 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
480static void mmci_check_status(unsigned long data) 506static 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
@@ -516,6 +541,9 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
516 host = mmc_priv(mmc); 541 host = mmc_priv(mmc);
517 host->mmc = mmc; 542 host->mmc = mmc;
518 543
544 host->gpio_wp = -ENOSYS;
545 host->gpio_cd = -ENOSYS;
546
519 host->hw_designer = amba_manf(dev); 547 host->hw_designer = amba_manf(dev);
520 host->hw_revision = amba_rev(dev); 548 host->hw_revision = amba_rev(dev);
521 DBG(host, "designer ID = 0x%02x\n", host->hw_designer); 549 DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
@@ -591,6 +619,25 @@ 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 if (gpio_is_valid(plat->gpio_cd)) {
623 ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
624 if (ret == 0)
625 ret = gpio_direction_input(plat->gpio_cd);
626 if (ret == 0)
627 host->gpio_cd = plat->gpio_cd;
628 else if (ret != -ENOSYS)
629 goto err_gpio_cd;
630 }
631 if (gpio_is_valid(plat->gpio_wp)) {
632 ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
633 if (ret == 0)
634 ret = gpio_direction_input(plat->gpio_wp);
635 if (ret == 0)
636 host->gpio_wp = plat->gpio_wp;
637 else if (ret != -ENOSYS)
638 goto err_gpio_wp;
639 }
640
594 ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); 641 ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
595 if (ret) 642 if (ret)
596 goto unmap; 643 goto unmap;
@@ -602,6 +649,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
602 writel(MCI_IRQENABLE, host->base + MMCIMASK0); 649 writel(MCI_IRQENABLE, host->base + MMCIMASK0);
603 650
604 amba_set_drvdata(dev, mmc); 651 amba_set_drvdata(dev, mmc);
652 host->oldstat = mmci_get_cd(host->mmc);
605 653
606 mmc_add_host(mmc); 654 mmc_add_host(mmc);
607 655
@@ -620,6 +668,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
620 irq0_free: 668 irq0_free:
621 free_irq(dev->irq[0], host); 669 free_irq(dev->irq[0], host);
622 unmap: 670 unmap:
671 if (host->gpio_wp != -ENOSYS)
672 gpio_free(host->gpio_wp);
673 err_gpio_wp:
674 if (host->gpio_cd != -ENOSYS)
675 gpio_free(host->gpio_cd);
676 err_gpio_cd:
623 iounmap(host->base); 677 iounmap(host->base);
624 clk_disable: 678 clk_disable:
625 clk_disable(host->clk); 679 clk_disable(host->clk);
@@ -655,6 +709,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
655 free_irq(dev->irq[0], host); 709 free_irq(dev->irq[0], host);
656 free_irq(dev->irq[1], host); 710 free_irq(dev->irq[1], host);
657 711
712 if (host->gpio_wp != -ENOSYS)
713 gpio_free(host->gpio_wp);
714 if (host->gpio_cd != -ENOSYS)
715 gpio_free(host->gpio_cd);
716
658 iounmap(host->base); 717 iounmap(host->base);
659 clk_disable(host->clk); 718 clk_disable(host->clk);
660 clk_put(host->clk); 719 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