summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpio-pca953x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-pca953x.c')
-rw-r--r--drivers/gpio/gpio-pca953x.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 54da66d02b0e..40983e2f888b 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -20,6 +20,7 @@
#include <linux/platform_data/pca953x.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
@@ -1020,17 +1021,21 @@ static int pca953x_probe(struct i2c_client *client,
chip->client = client;
- reg = devm_regulator_get(&client->dev, "vcc");
+ reg = devm_regulator_get_optional(&client->dev, "vcc");
if (IS_ERR(reg)) {
ret = PTR_ERR(reg);
- if (ret != -EPROBE_DEFER)
- dev_err(&client->dev, "reg get err: %d\n", ret);
- return ret;
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ dev_dbg(&client->dev, "reg get err: %d\n", ret);
+ reg = NULL;
}
- ret = regulator_enable(reg);
- if (ret) {
- dev_err(&client->dev, "reg en err: %d\n", ret);
- return ret;
+
+ if (reg) {
+ ret = regulator_enable(reg);
+ if (ret) {
+ dev_err(&client->dev, "reg en err: %d\n", ret);
+ return ret;
+ }
}
chip->regulator = reg;
@@ -1088,6 +1093,10 @@ static int pca953x_probe(struct i2c_client *client,
lockdep_set_subclass(&chip->i2c_lock,
i2c_adapter_depth(client->adapter));
+ ret = device_reset(&client->dev);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
/* initialize cached registers from their original values.
* we can't share this chip with another i2c master.
*/
@@ -1120,7 +1129,8 @@ static int pca953x_probe(struct i2c_client *client,
return 0;
err_exit:
- regulator_disable(chip->regulator);
+ if (chip->regulator)
+ regulator_disable(chip->regulator);
return ret;
}
@@ -1139,7 +1149,8 @@ static int pca953x_remove(struct i2c_client *client)
ret = 0;
}
- regulator_disable(chip->regulator);
+ if (chip->regulator)
+ regulator_disable(chip->regulator);
return ret;
}
@@ -1200,7 +1211,8 @@ static int pca953x_suspend(struct device *dev)
if (atomic_read(&chip->wakeup_path))
device_set_wakeup_path(dev);
else
- regulator_disable(chip->regulator);
+ if (chip->regulator)
+ regulator_disable(chip->regulator);
return 0;
}
@@ -1210,15 +1222,20 @@ static int pca953x_resume(struct device *dev)
struct pca953x_chip *chip = dev_get_drvdata(dev);
int ret;
+ regcache_cache_only(chip->regmap, false);
+
if (!atomic_read(&chip->wakeup_path)) {
- ret = regulator_enable(chip->regulator);
- if (ret) {
- dev_err(dev, "Failed to enable regulator: %d\n", ret);
+ if (chip->regulator) {
+ ret = regulator_enable(chip->regulator);
+ if (ret) {
+ dev_err(dev, "Failed to enable regulator: %d\n", ret);
+ return 0;
+ }
+ } else {
return 0;
}
}
- regcache_cache_only(chip->regmap, false);
regcache_mark_dirty(chip->regmap);
ret = pca953x_regcache_sync(dev);
if (ret)