Несоответствие дерева устройств: .probe никогда не вызывается

У меня проблемы с пониманием того, как работает дерево устройств, или, в частности, почему этот драйвер не запускается. Это в ядре производителя Rockchip для Android, версия 3.10

drivers / watchdog / rk29_wdt.c (уменьшено для удобства чтения)

static const struct of_device_id of_rk29_wdt_match[] = {
    { .compatible = "rockchip,watch dog" }
};
static struct platform_driver rk29_wdt_driver = {
    .probe          = rk29_wdt_probe,
    [..]
            .of_match_table = of_rk29_wdt_match,
            .name   = "rk29-wdt",
    },
};

static int __init watchdog_init(void)
{ 
    printk("watchdog_init\n");
    return platform_driver_register(&rk29_wdt_driver);
}

а это соц дци

арка / руки / загрузки / DTS /rk3288.dtsi

    watchdog: wdt@2004c000 {
            compatible = "rockchip,watch dog";
            reg = <0xff800000 0x100>;
            clocks = <&pclk_pd_alive>;
            clock-names = "pclk_wdt";
            interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
            rockchip,irq = <0>;
            rockchip,timeout = <2>;
            rockchip,atboot = <1>;
            rockchip,debug = <0>;
            status = "okay";
    };

однако функция драйвера.probe никогда не вызывается. Он компилируется и вызывается функция __init. Я подозреваю, что это связано с тем, что запись в дереве устройств не совпадает? Может быть, пространство это проблема?

Или есть еще что-то, что запускается до.probe, определяющее, должен ли драйвер продолжаться?

Также я не уверен, как работает сплющенное дерево, так что, возможно, это уместно:

арка / рука / маш-Rockchip/rk3288

DT_MACHINE_START(RK3288_DT, "Rockchip RK3288 (Flattened Device Tree)")
    .smp            = smp_ops(rockchip_smp_ops),
    .map_io         = rk3288_dt_map_io,
    .init_time      = rk3288_dt_init_timer,
    .dt_compat      = rk3288_dt_compat,
    .init_late      = rk3288_init_late,
    .reserve        = rk3288_reserve,
    .restart        = rk3288_restart,
MACHINE_END

1 ответ

Решение

Это может произойти несколькими способами, и большинство из них находятся далеко от самого кода драйвера. Во-первых, один фрагмент.dtsi не рассказывает всей истории - синтаксис дерева устройств является иерархическим, поэтому свойства (в частности, status) все еще может быть переопределено.dts уровня платы, который включает в себя основной файл.dtsi SoC . Во-вторых, скомпилированный DTB также не является последним словом, поскольку загрузчик может динамически изменять его перед передачей его ядру - это обычно делается для узлов памяти и методов включения SMP, но потенциально может повлиять на что угодно.

Этот вид отладки часто лучше всего решать в обратном порядке, изучая состояние загруженной системы, а затем работая в обратном направлении, чтобы выяснить, как все получилось - специфика этого конкретного вопроса уже кое-что проясняет, но ради полнота:

  • Если ядро ​​знает о драйвере, и оно загружено и правильно инициализировано, оно должно появиться где-то в /sys/bus/*/drivers / - в противном случае оно может быть в модуле, который нуждается в загрузке, или он не смог инициализироваться из-за некоторой неудовлетворенной зависимости от какого-либо другого драйвера или ресурса.
  • Если ядро ​​знает об устройстве, оно должно появиться где-то в /sys/bus/*/devices /, и если оно правильно связано с драйвером и проверено, то они оба должны иметь символическую ссылку друг на друга.
  • Если устройство нигде не найдено, то в системе на базе DT следующим местом для проверки будет / proc / device-tree/ (зависит от CONFIG_PROC_DEVICETREE на старых ядрах и канонически находится в / sys / firmware / devicetree / base / на более новых) - это покажет вид DT в том виде, в котором его нашло ядро, и немного осмотритесь там, надо надеяться, прояснить любые отсутствующие узлы или свойства не на своем месте, такие как отключенный узел, вызывающий ядро пропустить создание устройства вообще. Помните, что сами файлы свойств - это просто необработанные данные - так что вы, вероятно, захотите подглядывать с помощью hexdump, а не cat - и что все числовые ячейки имеют порядок байтов с прямым порядком байтов.

Я заметил, что в вашем определении вы упускаете так называемый SENTINEL в своем массиве, пустую пустую структуру. Вот пример:

static const struct of_device_id clk_ids[]  = {
{ .compatible = "sirf,atlas7-clkc" },
{},

};

Другие вопросы по тегам