diff options
author | Juha Yrjola juha.yrjola <at solidboot.com> | 2006-11-11 17:39:20 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2006-12-01 12:01:32 -0500 |
commit | 81ca70343f4d85637ac19b529dbcccd1db69a41d (patch) | |
tree | 203c8895f7f8c72294c0a169c88a133bf8c3ed10 /drivers/mmc | |
parent | 0551f4df35694c7f89e00da461d7bee9769f016f (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')
-rw-r--r-- | drivers/mmc/omap.c | 100 |
1 files changed, 59 insertions, 41 deletions
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c index 827753c1857..d46fd02ba0d 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 | ||
1162 | no_switch: | 1164 | mmc_add_host(mmc); |
1165 | |||
1163 | return 0; | 1166 | return 0; |
1164 | 1167 | ||
1165 | out: | 1168 | no_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 | } |
1177 | err_free_power_gpio: | ||
1178 | if (host->power_pin >= 0) | ||
1179 | omap_free_gpio(host->power_pin); | ||
1180 | err_free_fclk: | ||
1181 | clk_put(host->fclk); | ||
1182 | err_free_iclk: | ||
1183 | if (host->iclk != NULL) { | ||
1184 | clk_disable(host->iclk); | ||
1185 | clk_put(host->iclk); | ||
1186 | } | ||
1187 | err_free_mmc_host: | ||
1188 | mmc_free_host(host->mmc); | ||
1189 | err_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 | } |