summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-pca953x.c68
1 files changed, 35 insertions, 33 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 02695abd0eb1..0dedb2265744 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -1045,13 +1045,40 @@ out:
return ret;
}
+static void pca953x_disable_regulator(void *reg)
+{
+ regulator_disable(reg);
+}
+
+static int pca953x_get_and_enable_regulator(struct pca953x_chip *chip)
+{
+ struct device *dev = &chip->client->dev;
+ struct regulator *reg = chip->regulator;
+ int ret;
+
+ reg = devm_regulator_get(dev, "vcc");
+ if (IS_ERR(reg))
+ return dev_err_probe(dev, PTR_ERR(reg), "reg get err\n");
+
+ ret = regulator_enable(reg);
+ if (ret)
+ return dev_err_probe(dev, ret, "reg en err\n");
+
+ ret = devm_add_action_or_reset(dev, pca953x_disable_regulator, reg);
+ if (ret)
+ return ret;
+
+ chip->regulator = reg;
+ return 0;
+}
+
static int pca953x_probe(struct i2c_client *client)
{
+ struct device *dev = &client->dev;
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
int irq_base;
int ret;
- struct regulator *reg;
const struct regmap_config *regmap_config;
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
@@ -1086,16 +1113,9 @@ static int pca953x_probe(struct i2c_client *client)
if (!chip->driver_data)
return -ENODEV;
- reg = devm_regulator_get(&client->dev, "vcc");
- if (IS_ERR(reg))
- return dev_err_probe(&client->dev, PTR_ERR(reg), "reg get err\n");
-
- ret = regulator_enable(reg);
- if (ret) {
- dev_err(&client->dev, "reg en err: %d\n", ret);
+ ret = pca953x_get_and_enable_regulator(chip);
+ if (ret)
return ret;
- }
- chip->regulator = reg;
i2c_set_clientdata(client, chip);
@@ -1118,10 +1138,8 @@ static int pca953x_probe(struct i2c_client *client)
}
chip->regmap = devm_regmap_init_i2c(client, regmap_config);
- if (IS_ERR(chip->regmap)) {
- ret = PTR_ERR(chip->regmap);
- goto err_exit;
- }
+ if (IS_ERR(chip->regmap))
+ return PTR_ERR(chip->regmap);
regcache_mark_dirty(chip->regmap);
@@ -1156,28 +1174,13 @@ static int pca953x_probe(struct i2c_client *client)
ret = device_pca95xx_init(chip);
}
if (ret)
- goto err_exit;
+ return ret;
ret = pca953x_irq_setup(chip, irq_base);
if (ret)
- goto err_exit;
-
- ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip);
- if (ret)
- goto err_exit;
-
- return 0;
-
-err_exit:
- regulator_disable(chip->regulator);
- return ret;
-}
-
-static void pca953x_remove(struct i2c_client *client)
-{
- struct pca953x_chip *chip = i2c_get_clientdata(client);
+ return ret;
- regulator_disable(chip->regulator);
+ return devm_gpiochip_add_data(dev, &chip->gpio_chip, chip);
}
#ifdef CONFIG_PM_SLEEP
@@ -1345,7 +1348,6 @@ static struct i2c_driver pca953x_driver = {
.acpi_match_table = pca953x_acpi_ids,
},
.probe = pca953x_probe,
- .remove = pca953x_remove,
.id_table = pca953x_id,
};