MTD fixes for 4.0
* pxa3xx_nand - fix timeout issues when draining the FIFO (BCH only) - don't crash when no chip-selects are used * hisi504_nand - depend on HAS_DMA, to fix compile errors -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU/4s9AAoJEFySrpd9RFgtTp8P/AoOj+FoRZAjIcr1oRRvIj68 gUJTihk/2caf4PzLek1mk2BMHbs3axvnyNEGyXeTkPBnM03ZSMkq0MCdCF+qpGpV qWnkUG3Q1SlMTkhOr1Uq28DZpkx5PVi5j859wKxw9wfkprUXb5JksX2qno+Hmfet +CYp+65tU/6xNeaLGtDawfxvsVXEn40hKfP7JGYfyrrbQ3jEcCuZRm19fDb+JtTg W8oBR08CwSoOKmpcNyltHsjlmDiF35/u0pdfIZxym1BFWyLXAsmV723MtI9J2ILG hEHZZwG3rxyrV/JBFl6sPlcyU6zQGmXl3rCrEoK/rxqmY00gY2x9fsqGCJOUls+u A6aCoIjlJ/EOuRBm+wpyEopuljZ6ybVAkdMRmiY2cIt1oOcvMtkRQzw+I+9i/fLa qQuhqPlEFwB63TCsi/xVwNL8VXpeBfhsSTAeE/y2ZJFuKmOym040eoENKWoEThY/ 8Nhma3sLazeSCW4vX1r5glPP0sseARo0/z9HhzjRe249VBjR7Zz60/GoF4cCXW63 RJNXHfvxPbWvOPizT6x6HxlGcZX6dq18wgvBV46uxX2a0X3r1G3qtluyrNZHO3ab T2lG8Yx44uN+Bwbaxh74UB/RgvDBxeNoVf5onc+u1MhN1QU/09NfroLIY5eLEDcf d0+yZdOFKvYjY7pU1SFa =GF4t -----END PGP SIGNATURE----- Merge tag 'for-linus-20150310' of git://git.infradead.org/linux-mtd Pull MTD fixes from Brian Norris: * pxa3xx_nand - fix timeout issues when draining the FIFO (BCH only) - don't crash when no chip-selects are used * hisi504_nand - depend on HAS_DMA, to fix compile errors * tag 'for-linus-20150310' of git://git.infradead.org/linux-mtd: mtd: nand: MTD_NAND_HISI504 should depend on HAS_DMA mtd: pxa3xx_nand: fix driver when num_cs is 0 mtd: nand: pxa3xx: Fix PIO FIFO draining
This commit is contained in:
Коммит
cca28a5fda
|
@ -526,6 +526,7 @@ config MTD_NAND_SUNXI
|
|||
|
||||
config MTD_NAND_HISI504
|
||||
tristate "Support for NAND controller on Hisilicon SoC Hip04"
|
||||
depends on HAS_DMA
|
||||
help
|
||||
Enables support for NAND controller on Hisilicon SoC Hip04.
|
||||
|
||||
|
|
|
@ -480,6 +480,42 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
|
|||
nand_writel(info, NDCR, ndcr | int_mask);
|
||||
}
|
||||
|
||||
static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len)
|
||||
{
|
||||
if (info->ecc_bch) {
|
||||
int timeout;
|
||||
|
||||
/*
|
||||
* According to the datasheet, when reading from NDDB
|
||||
* with BCH enabled, after each 32 bytes reads, we
|
||||
* have to make sure that the NDSR.RDDREQ bit is set.
|
||||
*
|
||||
* Drain the FIFO 8 32 bits reads at a time, and skip
|
||||
* the polling on the last read.
|
||||
*/
|
||||
while (len > 8) {
|
||||
__raw_readsl(info->mmio_base + NDDB, data, 8);
|
||||
|
||||
for (timeout = 0;
|
||||
!(nand_readl(info, NDSR) & NDSR_RDDREQ);
|
||||
timeout++) {
|
||||
if (timeout >= 5) {
|
||||
dev_err(&info->pdev->dev,
|
||||
"Timeout on RDDREQ while draining the FIFO\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
data += 32;
|
||||
len -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
__raw_readsl(info->mmio_base + NDDB, data, len);
|
||||
}
|
||||
|
||||
static void handle_data_pio(struct pxa3xx_nand_info *info)
|
||||
{
|
||||
unsigned int do_bytes = min(info->data_size, info->chunk_size);
|
||||
|
@ -496,14 +532,14 @@ static void handle_data_pio(struct pxa3xx_nand_info *info)
|
|||
DIV_ROUND_UP(info->oob_size, 4));
|
||||
break;
|
||||
case STATE_PIO_READING:
|
||||
__raw_readsl(info->mmio_base + NDDB,
|
||||
info->data_buff + info->data_buff_pos,
|
||||
DIV_ROUND_UP(do_bytes, 4));
|
||||
drain_fifo(info,
|
||||
info->data_buff + info->data_buff_pos,
|
||||
DIV_ROUND_UP(do_bytes, 4));
|
||||
|
||||
if (info->oob_size > 0)
|
||||
__raw_readsl(info->mmio_base + NDDB,
|
||||
info->oob_buff + info->oob_buff_pos,
|
||||
DIV_ROUND_UP(info->oob_size, 4));
|
||||
drain_fifo(info,
|
||||
info->oob_buff + info->oob_buff_pos,
|
||||
DIV_ROUND_UP(info->oob_size, 4));
|
||||
break;
|
||||
default:
|
||||
dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
|
||||
|
@ -1572,6 +1608,8 @@ static int alloc_nand_resource(struct platform_device *pdev)
|
|||
int ret, irq, cs;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (pdata->num_cs <= 0)
|
||||
return -ENODEV;
|
||||
info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
|
||||
sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
|
||||
if (!info)
|
||||
|
|
Загрузка…
Ссылка в новой задаче