diff options
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch b/target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch new file mode 100644 index 0000000000..09f022b967 --- /dev/null +++ b/target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch @@ -0,0 +1,143 @@ +From 71d6267980d7590e38059a784785ca158e361f87 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +Date: Fri, 4 Oct 2013 15:30:38 -0300 +Subject: [PATCH 130/203] 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> +--- + drivers/mtd/nand/pxa3xx_nand.c | 45 ++++++++++++++++++++++++++++-------------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +--- a/drivers/mtd/nand/pxa3xx_nand.c ++++ b/drivers/mtd/nand/pxa3xx_nand.c +@@ -39,6 +39,13 @@ + #define NAND_STOP_DELAY (2 * HZ/50) + #define PAGE_CHUNK_SIZE (2048) + ++/* ++ * Define a buffer size for the initial command that detects the flash device: ++ * STATUS, READID and PARAM. The largest of these is the PARAM command, ++ * needing 256 bytes. ++ */ ++#define INIT_BUFFER_SIZE 256 ++ + /* registers and bit definitions */ + #define NDCR (0x00) /* Control register */ + #define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */ +@@ -164,6 +171,7 @@ struct pxa3xx_nand_info { + + unsigned int buf_start; + unsigned int buf_count; ++ unsigned int buf_size; + + /* DMA information */ + int drcmr_dat; +@@ -911,26 +919,20 @@ static int pxa3xx_nand_detect_config(str + return 0; + } + +-/* the maximum possible buffer size for large page with OOB data +- * is: 2048 + 64 = 2112 bytes, allocate a page here for both the +- * data buffer and the DMA descriptor +- */ +-#define MAX_BUFF_SIZE PAGE_SIZE +- + #ifdef ARCH_HAS_DMA + static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) + { + struct platform_device *pdev = info->pdev; +- int data_desc_offset = MAX_BUFF_SIZE - sizeof(struct pxa_dma_desc); ++ int data_desc_offset = info->buf_size - sizeof(struct pxa_dma_desc); + + if (use_dma == 0) { +- info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL); ++ info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); + if (info->data_buff == NULL) + return -ENOMEM; + return 0; + } + +- info->data_buff = dma_alloc_coherent(&pdev->dev, MAX_BUFF_SIZE, ++ info->data_buff = dma_alloc_coherent(&pdev->dev, info->buf_size, + &info->data_buff_phys, GFP_KERNEL); + if (info->data_buff == NULL) { + dev_err(&pdev->dev, "failed to allocate dma buffer\n"); +@@ -944,7 +946,7 @@ static int pxa3xx_nand_init_buff(struct + pxa3xx_nand_data_dma_irq, info); + if (info->data_dma_ch < 0) { + dev_err(&pdev->dev, "failed to request data dma\n"); +- dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE, ++ dma_free_coherent(&pdev->dev, info->buf_size, + info->data_buff, info->data_buff_phys); + return info->data_dma_ch; + } +@@ -962,7 +964,7 @@ static void pxa3xx_nand_free_buff(struct + struct platform_device *pdev = info->pdev; + if (use_dma) { + pxa_free_dma(info->data_dma_ch); +- dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE, ++ dma_free_coherent(&pdev->dev, info->buf_size, + info->data_buff, info->data_buff_phys); + } else { + kfree(info->data_buff); +@@ -971,7 +973,7 @@ static void pxa3xx_nand_free_buff(struct + #else + static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) + { +- info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL); ++ info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); + if (info->data_buff == NULL) + return -ENOMEM; + return 0; +@@ -1085,7 +1087,16 @@ KEEP_CONFIG: + else + host->col_addr_cycles = 1; + ++ /* release the initial buffer */ ++ kfree(info->data_buff); ++ ++ /* allocate the real data + oob buffer */ ++ info->buf_size = mtd->writesize + mtd->oobsize; ++ ret = pxa3xx_nand_init_buff(info); ++ if (ret) ++ return ret; + info->oob_buff = info->data_buff + mtd->writesize; ++ + if ((mtd->size >> chip->page_shift) > 65536) + host->row_addr_cycles = 3; + else +@@ -1191,9 +1202,13 @@ static int alloc_nand_resource(struct pl + } + info->mmio_phys = r->start; + +- ret = pxa3xx_nand_init_buff(info); +- if (ret) ++ /* Allocate a buffer to allow flash detection */ ++ info->buf_size = INIT_BUFFER_SIZE; ++ info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); ++ if (info->data_buff == NULL) { ++ ret = -ENOMEM; + goto fail_disable_clk; ++ } + + /* initialize all interrupts to be disabled */ + disable_int(info, NDSR_MASK); +@@ -1211,7 +1226,7 @@ static int alloc_nand_resource(struct pl + + fail_free_buf: + free_irq(irq, info); +- pxa3xx_nand_free_buff(info); ++ kfree(info->data_buff); + fail_disable_clk: + clk_disable_unprepare(info->clk); + return ret; |