rtc: ds1307: add support for the DT property 'wakeup-source'
authorMichael Lange <linuxstuff@milaw.biz>
Thu, 21 Jan 2016 17:10:16 +0000 (18:10 +0100)
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>
Thu, 4 Feb 2016 22:44:17 +0000 (23:44 +0100)
For RTC chips with no IRQ directly 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 "wakeup-source" boolean property.
This will guarantee the 'wakealarm' sysfs entry is available on the
device, if supported by the RTC.

With these changes to the driver rtc-ds1307 and the necessary entries
in the .dts file, I get an working ds1337 RTC on the Witty Pi extension
board by UUGear for the Raspberry Pi.

An example for the entry in the .dts file:

rtc: ds1337@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
wakeup-source;

If the "wakeup-source" property is set, do not request an IRQ.
Set also UIE mode to unsupported, to get a working 'hwclock' binary.

Signed-off-by: Michael Lange <linuxstuff@milaw.biz>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
drivers/rtc/rtc-ds1307.c

index cf685f6..bfedeb5 100644 (file)
@@ -851,6 +851,7 @@ static int ds1307_probe(struct i2c_client *client,
        struct chip_desc        *chip = &chips[id->driver_data];
        struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
        bool                    want_irq = false;
+       bool                    ds1307_can_wakeup_device = false;
        unsigned char           *buf;
        struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
        irq_handler_t   irq_handler = ds1307_irq;
@@ -898,6 +899,20 @@ static int ds1307_probe(struct i2c_client *client,
                ds1307->write_block_data = ds1307_write_block_data;
        }
 
+#ifdef CONFIG_OF
+/*
+ * For devices with no IRQ directly 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 "wakeup-source" boolean property.
+ * If the "wakeup-source" property is set, don't request an IRQ.
+ * This will guarantee the 'wakealarm' sysfs entry is available on the device,
+ * if supported by the RTC.
+ */
+       if (of_property_read_bool(client->dev.of_node, "wakeup-source")) {
+               ds1307_can_wakeup_device = true;
+       }
+#endif
+
        switch (ds1307->type) {
        case ds_1337:
        case ds_1339:
@@ -916,11 +931,13 @@ static int ds1307_probe(struct i2c_client *client,
                        ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
 
                /*
-                * Using IRQ?  Disable the square wave and both alarms.
+                * Using IRQ or defined as wakeup-source?
+                * Disable the square wave and both alarms.
                 * For some variants, be sure alarms can trigger when we're
                 * running on Vbackup (BBSQI/BBSQW)
                 */
-               if (ds1307->client->irq > 0 && chip->alarm) {
+               if (chip->alarm && (ds1307->client->irq > 0 ||
+                                               ds1307_can_wakeup_device)) {
                        ds1307->regs[0] |= DS1337_BIT_INTCN
                                        | bbsqi_bitpos[ds1307->type];
                        ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
@@ -1135,6 +1152,14 @@ read_rtc:
                return PTR_ERR(ds1307->rtc);
        }
 
+       if (ds1307_can_wakeup_device) {
+               /* Disable request for an IRQ */
+               want_irq = false;
+               dev_info(&client->dev, "'wakeup-source' is set, request for an IRQ is disabled!\n");
+               /* We cannot support UIE mode if we do not have an IRQ line */
+               ds1307->rtc->uie_unsupported = 1;
+       }
+
        if (want_irq) {
                err = devm_request_threaded_irq(&client->dev,
                                                client->irq, NULL, irq_handler,