aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJason Chen <jason.z.chen@intel.com>2024-01-22 03:54:34 +0100
committerMauro Carvalho Chehab <mchehab@kernel.org>2024-02-01 13:43:15 +0100
commitb1a42fde6e077ec2fdeac1bcbcf464210c5aa682 (patch)
treebd74a62f5137f2ee6ef25001dc5a34b4cb0e8f1d /drivers/media
parentf19cd265662df9bd6415bb71a23124486e85b117 (diff)
downloadlinux-b1a42fde6e077ec2fdeac1bcbcf464210c5aa682.tar.gz
media: ov08x40: Avoid sensor probing in D0 state
When the system enters the D0 state and attempt to probe the device, another component, such as LED, will also be pulled high due to the hardware design. It's advisable to keep the device being probed in a different D state. Signed-off-by: Jason Chen <jason.z.chen@intel.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/i2c/ov08x40.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index abbb0b774d43f..1f9a63cdf996f 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -2432,6 +2432,9 @@ struct ov08x40 {
/* Mutex for serialized access */
struct mutex mutex;
+
+ /* True if the device has been identified */
+ bool identified;
};
#define to_ov08x40(_sd) container_of(_sd, struct ov08x40, sd)
@@ -2948,6 +2951,9 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x)
int ret;
u32 val;
+ if (ov08x->identified)
+ return 0;
+
ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
OV08X40_REG_VALUE_24BIT, &val);
if (ret)
@@ -2956,9 +2962,11 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x)
if (val != OV08X40_CHIP_ID) {
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
OV08X40_CHIP_ID, val);
- return -EIO;
+ return -ENXIO;
}
+ ov08x->identified = true;
+
return 0;
}
@@ -3175,6 +3183,7 @@ static int ov08x40_probe(struct i2c_client *client)
{
struct ov08x40 *ov08x;
int ret;
+ bool full_power;
/* Check HW config */
ret = ov08x40_check_hwcfg(&client->dev);
@@ -3190,11 +3199,14 @@ static int ov08x40_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov08x->sd, client, &ov08x40_subdev_ops);
- /* Check module identity */
- ret = ov08x40_identify_module(ov08x);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
- return ret;
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ /* Check module identity */
+ ret = ov08x40_identify_module(ov08x);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ return ret;
+ }
}
/* Set default mode to max resolution */
@@ -3222,11 +3234,8 @@ static int ov08x40_probe(struct i2c_client *client)
if (ret < 0)
goto error_media_entity;
- /*
- * Device is already turned on by i2c-core with ACPI domain PM.
- * Enable runtime PM and turn off the device.
- */
- pm_runtime_set_active(&client->dev);
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -3270,6 +3279,7 @@ static struct i2c_driver ov08x40_i2c_driver = {
},
.probe = ov08x40_probe,
.remove = ov08x40_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(ov08x40_i2c_driver);