emmc host的初始化和scan 这个host上连接的设备
来源:互联网 发布:淘宝外卖和美团哪种好 编辑:程序博客网 时间:2024/06/04 19:13
在driver/mmc/host下面的makefile中和dw相关的config如下:
obj-$(CONFIG_MMC_DW) += dw_mmc.o
obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o
obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
我是打开了CONFIG_MMC_DW 和 CONFIG_MMC_DW_K3
所以dw的入口函数在dw_mmc-k3.c中
static struct platform_driver dw_mci_k3_pltfm_driver = {
.probe = dw_mci_k3_probe,
.remove = dw_mci_pltfm_remove,
.driver = {
.name = "dwmmc_k3",
.of_match_table = dw_mci_k3_match,
.pm = &dw_mci_k3_pmops,
},
};
module_platform_driver(dw_mci_k3_pltfm_driver);
如果在dts中检测到
static const struct of_device_id dw_mci_k3_match[] = {
{ .compatible = "hisilicon,hi4511-dw-mshc", .data = &k3_drv_data, },
{ .compatible = "hisilicon,hi6220-dw-mshc", .data = &hi6220_data, },
{},
};
这两个字符串就调用dw_mci_k3_probe
static int dw_mci_k3_probe(struct platform_device *pdev)
{
const struct dw_mci_drv_data *drv_data;
const struct of_device_id *match;
//得到drv_data本例中就是k3_drv_data
match = of_match_node(dw_mci_k3_match, pdev->dev.of_node);
drv_data = match->data;
//调用dw_mci_pltfm_register
return dw_mci_pltfm_register(pdev, drv_data);
}
int dw_mci_pltfm_register(struct platform_device *pdev,
const struct dw_mci_drv_data *drv_data)
{
struct dw_mci *host;
struct resource *regs;
host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL);
if (!host)
return -ENOMEM;
//得到irq
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0)
return host->irq;
host->drv_data = drv_data;
host->dev = &pdev->dev;
host->irq_flags = 0;
host->pdata = pdev->dev.platform_data;
//得到这个host的寄存器地址
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
//对reg做ioremap ,这样在kernel中就可以访问这个寄存器地址了
host->regs = devm_ioremap_resource(&pdev->dev, regs);
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
/* Get registers' physical base address */
host->phy_regs = regs->start;
//保存drv_data
platform_set_drvdata(pdev, host);
//继续probe
return dw_mci_probe(host);
}
在dw_mci_probe 中会从dts中parse其他变量例如:ciu/biu等
host->biu_clk = devm_clk_get(host->dev, "biu");
if (IS_ERR(host->biu_clk)) {
dev_dbg(host->dev, "biu clock not available\n");
} else {
ret = clk_prepare_enable(host->biu_clk);
if (ret) {
dev_err(host->dev, "failed to enable biu clock\n");
return ret;
}
}
但是最终要的是下面这段
/* We need at least one slot to succeed */
for (i = 0; i < host->num_slots; i++) {
ret = dw_mci_init_slot(host, i);
if (ret)
dev_dbg(host->dev, "slot %d init failed\n", i);
else
init_slots++;
}
在dw_mci_init_slot 中就调用mmc_alloc_host/mmc_add_host 向kernel 添加这个mmc host。
在mmc_alloc_host 中最重要的就是 INIT_DELAYED_WORK(&host->detect, mmc_rescan);,后面就可以通过mmc_rescan 来发现这个host上连接的设备,具体callstack如下:
[ 11.777356] [<ffffffc00008a438>] dump_backtrace+0x0/0x164
[ 11.782759] [<ffffffc00008a5b8>] show_stack+0x1c/0x28
[ 11.787816] [<ffffffc000bbca58>] dump_stack+0x78/0x98
[ 11.792870] [<ffffffc000bb9348>] panic+0xe8/0x244
[ 11.797577] [<ffffffc00092c564>] mmc_add_card+0xc0/0x228
[ 11.802894] [<ffffffc00092f71c>] mmc_attach_mmc+0xa8/0x18c
[ 11.808382] [<ffffffc00092bb8c>] mmc_rescan+0x2a8/0x2f8
[ 11.813612] [<ffffffc0000d4ef4>] process_one_work+0x154/0x3bc
[ 11.819362] [<ffffffc0000d52a4>] worker_thread+0x148/0x49c
[ 11.824852] [<ffffffc0000db200>] kthread+0xe0/0xf8
obj-$(CONFIG_MMC_DW) += dw_mmc.o
obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o
obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
我是打开了CONFIG_MMC_DW 和 CONFIG_MMC_DW_K3
所以dw的入口函数在dw_mmc-k3.c中
static struct platform_driver dw_mci_k3_pltfm_driver = {
.probe = dw_mci_k3_probe,
.remove = dw_mci_pltfm_remove,
.driver = {
.name = "dwmmc_k3",
.of_match_table = dw_mci_k3_match,
.pm = &dw_mci_k3_pmops,
},
};
module_platform_driver(dw_mci_k3_pltfm_driver);
如果在dts中检测到
static const struct of_device_id dw_mci_k3_match[] = {
{ .compatible = "hisilicon,hi4511-dw-mshc", .data = &k3_drv_data, },
{ .compatible = "hisilicon,hi6220-dw-mshc", .data = &hi6220_data, },
{},
};
这两个字符串就调用dw_mci_k3_probe
static int dw_mci_k3_probe(struct platform_device *pdev)
{
const struct dw_mci_drv_data *drv_data;
const struct of_device_id *match;
//得到drv_data本例中就是k3_drv_data
match = of_match_node(dw_mci_k3_match, pdev->dev.of_node);
drv_data = match->data;
//调用dw_mci_pltfm_register
return dw_mci_pltfm_register(pdev, drv_data);
}
int dw_mci_pltfm_register(struct platform_device *pdev,
const struct dw_mci_drv_data *drv_data)
{
struct dw_mci *host;
struct resource *regs;
host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL);
if (!host)
return -ENOMEM;
//得到irq
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0)
return host->irq;
host->drv_data = drv_data;
host->dev = &pdev->dev;
host->irq_flags = 0;
host->pdata = pdev->dev.platform_data;
//得到这个host的寄存器地址
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
//对reg做ioremap ,这样在kernel中就可以访问这个寄存器地址了
host->regs = devm_ioremap_resource(&pdev->dev, regs);
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
/* Get registers' physical base address */
host->phy_regs = regs->start;
//保存drv_data
platform_set_drvdata(pdev, host);
//继续probe
return dw_mci_probe(host);
}
在dw_mci_probe 中会从dts中parse其他变量例如:ciu/biu等
host->biu_clk = devm_clk_get(host->dev, "biu");
if (IS_ERR(host->biu_clk)) {
dev_dbg(host->dev, "biu clock not available\n");
} else {
ret = clk_prepare_enable(host->biu_clk);
if (ret) {
dev_err(host->dev, "failed to enable biu clock\n");
return ret;
}
}
但是最终要的是下面这段
/* We need at least one slot to succeed */
for (i = 0; i < host->num_slots; i++) {
ret = dw_mci_init_slot(host, i);
if (ret)
dev_dbg(host->dev, "slot %d init failed\n", i);
else
init_slots++;
}
在dw_mci_init_slot 中就调用mmc_alloc_host/mmc_add_host 向kernel 添加这个mmc host。
在mmc_alloc_host 中最重要的就是 INIT_DELAYED_WORK(&host->detect, mmc_rescan);,后面就可以通过mmc_rescan 来发现这个host上连接的设备,具体callstack如下:
[ 11.777356] [<ffffffc00008a438>] dump_backtrace+0x0/0x164
[ 11.782759] [<ffffffc00008a5b8>] show_stack+0x1c/0x28
[ 11.787816] [<ffffffc000bbca58>] dump_stack+0x78/0x98
[ 11.792870] [<ffffffc000bb9348>] panic+0xe8/0x244
[ 11.797577] [<ffffffc00092c564>] mmc_add_card+0xc0/0x228
[ 11.802894] [<ffffffc00092f71c>] mmc_attach_mmc+0xa8/0x18c
[ 11.808382] [<ffffffc00092bb8c>] mmc_rescan+0x2a8/0x2f8
[ 11.813612] [<ffffffc0000d4ef4>] process_one_work+0x154/0x3bc
[ 11.819362] [<ffffffc0000d52a4>] worker_thread+0x148/0x49c
[ 11.824852] [<ffffffc0000db200>] kthread+0xe0/0xf8
0 0
- emmc host的初始化和scan 这个host上连接的设备
- emmc host调用mmc_rescan发现设备
- usb-host一步一步学(一)安卓在usb-host模式下列出当前连接的usb设备
- usb-host一步一步学(二)安卓在usb-host模式下列出当前连接的usb设备
- USB host枚举设备的过程
- host和vpn的区别
- emmc/sd host层解析
- QualComm 8x50 上MMC host controller 驱动的初始化流程分析
- vmware下CentOS的host-only连接
- Visual Box 的 Host-only 连接
- USB Host的上拉下拉电阻
- 修改host可以上的一些网站
- VirtualBox中从guest系统中用adb与连在host上的设备通信
- STM32配置CH375B成HID Host模式读取自定义HID设备的数据 ——STM32端口初始化
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
- SuperMap iServer整合第三方地图服务
- 笔记本如何禁用触摸板
- 控制面板Plesk, cPanel, DirectAdmin, whmcs,WDCP, AMH比较
- spring声明事务失效问题(二)
- jboss控制台日志输出带日期问题解决方案
- emmc host的初始化和scan 这个host上连接的设备
- java基础(变量与数据类型)
- java—数据类型,变量,修饰符,非访问修饰符
- Maven经验分享(七)maven集成findBugs插件
- 面向对象三大基本特性和五大基本原则
- 存储过程中调用EXECUTE IMMEDIATE的“权限不足”
- ThreadPoolExecutor
- 编译Android平台的opencv
- Fiddler远程调试js