aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2008-02-04 12:12:48 -0500
committerPierre Ossman <drzeus@drzeus.cx>2008-02-08 03:02:47 -0500
commit6e996ee8e730a50eef51cdb072b166fe8f80831e (patch)
tree5cbe1dfe5dd33dead44c9f02d21dd78fd5b39b7e /drivers
parent541ceb5b8b4a90f7862ef24e4058fce520247827 (diff)
at91_mci: use generic GPIO calls
Update the AT91 MMC driver to use the generic GPIO calls instead of the AT91-specific calls; and to request (and release) those GPIO signals. That required updating the probe() fault cleanup codepaths. Now there is a single sequence for freeing resources, in reverse order of their allocation. Also that code uses use dev_*() for messaging, and has less abuse of KERN_ERR. Likewise with updating remove() cleanup. This had to free the GPIOs, and while adding that code I noticed and fixed two other problems: it was poking at a workqueue owned by the mmc core; and in one (rare) case would try freeing an IRQ that it didn't allocate. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/at91_mci.c114
1 files changed, 80 insertions, 34 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index b1edcefdd4f9..21acecc9fe3a 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -70,10 +70,11 @@
70 70
71#include <asm/io.h> 71#include <asm/io.h>
72#include <asm/irq.h> 72#include <asm/irq.h>
73#include <asm/gpio.h>
74
73#include <asm/mach/mmc.h> 75#include <asm/mach/mmc.h>
74#include <asm/arch/board.h> 76#include <asm/arch/board.h>
75#include <asm/arch/cpu.h> 77#include <asm/arch/cpu.h>
76#include <asm/arch/gpio.h>
77#include <asm/arch/at91_mci.h> 78#include <asm/arch/at91_mci.h>
78 79
79#define DRIVER_NAME "at91_mci" 80#define DRIVER_NAME "at91_mci"
@@ -659,11 +660,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
659 if (host->board->vcc_pin) { 660 if (host->board->vcc_pin) {
660 switch (ios->power_mode) { 661 switch (ios->power_mode) {
661 case MMC_POWER_OFF: 662 case MMC_POWER_OFF:
662 at91_set_gpio_value(host->board->vcc_pin, 0); 663 gpio_set_value(host->board->vcc_pin, 0);
663 break; 664 break;
664 case MMC_POWER_UP: 665 case MMC_POWER_UP:
665 case MMC_POWER_ON: 666 case MMC_POWER_ON:
666 at91_set_gpio_value(host->board->vcc_pin, 1); 667 gpio_set_value(host->board->vcc_pin, 1);
667 break; 668 break;
668 } 669 }
669 } 670 }
@@ -768,7 +769,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
768static irqreturn_t at91_mmc_det_irq(int irq, void *_host) 769static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
769{ 770{
770 struct at91mci_host *host = _host; 771 struct at91mci_host *host = _host;
771 int present = !at91_get_gpio_value(irq); 772 int present = !gpio_get_value(irq_to_gpio(irq));
772 773
773 /* 774 /*
774 * we expect this irq on both insert and remove, 775 * we expect this irq on both insert and remove,
@@ -793,7 +794,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc)
793 struct at91mci_host *host = mmc_priv(mmc); 794 struct at91mci_host *host = mmc_priv(mmc);
794 795
795 if (host->board->wp_pin) { 796 if (host->board->wp_pin) {
796 read_only = at91_get_gpio_value(host->board->wp_pin); 797 read_only = gpio_get_value(host->board->wp_pin);
797 printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc), 798 printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc),
798 (read_only ? "read-only" : "read-write") ); 799 (read_only ? "read-only" : "read-write") );
799 } 800 }
@@ -820,8 +821,6 @@ static int __init at91_mci_probe(struct platform_device *pdev)
820 struct resource *res; 821 struct resource *res;
821 int ret; 822 int ret;
822 823
823 pr_debug("Probe MCI devices\n");
824
825 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 824 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
826 if (!res) 825 if (!res)
827 return -ENXIO; 826 return -ENXIO;
@@ -831,9 +830,9 @@ static int __init at91_mci_probe(struct platform_device *pdev)
831 830
832 mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); 831 mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
833 if (!mmc) { 832 if (!mmc) {
834 pr_debug("Failed to allocate mmc host\n"); 833 ret = -ENOMEM;
835 release_mem_region(res->start, res->end - res->start + 1); 834 dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
836 return -ENOMEM; 835 goto fail6;
837 } 836 }
838 837
839 mmc->ops = &at91_mci_ops; 838 mmc->ops = &at91_mci_ops;
@@ -853,19 +852,44 @@ static int __init at91_mci_probe(struct platform_device *pdev)
853 if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) 852 if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
854 mmc->caps |= MMC_CAP_4_BIT_DATA; 853 mmc->caps |= MMC_CAP_4_BIT_DATA;
855 else 854 else
856 printk("AT91 MMC: 4 wire bus mode not supported" 855 dev_warn(&pdev->dev, "4 wire bus mode not supported"
857 " - using 1 wire\n"); 856 " - using 1 wire\n");
858 } 857 }
859 858
860 /* 859 /*
860 * Reserve GPIOs ... board init code makes sure these pins are set
861 * up as GPIOs with the right direction (input, except for vcc)
862 */
863 if (host->board->det_pin) {
864 ret = gpio_request(host->board->det_pin, "mmc_detect");
865 if (ret < 0) {
866 dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
867 goto fail5;
868 }
869 }
870 if (host->board->wp_pin) {
871 ret = gpio_request(host->board->wp_pin, "mmc_wp");
872 if (ret < 0) {
873 dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n");
874 goto fail4;
875 }
876 }
877 if (host->board->vcc_pin) {
878 ret = gpio_request(host->board->vcc_pin, "mmc_vcc");
879 if (ret < 0) {
880 dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n");
881 goto fail3;
882 }
883 }
884
885 /*
861 * Get Clock 886 * Get Clock
862 */ 887 */
863 host->mci_clk = clk_get(&pdev->dev, "mci_clk"); 888 host->mci_clk = clk_get(&pdev->dev, "mci_clk");
864 if (IS_ERR(host->mci_clk)) { 889 if (IS_ERR(host->mci_clk)) {
865 printk(KERN_ERR "AT91 MMC: no clock defined.\n"); 890 ret = -ENODEV;
866 mmc_free_host(mmc); 891 dev_dbg(&pdev->dev, "no mci_clk?\n");
867 release_mem_region(res->start, res->end - res->start + 1); 892 goto fail2;
868 return -ENODEV;
869 } 893 }
870 894
871 /* 895 /*
@@ -873,10 +897,8 @@ static int __init at91_mci_probe(struct platform_device *pdev)
873 */ 897 */
874 host->baseaddr = ioremap(res->start, res->end - res->start + 1); 898 host->baseaddr = ioremap(res->start, res->end - res->start + 1);
875 if (!host->baseaddr) { 899 if (!host->baseaddr) {
876 clk_put(host->mci_clk); 900 ret = -ENOMEM;
877 mmc_free_host(mmc); 901 goto fail1;
878 release_mem_region(res->start, res->end - res->start + 1);
879 return -ENOMEM;
880 } 902 }
881 903
882 /* 904 /*
@@ -890,15 +912,11 @@ static int __init at91_mci_probe(struct platform_device *pdev)
890 * Allocate the MCI interrupt 912 * Allocate the MCI interrupt
891 */ 913 */
892 host->irq = platform_get_irq(pdev, 0); 914 host->irq = platform_get_irq(pdev, 0);
893 ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); 915 ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED,
916 mmc_hostname(mmc), host);
894 if (ret) { 917 if (ret) {
895 printk(KERN_ERR "AT91 MMC: Failed to request MCI interrupt\n"); 918 dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
896 clk_disable(host->mci_clk); 919 goto fail0;
897 clk_put(host->mci_clk);
898 mmc_free_host(mmc);
899 iounmap(host->baseaddr);
900 release_mem_region(res->start, res->end - res->start + 1);
901 return ret;
902 } 920 }
903 921
904 platform_set_drvdata(pdev, mmc); 922 platform_set_drvdata(pdev, mmc);
@@ -907,8 +925,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
907 * Add host to MMC layer 925 * Add host to MMC layer
908 */ 926 */
909 if (host->board->det_pin) { 927 if (host->board->det_pin) {
910 host->present = !at91_get_gpio_value(host->board->det_pin); 928 host->present = !gpio_get_value(host->board->det_pin);
911 device_init_wakeup(&pdev->dev, 1);
912 } 929 }
913 else 930 else
914 host->present = -1; 931 host->present = -1;
@@ -919,15 +936,38 @@ static int __init at91_mci_probe(struct platform_device *pdev)
919 * monitor card insertion/removal if we can 936 * monitor card insertion/removal if we can
920 */ 937 */
921 if (host->board->det_pin) { 938 if (host->board->det_pin) {
922 ret = request_irq(host->board->det_pin, at91_mmc_det_irq, 939 ret = request_irq(gpio_to_irq(host->board->det_pin),
923 0, DRIVER_NAME, host); 940 at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
924 if (ret) 941 if (ret)
925 printk(KERN_ERR "AT91 MMC: Couldn't allocate MMC detect irq\n"); 942 dev_warn(&pdev->dev, "request MMC detect irq failed\n");
943 else
944 device_init_wakeup(&pdev->dev, 1);
926 } 945 }
927 946
928 pr_debug("Added MCI driver\n"); 947 pr_debug("Added MCI driver\n");
929 948
930 return 0; 949 return 0;
950
951fail0:
952 clk_disable(host->mci_clk);
953 iounmap(host->baseaddr);
954fail1:
955 clk_put(host->mci_clk);
956fail2:
957 if (host->board->vcc_pin)
958 gpio_free(host->board->vcc_pin);
959fail3:
960 if (host->board->wp_pin)
961 gpio_free(host->board->wp_pin);
962fail4:
963 if (host->board->det_pin)
964 gpio_free(host->board->det_pin);
965fail5:
966 mmc_free_host(mmc);
967fail6:
968 release_mem_region(res->start, res->end - res->start + 1);
969 dev_err(&pdev->dev, "probe failed, err %d\n", ret);
970 return ret;
931} 971}
932 972
933/* 973/*
@@ -945,9 +985,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
945 host = mmc_priv(mmc); 985 host = mmc_priv(mmc);
946 986
947 if (host->board->det_pin) { 987 if (host->board->det_pin) {
988 if (device_can_wakeup(&pdev->dev))
989 free_irq(gpio_to_irq(host->board->det_pin), host);
948 device_init_wakeup(&pdev->dev, 0); 990 device_init_wakeup(&pdev->dev, 0);
949 free_irq(host->board->det_pin, host); 991 gpio_free(host->board->det_pin);
950 cancel_delayed_work(&host->mmc->detect);
951 } 992 }
952 993
953 at91_mci_disable(host); 994 at91_mci_disable(host);
@@ -957,6 +998,11 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
957 clk_disable(host->mci_clk); /* Disable the peripheral clock */ 998 clk_disable(host->mci_clk); /* Disable the peripheral clock */
958 clk_put(host->mci_clk); 999 clk_put(host->mci_clk);
959 1000
1001 if (host->board->vcc_pin)
1002 gpio_free(host->board->vcc_pin);
1003 if (host->board->wp_pin)
1004 gpio_free(host->board->wp_pin);
1005
960 iounmap(host->baseaddr); 1006 iounmap(host->baseaddr);
961 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1007 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
962 release_mem_region(res->start, res->end - res->start + 1); 1008 release_mem_region(res->start, res->end - res->start + 1);