2023-01-22 18:08:04 +00:00
|
|
|
From: Florian Fainelli <f.fainelli@gmail.com>
|
|
|
|
Subject: [PATCH v3 5/9] mtd: rawnand: brcmnand: Allow working without interrupts
|
|
|
|
Date: Fri, 07 Jan 2022 10:46:10 -0800
|
|
|
|
Content-Type: text/plain; charset="utf-8"
|
|
|
|
|
|
|
|
The BCMA devices include the brcmnand controller but they do not wire up
|
|
|
|
any interrupt line, allow the main interrupt to be optional and update
|
|
|
|
the completion path to also check for the lack of an interrupt line.
|
|
|
|
|
|
|
|
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
|
|
|
---
|
|
|
|
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 52 +++++++++++-------------
|
|
|
|
1 file changed, 24 insertions(+), 28 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
|
|
|
|
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
|
|
|
|
@@ -216,7 +216,7 @@ struct brcmnand_controller {
|
|
|
|
void __iomem *nand_base;
|
|
|
|
void __iomem *nand_fc; /* flash cache */
|
|
|
|
void __iomem *flash_dma_base;
|
|
|
|
- unsigned int irq;
|
|
|
|
+ int irq;
|
|
|
|
unsigned int dma_irq;
|
|
|
|
int nand_version;
|
|
|
|
|
2023-01-22 19:04:35 +00:00
|
|
|
@@ -1610,7 +1610,7 @@ static bool brcmstb_nand_wait_for_comple
|
2023-01-22 18:08:04 +00:00
|
|
|
bool err = false;
|
|
|
|
int sts;
|
|
|
|
|
|
|
|
- if (mtd->oops_panic_write) {
|
|
|
|
+ if (mtd->oops_panic_write || ctrl->irq < 0) {
|
|
|
|
/* switch to interrupt polling and PIO mode */
|
|
|
|
disable_ctrl_irqs(ctrl);
|
|
|
|
sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY,
|
2023-01-22 19:04:35 +00:00
|
|
|
@@ -3144,33 +3144,29 @@ int brcmnand_probe(struct platform_devic
|
2023-01-22 18:08:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* IRQ */
|
|
|
|
- ctrl->irq = platform_get_irq(pdev, 0);
|
|
|
|
- if ((int)ctrl->irq < 0) {
|
|
|
|
- dev_err(dev, "no IRQ defined\n");
|
|
|
|
- ret = -ENODEV;
|
|
|
|
- goto err;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Some SoCs integrate this controller (e.g., its interrupt bits) in
|
|
|
|
- * interesting ways
|
|
|
|
- */
|
|
|
|
- if (soc) {
|
|
|
|
- ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
|
|
|
|
- DRV_NAME, ctrl);
|
|
|
|
-
|
|
|
|
- /* Enable interrupt */
|
|
|
|
- ctrl->soc->ctlrdy_ack(ctrl->soc);
|
|
|
|
- ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
|
|
|
|
- } else {
|
|
|
|
- /* Use standard interrupt infrastructure */
|
|
|
|
- ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
|
|
|
|
- DRV_NAME, ctrl);
|
|
|
|
- }
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(dev, "can't allocate IRQ %d: error %d\n",
|
|
|
|
- ctrl->irq, ret);
|
|
|
|
- goto err;
|
|
|
|
+ ctrl->irq = platform_get_irq_optional(pdev, 0);
|
|
|
|
+ if (ctrl->irq > 0) {
|
|
|
|
+ /*
|
|
|
|
+ * Some SoCs integrate this controller (e.g., its interrupt bits) in
|
|
|
|
+ * interesting ways
|
|
|
|
+ */
|
|
|
|
+ if (soc) {
|
|
|
|
+ ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
|
|
|
|
+ DRV_NAME, ctrl);
|
|
|
|
+
|
|
|
|
+ /* Enable interrupt */
|
|
|
|
+ ctrl->soc->ctlrdy_ack(ctrl->soc);
|
|
|
|
+ ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
|
|
|
|
+ } else {
|
|
|
|
+ /* Use standard interrupt infrastructure */
|
|
|
|
+ ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
|
|
|
|
+ DRV_NAME, ctrl);
|
|
|
|
+ }
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ dev_err(dev, "can't allocate IRQ %d: error %d\n",
|
|
|
|
+ ctrl->irq, ret);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
for_each_available_child_of_node(dn, child) {
|