summaryrefslogtreecommitdiffstats
path: root/drivers/misc/eeprom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/eeprom')
-rw-r--r--drivers/misc/eeprom/Kconfig5
-rw-r--r--drivers/misc/eeprom/at24.c82
-rw-r--r--drivers/misc/eeprom/ee1004.c6
-rw-r--r--drivers/misc/eeprom/eeprom.c4
-rw-r--r--drivers/misc/eeprom/max6875.c6
5 files changed, 71 insertions, 32 deletions
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index f2abe27010ef..0f791bfdc1f5 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -45,13 +45,16 @@ config EEPROM_AT25
will be called at25.
config EEPROM_LEGACY
- tristate "Old I2C EEPROM reader"
+ tristate "Old I2C EEPROM reader (DEPRECATED)"
depends on I2C && SYSFS
help
If you say yes here you get read-only access to the EEPROM data
available on modern memory DIMMs and Sony Vaio laptops via I2C. Such
EEPROMs could theoretically be available on other devices as well.
+ This driver is deprecated and will be removed soon, please use the
+ better at24 driver instead.
+
This driver can also be built as a module. If so, the module
will be called eeprom.
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 518945b2f737..031eb64549af 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* at24.c - handle most I2C EEPROMs
*
@@ -6,24 +6,23 @@
* Copyright (C) 2008 Wolfram Sang, Pengutronix
*/
-#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/mutex.h>
-#include <linux/mod_devicetable.h>
-#include <linux/log2.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/property.h>
-#include <linux/acpi.h>
-#include <linux/i2c.h>
#include <linux/nvmem-provider.h>
-#include <linux/regmap.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
-#include <linux/gpio/consumer.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
/* Address pointer is 16 bit. */
#define AT24_FLAG_ADDR16 BIT(7)
@@ -89,8 +88,7 @@ struct at24_data {
u8 flags;
struct nvmem_device *nvmem;
-
- struct gpio_desc *wp_gpio;
+ struct regulator *vcc_reg;
/*
* Some chips tie up multiple I2C addresses; dummy devices reserve
@@ -458,12 +456,10 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
* from this host, but not from other I2C masters.
*/
mutex_lock(&at24->lock);
- gpiod_set_value_cansleep(at24->wp_gpio, 0);
while (count) {
ret = at24_regmap_write(at24, buf, off, count);
if (ret < 0) {
- gpiod_set_value_cansleep(at24->wp_gpio, 1);
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
return ret;
@@ -473,7 +469,6 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
count -= ret;
}
- gpiod_set_value_cansleep(at24->wp_gpio, 1);
mutex_unlock(&at24->lock);
pm_runtime_put(dev);
@@ -663,9 +658,9 @@ static int at24_probe(struct i2c_client *client)
at24->client[0].client = client;
at24->client[0].regmap = regmap;
- at24->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_HIGH);
- if (IS_ERR(at24->wp_gpio))
- return PTR_ERR(at24->wp_gpio);
+ at24->vcc_reg = devm_regulator_get(dev, "vcc");
+ if (IS_ERR(at24->vcc_reg))
+ return PTR_ERR(at24->vcc_reg);
writable = !(flags & AT24_FLAG_READONLY);
if (writable) {
@@ -702,6 +697,12 @@ static int at24_probe(struct i2c_client *client)
i2c_set_clientdata(client, at24);
+ err = regulator_enable(at24->vcc_reg);
+ if (err) {
+ dev_err(dev, "Failed to enable vcc regulator\n");
+ return err;
+ }
+
/* enable runtime pm */
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -714,27 +715,58 @@ static int at24_probe(struct i2c_client *client)
pm_runtime_idle(dev);
if (err) {
pm_runtime_disable(dev);
+ regulator_disable(at24->vcc_reg);
return -ENODEV;
}
- dev_info(dev, "%u byte %s EEPROM, %s, %u bytes/write\n",
- byte_len, client->name,
- writable ? "writable" : "read-only", at24->write_max);
+ if (writable)
+ dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n",
+ byte_len, client->name, at24->write_max);
+ else
+ dev_info(dev, "%u byte %s EEPROM, read-only\n",
+ byte_len, client->name);
return 0;
}
static int at24_remove(struct i2c_client *client)
{
+ struct at24_data *at24 = i2c_get_clientdata(client);
+
pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ regulator_disable(at24->vcc_reg);
pm_runtime_set_suspended(&client->dev);
return 0;
}
+static int __maybe_unused at24_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct at24_data *at24 = i2c_get_clientdata(client);
+
+ return regulator_disable(at24->vcc_reg);
+}
+
+static int __maybe_unused at24_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct at24_data *at24 = i2c_get_clientdata(client);
+
+ return regulator_enable(at24->vcc_reg);
+}
+
+static const struct dev_pm_ops at24_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL)
+};
+
static struct i2c_driver at24_driver = {
.driver = {
.name = "at24",
+ .pm = &at24_pm_ops,
.of_match_table = at24_of_match,
.acpi_match_table = ACPI_PTR(at24_acpi_ids),
},
diff --git a/drivers/misc/eeprom/ee1004.c b/drivers/misc/eeprom/ee1004.c
index 6f00c33cfe22..b081c67416d7 100644
--- a/drivers/misc/eeprom/ee1004.c
+++ b/drivers/misc/eeprom/ee1004.c
@@ -195,13 +195,13 @@ static int ee1004_probe(struct i2c_client *client,
mutex_lock(&ee1004_bus_lock);
if (++ee1004_dev_count == 1) {
for (cnr = 0; cnr < 2; cnr++) {
- ee1004_set_page[cnr] = i2c_new_dummy(client->adapter,
+ ee1004_set_page[cnr] = i2c_new_dummy_device(client->adapter,
EE1004_ADDR_SET_PAGE + cnr);
- if (!ee1004_set_page[cnr]) {
+ if (IS_ERR(ee1004_set_page[cnr])) {
dev_err(&client->dev,
"address 0x%02x unavailable\n",
EE1004_ADDR_SET_PAGE + cnr);
- err = -EADDRINUSE;
+ err = PTR_ERR(ee1004_set_page[cnr]);
goto err_clients;
}
}
diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c
index 2cfe3d4ae144..226b5efa6a77 100644
--- a/drivers/misc/eeprom/eeprom.c
+++ b/drivers/misc/eeprom/eeprom.c
@@ -175,6 +175,10 @@ static int eeprom_probe(struct i2c_client *client,
}
}
+ /* Let the users know they are using deprecated driver */
+ dev_notice(&client->dev,
+ "eeprom driver is deprecated, please use at24 instead\n");
+
/* create the sysfs eeprom file */
return sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr);
}
diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c
index 4d0cb90f4aeb..9da81f6d4a1c 100644
--- a/drivers/misc/eeprom/max6875.c
+++ b/drivers/misc/eeprom/max6875.c
@@ -150,9 +150,9 @@ static int max6875_probe(struct i2c_client *client,
return -ENOMEM;
/* A fake client is created on the odd address */
- data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1);
- if (!data->fake_client) {
- err = -ENOMEM;
+ data->fake_client = i2c_new_dummy_device(client->adapter, client->addr + 1);
+ if (IS_ERR(data->fake_client)) {
+ err = PTR_ERR(data->fake_client);
goto exit_kfree;
}
OpenPOWER on IntegriCloud