近基在调一个收音机模块RDA5807,其32KHz时针由RK808的CLK32KOUT2提供,在rda5807的驱动中获取该时钟时一直获取不到,后面发现是由于RK808的CLK32注册较晚于rda5807的驱动加载,所以将rda5807驱动中的module_init(rda5807_init)改为late_initcall(rda5807_init)后,成功获取到RK808的32KHz时钟。
问题log1:rda5807驱动获取clk的时间
[ 1.576658] LDO_REG4: supplied by vcc_sys
[ 1.577744] LDO_REG5: supplied by vcc_sys
[ 1.578884] LDO_REG6: supplied by vcc_sys
[ 1.579981] LDO_REG7: supplied by vcc_sys
[ 1.581084] LDO_REG8: supplied by vcc_sys
[ 1.582164] SWITCH_REG1: supplied by vcc_io
[ 1.582487] SWITCH_REG2: supplied by vcc_io
[ 1.586245] rk808-rtc rk808-rtc: rtc core: registered rk808-rtc as rtc0
[ 1.586888] rk3x-i2c ff650000.i2c: Initialized RK3xxx I2C bus at ffffff80097e8000
[ 1.587270] __of_clk_get_by_name() name:(null), dev_id:ff140000.i2c
[ 1.587302] clk_hw_create_clk() enter
[ 1.587312] clk_hw_create_clk() dev_id:ff140000.i2c
[ 1.588064] __of_clk_get_by_name() name:rclk, dev_id:2-0010
[ 1.588092] rda5807 failed to get rclk
问题log2: rk808 注册clk的时间
[ 1.672716] ashmem: initialized
[ 1.673554] clk_register() name:rk808-clkout1
[ 1.673568] clk_hw_create_clk() enter
[ 1.673663] clk_register() name:rk808-clkout2
[ 1.673673] clk_hw_create_clk() enter
[ 1.674031] clk_register() name:xin32k
[ 1.674043] clk_hw_create_clk() enter
[ 1.675222] __of_clk_get_by_name() name:apb_pclk, dev_id:ff100000.saradc
[ 1.675264] clk_hw_create_clk() enter
[ 1.675275] clk_hw_create_clk() dev_id:ff100000.saradc
[ 1.675285] clk_hw_create_clk() con_id:apb_pclk
[ 1.675298] __of_clk_get_by_name() name:saradc, dev_id:ff100000.saradc
[ 1.675322] clk_hw_create_clk() enter
[ 1.675332] clk_hw_create_clk() dev_id:ff100000.saradc
[ 1.675342] clk_hw_create_clk() con_id:saradc
[ 1.677408] rknandbase v1.1 2016-11-08
[ 1.678225] usbcore: registered new interface driver snd-usb-audio
从以上两部分log可以看出,rk808的clk注册时间晚于rda5807驱动获取clk的时间。
rk808中clock相关的dts配置:
&i2c0 {
status = "okay";
clock-frequency = <400000>;
rk808: pmic@1b {
compatible = "rockchip,rk808";
reg = <0x1b>;
interrupt-parent = <&gpio0>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_int>;
rockchip,system-power-controller;
wakeup-source;
#clock-cells = <1>;
clock-output-names = "rk808-clkout1", "rk808-clkout2";
//省略余下代码
};
};
rda5807的dts配置:
&i2c2 {
status = "okay";
rda5807: rda5807@10{
compatible = "rda5807";
reg = <0x10>;
clocks = <&rk808 1>;
clock-names = "rclk";
status = "okay";
};
};
rda5807驱动中获取clock并使能:
static int rda5807_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int res = 0;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
{
pr_err("%s: functionality check failed\n", __FUNCTION__);
res = -ENODEV;
goto out;
}
this_client = client;
res = misc_register(&rda5807_device);
if (res) {
pr_err("%s: rda5807_device register failed\n", __FUNCTION__);
goto out;
}
rclk = devm_clk_get(&client->dev, "rclk");
if (PTR_ERR(rclk) == -EPROBE_DEFER) {
pr_err("rda5807 failed to get rclk");
goto out_deregister;
}
res = clk_prepare_enable(rclk);
if (res) {
pr_err("rda5807 failed to enable rclk");
goto out_deregister;
}
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
return 0;
}
驱动模块加载修改:
static int __init rda5807_init(void)
{
pr_info("rda5807 driver: init\n");
return i2c_add_driver(&rda5807_driver);
}
static void __exit rda5807_exit(void)
{
pr_info("rda5807 driver: exit\n");
i2c_del_driver(&rda5807_driver);
}
//module_init(rda5807_init);
late_initcall(rda5807_init);//晚一点加载
module_exit(rda5807_exit);