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:
@@ -526,6 +526,7 @@ config MTD_NAND_SUNXI
|
|||||||
|
|
||||||
config MTD_NAND_HISI504
|
config MTD_NAND_HISI504
|
||||||
tristate "Support for NAND controller on Hisilicon SoC Hip04"
|
tristate "Support for NAND controller on Hisilicon SoC Hip04"
|
||||||
|
depends on HAS_DMA
|
||||||
help
|
help
|
||||||
Enables support for NAND controller on Hisilicon SoC Hip04.
|
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);
|
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)
|
static void handle_data_pio(struct pxa3xx_nand_info *info)
|
||||||
{
|
{
|
||||||
unsigned int do_bytes = min(info->data_size, info->chunk_size);
|
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));
|
DIV_ROUND_UP(info->oob_size, 4));
|
||||||
break;
|
break;
|
||||||
case STATE_PIO_READING:
|
case STATE_PIO_READING:
|
||||||
__raw_readsl(info->mmio_base + NDDB,
|
drain_fifo(info,
|
||||||
info->data_buff + info->data_buff_pos,
|
info->data_buff + info->data_buff_pos,
|
||||||
DIV_ROUND_UP(do_bytes, 4));
|
DIV_ROUND_UP(do_bytes, 4));
|
||||||
|
|
||||||
if (info->oob_size > 0)
|
if (info->oob_size > 0)
|
||||||
__raw_readsl(info->mmio_base + NDDB,
|
drain_fifo(info,
|
||||||
info->oob_buff + info->oob_buff_pos,
|
info->oob_buff + info->oob_buff_pos,
|
||||||
DIV_ROUND_UP(info->oob_size, 4));
|
DIV_ROUND_UP(info->oob_size, 4));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
|
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;
|
int ret, irq, cs;
|
||||||
|
|
||||||
pdata = dev_get_platdata(&pdev->dev);
|
pdata = dev_get_platdata(&pdev->dev);
|
||||||
|
if (pdata->num_cs <= 0)
|
||||||
|
return -ENODEV;
|
||||||
info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
|
info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
|
||||||
sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
|
sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
|
||||||
if (!info)
|
if (!info)
|
||||||
|
Reference in New Issue
Block a user