2016-12-02 10:50:26 +00:00
|
|
|
From cc252ee4f3948d12a878c93cbdb0505a9ee7bc03 Mon Sep 17 00:00:00 2001
|
2016-02-25 10:14:01 +00:00
|
|
|
From: Michael Lange <linuxstuff@milaw.biz>
|
|
|
|
Date: Thu, 21 Jan 2016 18:10:16 +0100
|
2016-09-10 12:54:26 +00:00
|
|
|
Subject: [PATCH] rtc: ds1307: add support for the DT property 'wakeup-source'
|
2016-02-25 10:14:01 +00:00
|
|
|
|
|
|
|
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 | 29 +++++++++++++++++++++++++++--
|
|
|
|
1 file changed, 27 insertions(+), 2 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/rtc/rtc-ds1307.c
|
|
|
|
+++ b/drivers/rtc/rtc-ds1307.c
|
|
|
|
@@ -860,6 +860,7 @@ static int ds1307_probe(struct i2c_clien
|
|
|
|
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;
|
|
|
|
@@ -907,6 +908,20 @@ static int ds1307_probe(struct i2c_clien
|
|
|
|
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:
|
|
|
|
@@ -925,11 +940,13 @@ static int ds1307_probe(struct i2c_clien
|
|
|
|
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);
|
|
|
|
@@ -1144,6 +1161,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,
|