summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/brcmnand
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/brcmnand')
-rw-r--r--drivers/mtd/nand/brcmnand/brcmnand.c15
-rw-r--r--drivers/mtd/nand/brcmnand/brcmnand.h13
-rw-r--r--drivers/mtd/nand/brcmnand/iproc_nand.c18
3 files changed, 29 insertions, 17 deletions
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index 8eb2c64df38c..9d2424bfdbf5 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -1336,7 +1336,7 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command,
u32 *flash_cache = (u32 *)ctrl->flash_cache;
int i;
- brcmnand_soc_data_bus_prepare(ctrl->soc);
+ brcmnand_soc_data_bus_prepare(ctrl->soc, true);
/*
* Must cache the FLASH_CACHE now, since changes in
@@ -1349,7 +1349,7 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command,
*/
flash_cache[i] = be32_to_cpu(brcmnand_read_fc(ctrl, i));
- brcmnand_soc_data_bus_unprepare(ctrl->soc);
+ brcmnand_soc_data_bus_unprepare(ctrl->soc, true);
/* Cleanup from HW quirk: restore SECTOR_SIZE_1K */
if (host->hwcfg.sector_size_1k)
@@ -1565,12 +1565,12 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
brcmnand_waitfunc(mtd, chip);
if (likely(buf)) {
- brcmnand_soc_data_bus_prepare(ctrl->soc);
+ brcmnand_soc_data_bus_prepare(ctrl->soc, false);
for (j = 0; j < FC_WORDS; j++, buf++)
*buf = brcmnand_read_fc(ctrl, j);
- brcmnand_soc_data_bus_unprepare(ctrl->soc);
+ brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
}
if (oob)
@@ -1815,12 +1815,12 @@ static int brcmnand_write(struct mtd_info *mtd, struct nand_chip *chip,
(void)brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS);
if (buf) {
- brcmnand_soc_data_bus_prepare(ctrl->soc);
+ brcmnand_soc_data_bus_prepare(ctrl->soc, false);
for (j = 0; j < FC_WORDS; j++, buf++)
brcmnand_write_fc(ctrl, j, *buf);
- brcmnand_soc_data_bus_unprepare(ctrl->soc);
+ brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
} else if (oob) {
for (j = 0; j < FC_WORDS; j++)
brcmnand_write_fc(ctrl, j, 0xffffffff);
@@ -2370,8 +2370,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
init_completion(&ctrl->done);
init_completion(&ctrl->dma_done);
- spin_lock_init(&ctrl->controller.lock);
- init_waitqueue_head(&ctrl->controller.wq);
+ nand_hw_control_init(&ctrl->controller);
INIT_LIST_HEAD(&ctrl->host_list);
/* NAND register range */
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.h b/drivers/mtd/nand/brcmnand/brcmnand.h
index ef5eabba88e5..5c44cd4aba87 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/brcmnand/brcmnand.h
@@ -23,19 +23,22 @@ struct dev_pm_ops;
struct brcmnand_soc {
bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
- void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare);
+ void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
+ bool is_param);
};
-static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc)
+static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
+ bool is_param)
{
if (soc && soc->prepare_data_bus)
- soc->prepare_data_bus(soc, true);
+ soc->prepare_data_bus(soc, true, is_param);
}
-static inline void brcmnand_soc_data_bus_unprepare(struct brcmnand_soc *soc)
+static inline void brcmnand_soc_data_bus_unprepare(struct brcmnand_soc *soc,
+ bool is_param)
{
if (soc && soc->prepare_data_bus)
- soc->prepare_data_bus(soc, false);
+ soc->prepare_data_bus(soc, false, is_param);
}
static inline u32 brcmnand_readl(void __iomem *addr)
diff --git a/drivers/mtd/nand/brcmnand/iproc_nand.c b/drivers/mtd/nand/brcmnand/iproc_nand.c
index 585596c549b2..4c6ae113664d 100644
--- a/drivers/mtd/nand/brcmnand/iproc_nand.c
+++ b/drivers/mtd/nand/brcmnand/iproc_nand.c
@@ -74,7 +74,8 @@ static void iproc_nand_intc_set(struct brcmnand_soc *soc, bool en)
spin_unlock_irqrestore(&priv->idm_lock, flags);
}
-static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare)
+static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare,
+ bool is_param)
{
struct iproc_nand_soc *priv =
container_of(soc, struct iproc_nand_soc, soc);
@@ -86,10 +87,19 @@ static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare)
val = brcmnand_readl(mmio);
- if (prepare)
- val |= IPROC_NAND_APB_LE_MODE;
- else
+ /*
+ * In the case of BE or when dealing with NAND data, alway configure
+ * the APB bus to LE mode before accessing the FIFO and back to BE mode
+ * after the access is done
+ */
+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) || !is_param) {
+ if (prepare)
+ val |= IPROC_NAND_APB_LE_MODE;
+ else
+ val &= ~IPROC_NAND_APB_LE_MODE;
+ } else { /* when in LE accessing the parameter page, keep APB in BE */
val &= ~IPROC_NAND_APB_LE_MODE;
+ }
brcmnand_writel(val, mmio);
OpenPOWER on IntegriCloud