Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
sdhci: highmem capable PIO routines
sg: reimplement sg mapping iterator
mmc_test: print message when attaching to card
mmc: Remove Russell as primecell mci maintainer
mmc_block: bounce buffer highmem support
sdhci: fix bad warning from commit c8b3e02
sdhci: add warnings for bad buffers in ADMA path
mmc_test: test oversized sg lists
mmc_test: highmem tests
s3cmci: ensure host stopped on machine shutdown
au1xmmc: suspend/resume implementation
s3cmci: fixes for section mismatch warnings
pxamci: trivial fix of DMA alignment register bit clearing

+567 -242
+1 -4
MAINTAINERS
··· 441 441 S: Maintained 442 442 443 443 ARM PRIMECELL MMCI PL180/1 DRIVER 444 - P: Russell King 445 - M: rmk@arm.linux.org.uk 446 - L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) 447 - S: Maintained 444 + S: Orphan 448 445 449 446 ARM/ADI ROADRUNNER MACHINE SUPPORT 450 447 P: Lennert Buytenhek
+221 -4
drivers/mmc/card/mmc_test.c
··· 21 21 #define RESULT_UNSUP_HOST 2 22 22 #define RESULT_UNSUP_CARD 3 23 23 24 - #define BUFFER_SIZE (PAGE_SIZE * 4) 24 + #define BUFFER_ORDER 2 25 + #define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER) 25 26 26 27 struct mmc_test_card { 27 28 struct mmc_card *card; 28 29 29 30 u8 scratch[BUFFER_SIZE]; 30 31 u8 *buffer; 32 + #ifdef CONFIG_HIGHMEM 33 + struct page *highmem; 34 + #endif 31 35 }; 32 36 33 37 /*******************************************************************/ ··· 388 384 int ret, i; 389 385 unsigned long flags; 390 386 387 + BUG_ON(blocks * blksz > BUFFER_SIZE); 388 + 391 389 if (write) { 392 390 for (i = 0;i < blocks * blksz;i++) 393 391 test->scratch[i] = i; 394 392 } else { 395 - memset(test->scratch, 0, BUFFER_SIZE); 393 + memset(test->scratch, 0, blocks * blksz); 396 394 } 397 395 local_irq_save(flags); 398 - sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); 396 + sg_copy_from_buffer(sg, sg_len, test->scratch, blocks * blksz); 399 397 local_irq_restore(flags); 400 398 401 399 ret = mmc_test_set_blksize(test, blksz); ··· 444 438 } 445 439 } else { 446 440 local_irq_save(flags); 447 - sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); 441 + sg_copy_to_buffer(sg, sg_len, test->scratch, blocks * blksz); 448 442 local_irq_restore(flags); 449 443 for (i = 0;i < blocks * blksz;i++) { 450 444 if (test->scratch[i] != (u8)i) ··· 805 799 return 0; 806 800 } 807 801 802 + static int mmc_test_bigsg_write(struct mmc_test_card *test) 803 + { 804 + int ret; 805 + unsigned int size; 806 + struct scatterlist sg; 807 + 808 + if (test->card->host->max_blk_count == 1) 809 + return RESULT_UNSUP_HOST; 810 + 811 + size = PAGE_SIZE * 2; 812 + size = min(size, test->card->host->max_req_size); 813 + size = min(size, test->card->host->max_seg_size); 814 + size = min(size, test->card->host->max_blk_count * 512); 815 + 816 + memset(test->buffer, 0, BUFFER_SIZE); 817 + 818 + if (size < 1024) 819 + return RESULT_UNSUP_HOST; 820 + 821 + sg_init_table(&sg, 1); 822 + sg_init_one(&sg, test->buffer, BUFFER_SIZE); 823 + 824 + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); 825 + if (ret) 826 + return ret; 827 + 828 + return 0; 829 + } 830 + 831 + static int mmc_test_bigsg_read(struct mmc_test_card *test) 832 + { 833 + int ret, i; 834 + unsigned int size; 835 + struct scatterlist sg; 836 + 837 + if (test->card->host->max_blk_count == 1) 838 + return RESULT_UNSUP_HOST; 839 + 840 + size = PAGE_SIZE * 2; 841 + size = min(size, test->card->host->max_req_size); 842 + size = min(size, test->card->host->max_seg_size); 843 + size = min(size, test->card->host->max_blk_count * 512); 844 + 845 + if (size < 1024) 846 + return RESULT_UNSUP_HOST; 847 + 848 + memset(test->buffer, 0xCD, BUFFER_SIZE); 849 + 850 + sg_init_table(&sg, 1); 851 + sg_init_one(&sg, test->buffer, BUFFER_SIZE); 852 + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); 853 + if (ret) 854 + return ret; 855 + 856 + /* mmc_test_transfer() doesn't check for read overflows */ 857 + for (i = size;i < BUFFER_SIZE;i++) { 858 + if (test->buffer[i] != 0xCD) 859 + return RESULT_FAIL; 860 + } 861 + 862 + return 0; 863 + } 864 + 865 + #ifdef CONFIG_HIGHMEM 866 + 867 + static int mmc_test_write_high(struct mmc_test_card *test) 868 + { 869 + int ret; 870 + struct scatterlist sg; 871 + 872 + sg_init_table(&sg, 1); 873 + sg_set_page(&sg, test->highmem, 512, 0); 874 + 875 + ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); 876 + if (ret) 877 + return ret; 878 + 879 + return 0; 880 + } 881 + 882 + static int mmc_test_read_high(struct mmc_test_card *test) 883 + { 884 + int ret; 885 + struct scatterlist sg; 886 + 887 + sg_init_table(&sg, 1); 888 + sg_set_page(&sg, test->highmem, 512, 0); 889 + 890 + ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); 891 + if (ret) 892 + return ret; 893 + 894 + return 0; 895 + } 896 + 897 + static int mmc_test_multi_write_high(struct mmc_test_card *test) 898 + { 899 + int ret; 900 + unsigned int size; 901 + struct scatterlist sg; 902 + 903 + if (test->card->host->max_blk_count == 1) 904 + return RESULT_UNSUP_HOST; 905 + 906 + size = PAGE_SIZE * 2; 907 + size = min(size, test->card->host->max_req_size); 908 + size = min(size, test->card->host->max_seg_size); 909 + size = min(size, test->card->host->max_blk_count * 512); 910 + 911 + if (size < 1024) 912 + return RESULT_UNSUP_HOST; 913 + 914 + sg_init_table(&sg, 1); 915 + sg_set_page(&sg, test->highmem, size, 0); 916 + 917 + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); 918 + if (ret) 919 + return ret; 920 + 921 + return 0; 922 + } 923 + 924 + static int mmc_test_multi_read_high(struct mmc_test_card *test) 925 + { 926 + int ret; 927 + unsigned int size; 928 + struct scatterlist sg; 929 + 930 + if (test->card->host->max_blk_count == 1) 931 + return RESULT_UNSUP_HOST; 932 + 933 + size = PAGE_SIZE * 2; 934 + size = min(size, test->card->host->max_req_size); 935 + size = min(size, test->card->host->max_seg_size); 936 + size = min(size, test->card->host->max_blk_count * 512); 937 + 938 + if (size < 1024) 939 + return RESULT_UNSUP_HOST; 940 + 941 + sg_init_table(&sg, 1); 942 + sg_set_page(&sg, test->highmem, size, 0); 943 + 944 + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); 945 + if (ret) 946 + return ret; 947 + 948 + return 0; 949 + } 950 + 951 + #endif /* CONFIG_HIGHMEM */ 952 + 808 953 static const struct mmc_test_case mmc_test_cases[] = { 809 954 { 810 955 .name = "Basic write (no data verification)", ··· 1070 913 .name = "Correct xfer_size at read (midway failure)", 1071 914 .run = mmc_test_multi_xfersize_read, 1072 915 }, 916 + 917 + { 918 + .name = "Over-sized SG list write", 919 + .prepare = mmc_test_prepare_write, 920 + .run = mmc_test_bigsg_write, 921 + .cleanup = mmc_test_cleanup, 922 + }, 923 + 924 + { 925 + .name = "Over-sized SG list read", 926 + .prepare = mmc_test_prepare_read, 927 + .run = mmc_test_bigsg_read, 928 + .cleanup = mmc_test_cleanup, 929 + }, 930 + 931 + #ifdef CONFIG_HIGHMEM 932 + 933 + { 934 + .name = "Highmem write", 935 + .prepare = mmc_test_prepare_write, 936 + .run = mmc_test_write_high, 937 + .cleanup = mmc_test_cleanup, 938 + }, 939 + 940 + { 941 + .name = "Highmem read", 942 + .prepare = mmc_test_prepare_read, 943 + .run = mmc_test_read_high, 944 + .cleanup = mmc_test_cleanup, 945 + }, 946 + 947 + { 948 + .name = "Multi-block highmem write", 949 + .prepare = mmc_test_prepare_write, 950 + .run = mmc_test_multi_write_high, 951 + .cleanup = mmc_test_cleanup, 952 + }, 953 + 954 + { 955 + .name = "Multi-block highmem read", 956 + .prepare = mmc_test_prepare_read, 957 + .run = mmc_test_multi_read_high, 958 + .cleanup = mmc_test_cleanup, 959 + }, 960 + 961 + #endif /* CONFIG_HIGHMEM */ 962 + 1073 963 }; 1074 964 1075 965 static struct mutex mmc_test_lock; ··· 1218 1014 test->card = card; 1219 1015 1220 1016 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); 1017 + #ifdef CONFIG_HIGHMEM 1018 + test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER); 1019 + #endif 1020 + 1021 + #ifdef CONFIG_HIGHMEM 1022 + if (test->buffer && test->highmem) { 1023 + #else 1221 1024 if (test->buffer) { 1025 + #endif 1222 1026 mutex_lock(&mmc_test_lock); 1223 1027 mmc_test_run(test, testcase); 1224 1028 mutex_unlock(&mmc_test_lock); 1225 1029 } 1226 1030 1031 + #ifdef CONFIG_HIGHMEM 1032 + __free_pages(test->highmem, BUFFER_ORDER); 1033 + #endif 1227 1034 kfree(test->buffer); 1228 1035 kfree(test); 1229 1036 ··· 1255 1040 ret = device_create_file(&card->dev, &dev_attr_test); 1256 1041 if (ret) 1257 1042 return ret; 1043 + 1044 + dev_info(&card->dev, "Card claimed for testing.\n"); 1258 1045 1259 1046 return 0; 1260 1047 }
+31 -66
drivers/mmc/card/queue.c
··· 148 148 printk(KERN_WARNING "%s: unable to allocate " 149 149 "bounce buffer\n", mmc_card_name(card)); 150 150 } else { 151 - blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH); 151 + blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); 152 152 blk_queue_max_sectors(mq->queue, bouncesz / 512); 153 153 blk_queue_max_phys_segments(mq->queue, bouncesz / 512); 154 154 blk_queue_max_hw_segments(mq->queue, bouncesz / 512); ··· 290 290 } 291 291 } 292 292 293 - static void copy_sg(struct scatterlist *dst, unsigned int dst_len, 294 - struct scatterlist *src, unsigned int src_len) 295 - { 296 - unsigned int chunk; 297 - char *dst_buf, *src_buf; 298 - unsigned int dst_size, src_size; 299 - 300 - dst_buf = NULL; 301 - src_buf = NULL; 302 - dst_size = 0; 303 - src_size = 0; 304 - 305 - while (src_len) { 306 - BUG_ON(dst_len == 0); 307 - 308 - if (dst_size == 0) { 309 - dst_buf = sg_virt(dst); 310 - dst_size = dst->length; 311 - } 312 - 313 - if (src_size == 0) { 314 - src_buf = sg_virt(src); 315 - src_size = src->length; 316 - } 317 - 318 - chunk = min(dst_size, src_size); 319 - 320 - memcpy(dst_buf, src_buf, chunk); 321 - 322 - dst_buf += chunk; 323 - src_buf += chunk; 324 - dst_size -= chunk; 325 - src_size -= chunk; 326 - 327 - if (dst_size == 0) { 328 - dst++; 329 - dst_len--; 330 - } 331 - 332 - if (src_size == 0) { 333 - src++; 334 - src_len--; 335 - } 336 - } 337 - } 338 - 293 + /* 294 + * Prepare the sg list(s) to be handed of to the host driver 295 + */ 339 296 unsigned int mmc_queue_map_sg(struct mmc_queue *mq) 340 297 { 341 298 unsigned int sg_len; 299 + size_t buflen; 300 + struct scatterlist *sg; 301 + int i; 342 302 343 303 if (!mq->bounce_buf) 344 304 return blk_rq_map_sg(mq->queue, mq->req, mq->sg); ··· 309 349 310 350 mq->bounce_sg_len = sg_len; 311 351 312 - /* 313 - * Shortcut in the event we only get a single entry. 314 - */ 315 - if (sg_len == 1) { 316 - memcpy(mq->sg, mq->bounce_sg, sizeof(struct scatterlist)); 317 - return 1; 318 - } 352 + buflen = 0; 353 + for_each_sg(mq->bounce_sg, sg, sg_len, i) 354 + buflen += sg->length; 319 355 320 - sg_init_one(mq->sg, mq->bounce_buf, 0); 321 - 322 - while (sg_len) { 323 - mq->sg[0].length += mq->bounce_sg[sg_len - 1].length; 324 - sg_len--; 325 - } 356 + sg_init_one(mq->sg, mq->bounce_buf, buflen); 326 357 327 358 return 1; 328 359 } 329 360 361 + /* 362 + * If writing, bounce the data to the buffer before the request 363 + * is sent to the host driver 364 + */ 330 365 void mmc_queue_bounce_pre(struct mmc_queue *mq) 331 366 { 367 + unsigned long flags; 368 + 332 369 if (!mq->bounce_buf) 333 370 return; 334 371 335 - if (mq->bounce_sg_len == 1) 336 - return; 337 372 if (rq_data_dir(mq->req) != WRITE) 338 373 return; 339 374 340 - copy_sg(mq->sg, 1, mq->bounce_sg, mq->bounce_sg_len); 375 + local_irq_save(flags); 376 + sg_copy_to_buffer(mq->bounce_sg, mq->bounce_sg_len, 377 + mq->bounce_buf, mq->sg[0].length); 378 + local_irq_restore(flags); 341 379 } 342 380 381 + /* 382 + * If reading, bounce the data from the buffer after the request 383 + * has been handled by the host driver 384 + */ 343 385 void mmc_queue_bounce_post(struct mmc_queue *mq) 344 386 { 387 + unsigned long flags; 388 + 345 389 if (!mq->bounce_buf) 346 390 return; 347 391 348 - if (mq->bounce_sg_len == 1) 349 - return; 350 392 if (rq_data_dir(mq->req) != READ) 351 393 return; 352 394 353 - copy_sg(mq->bounce_sg, mq->bounce_sg_len, mq->sg, 1); 395 + local_irq_save(flags); 396 + sg_copy_from_buffer(mq->bounce_sg, mq->bounce_sg_len, 397 + mq->bounce_buf, mq->sg[0].length); 398 + local_irq_restore(flags); 354 399 } 355 400
+42 -12
drivers/mmc/host/au1xmmc.c
··· 1043 1043 goto out6; 1044 1044 } 1045 1045 1046 - platform_set_drvdata(pdev, mmc); 1046 + platform_set_drvdata(pdev, host); 1047 1047 1048 1048 printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X" 1049 1049 " (mode=%s)\n", pdev->id, host->iobase, ··· 1087 1087 1088 1088 static int __devexit au1xmmc_remove(struct platform_device *pdev) 1089 1089 { 1090 - struct mmc_host *mmc = platform_get_drvdata(pdev); 1091 - struct au1xmmc_host *host; 1090 + struct au1xmmc_host *host = platform_get_drvdata(pdev); 1092 1091 1093 - if (mmc) { 1094 - host = mmc_priv(mmc); 1095 - 1096 - mmc_remove_host(mmc); 1092 + if (host) { 1093 + mmc_remove_host(host->mmc); 1097 1094 1098 1095 #ifdef CONFIG_LEDS_CLASS 1099 1096 if (host->platdata && host->platdata->led) ··· 1098 1101 #endif 1099 1102 1100 1103 if (host->platdata && host->platdata->cd_setup && 1101 - !(mmc->caps & MMC_CAP_NEEDS_POLL)) 1102 - host->platdata->cd_setup(mmc, 0); 1104 + !(host->mmc->caps & MMC_CAP_NEEDS_POLL)) 1105 + host->platdata->cd_setup(host->mmc, 0); 1103 1106 1104 1107 au_writel(0, HOST_ENABLE(host)); 1105 1108 au_writel(0, HOST_CONFIG(host)); ··· 1119 1122 release_resource(host->ioarea); 1120 1123 kfree(host->ioarea); 1121 1124 1122 - mmc_free_host(mmc); 1125 + mmc_free_host(host->mmc); 1126 + platform_set_drvdata(pdev, NULL); 1123 1127 } 1124 1128 return 0; 1125 1129 } 1126 1130 1131 + #ifdef CONFIG_PM 1132 + static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state) 1133 + { 1134 + struct au1xmmc_host *host = platform_get_drvdata(pdev); 1135 + int ret; 1136 + 1137 + ret = mmc_suspend_host(host->mmc, state); 1138 + if (ret) 1139 + return ret; 1140 + 1141 + au_writel(0, HOST_CONFIG2(host)); 1142 + au_writel(0, HOST_CONFIG(host)); 1143 + au_writel(0xffffffff, HOST_STATUS(host)); 1144 + au_writel(0, HOST_ENABLE(host)); 1145 + au_sync(); 1146 + 1147 + return 0; 1148 + } 1149 + 1150 + static int au1xmmc_resume(struct platform_device *pdev) 1151 + { 1152 + struct au1xmmc_host *host = platform_get_drvdata(pdev); 1153 + 1154 + au1xmmc_reset_controller(host); 1155 + 1156 + return mmc_resume_host(host->mmc); 1157 + } 1158 + #else 1159 + #define au1xmmc_suspend NULL 1160 + #define au1xmmc_resume NULL 1161 + #endif 1162 + 1127 1163 static struct platform_driver au1xmmc_driver = { 1128 1164 .probe = au1xmmc_probe, 1129 1165 .remove = au1xmmc_remove, 1130 - .suspend = NULL, 1131 - .resume = NULL, 1166 + .suspend = au1xmmc_suspend, 1167 + .resume = au1xmmc_resume, 1132 1168 .driver = { 1133 1169 .name = DRIVER_NAME, 1134 1170 .owner = THIS_MODULE,
+1 -1
drivers/mmc/host/pxamci.c
··· 177 177 if (dalgn) 178 178 DALGN |= (1 << host->dma); 179 179 else 180 - DALGN &= (1 << host->dma); 180 + DALGN &= ~(1 << host->dma); 181 181 DDADR(host->dma) = host->sg_dma; 182 182 DCSR(host->dma) = DCSR_RUN; 183 183 }
+31 -19
drivers/mmc/host/s3cmci.c
··· 1331 1331 return ret; 1332 1332 } 1333 1333 1334 + static void s3cmci_shutdown(struct platform_device *pdev) 1335 + { 1336 + struct mmc_host *mmc = platform_get_drvdata(pdev); 1337 + struct s3cmci_host *host = mmc_priv(mmc); 1338 + 1339 + if (host->irq_cd >= 0) 1340 + free_irq(host->irq_cd, host); 1341 + 1342 + mmc_remove_host(mmc); 1343 + clk_disable(host->clk); 1344 + } 1345 + 1334 1346 static int __devexit s3cmci_remove(struct platform_device *pdev) 1335 1347 { 1336 1348 struct mmc_host *mmc = platform_get_drvdata(pdev); 1337 1349 struct s3cmci_host *host = mmc_priv(mmc); 1338 1350 1339 - mmc_remove_host(mmc); 1351 + s3cmci_shutdown(pdev); 1340 1352 1341 - clk_disable(host->clk); 1342 1353 clk_put(host->clk); 1343 1354 1344 1355 tasklet_disable(&host->pio_tasklet); 1345 1356 s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client); 1346 1357 1347 - if (host->irq_cd >= 0) 1348 - free_irq(host->irq_cd, host); 1349 1358 free_irq(host->irq, host); 1350 1359 1351 1360 iounmap(host->base); ··· 1364 1355 return 0; 1365 1356 } 1366 1357 1367 - static int __devinit s3cmci_probe_2410(struct platform_device *dev) 1358 + static int __devinit s3cmci_2410_probe(struct platform_device *dev) 1368 1359 { 1369 1360 return s3cmci_probe(dev, 0); 1370 1361 } 1371 1362 1372 - static int __devinit s3cmci_probe_2412(struct platform_device *dev) 1363 + static int __devinit s3cmci_2412_probe(struct platform_device *dev) 1373 1364 { 1374 1365 return s3cmci_probe(dev, 1); 1375 1366 } 1376 1367 1377 - static int __devinit s3cmci_probe_2440(struct platform_device *dev) 1368 + static int __devinit s3cmci_2440_probe(struct platform_device *dev) 1378 1369 { 1379 1370 return s3cmci_probe(dev, 1); 1380 1371 } ··· 1401 1392 #endif /* CONFIG_PM */ 1402 1393 1403 1394 1404 - static struct platform_driver s3cmci_driver_2410 = { 1395 + static struct platform_driver s3cmci_2410_driver = { 1405 1396 .driver.name = "s3c2410-sdi", 1406 1397 .driver.owner = THIS_MODULE, 1407 - .probe = s3cmci_probe_2410, 1398 + .probe = s3cmci_2410_probe, 1408 1399 .remove = __devexit_p(s3cmci_remove), 1400 + .shutdown = s3cmci_shutdown, 1409 1401 .suspend = s3cmci_suspend, 1410 1402 .resume = s3cmci_resume, 1411 1403 }; 1412 1404 1413 - static struct platform_driver s3cmci_driver_2412 = { 1405 + static struct platform_driver s3cmci_2412_driver = { 1414 1406 .driver.name = "s3c2412-sdi", 1415 1407 .driver.owner = THIS_MODULE, 1416 - .probe = s3cmci_probe_2412, 1408 + .probe = s3cmci_2412_probe, 1417 1409 .remove = __devexit_p(s3cmci_remove), 1410 + .shutdown = s3cmci_shutdown, 1418 1411 .suspend = s3cmci_suspend, 1419 1412 .resume = s3cmci_resume, 1420 1413 }; 1421 1414 1422 - static struct platform_driver s3cmci_driver_2440 = { 1415 + static struct platform_driver s3cmci_2440_driver = { 1423 1416 .driver.name = "s3c2440-sdi", 1424 1417 .driver.owner = THIS_MODULE, 1425 - .probe = s3cmci_probe_2440, 1418 + .probe = s3cmci_2440_probe, 1426 1419 .remove = __devexit_p(s3cmci_remove), 1420 + .shutdown = s3cmci_shutdown, 1427 1421 .suspend = s3cmci_suspend, 1428 1422 .resume = s3cmci_resume, 1429 1423 }; ··· 1434 1422 1435 1423 static int __init s3cmci_init(void) 1436 1424 { 1437 - platform_driver_register(&s3cmci_driver_2410); 1438 - platform_driver_register(&s3cmci_driver_2412); 1439 - platform_driver_register(&s3cmci_driver_2440); 1425 + platform_driver_register(&s3cmci_2410_driver); 1426 + platform_driver_register(&s3cmci_2412_driver); 1427 + platform_driver_register(&s3cmci_2440_driver); 1440 1428 return 0; 1441 1429 } 1442 1430 1443 1431 static void __exit s3cmci_exit(void) 1444 1432 { 1445 - platform_driver_unregister(&s3cmci_driver_2410); 1446 - platform_driver_unregister(&s3cmci_driver_2412); 1447 - platform_driver_unregister(&s3cmci_driver_2440); 1433 + platform_driver_unregister(&s3cmci_2410_driver); 1434 + platform_driver_unregister(&s3cmci_2412_driver); 1435 + platform_driver_unregister(&s3cmci_2440_driver); 1448 1436 } 1449 1437 1450 1438 module_init(s3cmci_init);
+73 -90
drivers/mmc/host/sdhci.c
··· 173 173 * * 174 174 \*****************************************************************************/ 175 175 176 - static inline char* sdhci_sg_to_buffer(struct sdhci_host* host) 177 - { 178 - return sg_virt(host->cur_sg); 179 - } 180 - 181 - static inline int sdhci_next_sg(struct sdhci_host* host) 182 - { 183 - /* 184 - * Skip to next SG entry. 185 - */ 186 - host->cur_sg++; 187 - host->num_sg--; 188 - 189 - /* 190 - * Any entries left? 191 - */ 192 - if (host->num_sg > 0) { 193 - host->offset = 0; 194 - host->remain = host->cur_sg->length; 195 - } 196 - 197 - return host->num_sg; 198 - } 199 - 200 176 static void sdhci_read_block_pio(struct sdhci_host *host) 201 177 { 202 - int blksize, chunk_remain; 203 - u32 data; 204 - char *buffer; 205 - int size; 178 + unsigned long flags; 179 + size_t blksize, len, chunk; 180 + u32 scratch; 181 + u8 *buf; 206 182 207 183 DBG("PIO reading\n"); 208 184 209 185 blksize = host->data->blksz; 210 - chunk_remain = 0; 211 - data = 0; 186 + chunk = 0; 212 187 213 - buffer = sdhci_sg_to_buffer(host) + host->offset; 188 + local_irq_save(flags); 214 189 215 190 while (blksize) { 216 - if (chunk_remain == 0) { 217 - data = readl(host->ioaddr + SDHCI_BUFFER); 218 - chunk_remain = min(blksize, 4); 219 - } 191 + if (!sg_miter_next(&host->sg_miter)) 192 + BUG(); 220 193 221 - size = min(host->remain, chunk_remain); 194 + len = min(host->sg_miter.length, blksize); 222 195 223 - chunk_remain -= size; 224 - blksize -= size; 225 - host->offset += size; 226 - host->remain -= size; 196 + blksize -= len; 197 + host->sg_miter.consumed = len; 227 198 228 - while (size) { 229 - *buffer = data & 0xFF; 230 - buffer++; 231 - data >>= 8; 232 - size--; 233 - } 199 + buf = host->sg_miter.addr; 234 200 235 - if (host->remain == 0) { 236 - if (sdhci_next_sg(host) == 0) { 237 - BUG_ON(blksize != 0); 238 - return; 201 + while (len) { 202 + if (chunk == 0) { 203 + scratch = readl(host->ioaddr + SDHCI_BUFFER); 204 + chunk = 4; 239 205 } 240 - buffer = sdhci_sg_to_buffer(host); 206 + 207 + *buf = scratch & 0xFF; 208 + 209 + buf++; 210 + scratch >>= 8; 211 + chunk--; 212 + len--; 241 213 } 242 214 } 215 + 216 + sg_miter_stop(&host->sg_miter); 217 + 218 + local_irq_restore(flags); 243 219 } 244 220 245 221 static void sdhci_write_block_pio(struct sdhci_host *host) 246 222 { 247 - int blksize, chunk_remain; 248 - u32 data; 249 - char *buffer; 250 - int bytes, size; 223 + unsigned long flags; 224 + size_t blksize, len, chunk; 225 + u32 scratch; 226 + u8 *buf; 251 227 252 228 DBG("PIO writing\n"); 253 229 254 230 blksize = host->data->blksz; 255 - chunk_remain = 4; 256 - data = 0; 231 + chunk = 0; 232 + scratch = 0; 257 233 258 - bytes = 0; 259 - buffer = sdhci_sg_to_buffer(host) + host->offset; 234 + local_irq_save(flags); 260 235 261 236 while (blksize) { 262 - size = min(host->remain, chunk_remain); 237 + if (!sg_miter_next(&host->sg_miter)) 238 + BUG(); 263 239 264 - chunk_remain -= size; 265 - blksize -= size; 266 - host->offset += size; 267 - host->remain -= size; 240 + len = min(host->sg_miter.length, blksize); 268 241 269 - while (size) { 270 - data >>= 8; 271 - data |= (u32)*buffer << 24; 272 - buffer++; 273 - size--; 274 - } 242 + blksize -= len; 243 + host->sg_miter.consumed = len; 275 244 276 - if (chunk_remain == 0) { 277 - writel(data, host->ioaddr + SDHCI_BUFFER); 278 - chunk_remain = min(blksize, 4); 279 - } 245 + buf = host->sg_miter.addr; 280 246 281 - if (host->remain == 0) { 282 - if (sdhci_next_sg(host) == 0) { 283 - BUG_ON(blksize != 0); 284 - return; 247 + while (len) { 248 + scratch |= (u32)*buf << (chunk * 8); 249 + 250 + buf++; 251 + chunk++; 252 + len--; 253 + 254 + if ((chunk == 4) || ((len == 0) && (blksize == 0))) { 255 + writel(scratch, host->ioaddr + SDHCI_BUFFER); 256 + chunk = 0; 257 + scratch = 0; 285 258 } 286 - buffer = sdhci_sg_to_buffer(host); 287 259 } 288 260 } 261 + 262 + sg_miter_stop(&host->sg_miter); 263 + 264 + local_irq_restore(flags); 289 265 } 290 266 291 267 static void sdhci_transfer_pio(struct sdhci_host *host) ··· 270 294 271 295 BUG_ON(!host->data); 272 296 273 - if (host->num_sg == 0) 297 + if (host->blocks == 0) 274 298 return; 275 299 276 300 if (host->data->flags & MMC_DATA_READ) ··· 284 308 else 285 309 sdhci_write_block_pio(host); 286 310 287 - if (host->num_sg == 0) 311 + host->blocks--; 312 + if (host->blocks == 0) 288 313 break; 289 314 } 290 315 ··· 366 389 if (offset) { 367 390 if (data->flags & MMC_DATA_WRITE) { 368 391 buffer = sdhci_kmap_atomic(sg, &flags); 392 + WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); 369 393 memcpy(align, buffer, offset); 370 394 sdhci_kunmap_atomic(buffer, &flags); 371 395 } ··· 488 510 size = 4 - (sg_dma_address(sg) & 0x3); 489 511 490 512 buffer = sdhci_kmap_atomic(sg, &flags); 513 + WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); 491 514 memcpy(buffer, align, size); 492 515 sdhci_kunmap_atomic(buffer, &flags); 493 516 ··· 666 687 WARN_ON(1); 667 688 host->flags &= ~SDHCI_USE_DMA; 668 689 } else { 669 - WARN_ON(count != 1); 690 + WARN_ON(sg_cnt != 1); 670 691 writel(sg_dma_address(data->sg), 671 692 host->ioaddr + SDHCI_DMA_ADDRESS); 672 693 } ··· 690 711 } 691 712 692 713 if (!(host->flags & SDHCI_REQ_USE_DMA)) { 693 - host->cur_sg = data->sg; 694 - host->num_sg = data->sg_len; 695 - 696 - host->offset = 0; 697 - host->remain = host->cur_sg->length; 714 + sg_miter_start(&host->sg_miter, 715 + data->sg, data->sg_len, SG_MITER_ATOMIC); 716 + host->blocks = data->blocks; 698 717 } 699 718 700 719 /* We do not handle DMA boundaries, so set it to max (512 KiB) */ ··· 1558 1581 } 1559 1582 } 1560 1583 1561 - /* XXX: Hack to get MMC layer to avoid highmem */ 1562 - if (!(host->flags & SDHCI_USE_DMA)) 1563 - mmc_dev(host->mmc)->dma_mask = NULL; 1584 + /* 1585 + * If we use DMA, then it's up to the caller to set the DMA 1586 + * mask, but PIO does not need the hw shim so we set a new 1587 + * mask here in that case. 1588 + */ 1589 + if (!(host->flags & SDHCI_USE_DMA)) { 1590 + host->dma_mask = DMA_BIT_MASK(64); 1591 + mmc_dev(host->mmc)->dma_mask = &host->dma_mask; 1592 + } 1564 1593 1565 1594 host->max_clk = 1566 1595 (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+3 -4
drivers/mmc/host/sdhci.h
··· 212 212 213 213 /* Internal data */ 214 214 struct mmc_host *mmc; /* MMC structure */ 215 + u64 dma_mask; /* custom DMA mask */ 215 216 216 217 #ifdef CONFIG_LEDS_CLASS 217 218 struct led_classdev led; /* LED control */ ··· 239 238 struct mmc_data *data; /* Current data request */ 240 239 unsigned int data_early:1; /* Data finished before cmd */ 241 240 242 - struct scatterlist *cur_sg; /* We're working on this */ 243 - int num_sg; /* Entries left */ 244 - int offset; /* Offset into current sg */ 245 - int remain; /* Bytes left in current */ 241 + struct sg_mapping_iter sg_miter; /* SG state for PIO */ 242 + unsigned int blocks; /* remaining PIO blocks */ 246 243 247 244 int sg_count; /* Mapped sg entries */ 248 245
+38
include/linux/scatterlist.h
··· 224 224 */ 225 225 #define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist)) 226 226 227 + 228 + /* 229 + * Mapping sg iterator 230 + * 231 + * Iterates over sg entries mapping page-by-page. On each successful 232 + * iteration, @miter->page points to the mapped page and 233 + * @miter->length bytes of data can be accessed at @miter->addr. As 234 + * long as an interation is enclosed between start and stop, the user 235 + * is free to choose control structure and when to stop. 236 + * 237 + * @miter->consumed is set to @miter->length on each iteration. It 238 + * can be adjusted if the user can't consume all the bytes in one go. 239 + * Also, a stopped iteration can be resumed by calling next on it. 240 + * This is useful when iteration needs to release all resources and 241 + * continue later (e.g. at the next interrupt). 242 + */ 243 + 244 + #define SG_MITER_ATOMIC (1 << 0) /* use kmap_atomic */ 245 + 246 + struct sg_mapping_iter { 247 + /* the following three fields can be accessed directly */ 248 + struct page *page; /* currently mapped page */ 249 + void *addr; /* pointer to the mapped area */ 250 + size_t length; /* length of the mapped area */ 251 + size_t consumed; /* number of consumed bytes */ 252 + 253 + /* these are internal states, keep away */ 254 + struct scatterlist *__sg; /* current entry */ 255 + unsigned int __nents; /* nr of remaining entries */ 256 + unsigned int __offset; /* offset within sg */ 257 + unsigned int __flags; 258 + }; 259 + 260 + void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl, 261 + unsigned int nents, unsigned int flags); 262 + bool sg_miter_next(struct sg_mapping_iter *miter); 263 + void sg_miter_stop(struct sg_mapping_iter *miter); 264 + 227 265 #endif /* _LINUX_SCATTERLIST_H */
+126 -42
lib/scatterlist.c
··· 295 295 EXPORT_SYMBOL(sg_alloc_table); 296 296 297 297 /** 298 + * sg_miter_start - start mapping iteration over a sg list 299 + * @miter: sg mapping iter to be started 300 + * @sgl: sg list to iterate over 301 + * @nents: number of sg entries 302 + * 303 + * Description: 304 + * Starts mapping iterator @miter. 305 + * 306 + * Context: 307 + * Don't care. 308 + */ 309 + void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl, 310 + unsigned int nents, unsigned int flags) 311 + { 312 + memset(miter, 0, sizeof(struct sg_mapping_iter)); 313 + 314 + miter->__sg = sgl; 315 + miter->__nents = nents; 316 + miter->__offset = 0; 317 + miter->__flags = flags; 318 + } 319 + EXPORT_SYMBOL(sg_miter_start); 320 + 321 + /** 322 + * sg_miter_next - proceed mapping iterator to the next mapping 323 + * @miter: sg mapping iter to proceed 324 + * 325 + * Description: 326 + * Proceeds @miter@ to the next mapping. @miter@ should have been 327 + * started using sg_miter_start(). On successful return, 328 + * @miter@->page, @miter@->addr and @miter@->length point to the 329 + * current mapping. 330 + * 331 + * Context: 332 + * IRQ disabled if SG_MITER_ATOMIC. IRQ must stay disabled till 333 + * @miter@ is stopped. May sleep if !SG_MITER_ATOMIC. 334 + * 335 + * Returns: 336 + * true if @miter contains the next mapping. false if end of sg 337 + * list is reached. 338 + */ 339 + bool sg_miter_next(struct sg_mapping_iter *miter) 340 + { 341 + unsigned int off, len; 342 + 343 + /* check for end and drop resources from the last iteration */ 344 + if (!miter->__nents) 345 + return false; 346 + 347 + sg_miter_stop(miter); 348 + 349 + /* get to the next sg if necessary. __offset is adjusted by stop */ 350 + if (miter->__offset == miter->__sg->length && --miter->__nents) { 351 + miter->__sg = sg_next(miter->__sg); 352 + miter->__offset = 0; 353 + } 354 + 355 + /* map the next page */ 356 + off = miter->__sg->offset + miter->__offset; 357 + len = miter->__sg->length - miter->__offset; 358 + 359 + miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT); 360 + off &= ~PAGE_MASK; 361 + miter->length = min_t(unsigned int, len, PAGE_SIZE - off); 362 + miter->consumed = miter->length; 363 + 364 + if (miter->__flags & SG_MITER_ATOMIC) 365 + miter->addr = kmap_atomic(miter->page, KM_BIO_SRC_IRQ) + off; 366 + else 367 + miter->addr = kmap(miter->page) + off; 368 + 369 + return true; 370 + } 371 + EXPORT_SYMBOL(sg_miter_next); 372 + 373 + /** 374 + * sg_miter_stop - stop mapping iteration 375 + * @miter: sg mapping iter to be stopped 376 + * 377 + * Description: 378 + * Stops mapping iterator @miter. @miter should have been started 379 + * started using sg_miter_start(). A stopped iteration can be 380 + * resumed by calling sg_miter_next() on it. This is useful when 381 + * resources (kmap) need to be released during iteration. 382 + * 383 + * Context: 384 + * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise. 385 + */ 386 + void sg_miter_stop(struct sg_mapping_iter *miter) 387 + { 388 + WARN_ON(miter->consumed > miter->length); 389 + 390 + /* drop resources from the last iteration */ 391 + if (miter->addr) { 392 + miter->__offset += miter->consumed; 393 + 394 + if (miter->__flags & SG_MITER_ATOMIC) { 395 + WARN_ON(!irqs_disabled()); 396 + kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ); 397 + } else 398 + kunmap(miter->addr); 399 + 400 + miter->page = NULL; 401 + miter->addr = NULL; 402 + miter->length = 0; 403 + miter->consumed = 0; 404 + } 405 + } 406 + EXPORT_SYMBOL(sg_miter_stop); 407 + 408 + /** 298 409 * sg_copy_buffer - Copy data between a linear buffer and an SG list 299 410 * @sgl: The SG list 300 411 * @nents: Number of SG entries ··· 420 309 static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, 421 310 void *buf, size_t buflen, int to_buffer) 422 311 { 423 - struct scatterlist *sg; 424 - size_t buf_off = 0; 425 - int i; 312 + unsigned int offset = 0; 313 + struct sg_mapping_iter miter; 426 314 427 - WARN_ON(!irqs_disabled()); 315 + sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC); 428 316 429 - for_each_sg(sgl, sg, nents, i) { 430 - struct page *page; 431 - int n = 0; 432 - unsigned int sg_off = sg->offset; 433 - unsigned int sg_copy = sg->length; 317 + while (sg_miter_next(&miter) && offset < buflen) { 318 + unsigned int len; 434 319 435 - if (sg_copy > buflen) 436 - sg_copy = buflen; 437 - buflen -= sg_copy; 320 + len = min(miter.length, buflen - offset); 438 321 439 - while (sg_copy > 0) { 440 - unsigned int page_copy; 441 - void *p; 442 - 443 - page_copy = PAGE_SIZE - sg_off; 444 - if (page_copy > sg_copy) 445 - page_copy = sg_copy; 446 - 447 - page = nth_page(sg_page(sg), n); 448 - p = kmap_atomic(page, KM_BIO_SRC_IRQ); 449 - 450 - if (to_buffer) 451 - memcpy(buf + buf_off, p + sg_off, page_copy); 452 - else { 453 - memcpy(p + sg_off, buf + buf_off, page_copy); 454 - flush_kernel_dcache_page(page); 455 - } 456 - 457 - kunmap_atomic(p, KM_BIO_SRC_IRQ); 458 - 459 - buf_off += page_copy; 460 - sg_off += page_copy; 461 - if (sg_off == PAGE_SIZE) { 462 - sg_off = 0; 463 - n++; 464 - } 465 - sg_copy -= page_copy; 322 + if (to_buffer) 323 + memcpy(buf + offset, miter.addr, len); 324 + else { 325 + memcpy(miter.addr, buf + offset, len); 326 + flush_kernel_dcache_page(miter.page); 466 327 } 467 328 468 - if (!buflen) 469 - break; 329 + offset += len; 470 330 } 471 331 472 - return buf_off; 332 + sg_miter_stop(&miter); 333 + 334 + return offset; 473 335 } 474 336 475 337 /**