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; + return ret; - 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); - - 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, };