aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mxcmmc.c
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2014-03-22 04:52:45 -0400
committerChris Ball <chris@printf.net>2014-05-12 18:04:31 -0400
commit01e4f9585350a15faf1bdd185d80ec6160217d35 (patch)
tree2b12595de01f75fc2d69aaa678d59ade08ef4dbf /drivers/mmc/host/mxcmmc.c
parent15a2e2ab62f1f1d8b43ae43670de7bc2b21f7f86 (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.c101
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
125struct mxcmci_host { 125struct 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
242static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); 241static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
243 242
244static inline void mxcmci_init_ocr(struct mxcmci_host *host) 243static 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
266static inline void mxcmci_set_power(struct mxcmci_host *host, 259static 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}
302static int mxcmci_setup_dma(struct mmc_host *mmc);
303 294
304#if IS_ENABLED(CONFIG_PPC_MPC512x) 295#if IS_ENABLED(CONFIG_PPC_MPC512x)
305static inline void buffer_swap32(u32 *buf, int len) 296static 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 = {
1040static int mxcmci_probe(struct platform_device *pdev) 1031static 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
1202out_free_irq:
1203 free_irq(host->irq, host);
1204out_free_dma: 1188out_free_dma:
1205 if (host->dma) 1189 if (host->dma)
1206 dma_release_channel(host->dma); 1190 dma_release_channel(host->dma);
1191
1207out_clk_put: 1192out_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);
1210out_iounmap: 1195
1211 iounmap(host->base);
1212out_free: 1196out_free:
1213 mmc_free_host(mmc); 1197 mmc_free_host(mmc);
1214out_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;