Message ID | 1588163348-31640-1-git-send-email-fabrice.gasnier@st.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] iio: adc: stm32-adc: fix runtime autosuspend delay when slow polling | expand |
On Wed, 29 Apr 2020 14:29:08 +0200 Fabrice Gasnier <fabrice.gasnier@st.com> wrote: > When the ADC is runtime suspended and starting a conversion, the stm32-adc > driver calls pm_runtime_get_sync() that gets cascaded to the parent > (e.g. runtime resume of stm32-adc-core driver). This also kicks the > autosuspend delay (e.g. 2s) of the parent. > Once the ADC is active, calling pm_runtime_get_sync() again (upon a new > capture) won't kick the autosuspend delay for the parent (stm32-adc-core > driver) as already active. > > Currently, this makes the stm32-adc-core driver go in suspend state > every 2s when doing slow polling. As an example, doing a capture, e.g. > cat in_voltageY_raw at a 0.2s rate, the auto suspend delay for the parent > isn't refreshed. Once it expires, the parent immediately falls into > runtime suspended state, in between two captures, as soon as the child > driver falls into runtime suspend state: > - e.g. after 2s, + child calls pm_runtime_put_autosuspend() + 100ms > autosuspend delay of the child. > - stm32-adc-core switches off regulators, clocks and so on. > - They get switched on back again 100ms later in this example (at 2.2s). > > So, use runtime_idle() callback in stm32-adc-core driver to call > pm_runtime_mark_last_busy() for the parent driver (stm32-adc-core), > to avoid this. > > Fixes: 9bdbb1139ca1 ("iio: adc: stm32-adc: add power management support") > > Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> Whilst this seems 'sensible' to me, I really don't have a good enough grasp of runtime pm to be sure. I see something similar looking in the greybus driver, but not sure on the reason it is there. Hence, ideally looking for an ack from Rafael on this one! Thanks, Jonathan > --- > Changes in v2: > - Use runtime_idle callback in stm32-adc-core driver, instead of refreshing > last_busy from the child (for the parent) at many place. Initial patch v1 > looked like "somewhat adhoc solution" as commented by Jonathan. > --- > drivers/iio/adc/stm32-adc-core.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c > index 2df88d2..ebe5dbc 100644 > --- a/drivers/iio/adc/stm32-adc-core.c > +++ b/drivers/iio/adc/stm32-adc-core.c > @@ -803,6 +803,13 @@ static int stm32_adc_core_runtime_resume(struct device *dev) > { > return stm32_adc_core_hw_start(dev); > } > + > +static int stm32_adc_core_runtime_idle(struct device *dev) > +{ > + pm_runtime_mark_last_busy(dev); > + > + return 0; > +} > #endif > > static const struct dev_pm_ops stm32_adc_core_pm_ops = { > @@ -810,7 +817,7 @@ static const struct dev_pm_ops stm32_adc_core_pm_ops = { > pm_runtime_force_resume) > SET_RUNTIME_PM_OPS(stm32_adc_core_runtime_suspend, > stm32_adc_core_runtime_resume, > - NULL) > + stm32_adc_core_runtime_idle) > }; > > static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = {
On 5/3/20 1:48 PM, Jonathan Cameron wrote: > On Wed, 29 Apr 2020 14:29:08 +0200 > Fabrice Gasnier <fabrice.gasnier@st.com> wrote: > >> When the ADC is runtime suspended and starting a conversion, the stm32-adc >> driver calls pm_runtime_get_sync() that gets cascaded to the parent >> (e.g. runtime resume of stm32-adc-core driver). This also kicks the >> autosuspend delay (e.g. 2s) of the parent. >> Once the ADC is active, calling pm_runtime_get_sync() again (upon a new >> capture) won't kick the autosuspend delay for the parent (stm32-adc-core >> driver) as already active. >> >> Currently, this makes the stm32-adc-core driver go in suspend state >> every 2s when doing slow polling. As an example, doing a capture, e.g. >> cat in_voltageY_raw at a 0.2s rate, the auto suspend delay for the parent >> isn't refreshed. Once it expires, the parent immediately falls into >> runtime suspended state, in between two captures, as soon as the child >> driver falls into runtime suspend state: >> - e.g. after 2s, + child calls pm_runtime_put_autosuspend() + 100ms >> autosuspend delay of the child. >> - stm32-adc-core switches off regulators, clocks and so on. >> - They get switched on back again 100ms later in this example (at 2.2s). >> >> So, use runtime_idle() callback in stm32-adc-core driver to call >> pm_runtime_mark_last_busy() for the parent driver (stm32-adc-core), >> to avoid this. >> >> Fixes: 9bdbb1139ca1 ("iio: adc: stm32-adc: add power management support") >> >> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> > > Whilst this seems 'sensible' to me, I really don't have a good enough grasp > of runtime pm to be sure. > > I see something similar looking in the greybus driver, but not sure on the > reason it is there. > > Hence, ideally looking for an ack from Rafael on this one! Hi, Gentle reminder, I'm not sure how to progress on this patch. Rafael, or maybe Ulf, could take a look at it ? Thanks in advance, Best Regards, Fabrice > > Thanks, > > Jonathan > >> --- >> Changes in v2: >> - Use runtime_idle callback in stm32-adc-core driver, instead of refreshing >> last_busy from the child (for the parent) at many place. Initial patch v1 >> looked like "somewhat adhoc solution" as commented by Jonathan. >> --- >> drivers/iio/adc/stm32-adc-core.c | 9 ++++++++- >> 1 file changed, 8 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c >> index 2df88d2..ebe5dbc 100644 >> --- a/drivers/iio/adc/stm32-adc-core.c >> +++ b/drivers/iio/adc/stm32-adc-core.c >> @@ -803,6 +803,13 @@ static int stm32_adc_core_runtime_resume(struct device *dev) >> { >> return stm32_adc_core_hw_start(dev); >> } >> + >> +static int stm32_adc_core_runtime_idle(struct device *dev) >> +{ >> + pm_runtime_mark_last_busy(dev); >> + >> + return 0; >> +} >> #endif >> >> static const struct dev_pm_ops stm32_adc_core_pm_ops = { >> @@ -810,7 +817,7 @@ static const struct dev_pm_ops stm32_adc_core_pm_ops = { >> pm_runtime_force_resume) >> SET_RUNTIME_PM_OPS(stm32_adc_core_runtime_suspend, >> stm32_adc_core_runtime_resume, >> - NULL) >> + stm32_adc_core_runtime_idle) >> }; >> >> static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = { >
diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 2df88d2..ebe5dbc 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -803,6 +803,13 @@ static int stm32_adc_core_runtime_resume(struct device *dev) { return stm32_adc_core_hw_start(dev); } + +static int stm32_adc_core_runtime_idle(struct device *dev) +{ + pm_runtime_mark_last_busy(dev); + + return 0; +} #endif static const struct dev_pm_ops stm32_adc_core_pm_ops = { @@ -810,7 +817,7 @@ static const struct dev_pm_ops stm32_adc_core_pm_ops = { pm_runtime_force_resume) SET_RUNTIME_PM_OPS(stm32_adc_core_runtime_suspend, stm32_adc_core_runtime_resume, - NULL) + stm32_adc_core_runtime_idle) }; static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = {
When the ADC is runtime suspended and starting a conversion, the stm32-adc driver calls pm_runtime_get_sync() that gets cascaded to the parent (e.g. runtime resume of stm32-adc-core driver). This also kicks the autosuspend delay (e.g. 2s) of the parent. Once the ADC is active, calling pm_runtime_get_sync() again (upon a new capture) won't kick the autosuspend delay for the parent (stm32-adc-core driver) as already active. Currently, this makes the stm32-adc-core driver go in suspend state every 2s when doing slow polling. As an example, doing a capture, e.g. cat in_voltageY_raw at a 0.2s rate, the auto suspend delay for the parent isn't refreshed. Once it expires, the parent immediately falls into runtime suspended state, in between two captures, as soon as the child driver falls into runtime suspend state: - e.g. after 2s, + child calls pm_runtime_put_autosuspend() + 100ms autosuspend delay of the child. - stm32-adc-core switches off regulators, clocks and so on. - They get switched on back again 100ms later in this example (at 2.2s). So, use runtime_idle() callback in stm32-adc-core driver to call pm_runtime_mark_last_busy() for the parent driver (stm32-adc-core), to avoid this. Fixes: 9bdbb1139ca1 ("iio: adc: stm32-adc: add power management support") Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> --- Changes in v2: - Use runtime_idle callback in stm32-adc-core driver, instead of refreshing last_busy from the child (for the parent) at many place. Initial patch v1 looked like "somewhat adhoc solution" as commented by Jonathan. --- drivers/iio/adc/stm32-adc-core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)