summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/dw9768.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/dw9768.c')
-rw-r--r--drivers/media/i2c/dw9768.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
index 0f47ef015a1d..83a3ee275bbe 100644
--- a/drivers/media/i2c/dw9768.c
+++ b/drivers/media/i2c/dw9768.c
@@ -414,6 +414,7 @@ static int dw9768_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct dw9768 *dw9768;
+ bool full_power;
unsigned int i;
int ret;
@@ -469,13 +470,23 @@ static int dw9768_probe(struct i2c_client *client)
dw9768->sd.entity.function = MEDIA_ENT_F_LENS;
+ /*
+ * Figure out whether we're going to power up the device here. Generally
+ * this is done if CONFIG_PM is disabled in a DT system or the device is
+ * to be powered on in an ACPI system. Similarly for power off in
+ * remove.
+ */
pm_runtime_enable(dev);
- if (!pm_runtime_enabled(dev)) {
+ full_power = (is_acpi_node(dev_fwnode(dev)) &&
+ acpi_dev_state_d0(dev)) ||
+ (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
+ if (full_power) {
ret = dw9768_runtime_resume(dev);
if (ret < 0) {
dev_err(dev, "failed to power on: %d\n", ret);
goto err_clean_entity;
}
+ pm_runtime_set_active(dev);
}
ret = v4l2_async_register_subdev(&dw9768->sd);
@@ -484,14 +495,17 @@ static int dw9768_probe(struct i2c_client *client)
goto err_power_off;
}
+ pm_runtime_idle(dev);
+
return 0;
err_power_off:
- if (pm_runtime_enabled(dev))
- pm_runtime_disable(dev);
- else
+ 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);
@@ -503,14 +517,17 @@ static void dw9768_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct dw9768 *dw9768 = sd_to_dw9768(sd);
+ struct device *dev = &client->dev;
v4l2_async_unregister_subdev(&dw9768->sd);
v4l2_ctrl_handler_free(&dw9768->ctrls);
media_entity_cleanup(&dw9768->sd.entity);
- pm_runtime_disable(&client->dev);
- if (!pm_runtime_status_suspended(&client->dev))
- dw9768_runtime_suspend(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
+ (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
+ dw9768_runtime_suspend(dev);
+ pm_runtime_set_suspended(dev);
+ }
+ pm_runtime_disable(dev);
}
static const struct of_device_id dw9768_of_table[] = {