flash 驱动流程
/* chip 函数需要自己实现,没办法由mtd提供 */
static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
785 struct s3c2410_nand_mtd *nmtd,
786 struct s3c2410_nand_set *set)
787 {
788 struct nand_chip *chip = &nmtd->chip;
789 void __iomem *regs = info->regs;
790
791 chip->write_buf = s3c2410_nand_write_buf;
792 chip->read_buf = s3c2410_nand_read_buf;
793 chip->select_chip = s3c2410_nand_select_chip;
794 chip->chip_delay = 50;
795 chip->priv = nmtd;
796 chip->options = set->options;
797 chip->controller = &info->controller;
798
799 switch (info->cpu_type) {
800 case TYPE_S3C2410:
801 chip->IO_ADDR_W = regs + S3C2410_NFDATA;
802 info->sel_reg = regs + S3C2410_NFCONF;
803 info->sel_bit = S3C2410_NFCONF_nFCE;
804 chip->cmd_ctrl = s3c2410_nand_hwcontrol;
805 chip->dev_ready = s3c2410_nand_devready;
806 break;
807
808 case TYPE_S3C2440:
809 chip->IO_ADDR_W = regs + S3C2440_NFDATA;
810 info->sel_reg = reg
...
/* s3c2440驱动是根据cpu的类型区别,来填充chip 结构体 */
}
static int s3c24xx_nand_probe(struct platform_device *pdev)
{
/* 1.定义 重要结构体 */
static struct nand_chip *s3c_nand;
static struct mtd_info *s3c_mtd;
/* 2. 填充nandchip */
s3c2410_nand_init_chip(info, nmtd, sets);
/*3. 使用 nand_scan 填充mtd*/
nand_scan(s3c_mtd, 1);
/*4. 分区设置 */
add_mtd_partitions(s3c_mtd, s3c_nand_parts, 4);
/* 5. 添加设备至mtd */
add_mtd_device(s3c_mtd);
}
1130 static struct platform_driver s3c24xx_nand_driver = {
1131 .probe = s3c24xx_nand_probe, /**/主要实现 函数**
1132 .remove = s3c24xx_nand_remove,
1133 .suspend = s3c24xx_nand_suspend,
1134 .resume = s3c24xx_nand_resume,
1135 .id_table = s3c24xx_driver_ids,
1136 .driver = {
1137 .name = "s3c24xx-nand",
1138 .owner = THIS_MODULE,
1139 },
1140 };
1141
1142 module_platform_driver(s3c24xx_nand_driver);;
hisi spi nand flash驱动
/* chip 函数需要自己实现,没办法由mtd提供 */
890 static void hifmc100_chip_init(struct nand_chip *chip)
891 {
892 chip->read_byte = hifmc100_read_byte;
893 chip->read_word = hifmc100_read_word;
894 chip->write_buf = hifmc100_write_buf;
895 chip->read_buf = hifmc100_read_buf;
896
897 chip->select_chip = hifmc100_select_chip;
898
899 chip->cmd_ctrl = hifmc100_cmd_ctrl;
900 chip->dev_ready = hifmc100_dev_ready;
901
902 chip->chip_delay = FMC_CHIP_DELAY;
903
904 chip->options = NAND_NO_AUTOINCR | NAND_SKIP_BBTSCAN | NAND_BROKEN_XD
905 | NAND_SCAN_SILENT_NODEV;
906
907 chip->ecc.layout = NULL;
908 chip->ecc.mode = NAND_ECC_NONE;
909 }
/* 不同的是,hisi有关flash型号的驱动,是通过nand flash的id号作为区分的*/
1511 static struct nand_flash_dev *spi_nand_get_flash_info(struct mtd_info *mtd,
1512 unsigned char *id)
1513 {
1514 unsigned char ix, len = 0;
1515 char buffer[100];
1516 struct nand_chip *chip = mtd->priv;
1517 struct hifmc_host *host = chip->priv;
1518 struct spi_nand_info *spi_dev = hifmc_spi_nand_flash_table;
1519 struct nand_flash_dev *type = &spi_nand_dev;
1520
1521 FMC_PR(BT_DBG, "\t*-Start find SPI Nand flash\n");
1522
1523 len = sprintf(buffer, "SPI Nand(cs %d) ID: %#x %#x",
1524 host->cmd_op.cs, id[0], id[1]);
1525
1526 for (; spi_dev->id_len; spi_dev++) {
1527 if (memcmp(id, spi_dev->id, spi_dev->id_len))
1528 continue;
1529
1530 for (ix = 2; ix < spi_dev->id_len; ix++)
1531 len += sprintf(buffer + len, " %#x", id[ix]);
1532 pr_info("%s\n", buffer);
1533
1534 FMC_PR(BT_DBG, "\t||-CS(%d) found SPI Nand: %s\n",
1535 host->cmd_op.cs, spi_dev->name);
1536
1537 type->name = spi_dev->name;
1538 memcpy(type->id, spi_dev->id, spi_dev->id_len);
1539 type->pagesize = spi_dev->pagesize;
1540 type->chipsize = spi_dev->chipsize >> 20;
1541 type->erasesize = spi_dev->erasesize;
1542 type->id_len = spi_dev->id_len;
1543 type->oobsize = spi_dev->oobsize;
...
}
int hifmc100_spi_nand_init(struct nand_chip *chip)
{
hifmc100_chip_init(chip);
hifmc_spi_nand_ids_register();
}
186 static int hisi_spi_nand_probe(struct platform_device *pltdev)
{
/* 1.定义 重要结构体 */
190 struct nand_chip *chip;
191 struct mtd_info *mtd;
/* 2. 填充nandchip */
result = hifmc100_spi_nand_init(chip);
/*3. 使用 nand_scan 填充mtd*/
result = hifmc_nand_scan(mtd);
/*4. 分区设置 */
252 result = hifmc_os_add_paratitions(host);
253 if (host->add_partition)
254 goto end;
/* 5. 添加设备至mtd */
256 if (!add_mtd_device(host->mtd)) {
257 result = 0;
258 goto end;
259 }
}
314 static struct platform_driver hisi_spi_nand_driver = {
315 .driver = {
316 .name = "hisi_spi_nand",
317 .of_match_table = hisi_spi_nand_dt_ids,
318 },
319 .probe = hisi_spi_nand_probe,
320 .remove = hisi_spi_nand_remove,
321 #ifdef CONFIG_PM
322 .suspend = hifmc100_os_suspend,
323 .resume = hifmc100_os_resume,
324 #endif
325 };
326 module_platform_driver(hisi_spi_nand_driver)