您的位置:首页 > 其它

高通SDHCI(SDC)接口,SD卡初始化,检测等

2017-03-01 17:15 507 查看
sdhc_2: sdhci@7864900 {
compatible = "qcom,sdhci-msm";
reg = <0x7864900 0x11c>, <0x7864000 0x800>;
reg-names = "hc_mem", "core_mem";

interrupts = <0 125 0>, <0 221 0>;
interrupt-names = "hc_irq", "pwr_irq";

qcom,bus-width = <4>;
qcom,large-address-bus;

qcom,cpu-dma-latency-us = <701>;

qcom,msm-bus,name = "sdhc2";
qcom,msm-bus,num-cases = <8>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */
<81 512 1046 3200>,    /* 400 KB/s*/
<81 512 52286 160000>, /* 20 MB/s */
<81 512 65360 200000>, /* 25 MB/s */
<81 512 130718 400000>, /* 50 MB/s */
<81 512 261438 800000>, /* 100 MB/s */
<81 512 261438 800000>, /* 200 MB/s */
<81 512 1338562 4096000>; /* Max. bandwidth */
qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
100000000 200000000 4294967295>;

clocks = <&clock_gcc clk_gcc_sdcc2_ahb_clk>,
<&clock_gcc clk_gcc_sdcc2_apps_clk>;
clock-names = "iface_clk", "core_clk";

qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;

status = "disabled";
};


&sdhc_2 {
vdd-supply = <&pm8950_l11>;
qcom,vdd-voltage-level = <2950000 2950000>;
qcom,vdd-current-level = <15000 800000>;

vdd-io-supply = <&pm8950_l12>;
qcom,vdd-io-voltage-level = <1800000 2950000>;
qcom,vdd-io-current-level = <200 22000>;

pinctrl-names = "active", "sleep";
pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;

#address-cells = <0>;
interrupt-parent = <&sdhc_2>;
interrupts = <0 1 2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xffffffff>;
interrupt-map = <0 &intc 0 125 0
1 &intc 0 221 0
2 &msm_gpio 52 0>;
interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&msm_gpio 52 0x1>;

status = "ok";
};


sdhci_msm_probe() [sdhci-msm.c文件]除了读取上面的of内容初始化gpio,reg等之外,比较重要的有以下几个

1. 调用mmc_gpio_request_cd()设置sd卡检测中断,中断回调函数是mmc_rescan()。检测的地方还有一处就是mmc_start_host->mmc_detect_change -> mmc_rescan ->mmc_rescan_try_freq()

2. sdhci_alloc_host()->创建mmc_host赋值,并初始化一个workqueue以便mmc_rescan函数调用。然后调用mmc_add_host(mmc)初始化驱动文件等。

[http://blog.csdn.net/kickxxx/article/details/51130888 # emmc初始化过程]

驱动初始化之后,vold就可以收到uevent消息,并开始mount。中间过程省略,直接到PublicVolume::doMount()函数,这里check_filesystem_format会读/dev/block/vold/public:179,65设备节点检查文件系统类型。我的sd卡是fat类型的,最后vfat::Mount()调到kernel/fs/fat下面对应的mount文件输出如下log。

<6>[73637.264432]  [7:           vold:  462] FAT-fs (mmcblk1p1[179:65]): trying to mount...
<6>[73637.283354]  [3:           vold:  462] FAT-fs (mmcblk1p1[179:65]): mounted successfully!
<7>[73637.283581]  [3:           vold:  462] SELinux: initialized (dev mmcblk1p1, type vfat), uses genfs_contexts


mount成功后,vold就把vfat文件系统mount到/mnt/media_rw/XXX这个文件夹下面了。

随后vold会再execl(“/system/bin/sdcard”,xxx),居然运行sdcard再去用sdcardfs文件系统类型(这个在kernel/fs/sdcard里,是三星做的,可以比fuse减少io交互,提高读写性能),再mount一下。内核的sdcardfs文件系统的内容就不在这里说了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: