Skip to content

Commit cd5676d

Browse files
BibbyHsiehbrgl
authored andcommitted
misc: eeprom: at24: support pm_runtime control
Although in the most platforms, the power of eeprom are alway on, some platforms disable the eeprom power in order to meet low power request. This patch add the pm_runtime ops to control power to support all platforms. Signed-off-by: Bibby Hsieh <[email protected]> [Bartosz: rebased on top of current at24/for-next] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent c6cadc7 commit cd5676d

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

drivers/misc/eeprom/at24.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/pm_runtime.h>
2222
#include <linux/property.h>
2323
#include <linux/regmap.h>
24+
#include <linux/regulator/consumer.h>
2425
#include <linux/slab.h>
2526

2627
/* Address pointer is 16 bit. */
@@ -87,6 +88,7 @@ struct at24_data {
8788
u8 flags;
8889

8990
struct nvmem_device *nvmem;
91+
struct regulator *vcc_reg;
9092

9193
/*
9294
* Some chips tie up multiple I2C addresses; dummy devices reserve
@@ -656,6 +658,9 @@ static int at24_probe(struct i2c_client *client)
656658
at24->client[0].client = client;
657659
at24->client[0].regmap = regmap;
658660

661+
at24->vcc_reg = devm_regulator_get(dev, "vcc");
662+
if (IS_ERR(at24->vcc_reg))
663+
return PTR_ERR(at24->vcc_reg);
659664

660665
writable = !(flags & AT24_FLAG_READONLY);
661666
if (writable) {
@@ -692,6 +697,12 @@ static int at24_probe(struct i2c_client *client)
692697

693698
i2c_set_clientdata(client, at24);
694699

700+
err = regulator_enable(at24->vcc_reg);
701+
if (err) {
702+
dev_err(dev, "Failed to enable vcc regulator\n");
703+
return err;
704+
}
705+
695706
/* enable runtime pm */
696707
pm_runtime_set_active(dev);
697708
pm_runtime_enable(dev);
@@ -704,6 +715,7 @@ static int at24_probe(struct i2c_client *client)
704715
pm_runtime_idle(dev);
705716
if (err) {
706717
pm_runtime_disable(dev);
718+
regulator_disable(at24->vcc_reg);
707719
return -ENODEV;
708720
}
709721

@@ -719,15 +731,42 @@ static int at24_probe(struct i2c_client *client)
719731

720732
static int at24_remove(struct i2c_client *client)
721733
{
734+
struct at24_data *at24 = i2c_get_clientdata(client);
735+
722736
pm_runtime_disable(&client->dev);
737+
if (!pm_runtime_status_suspended(&client->dev))
738+
regulator_disable(at24->vcc_reg);
723739
pm_runtime_set_suspended(&client->dev);
724740

725741
return 0;
726742
}
727743

744+
static int __maybe_unused at24_suspend(struct device *dev)
745+
{
746+
struct i2c_client *client = to_i2c_client(dev);
747+
struct at24_data *at24 = i2c_get_clientdata(client);
748+
749+
return regulator_disable(at24->vcc_reg);
750+
}
751+
752+
static int __maybe_unused at24_resume(struct device *dev)
753+
{
754+
struct i2c_client *client = to_i2c_client(dev);
755+
struct at24_data *at24 = i2c_get_clientdata(client);
756+
757+
return regulator_enable(at24->vcc_reg);
758+
}
759+
760+
static const struct dev_pm_ops at24_pm_ops = {
761+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
762+
pm_runtime_force_resume)
763+
SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL)
764+
};
765+
728766
static struct i2c_driver at24_driver = {
729767
.driver = {
730768
.name = "at24",
769+
.pm = &at24_pm_ops,
731770
.of_match_table = at24_of_match,
732771
.acpi_match_table = ACPI_PTR(at24_acpi_ids),
733772
},

0 commit comments

Comments
 (0)