diff options
Diffstat (limited to 'drivers/mfd/stmfx.c')
-rw-r--r-- | drivers/mfd/stmfx.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c index 857991cb3cbb..5dd7d9688459 100644 --- a/drivers/mfd/stmfx.c +++ b/drivers/mfd/stmfx.c @@ -287,14 +287,21 @@ static int stmfx_irq_init(struct i2c_client *client) ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin); if (ret) - return ret; + goto irq_exit; ret = devm_request_threaded_irq(stmfx->dev, client->irq, NULL, stmfx_irq_handler, irqtrigger | IRQF_ONESHOT, "stmfx", stmfx); if (ret) - stmfx_irq_exit(client); + goto irq_exit; + + stmfx->irq = client->irq; + + return 0; + +irq_exit: + stmfx_irq_exit(client); return ret; } @@ -322,13 +329,11 @@ static int stmfx_chip_init(struct i2c_client *client) stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd"); ret = PTR_ERR_OR_ZERO(stmfx->vdd); - if (ret == -ENODEV) { - stmfx->vdd = NULL; - } else if (ret == -EPROBE_DEFER) { - return ret; - } else if (ret) { - dev_err(&client->dev, "Failed to get VDD regulator: %d\n", ret); - return ret; + if (ret) { + if (ret == -ENODEV) + stmfx->vdd = NULL; + else + return dev_err_probe(&client->dev, ret, "Failed to get VDD regulator\n"); } if (stmfx->vdd) { @@ -387,17 +392,22 @@ err: return ret; } -static int stmfx_chip_exit(struct i2c_client *client) +static void stmfx_chip_exit(struct i2c_client *client) { struct stmfx *stmfx = i2c_get_clientdata(client); regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0); regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0); - if (stmfx->vdd) - return regulator_disable(stmfx->vdd); + if (stmfx->vdd) { + int ret; - return 0; + ret = regulator_disable(stmfx->vdd); + if (ret) + dev_err(&client->dev, + "Failed to disable vdd regulator: %pe\n", + ERR_PTR(ret)); + } } static int stmfx_probe(struct i2c_client *client, @@ -457,11 +467,11 @@ err_chip_exit: return ret; } -static int stmfx_remove(struct i2c_client *client) +static void stmfx_remove(struct i2c_client *client) { stmfx_irq_exit(client); - return stmfx_chip_exit(client); + stmfx_chip_exit(client); } #ifdef CONFIG_PM_SLEEP @@ -481,6 +491,8 @@ static int stmfx_suspend(struct device *dev) if (ret) return ret; + disable_irq(stmfx->irq); + if (stmfx->vdd) return regulator_disable(stmfx->vdd); @@ -501,6 +513,13 @@ static int stmfx_resume(struct device *dev) } } + /* Reset STMFX - supply has been stopped during suspend */ + ret = stmfx_chip_reset(stmfx); + if (ret) { + dev_err(stmfx->dev, "Failed to reset chip: %d\n", ret); + return ret; + } + ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL, &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl)); if (ret) @@ -517,6 +536,8 @@ static int stmfx_resume(struct device *dev) if (ret) return ret; + enable_irq(stmfx->irq); + return 0; } #endif @@ -532,7 +553,7 @@ MODULE_DEVICE_TABLE(of, stmfx_of_match); static struct i2c_driver stmfx_driver = { .driver = { .name = "stmfx-core", - .of_match_table = of_match_ptr(stmfx_of_match), + .of_match_table = stmfx_of_match, .pm = &stmfx_dev_pm_ops, }, .probe = stmfx_probe, |