Skip to content

Commit 1e96078

Browse files
Sakari Ailusrafaeljw
authored andcommitted
at24: Support probing while in non-zero ACPI D state
In certain use cases (where the chip is part of a camera module, and the camera module is wired together with a camera privacy LED), powering on the device during probe is undesirable. Add support for the at24 to execute probe while being in ACPI D state other than 0 (which means fully powered on). Signed-off-by: Sakari Ailus <[email protected]> Reviewed-by: Tomasz Figa <[email protected]> Acked-by: Bartosz Golaszewski <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 434aa74 commit 1e96078

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

drivers/misc/eeprom/at24.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ static int at24_probe(struct i2c_client *client)
595595
bool i2c_fn_i2c, i2c_fn_block;
596596
unsigned int i, num_addresses;
597597
struct at24_data *at24;
598+
bool full_power;
598599
struct regmap *regmap;
599600
bool writable;
600601
u8 test_byte;
@@ -747,14 +748,16 @@ static int at24_probe(struct i2c_client *client)
747748

748749
i2c_set_clientdata(client, at24);
749750

750-
err = regulator_enable(at24->vcc_reg);
751-
if (err) {
752-
dev_err(dev, "Failed to enable vcc regulator\n");
753-
return err;
754-
}
751+
full_power = acpi_dev_state_d0(&client->dev);
752+
if (full_power) {
753+
err = regulator_enable(at24->vcc_reg);
754+
if (err) {
755+
dev_err(dev, "Failed to enable vcc regulator\n");
756+
return err;
757+
}
755758

756-
/* enable runtime pm */
757-
pm_runtime_set_active(dev);
759+
pm_runtime_set_active(dev);
760+
}
758761
pm_runtime_enable(dev);
759762

760763
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
@@ -766,15 +769,18 @@ static int at24_probe(struct i2c_client *client)
766769
}
767770

768771
/*
769-
* Perform a one-byte test read to verify that the
770-
* chip is functional.
772+
* Perform a one-byte test read to verify that the chip is functional,
773+
* unless powering on the device is to be avoided during probe (i.e.
774+
* it's powered off right now).
771775
*/
772-
err = at24_read(at24, 0, &test_byte, 1);
773-
if (err) {
774-
pm_runtime_disable(dev);
775-
if (!pm_runtime_status_suspended(dev))
776-
regulator_disable(at24->vcc_reg);
777-
return -ENODEV;
776+
if (full_power) {
777+
err = at24_read(at24, 0, &test_byte, 1);
778+
if (err) {
779+
pm_runtime_disable(dev);
780+
if (!pm_runtime_status_suspended(dev))
781+
regulator_disable(at24->vcc_reg);
782+
return -ENODEV;
783+
}
778784
}
779785

780786
pm_runtime_idle(dev);
@@ -794,9 +800,11 @@ static int at24_remove(struct i2c_client *client)
794800
struct at24_data *at24 = i2c_get_clientdata(client);
795801

796802
pm_runtime_disable(&client->dev);
797-
if (!pm_runtime_status_suspended(&client->dev))
798-
regulator_disable(at24->vcc_reg);
799-
pm_runtime_set_suspended(&client->dev);
803+
if (acpi_dev_state_d0(&client->dev)) {
804+
if (!pm_runtime_status_suspended(&client->dev))
805+
regulator_disable(at24->vcc_reg);
806+
pm_runtime_set_suspended(&client->dev);
807+
}
800808

801809
return 0;
802810
}
@@ -833,6 +841,7 @@ static struct i2c_driver at24_driver = {
833841
.probe_new = at24_probe,
834842
.remove = at24_remove,
835843
.id_table = at24_ids,
844+
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
836845
};
837846

838847
static int __init at24_init(void)

0 commit comments

Comments
 (0)