diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2010-08-09 07:55:48 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-09-23 10:01:59 -0400 |
commit | 148b8b39c156424da22693d26adcb69800faf95e (patch) | |
tree | cf3c1f37a69d81cfb04e968cb7911371ddf9ed80 /drivers/mmc/host | |
parent | 8301bb68c6bb9836889641a47443aeb97b763f6c (diff) |
ARM: 6308/1: mmci: support card detection interrupts
If an IRQ can be requested on the card detected GPIO, use it instead of
polling.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/mmci.c | 24 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 1 |
2 files changed, 24 insertions, 1 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1932e9cc8f52..a922a0028836 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -601,6 +601,15 @@ static int mmci_get_cd(struct mmc_host *mmc) | |||
601 | return status; | 601 | return status; |
602 | } | 602 | } |
603 | 603 | ||
604 | static irqreturn_t mmci_cd_irq(int irq, void *dev_id) | ||
605 | { | ||
606 | struct mmci_host *host = dev_id; | ||
607 | |||
608 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
609 | |||
610 | return IRQ_HANDLED; | ||
611 | } | ||
612 | |||
604 | static const struct mmc_host_ops mmci_ops = { | 613 | static const struct mmc_host_ops mmci_ops = { |
605 | .request = mmci_request, | 614 | .request = mmci_request, |
606 | .set_ios = mmci_set_ios, | 615 | .set_ios = mmci_set_ios, |
@@ -637,6 +646,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
637 | 646 | ||
638 | host->gpio_wp = -ENOSYS; | 647 | host->gpio_wp = -ENOSYS; |
639 | host->gpio_cd = -ENOSYS; | 648 | host->gpio_cd = -ENOSYS; |
649 | host->gpio_cd_irq = -1; | ||
640 | 650 | ||
641 | host->hw_designer = amba_manf(dev); | 651 | host->hw_designer = amba_manf(dev); |
642 | host->hw_revision = amba_rev(dev); | 652 | host->hw_revision = amba_rev(dev); |
@@ -716,7 +726,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
716 | if (host->vcc == NULL) | 726 | if (host->vcc == NULL) |
717 | mmc->ocr_avail = plat->ocr_mask; | 727 | mmc->ocr_avail = plat->ocr_mask; |
718 | mmc->caps = plat->capabilities; | 728 | mmc->caps = plat->capabilities; |
719 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
720 | 729 | ||
721 | /* | 730 | /* |
722 | * We can do SGIO | 731 | * We can do SGIO |
@@ -761,6 +770,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
761 | host->gpio_cd = plat->gpio_cd; | 770 | host->gpio_cd = plat->gpio_cd; |
762 | else if (ret != -ENOSYS) | 771 | else if (ret != -ENOSYS) |
763 | goto err_gpio_cd; | 772 | goto err_gpio_cd; |
773 | |||
774 | ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd), | ||
775 | mmci_cd_irq, 0, | ||
776 | DRIVER_NAME " (cd)", host); | ||
777 | if (ret >= 0) | ||
778 | host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); | ||
764 | } | 779 | } |
765 | if (gpio_is_valid(plat->gpio_wp)) { | 780 | if (gpio_is_valid(plat->gpio_wp)) { |
766 | ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); | 781 | ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); |
@@ -772,6 +787,9 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
772 | goto err_gpio_wp; | 787 | goto err_gpio_wp; |
773 | } | 788 | } |
774 | 789 | ||
790 | if (host->gpio_cd_irq < 0) | ||
791 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
792 | |||
775 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); | 793 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); |
776 | if (ret) | 794 | if (ret) |
777 | goto unmap; | 795 | goto unmap; |
@@ -798,6 +816,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
798 | if (host->gpio_wp != -ENOSYS) | 816 | if (host->gpio_wp != -ENOSYS) |
799 | gpio_free(host->gpio_wp); | 817 | gpio_free(host->gpio_wp); |
800 | err_gpio_wp: | 818 | err_gpio_wp: |
819 | if (host->gpio_cd_irq >= 0) | ||
820 | free_irq(host->gpio_cd_irq, host); | ||
801 | if (host->gpio_cd != -ENOSYS) | 821 | if (host->gpio_cd != -ENOSYS) |
802 | gpio_free(host->gpio_cd); | 822 | gpio_free(host->gpio_cd); |
803 | err_gpio_cd: | 823 | err_gpio_cd: |
@@ -836,6 +856,8 @@ static int __devexit mmci_remove(struct amba_device *dev) | |||
836 | 856 | ||
837 | if (host->gpio_wp != -ENOSYS) | 857 | if (host->gpio_wp != -ENOSYS) |
838 | gpio_free(host->gpio_wp); | 858 | gpio_free(host->gpio_wp); |
859 | if (host->gpio_cd_irq >= 0) | ||
860 | free_irq(host->gpio_cd_irq, host); | ||
839 | if (host->gpio_cd != -ENOSYS) | 861 | if (host->gpio_cd != -ENOSYS) |
840 | gpio_free(host->gpio_cd); | 862 | gpio_free(host->gpio_cd); |
841 | 863 | ||
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 4e18f5403f48..c7d373c7aec9 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -147,6 +147,7 @@ struct mmci_host { | |||
147 | struct clk *clk; | 147 | struct clk *clk; |
148 | int gpio_cd; | 148 | int gpio_cd; |
149 | int gpio_wp; | 149 | int gpio_wp; |
150 | int gpio_cd_irq; | ||
150 | 151 | ||
151 | unsigned int data_xfered; | 152 | unsigned int data_xfered; |
152 | 153 | ||