summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/cs42l43.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/drivers/mfd/cs42l43.c b/drivers/mfd/cs42l43.c
index 3b4efb294471..e5f17fc430e4 100644
--- a/drivers/mfd/cs42l43.c
+++ b/drivers/mfd/cs42l43.c
@@ -1109,16 +1109,39 @@ EXPORT_SYMBOL_NS_GPL(cs42l43_dev_remove, MFD_CS42L43);
static int cs42l43_suspend(struct device *dev)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
+ static const struct reg_sequence mask_all[] = {
+ { CS42L43_DECIM_MASK, 0xFFFFFFFF, },
+ { CS42L43_EQ_MIX_MASK, 0xFFFFFFFF, },
+ { CS42L43_ASP_MASK, 0xFFFFFFFF, },
+ { CS42L43_PLL_MASK, 0xFFFFFFFF, },
+ { CS42L43_SOFT_MASK, 0xFFFFFFFF, },
+ { CS42L43_SWIRE_MASK, 0xFFFFFFFF, },
+ { CS42L43_MSM_MASK, 0xFFFFFFFF, },
+ { CS42L43_ACC_DET_MASK, 0xFFFFFFFF, },
+ { CS42L43_I2C_TGT_MASK, 0xFFFFFFFF, },
+ { CS42L43_SPI_MSTR_MASK, 0xFFFFFFFF, },
+ { CS42L43_SW_TO_SPI_BRIDGE_MASK, 0xFFFFFFFF, },
+ { CS42L43_OTP_MASK, 0xFFFFFFFF, },
+ { CS42L43_CLASS_D_AMP_MASK, 0xFFFFFFFF, },
+ { CS42L43_GPIO_INT_MASK, 0xFFFFFFFF, },
+ { CS42L43_ASRC_MASK, 0xFFFFFFFF, },
+ { CS42L43_HPOUT_MASK, 0xFFFFFFFF, },
+ };
int ret;
- /*
- * Don't care about being resumed here, but the driver does want
- * force_resume to always trigger an actual resume, so that register
- * state for the MCU/GPIOs is returned as soon as possible after system
- * resume. force_resume will resume if the reference count is resumed on
- * suspend hence the get_noresume.
- */
- pm_runtime_get_noresume(dev);
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret) {
+ dev_err(cs42l43->dev, "Failed to resume for suspend: %d\n", ret);
+ return ret;
+ }
+
+ /* The IRQs will be re-enabled on resume by the cache sync */
+ ret = regmap_multi_reg_write_bypassed(cs42l43->regmap,
+ mask_all, ARRAY_SIZE(mask_all));
+ if (ret) {
+ dev_err(cs42l43->dev, "Failed to mask IRQs: %d\n", ret);
+ return ret;
+ }
ret = pm_runtime_force_suspend(dev);
if (ret) {
@@ -1133,6 +1156,26 @@ static int cs42l43_suspend(struct device *dev)
if (ret)
return ret;
+ disable_irq(cs42l43->irq);
+
+ return 0;
+}
+
+static int cs42l43_suspend_noirq(struct device *dev)
+{
+ struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
+
+ enable_irq(cs42l43->irq);
+
+ return 0;
+}
+
+static int cs42l43_resume_noirq(struct device *dev)
+{
+ struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
+
+ disable_irq(cs42l43->irq);
+
return 0;
}
@@ -1145,6 +1188,8 @@ static int cs42l43_resume(struct device *dev)
if (ret)
return ret;
+ enable_irq(cs42l43->irq);
+
ret = pm_runtime_force_resume(dev);
if (ret) {
dev_err(cs42l43->dev, "Failed to force resume: %d\n", ret);
@@ -1212,6 +1257,7 @@ err:
EXPORT_NS_GPL_DEV_PM_OPS(cs42l43_pm_ops, MFD_CS42L43) = {
SYSTEM_SLEEP_PM_OPS(cs42l43_suspend, cs42l43_resume)
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(cs42l43_suspend_noirq, cs42l43_resume_noirq)
RUNTIME_PM_OPS(cs42l43_runtime_suspend, cs42l43_runtime_resume, NULL)
};