- 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
- 注册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);
- 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,
};
- 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;
}