lkml.org 
[lkml]   [2017]   [Jun]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v6 09/18] mtd: nand: denali: use interrupt instead of polling for bank reset
Date
The current bank reset implementation polls the INTR_STATUS register
until interested bits are set. This is not good because:

- polling simply wastes time-slice of the thread

- The while() loop may continue eternally if no bit is set, for
example, due to the controller problem. The denali_wait_for_irq()
uses wait_for_completion_timeout(), which is safer.

We can use interrupt by moving the denali_reset_bank() call below
the interrupt setup.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- Newly added

drivers/mtd/nand/denali.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 61a2ee9fb367..7ae2fa65d601 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -973,24 +973,25 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr,

static void denali_reset_banks(struct denali_nand_info *denali)
{
+ u32 irq_status;
int i;

- denali_clear_irq_all(denali);
-
for (i = 0; i < denali->max_banks; i++) {
- iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
- while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
- (INTR__RST_COMP | INTR__TIME_OUT)))
- cpu_relax();
- if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
- INTR__INT_ACT))
+ denali->flash_bank = i;
+
+ denali_reset_irq(denali);
+
+ iowrite32(DEVICE_RESET__BANK(i),
+ denali->flash_reg + DEVICE_RESET);
+
+ irq_status = denali_wait_for_irq(denali,
+ INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
+ if (!(irq_status & INTR__INT_ACT))
break;
}

dev_dbg(denali->dev, "%d chips connected\n", i);
denali->max_banks = i;
-
- denali_clear_irq_all(denali);
}

static void denali_hw_init(struct denali_nand_info *denali)
@@ -1012,7 +1013,6 @@ static void denali_hw_init(struct denali_nand_info *denali)
denali->bbtskipbytes = ioread32(denali->flash_reg +
SPARE_AREA_SKIP_BYTES);
detect_max_banks(denali);
- denali_reset_banks(denali);
iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
iowrite32(CHIP_EN_DONT_CARE__FLAG,
denali->flash_reg + CHIP_ENABLE_DONT_CARE);
@@ -1130,9 +1130,6 @@ static void denali_drv_init(struct denali_nand_info *denali)
* element that might be access shared data (interrupt status)
*/
spin_lock_init(&denali->irq_lock);
-
- /* indicate that MTD has not selected a valid bank yet */
- denali->flash_bank = CHIP_SELECT_INVALID;
}

static int denali_multidev_fixup(struct denali_nand_info *denali)
@@ -1207,6 +1204,9 @@ int denali_init(struct denali_nand_info *denali)
}

denali_enable_irq(denali);
+ denali_reset_banks(denali);
+
+ denali->flash_bank = CHIP_SELECT_INVALID;

nand_set_flash_node(chip, denali->dev->of_node);
/* Fallback to the default name if DT did not give "label" property */
--
2.7.4
\
 
 \ /
  Last update: 2017-06-13 07:11    [W:2.060 / U:1.064 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site