summaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-isl12057.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-isl12057.c')
-rw-r--r--drivers/rtc/rtc-isl12057.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c
index 3ec73ad7f2d8..bd76c5e35fa5 100644
--- a/drivers/rtc/rtc-isl12057.c
+++ b/drivers/rtc/rtc-isl12057.c
@@ -457,6 +457,40 @@ static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)
return 0;
}
+#ifdef CONFIG_OF
+/*
+ * One would expect the device to be marked as a wakeup source only
+ * when an IRQ pin of the RTC is routed to an interrupt line of the
+ * CPU. In practice, such an IRQ pin can be connected to a PMIC and
+ * this allows the device to be powered up when RTC alarm rings. This
+ * is for instance the case on ReadyNAS 102, 104 and 2120. On those
+ * devices with no IRQ driectly connected to the SoC, the RTC chip
+ * can be forced as a wakeup source by stating that explicitly in
+ * the device's .dts file using the "isil,irq2-can-wakeup-machine"
+ * boolean property. This will guarantee 'wakealarm' sysfs entry is
+ * available on the device.
+ *
+ * The function below returns 1, i.e. the capability of the chip to
+ * wakeup the device, based on IRQ availability or if the boolean
+ * property has been set in the .dts file. Otherwise, it returns 0.
+ */
+
+static bool isl12057_can_wakeup_machine(struct device *dev)
+{
+ struct isl12057_rtc_data *data = dev_get_drvdata(dev);
+
+ return (data->irq || of_property_read_bool(dev->of_node,
+ "isil,irq2-can-wakeup-machine"));
+}
+#else
+static bool isl12057_can_wakeup_machine(struct device *dev)
+{
+ struct isl12057_rtc_data *data = dev_get_drvdata(dev);
+
+ return !!data->irq;
+}
+#endif
+
static int isl12057_rtc_alarm_irq_enable(struct device *dev,
unsigned int enable)
{
@@ -555,7 +589,8 @@ static int isl12057_probe(struct i2c_client *client,
client->irq, ret);
}
- device_init_wakeup(dev, !!data->irq);
+ if (isl12057_can_wakeup_machine(dev))
+ device_init_wakeup(dev, true);
data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops,
THIS_MODULE);
@@ -576,9 +611,7 @@ err:
static int isl12057_remove(struct i2c_client *client)
{
- struct isl12057_rtc_data *rtc_data = dev_get_drvdata(&client->dev);
-
- if (rtc_data->irq)
+ if (isl12057_can_wakeup_machine(&client->dev))
device_init_wakeup(&client->dev, false);
return 0;
@@ -589,7 +622,7 @@ static int isl12057_rtc_suspend(struct device *dev)
{
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
+ if (rtc_data->irq && device_may_wakeup(dev))
return enable_irq_wake(rtc_data->irq);
return 0;
@@ -599,7 +632,7 @@ static int isl12057_rtc_resume(struct device *dev)
{
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
- if (device_may_wakeup(dev))
+ if (rtc_data->irq && device_may_wakeup(dev))
return disable_irq_wake(rtc_data->irq);
return 0;