Linux设备驱动程序:不调用具有地址的兼容设备的探测功能

时间:2020-04-15 11:24:13

标签: linux-kernel linux-device-driver device-tree

当我在设备树中添加单元地址和reg属性时,未调用我的探测功能。 我有一个模块原型:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>

#include <linux/platform_device.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_platform.h>
#endif

static int ect_probe(struct platform_device *pdev) {
    struct device *dev = &pdev->dev;
    struct device_node *np = dev->of_node;

    pr_info("We 're in probe function\n");
    pr_info("Reading device tree values\n");
    u32 parameter_address;
    if (of_property_read_u32(np, "parameter_address", &parameter_address)) {
            return -EINVAL;
    }
    pr_info("parameter_address is: %d\n", parameter_address);

    return 0;
}

static int ect_remove(struct platform_device *pdev)
{
    return -EBUSY;
}

static struct of_device_id ect_of_device_ids[] = {
    {.compatible = "exynos", },
    {},
};

static struct platform_device_id ect_plat_device_ids[] = {
    {.name = "ect"},
    {},
};

static struct platform_driver ect_parser = {
        .probe = ect_probe,
        .remove = ect_remove,
        .id_table = ect_plat_device_ids,
        .driver = {
                .name = "ect",
                .owner = THIS_MODULE,
                .of_match_table = ect_of_device_ids,
        },
};

static int __init ect_init(void)
{
    printk(KERN_INFO "Init ECT module\n");
    return platform_driver_register(&ect_parser);
}

static void ect_exit(void) {
    printk(KERN_INFO "Exit ECT module\n");
}

module_init(ect_init)
module_exit(ect_exit)

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Unknown samsung developer");
MODULE_DESCRIPTION("Samsung Exynos calibration table parser module.");
MODULE_VERSION("0.01");

以及设备树根目录中的相应条目:

ect@67FEB000 {
        compatible = "exynos,ect";
        reg = <0x00 0x67FEB000 0x00 0x14000>;
        parameter_address = <0x67FEB000>;
        parameter_size = <0x14000>;
    };

引导时,我可以看到调用了ect_init函数,因此我假设驱动程序已注册。但是由于某些原因未调用探测功能。

与此同时,与此设备树条目一起调用了探测功能

ect {
        compatible = "exynos,ect";
        parameter_address = <0x67FEB000>;
        parameter_size = <0x14000>;
    };

我认为设备和驱动程序linux中兼容属性的匹配应执行探测功能。

为什么单元地址和reg属性破坏了设备驱动程序匹配?

完整的设备树:

/dts-v1/;

