From a0916c94e9143e8aa0a1fe2a64794041657e99ac Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 20 Nov 2018 11:57:17 +0100 Subject: mtd: rawnand: tmio: Do not abuse nand_controller->wq nand_controller->wq has never been meant to be used by NAND controller drivers. This waitqueue is used by the framework to serialize accesses to a NAND controller, and messing up with its state is a really bad idea. Declare a completion object in tmio_nand and use it to wait for RB transitions. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/tmio_nand.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/raw/tmio_nand.c b/drivers/mtd/nand/raw/tmio_nand.c index f3b59e649b7d..4405273898ac 100644 --- a/drivers/mtd/nand/raw/tmio_nand.c +++ b/drivers/mtd/nand/raw/tmio_nand.c @@ -104,6 +104,7 @@ struct tmio_nand { struct nand_chip chip; + struct completion comp; struct platform_device *dev; @@ -168,15 +169,11 @@ static int tmio_nand_dev_ready(struct nand_chip *chip) static irqreturn_t tmio_irq(int irq, void *__tmio) { struct tmio_nand *tmio = __tmio; - struct nand_chip *nand_chip = &tmio->chip; /* disable RDYREQ interrupt */ tmio_iowrite8(0x00, tmio->fcr + FCR_IMR); + complete(&tmio->comp); - if (unlikely(!waitqueue_active(&nand_chip->controller->wq))) - dev_warn(&tmio->dev->dev, "spurious interrupt\n"); - - wake_up(&nand_chip->controller->wq); return IRQ_HANDLED; } @@ -193,12 +190,14 @@ static int tmio_nand_wait(struct nand_chip *nand_chip) u8 status; /* enable RDYREQ interrupt */ + tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR); + reinit_completion(&tmio->comp); tmio_iowrite8(0x81, tmio->fcr + FCR_IMR); - timeout = wait_event_timeout(nand_chip->controller->wq, - tmio_nand_dev_ready(nand_chip), - msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20)); + timeout = nand_chip->state == FL_ERASING ? 400 : 20; + timeout = wait_for_completion_timeout(&tmio->comp, + msecs_to_jiffies(timeout)); if (unlikely(!tmio_nand_dev_ready(nand_chip))) { tmio_iowrite8(0x00, tmio->fcr + FCR_IMR); @@ -378,6 +377,8 @@ static int tmio_probe(struct platform_device *dev) if (!tmio) return -ENOMEM; + init_completion(&tmio->comp); + tmio->dev = dev; platform_set_drvdata(dev, tmio); -- cgit v1.2.3