Драйвер mfd serdev для Linux не проверяется

Я пытаюсь написать драйвер MFD с сопутствующим драйвером GPIO, используя новую последовательную шину устройств в Linux (с использованием ядра 4.11rc6).

Я использую qemu для устройств arm, и я изменил arch/arm/boot/dts/versatile-ab.dts так, чтобы uart2 читал:

uart2: uart@101f3000 {
    compatible = "arm,pl011", "arm,primecell";
    reg = <0x101f3000 0x1000>;
    interrupts = <14>;
    clocks = <&xtal24mhz>, <&pclk>;
    clock-names = "uartclk", "apb_pclk";

    fcd16999 {
        compatible = "ev,fcd16999";

        fcd16999gpio: fcd16999-gpio {
            compatible = "ev,fcd16999-gpio";
        };
    };
};

/proc/device-tree/amba/uart@101f3000/fcd16999/compatible читает ev,fcd16999, а дочерний узел fcd16999-gpio/compatible - ev,fcd16999-gpio.

Тем не менее вызывается функция инициализации обоих устройств, но не их функции проверки. Я упустил здесь что-то очевидное? Совместимые флаги совпадают, и дерево устройств загружается, так что все должно работать, верно?

Файлы ниже.

драйверы / mfd / fcd16999.c

#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/serdev.h>
#include <linux/slab.h>
/*#include <linux/mfd/tps6507x.h>*/

static const struct mfd_cell fcd16999_devs[] = {
    {
        .name = "fcd16999-gpio",
    .of_compatible = "ev,fcd16999-gpio",
    },
  /*
    {
        .name = "fcd16999-adc",
    },
    {
        .name = "fcd16999-thermometer",
    },
  */
};

static int fcd16999_serdev_probe(struct serdev_device *serdev)
{
    dev_warn(&serdev->dev, "fcd16999_serdev_probe\n");

    return devm_mfd_add_devices(&serdev->dev, 1, fcd16999_devs,
                    ARRAY_SIZE(fcd16999_devs), NULL, 0, NULL);
}

void fcd16999_serdev_remove(struct serdev_device *serdev)
{
    dev_warn(&serdev->dev, "fcd16999_serdev_remove\n");
}

static const struct of_device_id fcd16999_of_match[] = {
    {.compatible = "ev,fcd16999", },
    {},
};
MODULE_DEVICE_TABLE(of, fcd16999_of_match);

static struct serdev_device_driver fcd16999_driver = {
    .driver = {
           .name = "fcd16999",
           .of_match_table = of_match_ptr(fcd16999_of_match),
    },
    .probe = fcd16999_serdev_probe,
    .remove = fcd16999_serdev_remove,
};

static int __init fcd16999_serdev_init(void)
{
  int ret = 101;
    printk("Hello from fcd16999!\n");
    ret = serdev_device_driver_register(&fcd16999_driver);
  printk("serdev_device_driver_register returned %d\n", ret);
  return  ret;
}
/* init early so consumer devices can complete system boot */
subsys_initcall(fcd16999_serdev_init);

static void __exit fcd16999_serdev_exit(void)
{
    printk("Goodbye from fcd16999!\n");
    serdev_device_driver_unregister(&fcd16999_driver);
}
module_exit(fcd16999_serdev_exit);

драйверы / gpio / gpio-fcd16999.c

#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
/* #include <linux/mfd/stmpe.h> */

static int fcd16999_gpio_probe(struct platform_device *pdev)
{
    printk("Hellow, fcd16999\n");
    dev_warn(&pdev->dev, "fcd16999_gpio probing...\n");

    return 0;
}

static struct platform_driver fcd16999_gpio_driver = {
    .driver = {
        .suppress_bind_attrs    = true,
        .name           = "fcd16999-gpio",
    },
    .probe  = fcd16999_gpio_probe,
};

static int __init fcd16999_gpio_init(void)
{
    printk("Init Hellow, gpio-fcd16999\n");
    return platform_driver_register(&fcd16999_gpio_driver);
}
subsys_initcall(fcd16999_gpio_init);

static void __exit fcd16999_gpio_exit(void)
{
    printk("Goodbye from gpio-fcd16999!\n");
    platform_driver_unregister(&fcd16999_gpio_driver);
}
module_exit(fcd16999_gpio_exit);

person evading    schedule 09.07.2017    source источник
comment
Вы пропустили показать драйвер UART (части зонда и инициализации). Лучше использовать репо на Github или что-то подобное и поделиться ссылкой.   -  person 0andriy    schedule 09.07.2017
comment
Я даже не думал об этом, но я совсем не касался этой части. Я думаю, это должно быть хорошо, так как это драйвер руки qemu по умолчанию.   -  person evading    schedule 09.07.2017


Ответы (1)


Оказывается, мне нужно было включить опцию SERIAL_DEV_CTRL_TTYPORT в ядре, чтобы заставить его зондировать.

person evading    schedule 25.07.2017