سؤال

I am working on power management on an i2c driver and noticed something odd.

include/linux/i2c.h

struct i2c_driver {
    //...
    int (*suspend)(struct i2c_client *, pm_message_t mesg);
    int (*resume)(struct i2c_client *);
    //...
    struct device_driver driver;
    //...
}

include/linux/device.h

struct device_driver {
    //...
    int (*suspend) (struct device *dev, pm_message_t state);
    int (*resume) (struct device *dev);
    //...
    const struct dev_pm_ops *pm;
    //...
}

include/linux/pm.h

struct dev_pm_ops {
    //...
    int (*suspend)(struct device *dev);
    int (*resume)(struct device *dev);
    //...
}

Why are there so many suspend and resume function pointers? Some kind of legacy thing? Which one should I use for my driver?

I am on an old kernel (2.6.35)

Thanks!

هل كانت مفيدة؟

المحلول

Why are there so many suspend and resume function pointers?

  1. i2c_driver - legacy support.
  2. device_driver - standard support.
  3. dev_pm_ops - extended power management.

Notice that they are all function pointers. There is sequencing for the suspend and resume. For instance, the i2c controller must be suspended after the devices but resumed before.

Some kind of legacy thing?

The struct i2c_driver is a legacy mechism. It existed before the entire power infrastructure was created. As well, some configurations may exclude the full struct dev_pm_ops pointer, but have the suspend and resume driver hooks. The full struct dev_pm_ops supports suspend to disk and other features. Suspend to memory is more common and is given pointers space in struct device_driver. If struct dev_pm_ops is non-NULL, the two pointer will be the same. These two should call the same routine in your driver.

Which one should I use for my driver?

You probably shouldn't use any of them. It is probably more likely that your driver is part of some other sub-system. see Note For instance, the i2c is used in codecs like the wm8940.c. Generally, i2c is not the central controlling sub-system. It is a driver that is used by something else to control a chip-set. The sound sub-system will be suspended before i2c and it is better to put your hooks there. If your driver is pure i2c, then use the macros in pm.h, like SET_SYSTEM_SLEEP_PM_OPS to conditionalize the setting of dev_pm_ops; so set both of them. Most likely the device_driver will be copied to dev_pm_ops if it exists, but doing it explicitly is better.

The driver-model, i2c power management and power driver documentation have more information on the structure and overviews.

Note: In this case, there are multiple device_driver structures. Usually the i2c_driver is managed by a controlling driver. The controlling driver should implement a suspend/resume for it's sub-system, which uses the i2c_driver interface.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top