Одна из задач учебных курсов по ядру Linux - добавить поддержку sysfs к одному из ранее написанных драйверов устройств. Я выбираю драйвер ds1307 rtc и хочу добавить атрибуты устройства, а не драйвера.
Но я не уверен, что мое решение верное.
В тот момент, когда функция зонда вызывается, клиентское устройство i2c уже создано, поэтому любые манипуляции с атрибутами устройства вызовут состояние гонки.
Поэтому я решаю добавить свои атрибуты на устройство rtc перед регистрацией устройства. Я просто считаю группы атрибутов rtc по умолчанию, выделяю новый массив с одной дополнительной позицией для моей группы атрибутов и заменяю указатель групп устройств rtc выделенным массивом.
static int ds1307x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev;
const struct attribute_group **grp, **ngrp;
struct rtc_device *rtc;
int ret, cnt;
/* device presence check code skipped */
dev = &client->dev;
rtc = devm_rtc_allocate_device(dev);
if (!rtc)
return -ENOMEM;
dev = &rtc->dev;
grp = dev->groups;
if (!grp) {
/* no default groups, just use own groups array */
dev->groups = ds1307x_groups;
} else {
/* copy rtc groups array, add own group at end */
cnt = 0;
while (grp[cnt])
++cnt;
ngrp = devm_kmalloc(&rtc->dev, (cnt+2) * sizeof(*ngrp),
GFP_KERNEL);
if (!ngrp)
return -ENOMEM;
memcpy(ngrp, grp, cnt * sizeof(*ngrp));
ngrp[cnt] = &ds1307x_group;
ngrp[cnt+1] = NULL;
dev->groups = ngrp;
}
rtc->uie_unsupported = 1;
rtc->ops = &ds1307x_ops;
ret = rtc_register_device(rtc);
/* remaining of code skipped */
}
Группа атрибутов ds1307x_control
с атрибутами clock_halt
и out_ctrl
появляется в каталоге устройств rtc0 среди стандартных атрибутов класса rtc:
~ # ls /sys/class/rtc/rtc0/
date ds1307x_control name subsystem
dev hctosys power time
device max_user_freq since_epoch uevent
~ # ls /sys/class/rtc/rtc0/ds1307x_control/
clock_halt out_ctrl
Это решение работает для меня, и я надеюсь, что оно достаточно хорошо для учебных курсов.
Но как насчет реальной жизни? Есть ли скрытые проблемы?