Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the possible use of dev_set_drvdata and dev_get_drvdata

I just want to know what is the possible use case when we have to use these set and get driver APIs. All I get to know that the data is saved, and at a later time we can use data to do something. My question is when we really need to do that?

     /*
      * These exports can't be _GPL due to .h files using this within them, and it
      * might break something that was previously working...
     */
     void *dev_get_drvdata(const struct device *dev)
     {
          if (dev && dev->p)
                  return dev->p->driver_data;
          return NULL;
     }
     EXPORT_SYMBOL(dev_get_drvdata);

     void dev_set_drvdata(struct device *dev, void *data)
     {
        int error;
 
        if (!dev)
                 return;
        if (!dev->p) {
                 error = device_private_init(dev);
                 if (error)
                         return;
        }
        dev->p->driver_data = data;
     }
     EXPORT_SYMBOL(dev_set_drvdata);
like image 397
mrigendra Avatar asked May 22 '14 07:05

mrigendra


1 Answers

The driver core handles different stages of running the driver. You may consider a driver code as a set of callbacks, such as ->probe(), ->remove(), and so on. For details you can check struct platform_driver or struct pci_driver definition.

So, how can you communicate between the callbacks?

Right, you have at least two ways:

  • introduce global variable in the module [usually BAD idea]
  • specify something in the parameters of callback, in your case struct device or its children (struct pci_dev for example).

Thus, we have a pointer to a private member which can be used as a container of useful information that should be passed through callbacks.

Why we need that? Most of the drivers request some resources and save pointers to them somewhere at probe stage. To avoid a leak of the resources you have to free them at the remove stage. That's how it used.

As pointed out by allsey87, another useful pattern is to pass a current state of the device across callbacks. One of the real example is power management callbacks (->suspend(), ->resume(), etc).

like image 87
0andriy Avatar answered Nov 14 '22 04:11

0andriy