diff options
Diffstat (limited to 'drivers/gpio/gpio-pca953x.c')
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 47 |
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) |