i2c从设备rtc时钟设备的初始化:
[ 4.075355] Call trace:
[ 4.075365] [<ffff00000808aae8>] dump_backtrace+0x0/0x270
[ 4.075368] [<ffff00000808af6c>] show_stack+0x24/0x30
[ 4.075373] [<ffff0000084aa108>] dump_stack+0xa8/0xd0
[ 4.075376] [<ffff0000087c9b80>] rx8581_probe+0x20/0x140
[ 4.075378] [<ffff0000087cb95c>] i2c_device_probe+0x17c/0x230
[ 4.075381] [<ffff0000085b08cc>] driver_probe_device+0x204/0x2b0
[ 4.075383] [<ffff0000085b0a34>] __driver_attach+0xbc/0xc0
[ 4.075385] [<ffff0000085ae5d0>] bus_for_each_dev+0x70/0xb0
[ 4.075387] [<ffff0000085affd8>] driver_attach+0x30/0x40
[ 4.075389] [<ffff0000085afae0>] bus_add_driver+0x110/0x230
[ 4.075391] [<ffff0000085b1588>] driver_register+0x68/0x100
[ 4.075393] [<ffff0000087cc69c>] i2c_register_driver+0x4c/0x90
[ 4.075398] [<ffff000008df18a0>] rx8581_driver_init+0x18/0x20
[ 4.075400] [<ffff000008083d04>] do_one_initcall+0x44/0x130
[ 4.075404] [<ffff000008db0cf8>] kernel_init_freeable+0x194/0x234
[ 4.075407] [<ffff0000089f3780>] kernel_init+0x18/0x108
[ 4.075409] [<ffff000008083aa0>] ret_from_fork+0x10/0x30
[ 4.075435] error rtc name is rtc-rx8581 id is 0
[ 4.075437] error dev name is (null)
[ 4.075439] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.115-rt93-CGEL-V6.02.10.R2 #55
[ 4.075440] Hardware name: LS1046A RDB Board (DT)
[ 4.075441] Call trace:
[ 4.075443] [<ffff00000808aae8>] dump_backtrace+0x0/0x270
[ 4.075446] [<ffff00000808af6c>] show_stack+0x24/0x30
[ 4.075448] [<ffff0000084aa108>] dump_stack+0xa8/0xd0
[ 4.075452] [<ffff0000087c3ee0>] __rtc_read_time.isra.1+0x30/0xb8
[ 4.075454] [<ffff0000087c3fac>] rtc_read_time+0x44/0x68
[ 4.075456] [<ffff0000087c48e4>] __rtc_read_alarm+0x34/0x398
[ 4.075458] [<ffff0000087c361c>] rtc_device_register+0x27c/0x300
[ 4.075460] [<ffff0000087c3794>] devm_rtc_device_register+0x64/0xc8
[ 4.075462] [<ffff0000087c9c40>] rx8581_probe+0xe0/0x140
[ 4.075464] [<ffff0000087cb95c>] i2c_device_probe+0x17c/0x230
[ 4.075467] [<ffff0000085b08cc>] driver_probe_device+0x204/0x2b0
[ 4.075469] [<ffff0000085b0a34>] __driver_attach+0xbc/0xc0
[ 4.075471] [<ffff0000085ae5d0>] bus_for_each_dev+0x70/0xb0
[ 4.075472] [<ffff0000085affd8>] driver_attach+0x30/0x40
[ 4.075474] [<ffff0000085afae0>] bus_add_driver+0x110/0x230
[ 4.075476] [<ffff0000085b1588>] driver_register+0x68/0x100
[ 4.075478] [<ffff0000087cc69c>] i2c_register_driver+0x4c/0x90
[ 4.075481] [<ffff000008df18a0>] rx8581_driver_init+0x18/0x20
[ 4.075482] [<ffff000008083d04>] do_one_initcall+0x44/0x130
[ 4.075485] [<ffff000008db0cf8>] kernel_init_freeable+0x194/0x234
[ 4.075486] [<ffff0000089f3780>] kernel_init+0x18/0x108
[ 4.075488] [<ffff000008083aa0>] ret_from_fork+0x10/0x30
[ 4.075491] zhanged rtc ops rx8581_rtc_ops
[ 4.075493] zhanged rtc ops rx8581_rtc_read_time
[ 4.185401] rtc-rx8581 3-0032: rtc core: registered rtc-rx8581 as rtc8
[ 4.185418] i2c /dev entries driver
dts配置:
i2c@21b0000 {
compatible = "fsl,vf610-i2c";
#address-cells = <0x1>;
#size-cells = <0x0>;
reg = <0x0 0x21b0000 0x0 0x10000>;
interrupts = <0x0 0x3b 0x4>;
clocks = <0x2 0x4 0x1>;
status = "okay";
rx8581@32 {
#address-cells = <0x1>;
#size-cells = <0x0>;
compatible = "rx8581";
reg = <0x32>;
};
};
修改驱动代码id为8后,可以发现,在文件系统dev目录下会自动出现dev/rtc8设备。
# ls -l dev/rtc
rtc0 rtc8
# ls -l dev/rtc
rtc0 rtc8
# ls -l dev/rtc
rtc0 rtc8
# ls -l dev/rtc8
crw-rw---- 1 root root 253, 0 Jan 1 00:00 dev/rtc8
/**
* rtc_device_register - register w/ RTC class
* @dev: the device to register
*
* rtc_device_unregister() must be called when the class device is no
* longer needed.
*
* Returns the pointer to the new struct class device.
*/
struct rtc_device *rtc_device_register(const char *name, struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner)
{
struct rtc_device *rtc;
struct rtc_wkalrm alrm;
int of_id = -1, id = -1, err;
if (dev->of_node)
of_id = of_alias_get_id(dev->of_node, "rtc");
else if (dev->parent && dev->parent->of_node)
of_id = of_alias_get_id(dev->parent->of_node, "rtc");
if (of_id >= 0) {
id = ida_simple_get(&rtc_ida, of_id, of_id + 1,
GFP_KERNEL);
if (id < 0)
dev_warn(dev, "/aliases ID %d not available\n",
of_id);
}
if (id < 0) {
id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
goto exit;
}
}
rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
if (rtc == NULL) {
err = -ENOMEM;
goto exit_ida;
}
rtc->id = id;
rtc->ops = ops;
rtc->owner = owner;
rtc->irq_freq = 1;
rtc->max_user_freq = 64;
rtc->dev.parent = dev;
rtc->dev.class = rtc_class;
rtc->dev.groups = rtc_get_dev_attribute_groups();
rtc->dev.release = rtc_device_release;
mutex_init(&rtc->ops_lock);
spin_lock_init(&rtc->irq_lock);
spin_lock_init(&rtc->irq_task_lock);
init_waitqueue_head(&rtc->irq_queue);
/* Init timerqueue */
timerqueue_init_head(&rtc->timerqueue);
INIT_WORK(&rtc->irqwork, rtc_timer_do_work);
/* Init aie timer */
rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);
/* Init uie timer */
rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);
/* Init pie timer */
hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
rtc->pie_timer.function = rtc_pie_update_irq;
rtc->pie_enabled = 0;
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
printk("error rtc name is %s id is %d\n", name, id);
id = 8; --修改为8。
dev_set_name(&rtc->dev, "rtc%d", id);
printk("error dev name is %s\n", rtc->name);
/* Check to see if there is an ALARM already set in hw */
err = __rtc_read_alarm(rtc, &alrm);
if (!err && !rtc_valid_tm(&alrm.time))
rtc_initialize_alarm(rtc, &alrm);
rtc_dev_prepare(rtc);
err = device_register(&rtc->dev);
if (err) {
/* This will free both memory and the ID */
put_device(&rtc->dev);
goto exit;
}
rtc_dev_add_device(rtc);
rtc_proc_add_device(rtc);
dev_info(dev, "rtc core: registered %s as %s\n",
rtc->name, dev_name(&rtc->dev));
return rtc;
exit_ida:
ida_simple_remove(&rtc_ida, id);
exit:
dev_err(dev, "rtc core: unable to register %s, err = %d\n",
name, err);
return ERR_PTR(err);
}