]> git.hungrycats.org Git - linux/commitdiff
media: i2c: dw9768: Fix pm_runtime_set_suspended() with runtime pm enabled
authorJinjie Ruan <ruanjinjie@huawei.com>
Fri, 1 Nov 2024 09:40:48 +0000 (17:40 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Dec 2024 09:33:02 +0000 (10:33 +0100)
commit d6594d50761728d09f23238cf9c368bab6260ef3 upstream.

It is not valid to call pm_runtime_set_suspended() and
pm_runtime_set_active() for devices with runtime PM enabled because it
returns -EAGAIN if it is enabled already and working. So, adjust the
order to fix it.

Cc: stable@vger.kernel.org
Fixes: 5f9a089b6de3 ("dw9768: Enable low-power probe on ACPI")
Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/media/i2c/dw9768.c

index daabbece8c7e903fc93b6bd2eb7ff46b229d3bf8..682a1aa7febd97f8598abf6b876c53f6dcc6b317 100644 (file)
@@ -476,10 +476,9 @@ static int dw9768_probe(struct i2c_client *client)
         * to be powered on in an ACPI system. Similarly for power off in
         * remove.
         */
-       pm_runtime_enable(dev);
        full_power = (is_acpi_node(dev_fwnode(dev)) &&
                      acpi_dev_state_d0(dev)) ||
-                    (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
+                    (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM));
        if (full_power) {
                ret = dw9768_runtime_resume(dev);
                if (ret < 0) {
@@ -489,6 +488,7 @@ static int dw9768_probe(struct i2c_client *client)
                pm_runtime_set_active(dev);
        }
 
+       pm_runtime_enable(dev);
        ret = v4l2_async_register_subdev(&dw9768->sd);
        if (ret < 0) {
                dev_err(dev, "failed to register V4L2 subdev: %d", ret);
@@ -500,12 +500,12 @@ static int dw9768_probe(struct i2c_client *client)
        return 0;
 
 err_power_off:
+       pm_runtime_disable(dev);
        if (full_power) {
                dw9768_runtime_suspend(dev);
                pm_runtime_set_suspended(dev);
        }
 err_clean_entity:
-       pm_runtime_disable(dev);
        media_entity_cleanup(&dw9768->sd.entity);
 err_free_handler:
        v4l2_ctrl_handler_free(&dw9768->ctrls);
@@ -522,12 +522,12 @@ static void dw9768_remove(struct i2c_client *client)
        v4l2_async_unregister_subdev(&dw9768->sd);
        v4l2_ctrl_handler_free(&dw9768->ctrls);
        media_entity_cleanup(&dw9768->sd.entity);
+       pm_runtime_disable(dev);
        if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
-           (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
+           (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM))) {
                dw9768_runtime_suspend(dev);
                pm_runtime_set_suspended(dev);
        }
-       pm_runtime_disable(dev);
 }
 
 static const struct of_device_id dw9768_of_table[] = {