From where platform device gets it name

Amit Singh Tomar picture Amit Singh Tomar · Oct 8, 2013 · Viewed 8.8k times · Source

I am reading about the Linux Device model which is built around buses,devices and drivers .I am able to understand a bit about how devices and driver matches happen but not clear about the role of buses here,how buses matches with device.

One more doubt I have regarding where platform device gets it name from.

"The platform bus,simply compares the name of each device against the name of each driver; if they are the same, the device matches the driver."

Now I could n't really understand above point .I believe device name is first defined in dts file and then corresponding Driver name is defined in platform driver code .

if these two name matches ,probe is called from driver code which will confirm device is really in existence.

Could anybody let me know the whole process specially from Bus point of view.

Answer

eepp picture eepp · Oct 8, 2013

To add to @Federico's answer, which describes very well the general case, platform devices can be matched to platform drivers using four things (that are prioritized). Here is the match function of the platform "bus":

static int platform_match(struct device *dev, struct device_driver *drv)
{
        struct platform_device *pdev = to_platform_device(dev);
        struct platform_driver *pdrv = to_platform_driver(drv);

        /* Attempt an OF style match first */
        if (of_driver_match_device(dev, drv))
                return 1;

        /* Then try ACPI style match */
        if (acpi_driver_match_device(dev, drv))
                return 1;

        /* Then try to match against the id table */
        if (pdrv->id_table)
                return platform_match_id(pdrv->id_table, pdev) != NULL;

        /* fall-back to driver name match */
        return (strcmp(pdev->name, drv->name) == 0);
}

Here are two important ones.

OF style match

Match using the device tree (of_driver_match_device). If you don't know the device tree concept yet, go read about it. In this data structure, each device has its own node within a tree representing the system. Each device also has a compatible property which is a list of strings. If any platform driver declares one of the compatible strings as being supported, there will be a match and the driver's probe will be called.

Here's an example of a node:

gpio0: gpio@44e07000 {
    compatible = "ti,omap4-gpio";
    ti,hwmods = "gpio1";
    gpio-controller;
    #gpio-cells = <2>;
    interrupt-controller;
    #interrupt-cells = <1>;
    reg = <0x44e07000 0x1000>;
    interrupts = <96>;
};

This describes a GPIO controller. It only has one compatible string which is ti,omap4-gpio. Any registered platform driver declaring this same compatible string will be probed. Here's its driver:

static const struct of_device_id omap_gpio_match[] = {
    {
        .compatible = "ti,omap4-gpio",
        .data = &omap4_pdata,
    },
    {
        .compatible = "ti,omap3-gpio",
        .data = &omap3_pdata,
    },
    {
        .compatible = "ti,omap2-gpio",
        .data = &omap2_pdata,
    },
    { },
};
MODULE_DEVICE_TABLE(of, omap_gpio_match);

static struct platform_driver omap_gpio_driver = {
    .probe      = omap_gpio_probe,
    .driver     = {
        .name   = "omap_gpio",
        .pm = &gpio_pm_ops,
        .of_match_table = of_match_ptr(omap_gpio_match),
    },
};

The driver is able to drive three types of GPIOs, including the one mentioned before.

Please note that platform devices are not magically added to the platform bus. The architecture/board initialization will call platform_device_add or platform_add_devices, in this case with the help of OF functions to scan the tree.

Name matching

If you look at platform_match, you will see that the match falls back to name matching. A simple string comparison is done between the driver name and the device name. This is how older platform driver worked. Some of them still do, like this one here:

static struct platform_driver imx_ssi_driver = {
    .probe = imx_ssi_probe,
    .remove = imx_ssi_remove,

    .driver = {
        .name = "imx-ssi",
        .owner = THIS_MODULE,
    },
};

module_platform_driver(imx_ssi_driver);

Again, the board specific initialization will have to call platform_device_add or platform_add_devices to add platform devices, which in the case of name matching ones are entirely created statically in C (name is given in C, resources like IRQs and base addresses, etc.).