.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * bcm2835 sdhost driver. |
---|
3 | 4 | * |
---|
.. | .. |
---|
25 | 26 | * sdhci-bcm2708.c by Broadcom |
---|
26 | 27 | * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko |
---|
27 | 28 | * sdhci.c and sdhci-pci.c by Pierre Ossman |
---|
28 | | - * |
---|
29 | | - * This program is free software; you can redistribute it and/or modify it |
---|
30 | | - * under the terms and conditions of the GNU General Public License, |
---|
31 | | - * version 2, as published by the Free Software Foundation. |
---|
32 | | - * |
---|
33 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
34 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
35 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
36 | | - * more details. |
---|
37 | | - * |
---|
38 | | - * You should have received a copy of the GNU General Public License |
---|
39 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
40 | 29 | */ |
---|
41 | 30 | #include <linux/clk.h> |
---|
42 | 31 | #include <linux/delay.h> |
---|
.. | .. |
---|
159 | 148 | void __iomem *ioaddr; |
---|
160 | 149 | u32 phys_addr; |
---|
161 | 150 | |
---|
162 | | - struct mmc_host *mmc; |
---|
163 | 151 | struct platform_device *pdev; |
---|
164 | 152 | |
---|
165 | 153 | int clock; /* Current clock speed */ |
---|
.. | .. |
---|
464 | 452 | static |
---|
465 | 453 | void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data) |
---|
466 | 454 | { |
---|
467 | | - int len, dir_data, dir_slave; |
---|
| 455 | + int sg_len, dir_data, dir_slave; |
---|
468 | 456 | struct dma_async_tx_descriptor *desc = NULL; |
---|
469 | 457 | struct dma_chan *dma_chan; |
---|
470 | 458 | |
---|
.. | .. |
---|
510 | 498 | &host->dma_cfg_rx : |
---|
511 | 499 | &host->dma_cfg_tx); |
---|
512 | 500 | |
---|
513 | | - len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, |
---|
514 | | - dir_data); |
---|
| 501 | + sg_len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, |
---|
| 502 | + dir_data); |
---|
| 503 | + if (!sg_len) |
---|
| 504 | + return; |
---|
515 | 505 | |
---|
516 | | - if (len > 0) { |
---|
517 | | - desc = dmaengine_prep_slave_sg(dma_chan, data->sg, |
---|
518 | | - len, dir_slave, |
---|
519 | | - DMA_PREP_INTERRUPT | |
---|
520 | | - DMA_CTRL_ACK); |
---|
| 506 | + desc = dmaengine_prep_slave_sg(dma_chan, data->sg, sg_len, dir_slave, |
---|
| 507 | + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
---|
| 508 | + |
---|
| 509 | + if (!desc) { |
---|
| 510 | + dma_unmap_sg(dma_chan->device->dev, data->sg, sg_len, dir_data); |
---|
| 511 | + return; |
---|
521 | 512 | } |
---|
522 | 513 | |
---|
523 | | - if (desc) { |
---|
524 | | - desc->callback = bcm2835_dma_complete; |
---|
525 | | - desc->callback_param = host; |
---|
526 | | - host->dma_desc = desc; |
---|
527 | | - host->dma_chan = dma_chan; |
---|
528 | | - host->dma_dir = dir_data; |
---|
529 | | - } |
---|
| 514 | + desc->callback = bcm2835_dma_complete; |
---|
| 515 | + desc->callback_param = host; |
---|
| 516 | + host->dma_desc = desc; |
---|
| 517 | + host->dma_chan = dma_chan; |
---|
| 518 | + host->dma_dir = dir_data; |
---|
530 | 519 | } |
---|
531 | 520 | |
---|
532 | 521 | static void bcm2835_start_dma(struct bcm2835_host *host) |
---|
.. | .. |
---|
628 | 617 | "failed to terminate DMA (%d)\n", err); |
---|
629 | 618 | } |
---|
630 | 619 | |
---|
631 | | - mmc_request_done(host->mmc, mrq); |
---|
| 620 | + mmc_request_done(mmc_from_priv(host), mrq); |
---|
632 | 621 | } |
---|
633 | 622 | |
---|
634 | 623 | static |
---|
.. | .. |
---|
847 | 836 | dev_err(dev, "timeout waiting for hardware interrupt.\n"); |
---|
848 | 837 | bcm2835_dumpregs(host); |
---|
849 | 838 | |
---|
850 | | - bcm2835_reset(host->mmc); |
---|
| 839 | + bcm2835_reset(mmc_from_priv(host)); |
---|
851 | 840 | |
---|
852 | 841 | if (host->data) { |
---|
853 | 842 | host->data->error = -ETIMEDOUT; |
---|
.. | .. |
---|
1064 | 1053 | { |
---|
1065 | 1054 | struct bcm2835_host *host = |
---|
1066 | 1055 | container_of(work, struct bcm2835_host, dma_work); |
---|
1067 | | - struct mmc_data *data = host->data; |
---|
| 1056 | + struct mmc_data *data; |
---|
1068 | 1057 | |
---|
1069 | 1058 | mutex_lock(&host->mutex); |
---|
| 1059 | + |
---|
| 1060 | + data = host->data; |
---|
1070 | 1061 | |
---|
1071 | 1062 | if (host->dma_chan) { |
---|
1072 | 1063 | dma_unmap_sg(host->dma_chan->device->dev, |
---|
.. | .. |
---|
1108 | 1099 | |
---|
1109 | 1100 | static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) |
---|
1110 | 1101 | { |
---|
| 1102 | + struct mmc_host *mmc = mmc_from_priv(host); |
---|
1111 | 1103 | int div; |
---|
1112 | 1104 | |
---|
1113 | 1105 | /* The SDCDIV register has 11 bits, and holds (div - 2). But |
---|
.. | .. |
---|
1151 | 1143 | div = SDCDIV_MAX_CDIV; |
---|
1152 | 1144 | |
---|
1153 | 1145 | clock = host->max_clk / (div + 2); |
---|
1154 | | - host->mmc->actual_clock = clock; |
---|
| 1146 | + mmc->actual_clock = clock; |
---|
1155 | 1147 | |
---|
1156 | 1148 | /* Calibrate some delays */ |
---|
1157 | 1149 | |
---|
1158 | 1150 | host->ns_per_fifo_word = (1000000000 / clock) * |
---|
1159 | | - ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); |
---|
| 1151 | + ((mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); |
---|
1160 | 1152 | |
---|
1161 | 1153 | host->cdiv = div; |
---|
1162 | 1154 | writel(host->cdiv, host->ioaddr + SDCDIV); |
---|
1163 | 1155 | |
---|
1164 | 1156 | /* Set the timeout to 500ms */ |
---|
1165 | | - writel(host->mmc->actual_clock / 2, host->ioaddr + SDTOUT); |
---|
| 1157 | + writel(mmc->actual_clock / 2, host->ioaddr + SDTOUT); |
---|
1166 | 1158 | } |
---|
1167 | 1159 | |
---|
1168 | 1160 | static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq) |
---|
.. | .. |
---|
1192 | 1184 | return; |
---|
1193 | 1185 | } |
---|
1194 | 1186 | |
---|
1195 | | - if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD)) |
---|
1196 | | - bcm2835_prepare_dma(host, mrq->data); |
---|
1197 | | - |
---|
1198 | 1187 | mutex_lock(&host->mutex); |
---|
1199 | 1188 | |
---|
1200 | 1189 | WARN_ON(host->mrq); |
---|
.. | .. |
---|
1217 | 1206 | mutex_unlock(&host->mutex); |
---|
1218 | 1207 | return; |
---|
1219 | 1208 | } |
---|
| 1209 | + |
---|
| 1210 | + if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD)) |
---|
| 1211 | + bcm2835_prepare_dma(host, mrq->data); |
---|
1220 | 1212 | |
---|
1221 | 1213 | host->use_sbc = !!mrq->sbc && host->mrq->data && |
---|
1222 | 1214 | (host->mrq->data->flags & MMC_DATA_READ); |
---|
.. | .. |
---|
1272 | 1264 | |
---|
1273 | 1265 | static int bcm2835_add_host(struct bcm2835_host *host) |
---|
1274 | 1266 | { |
---|
1275 | | - struct mmc_host *mmc = host->mmc; |
---|
| 1267 | + struct mmc_host *mmc = mmc_from_priv(host); |
---|
1276 | 1268 | struct device *dev = &host->pdev->dev; |
---|
1277 | 1269 | char pio_limit_string[20]; |
---|
1278 | 1270 | int ret; |
---|
.. | .. |
---|
1288 | 1280 | |
---|
1289 | 1281 | /* host controller capabilities */ |
---|
1290 | 1282 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | |
---|
1291 | | - MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | |
---|
1292 | | - MMC_CAP_CMD23; |
---|
| 1283 | + MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_CMD23; |
---|
1293 | 1284 | |
---|
1294 | 1285 | spin_lock_init(&host->lock); |
---|
1295 | 1286 | mutex_init(&host->mutex); |
---|
1296 | 1287 | |
---|
1297 | | - if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { |
---|
| 1288 | + if (!host->dma_chan_rxtx) { |
---|
1298 | 1289 | dev_warn(dev, "unable to initialise DMA channel. Falling back to PIO\n"); |
---|
1299 | 1290 | host->use_dma = false; |
---|
1300 | 1291 | } else { |
---|
.. | .. |
---|
1322 | 1313 | } |
---|
1323 | 1314 | |
---|
1324 | 1315 | mmc->max_segs = 128; |
---|
1325 | | - mmc->max_req_size = 524288; |
---|
| 1316 | + mmc->max_req_size = min_t(size_t, 524288, dma_max_mapping_size(dev)); |
---|
1326 | 1317 | mmc->max_seg_size = mmc->max_req_size; |
---|
1327 | 1318 | mmc->max_blk_size = 1024; |
---|
1328 | 1319 | mmc->max_blk_count = 65535; |
---|
.. | .. |
---|
1365 | 1356 | { |
---|
1366 | 1357 | struct device *dev = &pdev->dev; |
---|
1367 | 1358 | struct clk *clk; |
---|
1368 | | - struct resource *iomem; |
---|
1369 | 1359 | struct bcm2835_host *host; |
---|
1370 | 1360 | struct mmc_host *mmc; |
---|
1371 | 1361 | const __be32 *regaddr_p; |
---|
.. | .. |
---|
1378 | 1368 | |
---|
1379 | 1369 | mmc->ops = &bcm2835_ops; |
---|
1380 | 1370 | host = mmc_priv(mmc); |
---|
1381 | | - host->mmc = mmc; |
---|
1382 | 1371 | host->pdev = pdev; |
---|
1383 | 1372 | spin_lock_init(&host->lock); |
---|
1384 | 1373 | |
---|
1385 | | - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1386 | | - host->ioaddr = devm_ioremap_resource(dev, iomem); |
---|
| 1374 | + host->ioaddr = devm_platform_ioremap_resource(pdev, 0); |
---|
1387 | 1375 | if (IS_ERR(host->ioaddr)) { |
---|
1388 | 1376 | ret = PTR_ERR(host->ioaddr); |
---|
1389 | 1377 | goto err; |
---|
.. | .. |
---|
1404 | 1392 | host->dma_chan = NULL; |
---|
1405 | 1393 | host->dma_desc = NULL; |
---|
1406 | 1394 | |
---|
1407 | | - host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx"); |
---|
| 1395 | + host->dma_chan_rxtx = dma_request_chan(dev, "rx-tx"); |
---|
| 1396 | + if (IS_ERR(host->dma_chan_rxtx)) { |
---|
| 1397 | + ret = PTR_ERR(host->dma_chan_rxtx); |
---|
| 1398 | + host->dma_chan_rxtx = NULL; |
---|
| 1399 | + |
---|
| 1400 | + if (ret == -EPROBE_DEFER) |
---|
| 1401 | + goto err; |
---|
| 1402 | + |
---|
| 1403 | + /* Ignore errors to fall back to PIO mode */ |
---|
| 1404 | + } |
---|
| 1405 | + |
---|
1408 | 1406 | |
---|
1409 | 1407 | clk = devm_clk_get(dev, NULL); |
---|
1410 | 1408 | if (IS_ERR(clk)) { |
---|
1411 | | - ret = PTR_ERR(clk); |
---|
1412 | | - if (ret != -EPROBE_DEFER) |
---|
1413 | | - dev_err(dev, "could not get clk: %d\n", ret); |
---|
| 1409 | + ret = dev_err_probe(dev, PTR_ERR(clk), "could not get clk\n"); |
---|
1414 | 1410 | goto err; |
---|
1415 | 1411 | } |
---|
1416 | 1412 | |
---|
.. | .. |
---|
1418 | 1414 | |
---|
1419 | 1415 | host->irq = platform_get_irq(pdev, 0); |
---|
1420 | 1416 | if (host->irq <= 0) { |
---|
1421 | | - dev_err(dev, "get IRQ failed\n"); |
---|
1422 | 1417 | ret = -EINVAL; |
---|
1423 | 1418 | goto err; |
---|
1424 | 1419 | } |
---|
.. | .. |
---|
1449 | 1444 | static int bcm2835_remove(struct platform_device *pdev) |
---|
1450 | 1445 | { |
---|
1451 | 1446 | struct bcm2835_host *host = platform_get_drvdata(pdev); |
---|
| 1447 | + struct mmc_host *mmc = mmc_from_priv(host); |
---|
1452 | 1448 | |
---|
1453 | | - mmc_remove_host(host->mmc); |
---|
| 1449 | + mmc_remove_host(mmc); |
---|
1454 | 1450 | |
---|
1455 | 1451 | writel(SDVDD_POWER_OFF, host->ioaddr + SDVDD); |
---|
1456 | 1452 | |
---|
.. | .. |
---|
1459 | 1455 | cancel_work_sync(&host->dma_work); |
---|
1460 | 1456 | cancel_delayed_work_sync(&host->timeout_work); |
---|
1461 | 1457 | |
---|
1462 | | - mmc_free_host(host->mmc); |
---|
1463 | | - platform_set_drvdata(pdev, NULL); |
---|
| 1458 | + if (host->dma_chan_rxtx) |
---|
| 1459 | + dma_release_channel(host->dma_chan_rxtx); |
---|
| 1460 | + |
---|
| 1461 | + mmc_free_host(mmc); |
---|
1464 | 1462 | |
---|
1465 | 1463 | return 0; |
---|
1466 | 1464 | } |
---|
.. | .. |
---|
1476 | 1474 | .remove = bcm2835_remove, |
---|
1477 | 1475 | .driver = { |
---|
1478 | 1476 | .name = "sdhost-bcm2835", |
---|
| 1477 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
---|
1479 | 1478 | .of_match_table = bcm2835_match, |
---|
1480 | 1479 | }, |
---|
1481 | 1480 | }; |
---|