diff options
author | Alexander Shiyan <shc_work@mail.ru> | 2014-03-22 04:52:45 -0400 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2014-05-12 18:04:31 -0400 |
commit | 01e4f9585350a15faf1bdd185d80ec6160217d35 (patch) | |
tree | 2b12595de01f75fc2d69aaa678d59ade08ef4dbf /drivers/mmc/host/mxcmmc.c | |
parent | 15a2e2ab62f1f1d8b43ae43670de7bc2b21f7f86 (diff) |
mmc: mxcmmc: Convert to devm-* API
Replace existing resource handling in the driver with managed
device resource, this ensures more consistent error values and
simplifies error paths.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc/host/mxcmmc.c')
-rw-r--r-- | drivers/mmc/host/mxcmmc.c | 101 |
1 files changed, 38 insertions, 63 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index f7199c83f5cf..84d630e94b24 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -124,9 +124,8 @@ enum mxcmci_type { | |||
124 | 124 | ||
125 | struct mxcmci_host { | 125 | struct mxcmci_host { |
126 | struct mmc_host *mmc; | 126 | struct mmc_host *mmc; |
127 | struct resource *res; | ||
128 | void __iomem *base; | 127 | void __iomem *base; |
129 | int irq; | 128 | dma_addr_t phys_base; |
130 | int detect_irq; | 129 | int detect_irq; |
131 | struct dma_chan *dma; | 130 | struct dma_chan *dma; |
132 | struct dma_async_tx_descriptor *desc; | 131 | struct dma_async_tx_descriptor *desc; |
@@ -241,33 +240,26 @@ static inline void mxcmci_writew(struct mxcmci_host *host, u16 val, int reg) | |||
241 | 240 | ||
242 | static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); | 241 | static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); |
243 | 242 | ||
244 | static inline void mxcmci_init_ocr(struct mxcmci_host *host) | 243 | static void mxcmci_init_ocr(struct mxcmci_host *host) |
245 | { | 244 | { |
246 | host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); | 245 | host->vcc = devm_regulator_get(mmc_dev(host->mmc), "vmmc"); |
247 | |||
248 | if (IS_ERR(host->vcc)) { | 246 | if (IS_ERR(host->vcc)) { |
249 | host->vcc = NULL; | 247 | if (host->pdata && host->pdata->ocr_avail) |
248 | host->mmc->ocr_avail = host->pdata->ocr_avail; | ||
249 | else | ||
250 | host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
250 | } else { | 251 | } else { |
251 | host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); | 252 | host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); |
252 | if (host->pdata && host->pdata->ocr_avail) | 253 | if (host->pdata && host->pdata->ocr_avail) |
253 | dev_warn(mmc_dev(host->mmc), | 254 | dev_warn(mmc_dev(host->mmc), |
254 | "pdata->ocr_avail will not be used\n"); | 255 | "pdata->ocr_avail will not be used\n"); |
255 | } | 256 | } |
256 | |||
257 | if (host->vcc == NULL) { | ||
258 | /* fall-back to platform data */ | ||
259 | if (host->pdata && host->pdata->ocr_avail) | ||
260 | host->mmc->ocr_avail = host->pdata->ocr_avail; | ||
261 | else | ||
262 | host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
263 | } | ||
264 | } | 257 | } |
265 | 258 | ||
266 | static inline void mxcmci_set_power(struct mxcmci_host *host, | 259 | static void mxcmci_set_power(struct mxcmci_host *host, unsigned char power_mode, |
267 | unsigned char power_mode, | 260 | unsigned int vdd) |
268 | unsigned int vdd) | ||
269 | { | 261 | { |
270 | if (host->vcc) { | 262 | if (!IS_ERR(host->vcc)) { |
271 | if (power_mode == MMC_POWER_UP) | 263 | if (power_mode == MMC_POWER_UP) |
272 | mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); | 264 | mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); |
273 | else if (power_mode == MMC_POWER_OFF) | 265 | else if (power_mode == MMC_POWER_OFF) |
@@ -299,7 +291,6 @@ static void mxcmci_softreset(struct mxcmci_host *host) | |||
299 | 291 | ||
300 | mxcmci_writew(host, 0xff, MMC_REG_RES_TO); | 292 | mxcmci_writew(host, 0xff, MMC_REG_RES_TO); |
301 | } | 293 | } |
302 | static int mxcmci_setup_dma(struct mmc_host *mmc); | ||
303 | 294 | ||
304 | #if IS_ENABLED(CONFIG_PPC_MPC512x) | 295 | #if IS_ENABLED(CONFIG_PPC_MPC512x) |
305 | static inline void buffer_swap32(u32 *buf, int len) | 296 | static inline void buffer_swap32(u32 *buf, int len) |
@@ -868,8 +859,8 @@ static int mxcmci_setup_dma(struct mmc_host *mmc) | |||
868 | struct mxcmci_host *host = mmc_priv(mmc); | 859 | struct mxcmci_host *host = mmc_priv(mmc); |
869 | struct dma_slave_config *config = &host->dma_slave_config; | 860 | struct dma_slave_config *config = &host->dma_slave_config; |
870 | 861 | ||
871 | config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS; | 862 | config->dst_addr = host->phys_base + MMC_REG_BUFFER_ACCESS; |
872 | config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS; | 863 | config->src_addr = host->phys_base + MMC_REG_BUFFER_ACCESS; |
873 | config->dst_addr_width = 4; | 864 | config->dst_addr_width = 4; |
874 | config->src_addr_width = 4; | 865 | config->src_addr_width = 4; |
875 | config->dst_maxburst = host->burstlen; | 866 | config->dst_maxburst = host->burstlen; |
@@ -1040,8 +1031,8 @@ static const struct mmc_host_ops mxcmci_ops = { | |||
1040 | static int mxcmci_probe(struct platform_device *pdev) | 1031 | static int mxcmci_probe(struct platform_device *pdev) |
1041 | { | 1032 | { |
1042 | struct mmc_host *mmc; | 1033 | struct mmc_host *mmc; |
1043 | struct mxcmci_host *host = NULL; | 1034 | struct mxcmci_host *host; |
1044 | struct resource *iores, *r; | 1035 | struct resource *res; |
1045 | int ret = 0, irq; | 1036 | int ret = 0, irq; |
1046 | bool dat3_card_detect = false; | 1037 | bool dat3_card_detect = false; |
1047 | dma_cap_mask_t mask; | 1038 | dma_cap_mask_t mask; |
@@ -1052,21 +1043,25 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1052 | 1043 | ||
1053 | of_id = of_match_device(mxcmci_of_match, &pdev->dev); | 1044 | of_id = of_match_device(mxcmci_of_match, &pdev->dev); |
1054 | 1045 | ||
1055 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1046 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1056 | irq = platform_get_irq(pdev, 0); | 1047 | irq = platform_get_irq(pdev, 0); |
1057 | if (!iores || irq < 0) | 1048 | if (irq < 0) |
1058 | return -EINVAL; | 1049 | return -EINVAL; |
1059 | 1050 | ||
1060 | r = request_mem_region(iores->start, resource_size(iores), pdev->name); | 1051 | mmc = mmc_alloc_host(sizeof(*host), &pdev->dev); |
1061 | if (!r) | 1052 | if (!mmc) |
1062 | return -EBUSY; | 1053 | return -ENOMEM; |
1063 | 1054 | ||
1064 | mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev); | 1055 | host = mmc_priv(mmc); |
1065 | if (!mmc) { | 1056 | |
1066 | ret = -ENOMEM; | 1057 | host->base = devm_ioremap_resource(&pdev->dev, res); |
1067 | goto out_release_mem; | 1058 | if (IS_ERR(host->base)) { |
1059 | ret = PTR_ERR(host->base); | ||
1060 | goto out_free; | ||
1068 | } | 1061 | } |
1069 | 1062 | ||
1063 | host->phys_base = res->start; | ||
1064 | |||
1070 | ret = mmc_of_parse(mmc); | 1065 | ret = mmc_of_parse(mmc); |
1071 | if (ret) | 1066 | if (ret) |
1072 | goto out_free; | 1067 | goto out_free; |
@@ -1084,13 +1079,6 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1084 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 1079 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
1085 | mmc->max_seg_size = mmc->max_req_size; | 1080 | mmc->max_seg_size = mmc->max_req_size; |
1086 | 1081 | ||
1087 | host = mmc_priv(mmc); | ||
1088 | host->base = ioremap(r->start, resource_size(r)); | ||
1089 | if (!host->base) { | ||
1090 | ret = -ENOMEM; | ||
1091 | goto out_free; | ||
1092 | } | ||
1093 | |||
1094 | if (of_id) { | 1082 | if (of_id) { |
1095 | const struct platform_device_id *id_entry = of_id->data; | 1083 | const struct platform_device_id *id_entry = of_id->data; |
1096 | host->devtype = id_entry->driver_data; | 1084 | host->devtype = id_entry->driver_data; |
@@ -1120,19 +1108,16 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1120 | else | 1108 | else |
1121 | host->default_irq_mask = 0; | 1109 | host->default_irq_mask = 0; |
1122 | 1110 | ||
1123 | host->res = r; | ||
1124 | host->irq = irq; | ||
1125 | |||
1126 | host->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1111 | host->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1127 | if (IS_ERR(host->clk_ipg)) { | 1112 | if (IS_ERR(host->clk_ipg)) { |
1128 | ret = PTR_ERR(host->clk_ipg); | 1113 | ret = PTR_ERR(host->clk_ipg); |
1129 | goto out_iounmap; | 1114 | goto out_free; |
1130 | } | 1115 | } |
1131 | 1116 | ||
1132 | host->clk_per = devm_clk_get(&pdev->dev, "per"); | 1117 | host->clk_per = devm_clk_get(&pdev->dev, "per"); |
1133 | if (IS_ERR(host->clk_per)) { | 1118 | if (IS_ERR(host->clk_per)) { |
1134 | ret = PTR_ERR(host->clk_per); | 1119 | ret = PTR_ERR(host->clk_per); |
1135 | goto out_iounmap; | 1120 | goto out_free; |
1136 | } | 1121 | } |
1137 | 1122 | ||
1138 | clk_prepare_enable(host->clk_per); | 1123 | clk_prepare_enable(host->clk_per); |
@@ -1159,9 +1144,9 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1159 | if (!host->pdata) { | 1144 | if (!host->pdata) { |
1160 | host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx"); | 1145 | host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx"); |
1161 | } else { | 1146 | } else { |
1162 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 1147 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
1163 | if (r) { | 1148 | if (res) { |
1164 | host->dmareq = r->start; | 1149 | host->dmareq = res->start; |
1165 | host->dma_data.peripheral_type = IMX_DMATYPE_SDHC; | 1150 | host->dma_data.peripheral_type = IMX_DMATYPE_SDHC; |
1166 | host->dma_data.priority = DMA_PRIO_LOW; | 1151 | host->dma_data.priority = DMA_PRIO_LOW; |
1167 | host->dma_data.dma_request = host->dmareq; | 1152 | host->dma_data.dma_request = host->dmareq; |
@@ -1178,7 +1163,8 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1178 | 1163 | ||
1179 | INIT_WORK(&host->datawork, mxcmci_datawork); | 1164 | INIT_WORK(&host->datawork, mxcmci_datawork); |
1180 | 1165 | ||
1181 | ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); | 1166 | ret = devm_request_irq(&pdev->dev, irq, mxcmci_irq, 0, |
1167 | dev_name(&pdev->dev), host); | ||
1182 | if (ret) | 1168 | if (ret) |
1183 | goto out_free_dma; | 1169 | goto out_free_dma; |
1184 | 1170 | ||
@@ -1188,7 +1174,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1188 | ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq, | 1174 | ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq, |
1189 | host->mmc); | 1175 | host->mmc); |
1190 | if (ret) | 1176 | if (ret) |
1191 | goto out_free_irq; | 1177 | goto out_free_dma; |
1192 | } | 1178 | } |
1193 | 1179 | ||
1194 | init_timer(&host->watchdog); | 1180 | init_timer(&host->watchdog); |
@@ -1199,20 +1185,17 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1199 | 1185 | ||
1200 | return 0; | 1186 | return 0; |
1201 | 1187 | ||
1202 | out_free_irq: | ||
1203 | free_irq(host->irq, host); | ||
1204 | out_free_dma: | 1188 | out_free_dma: |
1205 | if (host->dma) | 1189 | if (host->dma) |
1206 | dma_release_channel(host->dma); | 1190 | dma_release_channel(host->dma); |
1191 | |||
1207 | out_clk_put: | 1192 | out_clk_put: |
1208 | clk_disable_unprepare(host->clk_per); | 1193 | clk_disable_unprepare(host->clk_per); |
1209 | clk_disable_unprepare(host->clk_ipg); | 1194 | clk_disable_unprepare(host->clk_ipg); |
1210 | out_iounmap: | 1195 | |
1211 | iounmap(host->base); | ||
1212 | out_free: | 1196 | out_free: |
1213 | mmc_free_host(mmc); | 1197 | mmc_free_host(mmc); |
1214 | out_release_mem: | 1198 | |
1215 | release_mem_region(iores->start, resource_size(iores)); | ||
1216 | return ret; | 1199 | return ret; |
1217 | } | 1200 | } |
1218 | 1201 | ||
@@ -1223,23 +1206,15 @@ static int mxcmci_remove(struct platform_device *pdev) | |||
1223 | 1206 | ||
1224 | mmc_remove_host(mmc); | 1207 | mmc_remove_host(mmc); |
1225 | 1208 | ||
1226 | if (host->vcc) | ||
1227 | regulator_put(host->vcc); | ||
1228 | |||
1229 | if (host->pdata && host->pdata->exit) | 1209 | if (host->pdata && host->pdata->exit) |
1230 | host->pdata->exit(&pdev->dev, mmc); | 1210 | host->pdata->exit(&pdev->dev, mmc); |
1231 | 1211 | ||
1232 | free_irq(host->irq, host); | ||
1233 | iounmap(host->base); | ||
1234 | |||
1235 | if (host->dma) | 1212 | if (host->dma) |
1236 | dma_release_channel(host->dma); | 1213 | dma_release_channel(host->dma); |
1237 | 1214 | ||
1238 | clk_disable_unprepare(host->clk_per); | 1215 | clk_disable_unprepare(host->clk_per); |
1239 | clk_disable_unprepare(host->clk_ipg); | 1216 | clk_disable_unprepare(host->clk_ipg); |
1240 | 1217 | ||
1241 | release_mem_region(host->res->start, resource_size(host->res)); | ||
1242 | |||
1243 | mmc_free_host(mmc); | 1218 | mmc_free_host(mmc); |
1244 | 1219 | ||
1245 | return 0; | 1220 | return 0; |