[PATCH v6 10/15] nand: spi: add basic blocks for infrastructure
Peter Pan 潘栋 (peterpandong)
peterpandong at micron.com
Wed May 31 00:02:03 PDT 2017
Hi Boris,
> On 30 May 2017, at 05:51, Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
>
> On Wed, 24 May 2017 15:07:06 +0800
> Peter Pan <peterpandong at micron.com> wrote:
>
>> This is the first commit for spi nand framkework.
>
> ^ framework
>
>> This commit is to add add basic building blocks
>
> is adding basic ...
>
>> for the SPI NAND infrastructure.
>>
>> Signed-off-by: Peter Pan <peterpandong at micron.com>
>> ---
>
> [...]
>
>> +
>> +/**
>> + * devm_spinand_alloc - [SPI NAND Interface] allocate SPI NAND device instance
>
> Let's drop those [SPI NAND Interface] specifier. It's pretty obvious
> that this is part of the spi-nand API, since those symbols are exported.
Okay
>
>> + * @dev: pointer to device model structure
>> + */
>> +struct spinand_device *devm_spinand_alloc(struct device *dev)
>
> You can pass a pointer to the nand_controller object driving the
> nand_device here.
>
>> +{
>> + struct spinand_device *spinand;
>> + struct mtd_info *mtd;
>> +
>> + spinand = devm_kzalloc(dev, sizeof(*spinand), GFP_KERNEL);
>> + if (!spinand)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + spinand_set_of_node(spinand, dev->of_node);
>> + mutex_init(&spinand->lock);
>> + spinand->dev = dev;
>
> Hm, I don't think this is correct. The device here is likely to
> represent the controller not the SPI NAND device. For the generic spi
> nand controller, I agree, it's the same, but, in case you have one
> controller that is attached several spi devices, it's not.
Yes, you are right. I only thought about generic spi bus when I was
writing the code.
>
> How about putting the struct device pointer in nand_controller and then
> pass the controller to this spinand_alloc() function.
Good solution
>
>> + mtd = spinand_to_mtd(spinand);
>> + mtd->dev.parent = dev;
>> +
>> + return spinand;
>> +}
>> +EXPORT_SYMBOL_GPL(devm_spinand_alloc);
>> +
>> +/**
>> + * spinand_init - [SPI NAND Interface] initialize the SPI NAND device
>> + * @spinand: SPI NAND device structure
>> + */
>> +int spinand_init(struct spinand_device *spinand)
>> +{
>> + struct mtd_info *mtd = spinand_to_mtd(spinand);
>> + struct nand_device *nand = mtd_to_nand(mtd);
>> + int ret;
>> +
>> + ret = spinand_detect(spinand);
>> + if (ret) {
>> + dev_err(spinand->dev,
>> + "Detect SPI NAND failed with error %d.\n", ret);
>> + goto err_out;
>
> return ret;
>
>
>> + }
>
> I'd still prefer to move the detection step out of this _init()
> function even if this implies duplicating the _detect()+_init()
> sequence in all drivers. Maybe you can provide a wrapper called
> spinand_detect_and_init() to do both in one go.
Okay for me
>
>> +
>> + spinand_set_rd_wr_op(spinand);
>> +
>> + /*
>> + * Use kzalloc() instead of devm_kzalloc() here, beacause some drivers
>> + * may use this buffer for DMA access.
>> + * Memory allocated by devm_ does not guarantee DMA-safe alignment.
>> + */
>> + spinand->buf = kzalloc(nand_page_size(nand) +
>> + nand_per_page_oobsize(nand),
>> + GFP_KERNEL);
>> + if (!spinand->buf) {
>> + ret = -ENOMEM;
>> + goto err_out;
>
> return -ENOMEM;
>
>> + }
>> +
>> + spinand->oobbuf = spinand->buf + nand_page_size(nand);
>> +
>> + ret = spinand_manufacturer_init(spinand);
>> + if (ret) {
>> + dev_err(spinand->dev,
>> + "Manufacurer init SPI NAND failed with err %d.\n",
>> + ret);
>> + goto err_free_buf;
>> + }
>> +
>> + mtd->name = spinand->name;
>> + mtd->size = nand_size(nand);
>> + mtd->erasesize = nand_eraseblock_size(nand);
>> + mtd->writesize = nand_page_size(nand);
>> + mtd->writebufsize = mtd->writesize;
>> + mtd->owner = THIS_MODULE;
>> + mtd->type = MTD_NANDFLASH;
>> + mtd->flags = MTD_CAP_NANDFLASH;
>> + mtd->oobsize = nand_per_page_oobsize(nand);
>> + /*
>> + * Right now, we don't support ECC, so let the whole oob
>> + * area is available for user.
>> + */
>> + mtd->oobavail = mtd->oobsize;
>> +
>> + /* After power up, all blocks are locked, so unlock it here. */
>> + spinand_lock_block(spinand, BL_ALL_UNLOCKED);
>> +
>> + return 0;
>> +
>> +err_free_buf:
>> + kfree(spinand->buf);
>> +err_out:
>
> You can get rid of err_out.
>
Okay
Thanks
Peter Pan
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(spinand_init);
>> +
>
More information about the linux-mtd
mailing list