Commit 8bc2a407 authored by Michael Lange's avatar Michael Lange Committed by Alexandre Belloni

rtc: ds1307: add support for the DT property 'wakeup-source'

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: default avatarMichael Lange <linuxstuff@milaw.biz>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent 04d3ba70
...@@ -851,6 +851,7 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -851,6 +851,7 @@ static int ds1307_probe(struct i2c_client *client,
struct chip_desc *chip = &chips[id->driver_data]; struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
bool want_irq = false; bool want_irq = false;
bool ds1307_can_wakeup_device = false;
unsigned char *buf; unsigned char *buf;
struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
irq_handler_t irq_handler = ds1307_irq; irq_handler_t irq_handler = ds1307_irq;
...@@ -898,6 +899,20 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -898,6 +899,20 @@ static int ds1307_probe(struct i2c_client *client,
ds1307->write_block_data = ds1307_write_block_data; 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) { switch (ds1307->type) {
case ds_1337: case ds_1337:
case ds_1339: case ds_1339:
...@@ -916,11 +931,13 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -916,11 +931,13 @@ static int ds1307_probe(struct i2c_client *client,
ds1307->regs[0] &= ~DS1337_BIT_nEOSC; 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 * For some variants, be sure alarms can trigger when we're
* running on Vbackup (BBSQI/BBSQW) * 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 ds1307->regs[0] |= DS1337_BIT_INTCN
| bbsqi_bitpos[ds1307->type]; | bbsqi_bitpos[ds1307->type];
ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
...@@ -1135,6 +1152,14 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1135,6 +1152,14 @@ static int ds1307_probe(struct i2c_client *client,
return PTR_ERR(ds1307->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) { if (want_irq) {
err = devm_request_threaded_irq(&client->dev, err = devm_request_threaded_irq(&client->dev,
client->irq, NULL, irq_handler, client->irq, NULL, irq_handler,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment