Commit d49f5790 authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Boris Brezillon

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: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent f486287d
...@@ -1028,24 +1028,25 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, ...@@ -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) static void denali_reset_banks(struct denali_nand_info *denali)
{ {
u32 irq_status;
int i; int i;
denali_clear_irq_all(denali);
for (i = 0; i < denali->max_banks; i++) { for (i = 0; i < denali->max_banks; i++) {
iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); denali->flash_bank = i;
while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) &
(INTR__RST_COMP | INTR__TIME_OUT))) denali_reset_irq(denali);
cpu_relax();
if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) & iowrite32(DEVICE_RESET__BANK(i),
INTR__INT_ACT)) 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; break;
} }
dev_dbg(denali->dev, "%d chips connected\n", i); dev_dbg(denali->dev, "%d chips connected\n", i);
denali->max_banks = i; denali->max_banks = i;
denali_clear_irq_all(denali);
} }
static void denali_hw_init(struct denali_nand_info *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) ...@@ -1067,7 +1068,6 @@ static void denali_hw_init(struct denali_nand_info *denali)
denali->bbtskipbytes = ioread32(denali->flash_reg + denali->bbtskipbytes = ioread32(denali->flash_reg +
SPARE_AREA_SKIP_BYTES); SPARE_AREA_SKIP_BYTES);
detect_max_banks(denali); detect_max_banks(denali);
denali_reset_banks(denali);
iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED); iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
iowrite32(CHIP_EN_DONT_CARE__FLAG, iowrite32(CHIP_EN_DONT_CARE__FLAG,
denali->flash_reg + CHIP_ENABLE_DONT_CARE); denali->flash_reg + CHIP_ENABLE_DONT_CARE);
...@@ -1185,9 +1185,6 @@ static void denali_drv_init(struct denali_nand_info *denali) ...@@ -1185,9 +1185,6 @@ static void denali_drv_init(struct denali_nand_info *denali)
* element that might be access shared data (interrupt status) * element that might be access shared data (interrupt status)
*/ */
spin_lock_init(&denali->irq_lock); 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) static int denali_multidev_fixup(struct denali_nand_info *denali)
...@@ -1262,6 +1259,9 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1262,6 +1259,9 @@ int denali_init(struct denali_nand_info *denali)
} }
denali_enable_irq(denali); denali_enable_irq(denali);
denali_reset_banks(denali);
denali->flash_bank = CHIP_SELECT_INVALID;
nand_set_flash_node(chip, denali->dev->of_node); nand_set_flash_node(chip, denali->dev->of_node);
/* Fallback to the default name if DT did not give "label" property */ /* Fallback to the default name if DT did not give "label" property */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment