aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2013-10-04 14:30:38 -0400
committerBrian Norris <computersforpeace@gmail.com>2013-11-07 02:32:54 -0500
commit62e8b851783138a11da63285be0fbf69530ff73d (patch)
tree5c284713748762bc11fa9575a373a4e87aa4b187 /drivers/mtd
parent95b26563c739d5ed5101318b1bd8895773a3d872 (diff)
mtd: nand: pxa3xx: Allocate data buffer on detected flash size
This commit replaces the currently hardcoded buffer size, by a dynamic detection scheme. First a small 256 bytes buffer is allocated so the device can be detected (using READID and friends commands). After detection, this buffer is released and a new buffer is allocated to acommodate the page size plus out-of-band size. Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Tested-by: Daniel Mack <zonque@gmail.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 287997487b95..64c258ec0170 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -39,6 +39,13 @@
39#define NAND_STOP_DELAY (2 * HZ/50) 39#define NAND_STOP_DELAY (2 * HZ/50)
40#define PAGE_CHUNK_SIZE (2048) 40#define PAGE_CHUNK_SIZE (2048)
41 41
42/*
43 * Define a buffer size for the initial command that detects the flash device:
44 * STATUS, READID and PARAM. The largest of these is the PARAM command,
45 * needing 256 bytes.
46 */
47#define INIT_BUFFER_SIZE 256
48
42/* registers and bit definitions */ 49/* registers and bit definitions */
43#define NDCR (0x00) /* Control register */ 50#define NDCR (0x00) /* Control register */
44#define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */ 51#define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */
@@ -164,6 +171,7 @@ struct pxa3xx_nand_info {
164 171
165 unsigned int buf_start; 172 unsigned int buf_start;
166 unsigned int buf_count; 173 unsigned int buf_count;
174 unsigned int buf_size;
167 175
168 /* DMA information */ 176 /* DMA information */
169 int drcmr_dat; 177 int drcmr_dat;
@@ -911,26 +919,20 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
911 return 0; 919 return 0;
912} 920}
913 921
914/* the maximum possible buffer size for large page with OOB data
915 * is: 2048 + 64 = 2112 bytes, allocate a page here for both the
916 * data buffer and the DMA descriptor
917 */
918#define MAX_BUFF_SIZE PAGE_SIZE
919
920#ifdef ARCH_HAS_DMA 922#ifdef ARCH_HAS_DMA
921static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) 923static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
922{ 924{
923 struct platform_device *pdev = info->pdev; 925 struct platform_device *pdev = info->pdev;
924 int data_desc_offset = MAX_BUFF_SIZE - sizeof(struct pxa_dma_desc); 926 int data_desc_offset = info->buf_size - sizeof(struct pxa_dma_desc);
925 927
926 if (use_dma == 0) { 928 if (use_dma == 0) {
927 info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL); 929 info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
928 if (info->data_buff == NULL) 930 if (info->data_buff == NULL)
929 return -ENOMEM; 931 return -ENOMEM;
930 return 0; 932 return 0;
931 } 933 }
932 934
933 info->data_buff = dma_alloc_coherent(&pdev->dev, MAX_BUFF_SIZE, 935 info->data_buff = dma_alloc_coherent(&pdev->dev, info->buf_size,
934 &info->data_buff_phys, GFP_KERNEL); 936 &info->data_buff_phys, GFP_KERNEL);
935 if (info->data_buff == NULL) { 937 if (info->data_buff == NULL) {
936 dev_err(&pdev->dev, "failed to allocate dma buffer\n"); 938 dev_err(&pdev->dev, "failed to allocate dma buffer\n");
@@ -944,7 +946,7 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
944 pxa3xx_nand_data_dma_irq, info); 946 pxa3xx_nand_data_dma_irq, info);
945 if (info->data_dma_ch < 0) { 947 if (info->data_dma_ch < 0) {
946 dev_err(&pdev->dev, "failed to request data dma\n"); 948 dev_err(&pdev->dev, "failed to request data dma\n");
947 dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE, 949 dma_free_coherent(&pdev->dev, info->buf_size,
948 info->data_buff, info->data_buff_phys); 950 info->data_buff, info->data_buff_phys);
949 return info->data_dma_ch; 951 return info->data_dma_ch;
950 } 952 }
@@ -962,7 +964,7 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
962 struct platform_device *pdev = info->pdev; 964 struct platform_device *pdev = info->pdev;
963 if (use_dma) { 965 if (use_dma) {
964 pxa_free_dma(info->data_dma_ch); 966 pxa_free_dma(info->data_dma_ch);
965 dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE, 967 dma_free_coherent(&pdev->dev, info->buf_size,
966 info->data_buff, info->data_buff_phys); 968 info->data_buff, info->data_buff_phys);
967 } else { 969 } else {
968 kfree(info->data_buff); 970 kfree(info->data_buff);
@@ -971,7 +973,7 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
971#else 973#else
972static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) 974static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
973{ 975{
974 info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL); 976 info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
975 if (info->data_buff == NULL) 977 if (info->data_buff == NULL)
976 return -ENOMEM; 978 return -ENOMEM;
977 return 0; 979 return 0;
@@ -1085,7 +1087,16 @@ KEEP_CONFIG:
1085 else 1087 else
1086 host->col_addr_cycles = 1; 1088 host->col_addr_cycles = 1;
1087 1089
1090 /* release the initial buffer */
1091 kfree(info->data_buff);
1092
1093 /* allocate the real data + oob buffer */
1094 info->buf_size = mtd->writesize + mtd->oobsize;
1095 ret = pxa3xx_nand_init_buff(info);
1096 if (ret)
1097 return ret;
1088 info->oob_buff = info->data_buff + mtd->writesize; 1098 info->oob_buff = info->data_buff + mtd->writesize;
1099
1089 if ((mtd->size >> chip->page_shift) > 65536) 1100 if ((mtd->size >> chip->page_shift) > 65536)
1090 host->row_addr_cycles = 3; 1101 host->row_addr_cycles = 3;
1091 else 1102 else
@@ -1191,9 +1202,13 @@ static int alloc_nand_resource(struct platform_device *pdev)
1191 } 1202 }
1192 info->mmio_phys = r->start; 1203 info->mmio_phys = r->start;
1193 1204
1194 ret = pxa3xx_nand_init_buff(info); 1205 /* Allocate a buffer to allow flash detection */
1195 if (ret) 1206 info->buf_size = INIT_BUFFER_SIZE;
1207 info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
1208 if (info->data_buff == NULL) {
1209 ret = -ENOMEM;
1196 goto fail_disable_clk; 1210 goto fail_disable_clk;
1211 }
1197 1212
1198 /* initialize all interrupts to be disabled */ 1213 /* initialize all interrupts to be disabled */
1199 disable_int(info, NDSR_MASK); 1214 disable_int(info, NDSR_MASK);
@@ -1211,7 +1226,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
1211 1226
1212fail_free_buf: 1227fail_free_buf:
1213 free_irq(irq, info); 1228 free_irq(irq, info);
1214 pxa3xx_nand_free_buff(info); 1229 kfree(info->data_buff);
1215fail_disable_clk: 1230fail_disable_clk:
1216 clk_disable_unprepare(info->clk); 1231 clk_disable_unprepare(info->clk);
1217 return ret; 1232 return ret;