Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0916c94 authored by Boris Brezillon's avatar Boris Brezillon Committed by Miquel Raynal
Browse files

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: default avatarBoris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent b5c2defc
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -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);