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 | |
| 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')
| -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 | ||
