Commit d03af162 authored by Miquel Raynal's avatar Miquel Raynal

mtd: rawnand: denali: convert to nand_scan()

Two helpers have been added to the core to do all kind of controller
side configuration/initialization between the detection phase and the
final NAND scan. Implement these hooks so that we can convert the driver
to just use nand_scan() instead of the nand_scan_ident() +
nand_scan_tail() pair.
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@bootlin.com>
Acked-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
parent b2342c1c
......@@ -1205,62 +1205,12 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
return 0;
}
int denali_init(struct denali_nand_info *denali)
static int denali_attach_chip(struct nand_chip *chip)
{
struct nand_chip *chip = &denali->nand;
struct mtd_info *mtd = nand_to_mtd(chip);
u32 features = ioread32(denali->reg + FEATURES);
struct denali_nand_info *denali = mtd_to_denali(mtd);
int ret;
mtd->dev.parent = denali->dev;
denali_hw_init(denali);
init_completion(&denali->complete);
spin_lock_init(&denali->irq_lock);
denali_clear_irq_all(denali);
ret = devm_request_irq(denali->dev, denali->irq, denali_isr,
IRQF_SHARED, DENALI_NAND_NAME, denali);
if (ret) {
dev_err(denali->dev, "Unable to request IRQ\n");
return ret;
}
denali_enable_irq(denali);
denali_reset_banks(denali);
denali->active_bank = DENALI_INVALID_BANK;
nand_set_flash_node(chip, denali->dev->of_node);
/* Fallback to the default name if DT did not give "label" property */
if (!mtd->name)
mtd->name = "denali-nand";
chip->select_chip = denali_select_chip;
chip->read_byte = denali_read_byte;
chip->write_byte = denali_write_byte;
chip->read_word = denali_read_word;
chip->cmd_ctrl = denali_cmd_ctrl;
chip->dev_ready = denali_dev_ready;
chip->waitfunc = denali_waitfunc;
if (features & FEATURES__INDEX_ADDR) {
denali->host_read = denali_indexed_read;
denali->host_write = denali_indexed_write;
} else {
denali->host_read = denali_direct_read;
denali->host_write = denali_direct_write;
}
/* clk rate info is needed for setup_data_interface */
if (denali->clk_rate && denali->clk_x_rate)
chip->setup_data_interface = denali_setup_data_interface;
ret = nand_scan_ident(mtd, denali->max_banks, NULL);
if (ret)
goto disable_irq;
if (ioread32(denali->reg + FEATURES) & FEATURES__DMA)
denali->dma_avail = 1;
......@@ -1293,7 +1243,7 @@ int denali_init(struct denali_nand_info *denali)
mtd->oobsize - denali->oob_skip_bytes);
if (ret) {
dev_err(denali->dev, "Failed to setup ECC settings.\n");
goto disable_irq;
return ret;
}
dev_dbg(denali->dev,
......@@ -1337,7 +1287,7 @@ int denali_init(struct denali_nand_info *denali)
ret = denali_multidev_fixup(denali);
if (ret)
goto disable_irq;
return ret;
/*
* This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not
......@@ -1345,26 +1295,92 @@ int denali_init(struct denali_nand_info *denali)
* guarantee DMA-safe alignment.
*/
denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
if (!denali->buf) {
ret = -ENOMEM;
goto disable_irq;
if (!denali->buf)
return -ENOMEM;
return 0;
}
static void denali_detach_chip(struct nand_chip *chip)
{
struct mtd_info *mtd = nand_to_mtd(chip);
struct denali_nand_info *denali = mtd_to_denali(mtd);
kfree(denali->buf);
}
static const struct nand_controller_ops denali_controller_ops = {
.attach_chip = denali_attach_chip,
.detach_chip = denali_detach_chip,
};
int denali_init(struct denali_nand_info *denali)
{
struct nand_chip *chip = &denali->nand;
struct mtd_info *mtd = nand_to_mtd(chip);
u32 features = ioread32(denali->reg + FEATURES);
int ret;
mtd->dev.parent = denali->dev;
denali_hw_init(denali);
init_completion(&denali->complete);
spin_lock_init(&denali->irq_lock);
denali_clear_irq_all(denali);
ret = devm_request_irq(denali->dev, denali->irq, denali_isr,
IRQF_SHARED, DENALI_NAND_NAME, denali);
if (ret) {
dev_err(denali->dev, "Unable to request IRQ\n");
return ret;
}
denali_enable_irq(denali);
denali_reset_banks(denali);
denali->active_bank = DENALI_INVALID_BANK;
nand_set_flash_node(chip, denali->dev->of_node);
/* Fallback to the default name if DT did not give "label" property */
if (!mtd->name)
mtd->name = "denali-nand";
chip->select_chip = denali_select_chip;
chip->read_byte = denali_read_byte;
chip->write_byte = denali_write_byte;
chip->read_word = denali_read_word;
chip->cmd_ctrl = denali_cmd_ctrl;
chip->dev_ready = denali_dev_ready;
chip->waitfunc = denali_waitfunc;
if (features & FEATURES__INDEX_ADDR) {
denali->host_read = denali_indexed_read;
denali->host_write = denali_indexed_write;
} else {
denali->host_read = denali_direct_read;
denali->host_write = denali_direct_write;
}
ret = nand_scan_tail(mtd);
/* clk rate info is needed for setup_data_interface */
if (denali->clk_rate && denali->clk_x_rate)
chip->setup_data_interface = denali_setup_data_interface;
chip->dummy_controller.ops = &denali_controller_ops;
ret = nand_scan(mtd, denali->max_banks);
if (ret)
goto free_buf;
goto disable_irq;
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
goto cleanup_nand;
}
return 0;
cleanup_nand:
nand_cleanup(chip);
free_buf:
kfree(denali->buf);
disable_irq:
denali_disable_irq(denali);
......@@ -1377,7 +1393,6 @@ void denali_remove(struct denali_nand_info *denali)
struct mtd_info *mtd = nand_to_mtd(&denali->nand);
nand_release(mtd);
kfree(denali->buf);
denali_disable_irq(denali);
}
EXPORT_SYMBOL(denali_remove);
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