aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/omap.c
diff options
context:
space:
mode:
authorJuha Yrjola juha.yrjola <at solidboot.com>2006-11-11 17:39:20 -0500
committerPierre Ossman <drzeus@drzeus.cx>2006-12-01 12:01:32 -0500
commit81ca70343f4d85637ac19b529dbcccd1db69a41d (patch)
tree203c8895f7f8c72294c0a169c88a133bf8c3ed10 /drivers/mmc/omap.c
parent0551f4df35694c7f89e00da461d7bee9769f016f (diff)
Platform device error handling cleanup
This patch is part of Juha Yrjola's earlier patch to add platform device error handling and a BUG_ON to verify if host == NULL Signed-off-by: Carlos Eduardo Aguiar <carlos.aguiar <at> indt.org.br> Signed-off-by: Juha Yrjola <juha.yrjola <at> solidboot.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/omap.c')
-rw-r--r--drivers/mmc/omap.c100
1 files changed, 59 insertions, 41 deletions
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
index 827753c18579..d46fd02ba0dc 100644
--- a/drivers/mmc/omap.c
+++ b/drivers/mmc/omap.c
@@ -1022,25 +1022,29 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1022 struct omap_mmc_conf *minfo = pdev->dev.platform_data; 1022 struct omap_mmc_conf *minfo = pdev->dev.platform_data;
1023 struct mmc_host *mmc; 1023 struct mmc_host *mmc;
1024 struct mmc_omap_host *host = NULL; 1024 struct mmc_omap_host *host = NULL;
1025 struct resource *r; 1025 struct resource *res;
1026 int ret = 0; 1026 int ret = 0;
1027 int irq; 1027 int irq;
1028 1028
1029 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1029 if (minfo == NULL) {
1030 dev_err(&pdev->dev, "platform data missing\n");
1031 return -ENXIO;
1032 }
1033
1034 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1030 irq = platform_get_irq(pdev, 0); 1035 irq = platform_get_irq(pdev, 0);
1031 if (!r || irq < 0) 1036 if (res == NULL || irq < 0)
1032 return -ENXIO; 1037 return -ENXIO;
1033 1038
1034 r = request_mem_region(pdev->resource[0].start, 1039 res = request_mem_region(res->start, res->end - res->start + 1,
1035 pdev->resource[0].end - pdev->resource[0].start + 1, 1040 pdev->name);
1036 pdev->name); 1041 if (res == NULL)
1037 if (!r)
1038 return -EBUSY; 1042 return -EBUSY;
1039 1043
1040 mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev); 1044 mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev);
1041 if (!mmc) { 1045 if (mmc == NULL) {
1042 ret = -ENOMEM; 1046 ret = -ENOMEM;
1043 goto out; 1047 goto err_free_mem_region;
1044 } 1048 }
1045 1049
1046 host = mmc_priv(mmc); 1050 host = mmc_priv(mmc);
@@ -1052,13 +1056,13 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1052 host->dma_timer.data = (unsigned long) host; 1056 host->dma_timer.data = (unsigned long) host;
1053 1057
1054 host->id = pdev->id; 1058 host->id = pdev->id;
1055 host->mem_res = r; 1059 host->mem_res = res;
1056 host->irq = irq; 1060 host->irq = irq;
1057 1061
1058 if (cpu_is_omap24xx()) { 1062 if (cpu_is_omap24xx()) {
1059 host->iclk = clk_get(&pdev->dev, "mmc_ick"); 1063 host->iclk = clk_get(&pdev->dev, "mmc_ick");
1060 if (IS_ERR(host->iclk)) 1064 if (IS_ERR(host->iclk))
1061 goto out; 1065 goto err_free_mmc_host;
1062 clk_enable(host->iclk); 1066 clk_enable(host->iclk);
1063 } 1067 }
1064 1068
@@ -1069,7 +1073,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1069 1073
1070 if (IS_ERR(host->fclk)) { 1074 if (IS_ERR(host->fclk)) {
1071 ret = PTR_ERR(host->fclk); 1075 ret = PTR_ERR(host->fclk);
1072 goto out; 1076 goto err_free_iclk;
1073 } 1077 }
1074 1078
1075 /* REVISIT: 1079 /* REVISIT:
@@ -1082,7 +1086,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1082 host->use_dma = 1; 1086 host->use_dma = 1;
1083 host->dma_ch = -1; 1087 host->dma_ch = -1;
1084 1088
1085 host->irq = pdev->resource[1].start; 1089 host->irq = irq;
1086 host->phys_base = host->mem_res->start; 1090 host->phys_base = host->mem_res->start;
1087 host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base); 1091 host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);
1088 1092
@@ -1108,20 +1112,18 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1108 if ((ret = omap_request_gpio(host->power_pin)) != 0) { 1112 if ((ret = omap_request_gpio(host->power_pin)) != 0) {
1109 dev_err(mmc_dev(host->mmc), 1113 dev_err(mmc_dev(host->mmc),
1110 "Unable to get GPIO pin for MMC power\n"); 1114 "Unable to get GPIO pin for MMC power\n");
1111 goto out; 1115 goto err_free_fclk;
1112 } 1116 }
1113 omap_set_gpio_direction(host->power_pin, 0); 1117 omap_set_gpio_direction(host->power_pin, 0);
1114 } 1118 }
1115 1119
1116 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); 1120 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
1117 if (ret) 1121 if (ret)
1118 goto out; 1122 goto err_free_power_gpio;
1119 1123
1120 host->dev = &pdev->dev; 1124 host->dev = &pdev->dev;
1121 platform_set_drvdata(pdev, host); 1125 platform_set_drvdata(pdev, host);
1122 1126
1123 mmc_add_host(mmc);
1124
1125 if (host->switch_pin >= 0) { 1127 if (host->switch_pin >= 0) {
1126 INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host); 1128 INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host);
1127 init_timer(&host->switch_timer); 1129 init_timer(&host->switch_timer);
@@ -1159,10 +1161,11 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1159 schedule_work(&host->switch_work); 1161 schedule_work(&host->switch_work);
1160 } 1162 }
1161 1163
1162no_switch: 1164 mmc_add_host(mmc);
1165
1163 return 0; 1166 return 0;
1164 1167
1165out: 1168no_switch:
1166 /* FIXME: Free other resources too. */ 1169 /* FIXME: Free other resources too. */
1167 if (host) { 1170 if (host) {
1168 if (host->iclk && !IS_ERR(host->iclk)) 1171 if (host->iclk && !IS_ERR(host->iclk))
@@ -1171,6 +1174,20 @@ out:
1171 clk_put(host->fclk); 1174 clk_put(host->fclk);
1172 mmc_free_host(host->mmc); 1175 mmc_free_host(host->mmc);
1173 } 1176 }
1177err_free_power_gpio:
1178 if (host->power_pin >= 0)
1179 omap_free_gpio(host->power_pin);
1180err_free_fclk:
1181 clk_put(host->fclk);
1182err_free_iclk:
1183 if (host->iclk != NULL) {
1184 clk_disable(host->iclk);
1185 clk_put(host->iclk);
1186 }
1187err_free_mmc_host:
1188 mmc_free_host(host->mmc);
1189err_free_mem_region:
1190 release_mem_region(res->start, res->end - res->start + 1);
1174 return ret; 1191 return ret;
1175} 1192}
1176 1193
@@ -1180,30 +1197,31 @@ static int mmc_omap_remove(struct platform_device *pdev)
1180 1197
1181 platform_set_drvdata(pdev, NULL); 1198 platform_set_drvdata(pdev, NULL);
1182 1199
1183 if (host) { 1200 BUG_ON(host == NULL);
1184 mmc_remove_host(host->mmc); 1201
1185 free_irq(host->irq, host); 1202 mmc_remove_host(host->mmc);
1186 1203 free_irq(host->irq, host);
1187 if (host->power_pin >= 0) 1204
1188 omap_free_gpio(host->power_pin); 1205 if (host->power_pin >= 0)
1189 if (host->switch_pin >= 0) { 1206 omap_free_gpio(host->power_pin);
1190 device_remove_file(&pdev->dev, &dev_attr_enable_poll); 1207 if (host->switch_pin >= 0) {
1191 device_remove_file(&pdev->dev, &dev_attr_cover_switch); 1208 device_remove_file(&pdev->dev, &dev_attr_enable_poll);
1192 free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); 1209 device_remove_file(&pdev->dev, &dev_attr_cover_switch);
1193 omap_free_gpio(host->switch_pin); 1210 free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
1194 host->switch_pin = -1; 1211 omap_free_gpio(host->switch_pin);
1195 del_timer_sync(&host->switch_timer); 1212 host->switch_pin = -1;
1196 flush_scheduled_work(); 1213 del_timer_sync(&host->switch_timer);
1197 } 1214 flush_scheduled_work();
1198 if (host->iclk && !IS_ERR(host->iclk))
1199 clk_put(host->iclk);
1200 if (host->fclk && !IS_ERR(host->fclk))
1201 clk_put(host->fclk);
1202 mmc_free_host(host->mmc);
1203 } 1215 }
1216 if (host->iclk && !IS_ERR(host->iclk))
1217 clk_put(host->iclk);
1218 if (host->fclk && !IS_ERR(host->fclk))
1219 clk_put(host->fclk);
1204 1220
1205 release_mem_region(pdev->resource[0].start, 1221 release_mem_region(pdev->resource[0].start,
1206 pdev->resource[0].end - pdev->resource[0].start + 1); 1222 pdev->resource[0].end - pdev->resource[0].start + 1);
1223
1224 mmc_free_host(host->mmc);
1207 1225
1208 return 0; 1226 return 0;
1209} 1227}