mirror of https://gitee.com/openkylin/linux.git
mtd: nand: denali: use interrupt instead of polling for bank reset
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> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
This commit is contained in:
parent
f486287d23
commit
d49f579027
|
@ -1028,24 +1028,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)
|
||||
|
@ -1067,7 +1068,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);
|
||||
|
@ -1185,9 +1185,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)
|
||||
|
@ -1262,6 +1259,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 */
|
||||
|
|
Loading…
Reference in New Issue