diff options
author | Boris BREZILLON <boris.brezillon@free-electrons.com> | 2015-11-16 14:37:34 +0100 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2015-11-19 19:59:25 +0100 |
commit | 1d8d8b5c852b6c7ae860ddc647ebb3ed3493c9a8 (patch) | |
tree | 03e12eaa397eccb39cee6ff3230a6a571b74e60b /drivers/mtd/nand/cafe_nand.c | |
parent | mtd: brcmnand: drop unused subpage_read() support (diff) | |
download | linux-1d8d8b5c852b6c7ae860ddc647ebb3ed3493c9a8.tar.xz linux-1d8d8b5c852b6c7ae860ddc647ebb3ed3493c9a8.zip |
mtd: nand: fix drivers abusing mtd->priv
The ->priv field of the mtd_info object attached to a nand_chip device
should point to the nand_chip device. The pxa and cafe drivers are
assigning this field their own private structure, which works fine as long
as the nand_chip field is the first one in the driver private struct but
seems a bit fragile.
Fix that by setting mtd->priv to point the nand_chip field and assigning
chip->priv to the private structure head.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd/nand/cafe_nand.c')
-rw-r--r-- | drivers/mtd/nand/cafe_nand.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 9de78d2a2eb1..cce3ac4939b6 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -101,7 +101,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); @@ -117,7 +118,8 @@ static int cafe_device_ready(struct mtd_info *mtd) static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; if (usedma) memcpy(cafe->dmabuf + cafe->datalen, buf, len); @@ -132,7 +134,8 @@ static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; if (usedma) memcpy(buf, cafe->dmabuf + cafe->datalen, len); @@ -146,7 +149,8 @@ static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static uint8_t cafe_read_byte(struct mtd_info *mtd) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; uint8_t d; cafe_read_buf(mtd, &d, 1); @@ -158,7 +162,8 @@ static uint8_t cafe_read_byte(struct mtd_info *mtd) static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; int adrbytes = 0; uint32_t ctl1; uint32_t doneint = 0x80000000; @@ -313,7 +318,8 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, static void cafe_select_chip(struct mtd_info *mtd, int chipnr) { - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); @@ -328,7 +334,8 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr) static irqreturn_t cafe_nand_interrupt(int irq, void *id) { struct mtd_info *mtd = id; - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); if (!irqs) @@ -377,7 +384,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct cafe_priv *cafe = mtd->priv; + struct cafe_priv *cafe = chip->priv; unsigned int max_bitflips = 0; cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", @@ -519,7 +526,7 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, const uint8_t *buf, int oob_required, int page) { - struct cafe_priv *cafe = mtd->priv; + struct cafe_priv *cafe = chip->priv; chip->write_buf(mtd, buf, mtd->writesize); chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); @@ -604,7 +611,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, cafe = (void *)(&mtd[1]); mtd->dev.parent = &pdev->dev; - mtd->priv = cafe; + mtd->priv = &cafe->nand; + cafe->nand.priv = cafe; cafe->pdev = pdev; cafe->mmio = pci_iomap(pdev, 0, 0); @@ -792,7 +800,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, static void cafe_nand_remove(struct pci_dev *pdev) { struct mtd_info *mtd = pci_get_drvdata(pdev); - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; /* Disable NAND IRQ in global IRQ mask register */ cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); @@ -819,7 +828,8 @@ static int cafe_nand_resume(struct pci_dev *pdev) { uint32_t ctrl; struct mtd_info *mtd = pci_get_drvdata(pdev); - struct cafe_priv *cafe = mtd->priv; + struct nand_chip *chip = mtd->priv; + struct cafe_priv *cafe = chip->priv; /* Start off by resetting the NAND controller completely */ cafe_writel(cafe, 1, NAND_RESET); |