On Tue, Mar 6, 2018 at 6:46 PM, Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> wrote: > On Tue, Mar 06, 2018 at 06:28:43PM +0900, Tomasz Figa wrote: >> On Tue, Mar 6, 2018 at 6:18 PM, Sakari Ailus >> <sakari.ailus@xxxxxxxxxxxxxxx> wrote: >> > On Tue, Mar 06, 2018 at 05:51:36PM +0900, Tomasz Figa wrote: >> >> On Tue, Mar 6, 2018 at 5:40 PM, Sakari Ailus >> >> <sakari.ailus@xxxxxxxxxxxxxxx> wrote: >> >> > Hi Tomasz and Andy, >> >> > >> >> > On Sat, Mar 03, 2018 at 12:43:59AM +0900, Tomasz Figa wrote: >> >> > ... >> >> >> > +static int imx258_set_ctrl(struct v4l2_ctrl *ctrl) >> >> >> > +{ >> >> >> > + struct imx258 *imx258 = >> >> >> > + container_of(ctrl->handler, struct imx258, ctrl_handler); >> >> >> > + struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd); >> >> >> > + int ret = 0; >> >> >> > + /* >> >> >> > + * Applying V4L2 control value only happens >> >> >> > + * when power is up for streaming >> >> >> > + */ >> >> >> > + if (pm_runtime_get_if_in_use(&client->dev) <= 0) >> >> >> > + return 0; >> >> >> >> >> >> I thought we decided to fix this to handle disabled runtime PM properly. >> >> > >> >> > Good point. I bet this is a problem in a few other drivers, too. How would >> >> > you fix that? Check for zero only? >> >> > >> >> >> >> bool need_runtime_put; >> >> >> >> ret = pm_runtime_get_if_in_use(&client->dev); >> >> if (ret <= 0 && ret != -EINVAL) >> >> return ret; >> >> need_runtime_put = ret > 0; >> >> >> >> // Do stuff ... >> >> >> >> if (need_runtime_put) >> >> pm_runtime_put(&client->dev); >> >> >> >> I don't like how ugly it is, but it appears to be the only way to >> >> handle this correctly. >> > >> > The driver enables runtime PM so if runtime PM is enabled in kernel >> > configuration, it is enabled here. In that case pm_runtime_get_if_in_use() >> > will return either 0 or 1. So as far as I can see, changing the lines to: >> > >> > if (!pm_runtime_get_if_in_use(&client->dev)) >> > return 0; >> > >> > is enough. >> >> Right, my bad. Somehow I was convinced that enable status can change at >> runtime. > > Good point. I guess in principle this could happen although I can't see a > reason to do so, other than to break things --- quoting > Documentation/power/runtime_pm.txt: > > The user space can effectively disallow the driver of the device to > power manage it at run time by changing the value of its > /sys/devices/.../power/control attribute to "on", which causes > pm_runtime_forbid() to be called. In principle, this mechanism may > also be used by the driver to effectively turn off the runtime > power management of the device until the user space turns it on. > Namely, during the initialization the driver can make sure that the > runtime PM status of the device is 'active' and call > pm_runtime_forbid(). It should be noted, however, that if the user > space has already intentionally changed the value of > /sys/devices/.../power/control to "auto" to allow the driver to > power manage the device at run time, the driver may confuse it by > using pm_runtime_forbid() this way. > > So that comes with a warning that things might not work well after doing > so. > > What comes to the driver code, I still wouldn't complicate it by attempting > to make a driver work in such a case. I think pm_runtime_forbid() and pm_runtime_enable() operate on complete different data. That was exactly the source of my confusion earlier. Looking at the code [1], even if runtime PM is "forbidden", it is still "enabled" and just the usage count is incremented. https://elixir.bootlin.com/linux/latest/source/drivers/base/power/runtime.c#L1314 Best regards, Tomasz