|
@@ -323,6 +323,8 @@ static int sec_pmic_probe(struct i2c_client *i2c,
|
|
|
if (ret)
|
|
|
goto err;
|
|
|
|
|
|
+ device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
|
|
|
+
|
|
|
return ret;
|
|
|
|
|
|
err:
|
|
@@ -341,6 +343,43 @@ static int sec_pmic_remove(struct i2c_client *i2c)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int sec_pmic_suspend(struct device *dev)
|
|
|
+{
|
|
|
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
|
|
|
+ struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
|
|
|
+
|
|
|
+ if (device_may_wakeup(dev)) {
|
|
|
+ enable_irq_wake(sec_pmic->irq);
|
|
|
+ /*
|
|
|
+ * PMIC IRQ must be disabled during suspend for RTC alarm
|
|
|
+ * to work properly.
|
|
|
+ * When device is woken up from suspend by RTC Alarm, an
|
|
|
+ * interrupt occurs before resuming I2C bus controller.
|
|
|
+ * The interrupt is handled by regmap_irq_thread which tries
|
|
|
+ * to read RTC registers. This read fails (I2C is still
|
|
|
+ * suspended) and RTC Alarm interrupt is disabled.
|
|
|
+ */
|
|
|
+ disable_irq(sec_pmic->irq);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int sec_pmic_resume(struct device *dev)
|
|
|
+{
|
|
|
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
|
|
|
+ struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
|
|
|
+
|
|
|
+ if (device_may_wakeup(dev)) {
|
|
|
+ disable_irq_wake(sec_pmic->irq);
|
|
|
+ enable_irq(sec_pmic->irq);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
|
|
|
+
|
|
|
static const struct i2c_device_id sec_pmic_id[] = {
|
|
|
{ "sec_pmic", 0 },
|
|
|
{ }
|
|
@@ -351,6 +390,7 @@ static struct i2c_driver sec_pmic_driver = {
|
|
|
.driver = {
|
|
|
.name = "sec_pmic",
|
|
|
.owner = THIS_MODULE,
|
|
|
+ .pm = &sec_pmic_pm_ops,
|
|
|
.of_match_table = of_match_ptr(sec_dt_match),
|
|
|
},
|
|
|
.probe = sec_pmic_probe,
|