/ {
    interrupt-parent = < 0x8001 >;
    #size-cells = < 0x02 >;
    #address-cells = < 0x02 >;
    compatible = "linux,dummy-virt";

    psci {
        migrate = < 0xc4000005 >;
        cpu_on = < 0xc4000003 >;
        cpu_off = < 0x84000002 >;
        cpu_suspend = < 0xc4000001 >;
        method = "hvc";
        compatible = "arm,psci-0.2\0arm,psci";
    };

    ect@67FEB000 {
            compatible = "exynos,ect";
            reg = <0x00 0x67FEB000 0x00 0x14000>;
            parameter_address = <0x67FEB000>;
            parameter_size = <0x14000>;
        };

    memory@40000000 {
        reg = < 0x00 0x40000000 0x00 0x10000000 >;
        device_type = "memory";
    };

    platform@c000000 {
        interrupt-parent = < 0x8001 >;
        ranges = < 0x00 0x00 0xc000000 0x2000000 >;
        #address-cells = < 0x01 >;
        #size-cells = < 0x01 >;
        compatible = "qemu,platform\0simple-bus";
    };

    fw-cfg@9020000 {
        dma-coherent;
        reg = < 0x00 0x9020000 0x00 0x18 >;
        compatible = "qemu,fw-cfg-mmio";
    };

    virtio_mmio@a000000 {
        dma-coherent;
        interrupts = < 0x00 0x10 0x01 >;
        reg = < 0x00 0xa000000 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000200 {
        dma-coherent;
        interrupts = < 0x00 0x11 0x01 >;
        reg = < 0x00 0xa000200 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000400 {
        dma-coherent;
        interrupts = < 0x00 0x12 0x01 >;
        reg = < 0x00 0xa000400 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000600 {
        dma-coherent;
        interrupts = < 0x00 0x13 0x01 >;
        reg = < 0x00 0xa000600 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000800 {
        dma-coherent;
        interrupts = < 0x00 0x14 0x01 >;
        reg = < 0x00 0xa000800 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000a00 {
        dma-coherent;
        interrupts = < 0x00 0x15 0x01 >;
        reg = < 0x00 0xa000a00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000c00 {
        dma-coherent;
        interrupts = < 0x00 0x16 0x01 >;
        reg = < 0x00 0xa000c00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a000e00 {
        dma-coherent;
        interrupts = < 0x00 0x17 0x01 >;
        reg = < 0x00 0xa000e00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001000 {
        dma-coherent;
        interrupts = < 0x00 0x18 0x01 >;
        reg = < 0x00 0xa001000 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001200 {
        dma-coherent;
        interrupts = < 0x00 0x19 0x01 >;
        reg = < 0x00 0xa001200 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001400 {
        dma-coherent;
        interrupts = < 0x00 0x1a 0x01 >;
        reg = < 0x00 0xa001400 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001600 {
        dma-coherent;
        interrupts = < 0x00 0x1b 0x01 >;
        reg = < 0x00 0xa001600 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001800 {
        dma-coherent;
        interrupts = < 0x00 0x1c 0x01 >;
        reg = < 0x00 0xa001800 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001a00 {
        dma-coherent;
        interrupts = < 0x00 0x1d 0x01 >;
        reg = < 0x00 0xa001a00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001c00 {
        dma-coherent;
        interrupts = < 0x00 0x1e 0x01 >;
        reg = < 0x00 0xa001c00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a001e00 {
        dma-coherent;
        interrupts = < 0x00 0x1f 0x01 >;
        reg = < 0x00 0xa001e00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002000 {
        dma-coherent;
        interrupts = < 0x00 0x20 0x01 >;
        reg = < 0x00 0xa002000 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002200 {
        dma-coherent;
        interrupts = < 0x00 0x21 0x01 >;
        reg = < 0x00 0xa002200 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002400 {
        dma-coherent;
        interrupts = < 0x00 0x22 0x01 >;
        reg = < 0x00 0xa002400 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002600 {
        dma-coherent;
        interrupts = < 0x00 0x23 0x01 >;
        reg = < 0x00 0xa002600 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002800 {
        dma-coherent;
        interrupts = < 0x00 0x24 0x01 >;
        reg = < 0x00 0xa002800 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002a00 {
        dma-coherent;
        interrupts = < 0x00 0x25 0x01 >;
        reg = < 0x00 0xa002a00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002c00 {
        dma-coherent;
        interrupts = < 0x00 0x26 0x01 >;
        reg = < 0x00 0xa002c00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a002e00 {
        dma-coherent;
        interrupts = < 0x00 0x27 0x01 >;
        reg = < 0x00 0xa002e00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003000 {
        dma-coherent;
        interrupts = < 0x00 0x28 0x01 >;
        reg = < 0x00 0xa003000 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003200 {
        dma-coherent;
        interrupts = < 0x00 0x29 0x01 >;
        reg = < 0x00 0xa003200 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003400 {
        dma-coherent;
        interrupts = < 0x00 0x2a 0x01 >;
        reg = < 0x00 0xa003400 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003600 {
        dma-coherent;
        interrupts = < 0x00 0x2b 0x01 >;
        reg = < 0x00 0xa003600 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003800 {
        dma-coherent;
        interrupts = < 0x00 0x2c 0x01 >;
        reg = < 0x00 0xa003800 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003a00 {
        dma-coherent;
        interrupts = < 0x00 0x2d 0x01 >;
        reg = < 0x00 0xa003a00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003c00 {
        dma-coherent;
        interrupts = < 0x00 0x2e 0x01 >;
        reg = < 0x00 0xa003c00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    virtio_mmio@a003e00 {
        dma-coherent;
        interrupts = < 0x00 0x2f 0x01 >;
        reg = < 0x00 0xa003e00 0x00 0x200 >;
        compatible = "virtio,mmio";
    };

    gpio-keys {
        #address-cells = < 0x01 >;
        #size-cells = < 0x00 >;
        compatible = "gpio-keys";

        poweroff {
            gpios = < 0x8003 0x03 0x00 >;
            linux,code = < 0x74 >;
            label = "GPIO Key Poweroff";
        };
    };

    pl061@9030000 {
        phandle = < 0x8003 >;
        clock-names = "apb_pclk";
        clocks = < 0x8000 >;
        interrupts = < 0x00 0x07 0x04 >;
        gpio-controller;
        #gpio-cells = < 0x02 >;
        compatible = "arm,pl061\0arm,primecell";
        reg = < 0x00 0x9030000 0x00 0x1000 >;
    };

    pcie@10000000 {
        interrupt-map-mask = < 0x1800 0x00 0x00 0x07 >;
        interrupt-map = < 0x00 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x05 0x04 >;
        #interrupt-cells = < 0x01 >;
        ranges = < 0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00 >;
        reg = < 0x40 0x10000000 0x00 0x10000000 >;
        msi-parent = < 0x8002 >;
        dma-coherent;
        bus-range = < 0x00 0xff >;
        linux,pci-domain = < 0x00 >;
        #size-cells = < 0x02 >;
        #address-cells = < 0x03 >;
        device_type = "pci";
        compatible = "pci-host-ecam-generic";
    };

    pl031@9010000 {
        clock-names = "apb_pclk";
        clocks = < 0x8000 >;
        interrupts = < 0x00 0x02 0x04 >;
        reg = < 0x00 0x9010000 0x00 0x1000 >;
        compatible = "arm,pl031\0arm,primecell";
    };

    pl011@9000000 {
        clock-names = "uartclk\0apb_pclk";
        clocks = < 0x8000 0x8000 >;
        interrupts = < 0x00 0x01 0x04 >;
        reg = < 0x00 0x9000000 0x00 0x1000 >;
        compatible = "arm,pl011\0arm,primecell";
    };

    pmu {
        interrupts = < 0x01 0x07 0x104 >;
        compatible = "arm,armv8-pmuv3";
    };

    intc@8000000 {
        phandle = < 0x8001 >;
        reg = < 0x00 0x8000000 0x00 0x10000 0x00 0x8010000 0x00 0x10000 >;
        compatible = "arm,cortex-a15-gic";
        ranges;
        #size-cells = < 0x02 >;
        #address-cells = < 0x02 >;
        interrupt-controller;
        #interrupt-cells = < 0x03 >;

        v2m@8020000 {
            phandle = < 0x8002 >;
            reg = < 0x00 0x8020000 0x00 0x1000 >;
            msi-controller;
            compatible = "arm,gic-v2m-frame";
        };
    };

    flash@0 {
        bank-width = < 0x04 >;
        reg = < 0x00 0x00 0x00 0x4000000 0x00 0x4000000 0x00 0x4000000 >;
        compatible = "cfi-flash";
    };

    cpus {
        #size-cells = < 0x00 >;
        #address-cells = < 0x01 >;

        cpu@0 {
            reg = < 0x00 >;
            compatible = "arm,cortex-a57";
            device_type = "cpu";
        };
    };

    timer {
        interrupts = < 0x01 0x0d 0x104 0x01 0x0e 0x104 0x01 0x0b 0x104 0x01 0x0a 0x104 >;
        always-on;
        compatible = "arm,armv8-timer\0arm,armv7-timer";
    };

    apb-pclk {
        phandle = < 0x8000 >;
        clock-output-names = "clk24mhz";
        clock-frequency = < 0x16e3600 >;
        #clock-cells = < 0x00 >;
        compatible = "fixed-clock";
    };

    chosen {
        bootargs = "ect root=/dev/vda console_msg_format=syslog nokaslr norandmaps panic=-1 printk.devkmsg=on printk.time=y rw console=ttyAMA0 - lkmc_home=/lkmc";
        stdout-path = "/pl011@9000000";
    };
};

1 个答案:

答案 0 :(得分:1)

.compatible = "exynos"中的ect_of_device_ids[]条目与设备树中的compatible = "exynos,ect";条目不匹配。如果将其更改为"exynos,ect",则应调用您的探测函数:

static struct of_device_id ect_of_device_ids[] = {
    {.compatible = "exynos,ect", },
    {},
}

此外,如果要支持用户空间中热插拔处理程序自动加载外部内核模块,则需要使用MODULE_DEVICE_TABLE宏在模块中包括必要的信息:

#ifdef CONFIG_OF
MODULE_DEVICE_TABLE(of, ect_of_device_ids);
#endif
MODULE_DEVICE_TABLE(platform, ect_plat_device_ids);
相关问题