aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/at91_mci.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index cc0546998367..9a6251a7815d 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -101,6 +101,7 @@ struct at91mci_host
101 struct mmc_request *request; 101 struct mmc_request *request;
102 102
103 void __iomem *baseaddr; 103 void __iomem *baseaddr;
104 int irq;
104 105
105 struct at91_mmc_data *board; 106 struct at91_mmc_data *board;
106 int present; 107 int present;
@@ -792,13 +793,22 @@ static int at91_mci_probe(struct platform_device *pdev)
792{ 793{
793 struct mmc_host *mmc; 794 struct mmc_host *mmc;
794 struct at91mci_host *host; 795 struct at91mci_host *host;
796 struct resource *res;
795 int ret; 797 int ret;
796 798
797 pr_debug("Probe MCI devices\n"); 799 pr_debug("Probe MCI devices\n");
798 800
801 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
802 if (!res)
803 return -ENXIO;
804
805 if (!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME))
806 return -EBUSY;
807
799 mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); 808 mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
800 if (!mmc) { 809 if (!mmc) {
801 pr_debug("Failed to allocate mmc host\n"); 810 pr_debug("Failed to allocate mmc host\n");
811 release_mem_region(res->start, res->end - res->start + 1);
802 return -ENOMEM; 812 return -ENOMEM;
803 } 813 }
804 814
@@ -828,27 +838,40 @@ static int at91_mci_probe(struct platform_device *pdev)
828 if (IS_ERR(mci_clk)) { 838 if (IS_ERR(mci_clk)) {
829 printk(KERN_ERR "AT91 MMC: no clock defined.\n"); 839 printk(KERN_ERR "AT91 MMC: no clock defined.\n");
830 mmc_free_host(mmc); 840 mmc_free_host(mmc);
841 release_mem_region(res->start, res->end - res->start + 1);
831 return -ENODEV; 842 return -ENODEV;
832 } 843 }
833 clk_enable(mci_clk); /* Enable the peripheral clock */
834 844
835 host->baseaddr = (void __iomem *)AT91_VA_BASE_MCI; 845 /*
846 * Map I/O region
847 */
848 host->baseaddr = ioremap(res->start, res->end - res->start + 1);
849 if (!host->baseaddr) {
850 clk_put(mci_clk);
851 mmc_free_host(mmc);
852 release_mem_region(res->start, res->end - res->start + 1);
853 return -ENOMEM;
854 }
836 855
837 /* 856 /*
838 * Reset hardware 857 * Reset hardware
839 */ 858 */
859 clk_enable(mci_clk); /* Enable the peripheral clock */
840 at91_mci_disable(host); 860 at91_mci_disable(host);
841 at91_mci_enable(host); 861 at91_mci_enable(host);
842 862
843 /* 863 /*
844 * Allocate the MCI interrupt 864 * Allocate the MCI interrupt
845 */ 865 */
846 ret = request_irq(AT91RM9200_ID_MCI, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); 866 host->irq = platform_get_irq(pdev, 0);
867 ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host);
847 if (ret) { 868 if (ret) {
848 printk(KERN_ERR "Failed to request MCI interrupt\n"); 869 printk(KERN_ERR "Failed to request MCI interrupt\n");
849 clk_disable(mci_clk); 870 clk_disable(mci_clk);
850 clk_put(mci_clk); 871 clk_put(mci_clk);
851 mmc_free_host(mmc); 872 mmc_free_host(mmc);
873 iounmap(host->baseaddr);
874 release_mem_region(res->start, res->end - res->start + 1);
852 return ret; 875 return ret;
853 } 876 }
854 877
@@ -886,6 +909,7 @@ static int at91_mci_remove(struct platform_device *pdev)
886{ 909{
887 struct mmc_host *mmc = platform_get_drvdata(pdev); 910 struct mmc_host *mmc = platform_get_drvdata(pdev);
888 struct at91mci_host *host; 911 struct at91mci_host *host;
912 struct resource *res;
889 913
890 if (!mmc) 914 if (!mmc)
891 return -1; 915 return -1;
@@ -897,16 +921,19 @@ static int at91_mci_remove(struct platform_device *pdev)
897 cancel_delayed_work(&host->mmc->detect); 921 cancel_delayed_work(&host->mmc->detect);
898 } 922 }
899 923
900 mmc_remove_host(mmc);
901 at91_mci_disable(host); 924 at91_mci_disable(host);
902 free_irq(AT91RM9200_ID_MCI, host); 925 mmc_remove_host(mmc);
903 mmc_free_host(mmc); 926 free_irq(host->irq, host);
904 927
905 clk_disable(mci_clk); /* Disable the peripheral clock */ 928 clk_disable(mci_clk); /* Disable the peripheral clock */
906 clk_put(mci_clk); 929 clk_put(mci_clk);
907 930
908 platform_set_drvdata(pdev, NULL); 931 iounmap(host->baseaddr);
932 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
933 release_mem_region(res->start, res->end - res->start + 1);
909 934
935 mmc_free_host(mmc);
936 platform_set_drvdata(pdev, NULL);
910 pr_debug("MCI Removed\n"); 937 pr_debug("MCI Removed\n");
911 938
912 return 0; 939 return 0;