aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorRostislav Lisovy <lisovy@gmail.com>2014-10-29 06:10:59 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-11-05 16:01:22 -0500
commit1dc338e856744b8ca62addd1e29cc25fe6aae14d (patch)
treecb1adf5004dc038dc744e0f2f85309c7ddca4c2c /drivers/mtd
parent4414d3efe57df6168d1ea564d56557d76b5ad8c7 (diff)
mtd: nand: omap: Synchronize the access to the ECC engine
The AM335x Technical Reference Manual (spruh73j.pdf) says "Because the ECC engine includes only one accumulation context, it can be allocated to only one chip-select at a time ... " (7.1.3.3.12.3). Since the commit 97a288ba2cfa ("ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc()") gpmc-nand driver supports multiple NAND flash devices connected to the single controller. Use global 'struct nand_hw_control' among multiple NAND instances to synchronize the access to the single ECC Engine. Tested with custom AM335x board using 2x NAND flash chips. Signed-off-by: Rostislav Lisovy <lisovy@merica.cz> Acked-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/omap2.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index b0f89d87de89..1ec0a1dbed3d 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -144,8 +144,13 @@ static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
144 0xac, 0x6b, 0xff, 0x99, 0x7b}; 144 0xac, 0x6b, 0xff, 0x99, 0x7b};
145static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; 145static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
146 146
147/* Shared among all NAND instances to synchronize access to the ECC Engine */
148static struct nand_hw_control omap_gpmc_controller = {
149 .lock = __SPIN_LOCK_UNLOCKED(omap_gpmc_controller.lock),
150 .wq = __WAIT_QUEUE_HEAD_INITIALIZER(omap_gpmc_controller.wq),
151};
152
147struct omap_nand_info { 153struct omap_nand_info {
148 struct nand_hw_control controller;
149 struct omap_nand_platform_data *pdata; 154 struct omap_nand_platform_data *pdata;
150 struct mtd_info mtd; 155 struct mtd_info mtd;
151 struct nand_chip nand; 156 struct nand_chip nand;
@@ -1685,9 +1690,6 @@ static int omap_nand_probe(struct platform_device *pdev)
1685 1690
1686 platform_set_drvdata(pdev, info); 1691 platform_set_drvdata(pdev, info);
1687 1692
1688 spin_lock_init(&info->controller.lock);
1689 init_waitqueue_head(&info->controller.wq);
1690
1691 info->pdev = pdev; 1693 info->pdev = pdev;
1692 info->gpmc_cs = pdata->cs; 1694 info->gpmc_cs = pdata->cs;
1693 info->reg = pdata->reg; 1695 info->reg = pdata->reg;
@@ -1707,7 +1709,7 @@ static int omap_nand_probe(struct platform_device *pdev)
1707 1709
1708 info->phys_base = res->start; 1710 info->phys_base = res->start;
1709 1711
1710 nand_chip->controller = &info->controller; 1712 nand_chip->controller = &omap_gpmc_controller;
1711 1713
1712 nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R; 1714 nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
1713 nand_chip->cmd_ctrl = omap_hwcontrol; 1715 nand_chip->cmd_ctrl = omap_hwcontrol;