5

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.

Amit Singh Tomar
  • 8,380
  • 27
  • 120
  • 199

2 Answers2

17

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.).

eepp
  • 7,255
  • 1
  • 38
  • 56
  • Thanks @eepp for your detailed answer,once again you did great help to me.I will go through your answer.Can I let you know if I have any query related to this post? – Amit Singh Tomar Oct 08 '13 at 18:18
  • If you have another question, post it on SO and tag with `linux-kernel`. Someone should answer ;-) – eepp Oct 08 '13 at 19:55
  • The example you gave is for "platform bus" which is virtual bus.It define all four method for matching device to driver.But if I talk about actual physical bus say in this example http://lxr.free-electrons.com/source/drivers/spi/spi-davinci.c it uses only method of device to driver match which is of style.Now .compatible string both in Device tree and platform driver wil let you the controller used for the bus and driver handling this controller is defined under .name="spi_davinci".Please confirm is my understanding ok here?? – Amit Singh Tomar Oct 10 '13 at 07:18
  • The file you pointed is a platform driver, too, and yes it uses OF style matching. – eepp Oct 10 '13 at 07:21
  • My doubt is ,Platform bus example you gave platform.c and spi-davinci.c are equivalent ? Are they driver for two different controllers? – Amit Singh Tomar Oct 10 '13 at 07:27
  • `platform.c` is not a driver, it's the platform devices/drivers base code (in fact it registers a new bus, platform, so that devices may be added and drivers registered with this bus afterwards). – eepp Oct 10 '13 at 17:47
  • Thanks for telling me this point,so is it safe to say platform.c is architecture dependent/platform specific?? How can find platform.c(may be name is different) for my specific platform ,Do I have to look for function with name platform_add_devices/platform_device_add in my code base?? – Amit Singh Tomar Oct 10 '13 at 17:54
  • `platform.c` is independent. The specific board files will call its functions to add devices with absolute values for IRQs and MMIO regions. [Here's an example](https://github.com/torvalds/linux/blob/master/arch/arm/mach-pxa/csb701.c). This one adds GPIO LEDs and GPIO keys devices to the platform bus. And then all the structures that must be shared between board files and device drivers are placed in [`include/linux/platform_data`](https://github.com/torvalds/linux/tree/master/include/linux/platform_data). – eepp Oct 10 '13 at 17:59
  • Fine @eepp, will go through the links you provides,Can you provide me links to docs which tells me how DO I add new device to platform bus,what all are the necessary steps for adding the new device and driver to exiting platform bus code? – Amit Singh Tomar Oct 10 '13 at 18:14
  • My Platform is based on TI'S Keystone2 Board and we just had put a new FPGA device(xilink) on our BOard ,So I guess to reflect it as a software ,First I have to make changes to https://github.com/torvalds/linux/blob/master/arch/arm/mach-keystone/keystone.c and make a call to platform_add_devices.Is it the right approach ?? – Amit Singh Tomar Oct 10 '13 at 18:38
  • @eepp what I cant understand is everywhere we call `platform_get_resource(pdev, IORESOURCE_MEM, 0);` or `clk_get(&pdev->dev, NULL);` or some function like that, there is no initialisation or creation of the `struct device pdev`. is it one static struct shared by all modules?? –  Jan 10 '15 at 08:50
  • 1
    @Makouda When a platform driver is registered (using `module_platform_driver()` for example), it is passed a probe callback, which is passed a pointer to a `struct platform_device` instance when called. The instances of `struct platform_device` are created either by the [OF infrastructure](http://lxr.free-electrons.com/source/drivers/of/platform.c#L104), or manually (old style, statically), for example [here](https://github.com/torvalds/linux/blob/master/arch/arm/mach-pxa/csb701.c). – eepp Jan 12 '15 at 18:43
3

In the Linux kernel there are different buses (SPI, I2C, PCI, USB, ...).

Each bus has the list of drivers and devices that are registered on the bus.

Each time you connect a new device or a new driver to a bus, it starts the matching loop.

Suppose that you register a new SPI device. The SPI bus start a matching loop where it invokes the SPI match function to verify if your device match with a driver already registered in on the bus. If it does not match, there is nothing to do.

Now, suppose that you register a new SPI driver. The bus start again the matching loop in order to verify if any of the registered device match with this new driver. If it match, the driver probe() function is invoked.

Each bus has it own method to match a driver with a device. In order to implement a bus you have to write the matching function. So, you can implement a bus that match by name, by integer value, or anything you want.

You start the bus mechanism each time you register a driver or a device.

Here how I implemented the ZIO bus. Here you can find the SPI bus Here the core of the bus system

Federico
  • 3,782
  • 32
  • 46
  • Thanks Federico for your kind response.It would be great if you can provide some example for every case you mentioned. – Amit Singh Tomar Oct 08 '13 at 14:09
  • what if the device is to be interfaced over GPIO? and no BUS....!Which match will be required? – Raulp Jul 20 '16 at 10:46
  • The concept of bus in Linux is different that what we typically intend as bus. The Linux bus is just this mechanism that match devices and drivers. Regarding your question. It's not clear what you mean. But you can take a look at some GPIO driver in the Linux directory drivers/gpio. Here an example http://lxr.free-electrons.com/source/drivers/gpio/gpio-ts4800.c – Federico Jul 21 '16 at 07:54