Platform device driver autoloading mechanism

1.1k views Asked by At

As I understand, platform device drivers could be autoloaded when "compatible" field in the device tree matches with "compatible" field in the kernel module. Here is pwm-overlay.dts file from Raspberry Pi distro:

/ {
    fragment@0 {
        target = <&gpio>;
        __overlay__ {
            pwm_pins: pwm_pins {
                brcm,pins = <18>;
                brcm,function = <2>; /* Alt5 */
            };
        };
    };

    fragment@1 {
        target = <&pwm>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <&pwm_pins>;
            status = "okay";
        };
    };

    fragment@2 {
        target = <&clk_pwm>;
        frag2: __overlay__ {
            clock-frequency = <100000000>;
        };
    };

    __overrides__ {
        pin   = <&pwm_pins>,"brcm,pins:0";
        func  = <&pwm_pins>,"brcm,function:0";
        clock = <&frag2>,"clock-frequency:0";
    };
};

First of all, I do not see any "compatible" field, but in pwm-bcm2835.c file there are such strings:

static const struct of_device_id bcm2835_pwm_of_match[] = {
    { .compatible = "brcm,bcm2835-pwm", },
    { /* sentinel */ }
};

Also, when I load overlay, driver successfully autoloaded too. How it works? How it knows what driver to load?

1

There are 1 answers

0
TrentP On BEST ANSWER

You're right about how "compatible" fields are matched to bind a driver to a device, you're just not looking the right place for it.

The file you are looking at is a device tree overlay. It's added to an existing device tree, adding, removing, or changing some of the nodes and properties. The final device tree is the result of combing the original with some number of overlays. A given property might be (re-)defined in any of the original's and/or overlays' source files. It's an arbitrary decision of the designer how to structure the device tree source code.

But think a bit about why overlays exist. This overlay is for configuring the PWM, as the configuration of the PWM is not identical for every board (you might not use it at all). Using overlays for something that can change lets us make that change without building and booting from a new device tree. The existence of the PWM hardware in the SoC is constant. Even if not used, it's never not there. Certain things about it, like the base address of the device registers, also do not change. So there is no point in putting this in an overlay, as it doesn't change, and it would likely be in the base device tree source.

In the overlay, fragment@1 is modifying an existing target node labeled "pwm". If we look for this node, we find it in bcm283x.dtsi:

            pwm: pwm@7e20c000 {
                    compatible = "brcm,bcm2835-pwm";
                    reg = <0x7e20c000 0x28>;
                    clocks = <&clocks BCM2835_CLOCK_PWM>;
                    assigned-clocks = <&clocks BCM2835_CLOCK_PWM>;
                    assigned-clock-rates = <10000000>;
                    #pwm-cells = <2>;
                    status = "disabled";
            };

And there you have the compatible property with value "brcm,bcm2835-pwm". Since it would not need to be changed, it is in the source of the base device tree like we would expect.