NandFlash 驱动--01

  • DTS位置

kernel/arch/arm/boot/dts/atlas7.dtsi

			nand@17050000 {
				compatible = "sirf,atlas7-nand";
				reg = <0x17050000 0x10000>;
				pinctrl-names = "default";
				pinctrl-0 = <&nd_df_basic_pmx>;
				interrupts = <0 41 0>;
				clocks = <&car 57>, <&car 112>;
				clock-names = "nand_io", "nand_nand";
				status = "okay";
			};

  • NandFlash源码位置

kernel/drivers/block/nanddisk/nand.c

  1. 注册platform驱动
static struct platform_driver sirfsoc_nand_driver = {
	.probe	= sirfsoc_nand_probe,
	.remove = sirfsoc_nand_remove,
	.shutdown = sirfsoc_nand_shutdown,
	.driver = {
		.name = "sirfsoc-nand",
		.owner = THIS_MODULE,
		.pm = &sirfsoc_nand_pm_ops,
		.of_match_table = nand_sirfsoc_of_match,
	},
};
module_platform_driver(sirfsoc_nand_driver);
  1. pm相关的操作函数集 sirfsoc_nand_pm_ops
static const struct dev_pm_ops sirfsoc_nand_pm_ops = {
	.resume_noirq = sirfsoc_nand_resume_noirq,
	.thaw_noirq = sirfsoc_nand_resume_noirq,
	.restore_noirq = sirfsoc_nand_resume_noirq,
	.resume = sirfsoc_nand_resume,
	.restore = sirfsoc_nand_resume,
	.thaw = sirfsoc_nand_resume,
	.suspend = sirfsoc_nand_suspend,
	.freeze = sirfsoc_nand_suspend,
};
  1. sirfsoc_nand_probe函数
  • 在数组arch_nres中找到适配的nand控制器,这里适配的是"sirf,atlas7"
	arch_nres_used = &arch_nres[0];
	for (i = 0; i < ARRAY_SIZE(arch_nres); i++) {
		dn = of_find_compatible_node(NULL, NULL,
			arch_nres_used->arch_compatible);
		if (dn)
			break;
		arch_nres_used++;
	}

	if (!dn) {
		dev_err(dev, "no suitable nand controller!!\n");
		error = -ENODEV;
		goto err_exit;
	}

	dev_info(dev, "find nand controller(%s).\n",
		 arch_nres_used->arch_compatible);

root@atlas7-arm:~# dmesg | grep -rn “find nand controller”

216:[ 0.428861] sirfsoc-nand 17050000.nand: find nand controller(sirf,atlas7).

  • 获取nanddisk固件的地址:通过of_parse_phandle解析dts中“memory-region”,然后设置nanddisk的起始地址和size
	/* get reserved memory for nanddisk firmware */
	fw_memory = of_parse_phandle(dev->of_node, "memory-region", 0);
	if (!fw_memory) {
		error = -ENODEV;
		goto err_exit;
	}

	addr = of_get_address(fw_memory, 0, &size, NULL);
	if (!addr) {
		error = -EINVAL;
		goto err_exit;
	}
	
	nand_dev.nanddisk_code_start = of_translate_address(fw_memory, addr);
	nand_dev.nanddisk_code_size = size;

“memory-region”在dts中定义的位置:

arch\arm\boot\dts\atlas7-evb-common.dtsi

		mediam {
			nand@17050000 {
				memory-region = <&nanddisk_reserved>;
			};
			...

nanddisk固件存放的地址是0x45000000,空间大小为2M

		nanddisk_reserved: nanddisk@45000000 {
			reg = <0x45000000 0x200000>;
			no-map;
		};
  • 分配空间给地址映射表
	/* total other controller */
	nand_dev.addr_entry_num = arch_nres_used->res_num;
	/* add nand controller */
	nand_dev.addr_entry_num += 1;
	/* add 2 item, ram and zero-end */
	nand_dev.addr_entry_num += 3;
	addr_map_tbl_size = sizeof(struct ADDRMAP) * nand_dev.addr_entry_num;
	nand_dev.addr_map_tbl = devm_kzalloc(dev,
					addr_map_tbl_size, GFP_KERNEL);
	if (!nand_dev.addr_map_tbl) {
		error = -ENOMEM;
		goto err_exit;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值