aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2015-06-24 12:26:54 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-09-05 07:19:05 -0400
commit7abea617a4bae178da0f42983998c779ec2f732d (patch)
treea4053e8b785c6d3b63e01f78a30e751618371da1 /drivers/rtc
parenteac7237fd8432e232af3c407e667dbdc17ebf1d8 (diff)
rtc: ds1307: Support optional wakeup interrupt source
With the recent pinctrl-single changes, SoCs such as Texas Instrument's OMAP processors can treat wake-up events from deeper idle states as interrupts. Let's add support for the optional second interrupt for wake-up using the generic wakeirq support added in commit 4990d4fe327b ("PM / Wakeirq: Add automated device wake IRQ handling") Finally, to pass the wake-up interrupt in the dts file, interrupts-extended property needs to be passed. This is similar in approach to commit 2a0b965cfb6e ("serial: omap: Add support for optional wake-up") + ee83bd3b6483 ("serial: omap: Switch wake-up interrupt to generic wakeirq") Signed-off-by: Nishanth Menon <nm@ti.com> Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ds1307.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index b03880fc32b5..e16989c48a90 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -15,6 +15,9 @@
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of_device.h>
19#include <linux/of_irq.h>
20#include <linux/pm_wakeirq.h>
18#include <linux/rtc/ds1307.h> 21#include <linux/rtc/ds1307.h>
19#include <linux/rtc.h> 22#include <linux/rtc.h>
20#include <linux/slab.h> 23#include <linux/slab.h>
@@ -114,6 +117,7 @@ struct ds1307 {
114#define HAS_ALARM 1 /* bit 1 == irq claimed */ 117#define HAS_ALARM 1 /* bit 1 == irq claimed */
115 struct i2c_client *client; 118 struct i2c_client *client;
116 struct rtc_device *rtc; 119 struct rtc_device *rtc;
120 int wakeirq;
117 s32 (*read_block_data)(const struct i2c_client *client, u8 command, 121 s32 (*read_block_data)(const struct i2c_client *client, u8 command,
118 u8 length, u8 *values); 122 u8 length, u8 *values);
119 s32 (*write_block_data)(const struct i2c_client *client, u8 command, 123 s32 (*write_block_data)(const struct i2c_client *client, u8 command,
@@ -1156,6 +1160,8 @@ read_rtc:
1156 } 1160 }
1157 1161
1158 if (want_irq) { 1162 if (want_irq) {
1163 struct device_node *node = client->dev.of_node;
1164
1159 err = devm_request_threaded_irq(&client->dev, 1165 err = devm_request_threaded_irq(&client->dev,
1160 client->irq, NULL, irq_handler, 1166 client->irq, NULL, irq_handler,
1161 IRQF_SHARED | IRQF_ONESHOT, 1167 IRQF_SHARED | IRQF_ONESHOT,
@@ -1163,13 +1169,34 @@ read_rtc:
1163 if (err) { 1169 if (err) {
1164 client->irq = 0; 1170 client->irq = 0;
1165 dev_err(&client->dev, "unable to request IRQ!\n"); 1171 dev_err(&client->dev, "unable to request IRQ!\n");
1166 } else { 1172 goto no_irq;
1173 }
1167 1174
1168 set_bit(HAS_ALARM, &ds1307->flags); 1175 set_bit(HAS_ALARM, &ds1307->flags);
1169 dev_dbg(&client->dev, "got IRQ %d\n", client->irq); 1176 dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
1177
1178 /* Currently supported by OF code only! */
1179 if (!node)
1180 goto no_irq;
1181
1182 err = of_irq_get(node, 1);
1183 if (err <= 0) {
1184 if (err == -EPROBE_DEFER)
1185 goto exit;
1186 goto no_irq;
1187 }
1188 ds1307->wakeirq = err;
1189
1190 err = dev_pm_set_dedicated_wake_irq(&client->dev,
1191 ds1307->wakeirq);
1192 if (err) {
1193 dev_err(&client->dev, "unable to setup wakeIRQ %d!\n",
1194 err);
1195 goto exit;
1170 } 1196 }
1171 } 1197 }
1172 1198
1199no_irq:
1173 if (chip->nvram_size) { 1200 if (chip->nvram_size) {
1174 1201
1175 ds1307->nvram = devm_kzalloc(&client->dev, 1202 ds1307->nvram = devm_kzalloc(&client->dev,
@@ -1213,6 +1240,9 @@ static int ds1307_remove(struct i2c_client *client)
1213{ 1240{
1214 struct ds1307 *ds1307 = i2c_get_clientdata(client); 1241 struct ds1307 *ds1307 = i2c_get_clientdata(client);
1215 1242
1243 if (ds1307->wakeirq)
1244 dev_pm_clear_wake_irq(&client->dev);
1245
1216 if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) 1246 if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
1217 sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram); 1247 sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram);
1218 1248