-
Notifications
You must be signed in to change notification settings - Fork 7.5k
drivers: sensor: nxp: p3t1755: impl pm device runtime #90946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
drivers: sensor: nxp: p3t1755: impl pm device runtime #90946
Conversation
int p3t1755_i2c_get(const struct device *dev) | ||
{ | ||
const struct p3t1755_config *config = dev->config; | ||
|
||
return pm_device_runtime_get(config->bus_cfg.i2c.bus); | ||
} | ||
|
||
int p3t1755_i2c_put(const struct device *dev) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not static
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm following the pattern of the other APIs, I tried making them static and I get an "unused" warning :) outside scope of this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These, make them static and compiler complains
zephyr/drivers/sensor/nxp/p3t1755/p3t1755.c
Lines 35 to 47 in e0a915a
int p3t1755_i2c_read_reg(const struct device *dev, uint8_t reg, uint8_t *value, uint8_t len) | |
{ | |
const struct p3t1755_config *config = dev->config; | |
return i2c_burst_read_dt(&config->bus_cfg.i2c, reg, value, len); | |
} | |
int p3t1755_i2c_write_reg(const struct device *dev, uint8_t reg, uint8_t *byte, uint8_t len) | |
{ | |
const struct p3t1755_config *config = dev->config; | |
return i2c_burst_write_dt(&config->bus_cfg.i2c, reg, byte, len); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add __maybe_unused
:
__maybe_unused static int p3t1755_i2c_get(const struct device*dev)
drivers/sensor/nxp/p3t1755/p3t1755.c
Outdated
case PM_DEVICE_ACTION_SUSPEND: | ||
ret = p3t1755_pm_suspend(dev); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we calling this if it's a no-op?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keeping it simple following the style of the other APIs :) I can ifdef it out... EDIT sorry, yeah, removed it :)
Implement pm device runtime for p3t1755 sensor. Signed-off-by: Bjarki Arge Andreasen <[email protected]>
67707f5
to
ec3d0b6
Compare
{ | ||
const struct p3t1755_config *config = dev->config; | ||
|
||
return pm_device_runtime_get(config->i3c.bus); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be happening in the i2c/i3c driver code instead, when they are being used, hence "runtime" power management?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the driver sensor gets its bus when it needs to do transfers, and puts it when done, just like a user would with any other device :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the driver sensor gets its bus when it needs to do transfers, and puts it when done, just like a user would with any other device :)
But this is not the case really and how runtime power management should work, the device itself does the get/put, not the user. Sure there are special cases, maybe with sensors, but the idea is for users not to bother with power management and have this happen at the level driver itself, not its users. Our get/put helpers are very simplified and do not deal with special cases like Linux does as can be seen here: https://docs.kernel.org/power/runtime_pm.html#runtime-pm-device-helper-functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the driver sensor gets its bus when it needs to do transfers, and puts it when done, just like a user would with any other device :)
But this is not the case really and how runtime power management should work, the device itself does the get/put, not the user. Sure there are special cases, maybe with sensors, but the idea is for users not to bother with power management and have this happen at the level driver itself, not its users. Our get/put helpers are very simplified and do not deal with special cases like Linux does as can be seen here: https://docs.kernel.org/power/runtime_pm.html#runtime-pm-device-helper-functions
I really do not agree with this at all whatsoever, how it should work is the devices are all suspended by default and anything that knows it uses the hard needs to participate in the reference counting by calling these pm get/put APIs, and as far as I can see that includes both the client layer and the driver if it is a transactional API and needs to finish the transaction, like in the case of I2C. For example, if the client doesn't participate then you get a lot of extra suspend and resume that load the system and might not be desired since only the client has a better idea of the system load and situation, if the implementer doesn't then you potentially get issues like suspending during a bus transaction. You can't just say that one layer has the responsibility alone, because all the different components of software have different knowledge about the system, that's why reference counting is so crucial on complex computing systems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A funny example is nordics GPIO ports on the nrf54h20, to change the state of a pin, we need to power a power domain, which is done using IPC, so every single toggle of a pin, comes with two IPC transactions if we hide this in the gpio_pin_toggle
API implementation, worse, this also makes gpio_pin_toggle
impossible from ISRs since we need to send an IPC message and wait for it, twice... However, if the user gets the port before doing the toggle, its done only once and likely from thread context, after which gpio_pin_toggle
becomes a single register write again :)
|
int p3t1755_i2c_get(const struct device *dev) | ||
{ | ||
const struct p3t1755_config *config = dev->config; | ||
|
||
return pm_device_runtime_get(config->bus_cfg.i2c.bus); | ||
} | ||
|
||
int p3t1755_i2c_put(const struct device *dev) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add __maybe_unused
:
__maybe_unused static int p3t1755_i2c_get(const struct device*dev)
ret = 0; | ||
break; | ||
case PM_DEVICE_ACTION_RESUME: | ||
ret = p3t1755_pm_resume(dev); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any power savings in this implementation other than adding latency of calling resume repeatedly on resume.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be in the TURN_ON
action instead of RESUME
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think so, turn on will happen if power domain comes up for any reason, not necessarily because this device is being used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TURN_ON action is called as part of pm_device_driver_init
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure you're understanding what I mean. a device resumes if it has any reference count indicating that it is actually being used. So if the sensor is resumed, it means it's being used, so it needs to use it's bus device, and therefore puts a claim on it. If the sensor is not being used, it won't be resumed. The only time you need to resume the bus device from the perspective of this sensor driver is if the sensor is resumed.
Turn on action has nothing to do with the sensor being used. Any time a domain goes up it will call turn on on all of it's children, doesn't matter if they are supposed to be used or not, it's just a notification that their power is available. There's no reason to resume the bus device if the sensor driver get's a turn on action, because it doesn't mean that we actually need to do anything. And resuming the bus device will just potentially result in another domain getting turned on and wasting a bunch of time for no reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, thanks for explaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need information why this is needed as the implementation does not seem to be saving power..
@mmahadevan108 the point of the PR is clearly not to save power directly from the sensor, it's to claim and release the i2c bus device resource properly with the pm APIs.... because you can't use the sensor if the underlying i2c to talk to it is suspended... |
@bjarki-andreasen maybe this is a stupid question, but, instead of putting all this pm resuming/getting and suspending/putting code in these drivers like you are doing here with the sensor driver, I thought this was supposed to be the point of your refactor in #89372 for the PM subsystem to handle this automatically? So couldn't you just make the bus device the power domain of the sensor device and it would have the same effect, where if you resume the sensor then the bus also would get automatically resumed? |
Two things to consider:
|
Implement pm device runtime for p3t1755 sensor.