Message ID | 20221031232202.131945-1-prabhakar.mahadev-lad.rj@bp.renesas.com |
---|---|
Headers | show |
Series | media: i2c: ov5645 driver enhancements | expand |
Hi Prabhakar, On 11/1/22 00:21, Prabhakar wrote: > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > Switch to using runtime PM for power management. > > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > --- > v3->v4 > * Fixed comments pointed by Sakari > > v2->v3 > * Jumped to err_pm_runtime label in case of sd register failure > * Now calling pm_runtime_mark_last_busy() before pm_runtime_put_autosuspend() > call > * Now calling pm_runtime_put_sync() in case s_stream(1) fails > * In s_stream(0) no calling pm_runtime_mark_last_busy() and > pm_runtime_put_autosuspend() > * Included RB tag from Laurent. > > v1->v2 > * Moved pm_runtime_*_autosuspend() calls after registering the subdev. > --- > drivers/media/i2c/ov5645.c | 133 +++++++++++++++++++------------------ > 1 file changed, 68 insertions(+), 65 deletions(-) > > diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c > index 47451238ca05..2e6135d0a31a 100644 > --- a/drivers/media/i2c/ov5645.c > +++ b/drivers/media/i2c/ov5645.c > @@ -27,6 +27,7 @@ > #include <linux/module.h> > #include <linux/of.h> > #include <linux/of_graph.h> > +#include <linux/pm_runtime.h> > #include <linux/regulator/consumer.h> > #include <linux/slab.h> > #include <linux/types.h> > @@ -108,7 +109,6 @@ struct ov5645 { > u8 timing_tc_reg21; > > struct mutex power_lock; /* lock to protect power state */ > - int power_count; > > struct gpio_desc *enable_gpio; > struct gpio_desc *rst_gpio; > @@ -635,8 +635,24 @@ static int ov5645_set_register_array(struct ov5645 *ov5645, > return 0; > } > > -static int ov5645_set_power_on(struct ov5645 *ov5645) > +static int ov5645_set_power_off(struct device *dev) > { > + struct v4l2_subdev *sd = dev_get_drvdata(dev); > + struct ov5645 *ov5645 = to_ov5645(sd); > + > + ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); > + gpiod_set_value_cansleep(ov5645->rst_gpio, 1); > + gpiod_set_value_cansleep(ov5645->enable_gpio, 0); > + clk_disable_unprepare(ov5645->xclk); > + regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); > + > + return 0; > +} > + > +static int ov5645_set_power_on(struct device *dev) > +{ > + struct v4l2_subdev *sd = dev_get_drvdata(dev); > + struct ov5645 *ov5645 = to_ov5645(sd); > int ret; > > ret = regulator_bulk_enable(OV5645_NUM_SUPPLIES, ov5645->supplies); > @@ -658,57 +674,19 @@ static int ov5645_set_power_on(struct ov5645 *ov5645) > > msleep(20); > > - return 0; > -} > - > -static void ov5645_set_power_off(struct ov5645 *ov5645) > -{ > - gpiod_set_value_cansleep(ov5645->rst_gpio, 1); > - gpiod_set_value_cansleep(ov5645->enable_gpio, 0); > - clk_disable_unprepare(ov5645->xclk); > - regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); > -} > - > -static int ov5645_s_power(struct v4l2_subdev *sd, int on) > -{ > - struct ov5645 *ov5645 = to_ov5645(sd); > - int ret = 0; > - > - mutex_lock(&ov5645->power_lock); > - > - /* If the power count is modified from 0 to != 0 or from != 0 to 0, > - * update the power state. > - */ > - if (ov5645->power_count == !on) { > - if (on) { > - ret = ov5645_set_power_on(ov5645); > - if (ret < 0) > - goto exit; > - > - ret = ov5645_set_register_array(ov5645, > - ov5645_global_init_setting, > + ret = ov5645_set_register_array(ov5645, ov5645_global_init_setting, > ARRAY_SIZE(ov5645_global_init_setting)); > - if (ret < 0) { > - dev_err(ov5645->dev, > - "could not set init registers\n"); > - ov5645_set_power_off(ov5645); > - goto exit; > - } > - > - usleep_range(500, 1000); > - } else { > - ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); > - ov5645_set_power_off(ov5645); > - } > + if (ret < 0) { > + dev_err(ov5645->dev, "could not set init registers\n"); > + goto exit; > } > > - /* Update the power count. */ > - ov5645->power_count += on ? 1 : -1; > - WARN_ON(ov5645->power_count < 0); > + usleep_range(500, 1000); > > -exit: > - mutex_unlock(&ov5645->power_lock); > + return 0; > > +exit: > + ov5645_set_power_off(dev); > return ret; smatch gives this warning: drivers/media/i2c/ov5645.c:687 ov5645_set_power_on() warn: 'ov5645->xclk' from clk_prepare_enable() not released on lines: 687. Can you take a look? Thanks! Hans > }
Hi Hans, On Mon, Nov 28, 2022 at 1:49 PM Hans Verkuil <hverkuil@xs4all.nl> wrote: > <snip> > > +exit: > > + ov5645_set_power_off(dev); > > return ret; > > smatch gives this warning: > > drivers/media/i2c/ov5645.c:687 ov5645_set_power_on() warn: 'ov5645->xclk' from clk_prepare_enable() not released on lines: 687. > > Can you take a look? > Sure I'll have a look at it. Cheers, Prabhakar
Hi Hans, On Mon, Nov 28, 2022 at 1:49 PM Hans Verkuil <hverkuil@xs4all.nl> wrote: > > Hi Prabhakar, > > On 11/1/22 00:21, Prabhakar wrote: > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > <snip> > > -static void ov5645_set_power_off(struct ov5645 *ov5645) > > -{ > > - gpiod_set_value_cansleep(ov5645->rst_gpio, 1); > > - gpiod_set_value_cansleep(ov5645->enable_gpio, 0); > > - clk_disable_unprepare(ov5645->xclk); > > - regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); > > -} > > - > > -static int ov5645_s_power(struct v4l2_subdev *sd, int on) > > -{ > > - struct ov5645 *ov5645 = to_ov5645(sd); > > - int ret = 0; > > - > > - mutex_lock(&ov5645->power_lock); > > - > > - /* If the power count is modified from 0 to != 0 or from != 0 to 0, > > - * update the power state. > > - */ > > - if (ov5645->power_count == !on) { > > - if (on) { > > - ret = ov5645_set_power_on(ov5645); > > - if (ret < 0) > > - goto exit; > > - > > - ret = ov5645_set_register_array(ov5645, > > - ov5645_global_init_setting, > > + ret = ov5645_set_register_array(ov5645, ov5645_global_init_setting, > > ARRAY_SIZE(ov5645_global_init_setting)); > > - if (ret < 0) { > > - dev_err(ov5645->dev, > > - "could not set init registers\n"); > > - ov5645_set_power_off(ov5645); > > - goto exit; > > - } > > - > > - usleep_range(500, 1000); > > - } else { > > - ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); > > - ov5645_set_power_off(ov5645); > > - } > > + if (ret < 0) { > > + dev_err(ov5645->dev, "could not set init registers\n"); > > + goto exit; > > } > > > > - /* Update the power count. */ > > - ov5645->power_count += on ? 1 : -1; > > - WARN_ON(ov5645->power_count < 0); > > + usleep_range(500, 1000); > > > > -exit: > > - mutex_unlock(&ov5645->power_lock); > > + return 0; > > > > +exit: > > + ov5645_set_power_off(dev); > > return ret; > > smatch gives this warning: > > drivers/media/i2c/ov5645.c:687 ov5645_set_power_on() warn: 'ov5645->xclk' from clk_prepare_enable() not released on lines: 687. > it's a false positive, as in case of error we jump to the exit label which calls ov5645_set_power_off() which internally calls clk_disable_unprepare() for xclk and on success we need to have xclk ON during s_stream(ON) and eventually the xclk will be unprepared in s_stream(OFF). Cheers, Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Hi All, The main aim of this series is to add Runtime PM support to the sensor driver alongside some cleanups and fixes. v3 -> v4 * Fixed comments pointed by Sakari for runtime PM patch * Fixed spaces for example node in DT binding * Fixed comments pointed by Marco * Included Acks from maintainers for the DT patches v2 -> v3 - Included patch#1 [2] as part of this series - Patched all in-tree DTS for dropping the clock preoperty to avoid dt warnings - Fixed review comments pointed by Sakari and Laurent for the Runtime PM patch - Now sending the error code of first error while stream off. - Included RB tags from Laurent v1-> v2 - patch #1 is infact a v3 [1] no changes - patch #2 fixed review comments pointed by Sakari - patch #3 [0] no changes - patches #4 and #5 are new [0] https://patchwork.linuxtv.org/project/linux-media/patch/20220927202005.750621-1-prabhakar.mahadev-lad.rj@bp.renesas.com/ [1] https://patchwork.linuxtv.org/project/linux-media/patch/20220919153540.178732-1-prabhakar.mahadev-lad.rj@bp.renesas.com/ [2] https://patchwork.kernel.org/project/linux-media/patch/20220919143350.176746-1-prabhakar.mahadev-lad.rj@bp.renesas.com/ Cheers, Prabhakar Lad Prabhakar (9): media: i2c: ov5645: Drop fetching the clk reference by name ARM: dts: imx6qdl-pico: Drop clock-names property ARM: dts: imx6qdl-wandboard: Drop clock-names property arm64: dts: renesas: aistarvision-mipi-adapter-2.1: Drop clock-names property media: dt-bindings: ov5645: Convert OV5645 binding to a schema media: i2c: ov5645: Use runtime PM media: i2c: ov5645: Drop empty comment media: i2c: ov5645: Make sure to call PM functions media: i2c: ov5645: Call ov5645_entity_init_cfg() before registering the subdev .../devicetree/bindings/media/i2c/ov5645.txt | 54 ------- .../bindings/media/i2c/ovti,ov5645.yaml | 104 ++++++++++++ arch/arm/boot/dts/imx6qdl-pico.dtsi | 1 - arch/arm/boot/dts/imx6qdl-wandboard.dtsi | 1 - .../aistarvision-mipi-adapter-2.1.dtsi | 1 - drivers/media/i2c/ov5645.c | 148 +++++++++--------- 6 files changed, 179 insertions(+), 130 deletions(-) delete mode 100644 Documentation/devicetree/bindings/media/i2c/ov5645.txt create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov5645.yaml