linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source
@ 2014-01-21  5:24 Dongsheng Wang
  2014-02-25 22:07 ` [rtc-linux] " Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: Dongsheng Wang @ 2014-01-21  5:24 UTC (permalink / raw)
  To: a.zummo; +Cc: linuxppc-dev, chenhui.zhao, rtc-linux, Wang Dongsheng

From: Wang Dongsheng <dongsheng.wang@freescale.com>

Add suspend/resume and device_init_wakeup to enable ds3232 as
wakeup source, /sys/class/rtc/rtcX/wakealarm for set wakeup alarm.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>

diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index b83bb5a5..a3c40d5 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -57,6 +57,7 @@ struct ds3232 {
 	 * in the remove function.
 	 */
 	struct mutex mutex;
+	bool suspended;
 	int exiting;
 };
 
@@ -345,7 +346,15 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
 	struct ds3232 *ds3232 = i2c_get_clientdata(client);
 
 	disable_irq_nosync(irq);
-	schedule_work(&ds3232->work);
+
+	/*
+	 * If rtc as a wakeup source, can't schedule the work
+	 * at system resume flow, because at this time the i2c bus
+	 * has not been resumed.
+	 */
+	if (!ds3232->suspended)
+		schedule_work(&ds3232->work);
+
 	return IRQ_HANDLED;
 }
 
@@ -363,22 +372,26 @@ static void ds3232_work(struct work_struct *work)
 
 	if (stat & DS3232_REG_SR_A1F) {
 		control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
-		if (control < 0)
-			goto out;
-		/* disable alarm1 interrupt */
-		control &= ~(DS3232_REG_CR_A1IE);
-		i2c_smbus_write_byte_data(client, DS3232_REG_CR, control);
-
-		/* clear the alarm pend flag */
-		stat &= ~DS3232_REG_SR_A1F;
-		i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
-
-		rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
+		if (control < 0) {
+			pr_warn("Read DS3232 Control Register error."
+				"Disable IRQ%d.\n", client->irq);
+		} else {
+			/* disable alarm1 interrupt */
+			control &= ~(DS3232_REG_CR_A1IE);
+			i2c_smbus_write_byte_data(client, DS3232_REG_CR,
+						control);
+
+			/* clear the alarm pend flag */
+			stat &= ~DS3232_REG_SR_A1F;
+			i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat);
+
+			rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
+
+			if (!ds3232->exiting)
+				enable_irq(client->irq);
+		}
 	}
 
-out:
-	if (!ds3232->exiting)
-		enable_irq(client->irq);
 unlock:
 	mutex_unlock(&ds3232->mutex);
 }
@@ -411,23 +424,21 @@ static int ds3232_probe(struct i2c_client *client,
 	if (ret)
 		return ret;
 
-	ds3232->rtc = devm_rtc_device_register(&client->dev, client->name,
-					  &ds3232_rtc_ops, THIS_MODULE);
-	if (IS_ERR(ds3232->rtc)) {
-		dev_err(&client->dev, "unable to register the class device\n");
-		return PTR_ERR(ds3232->rtc);
-	}
-
-	if (client->irq >= 0) {
+	if (client->irq != NO_IRQ) {
 		ret = devm_request_irq(&client->dev, client->irq, ds3232_irq, 0,
 				 "ds3232", client);
 		if (ret) {
 			dev_err(&client->dev, "unable to request IRQ\n");
 			return ret;
 		}
+
+		device_init_wakeup(&client->dev, 1);
+
 	}
 
-	return 0;
+	ds3232->rtc = devm_rtc_device_register(&client->dev, client->name,
+					  &ds3232_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(ds3232->rtc);
 }
 
 static int ds3232_remove(struct i2c_client *client)
@@ -446,6 +457,42 @@ static int ds3232_remove(struct i2c_client *client)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int ds3232_suspend(struct device *dev)
+{
+	struct ds3232 *ds3232 = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+
+	if (device_can_wakeup(dev)) {
+		ds3232->suspended = true;
+		irq_set_irq_wake(client->irq, 1);
+	}
+
+	return 0;
+}
+
+static int ds3232_resume(struct device *dev)
+{
+	struct ds3232 *ds3232 = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+
+	if (ds3232->suspended) {
+		ds3232->suspended = false;
+
+		/* Clear the hardware alarm pend flag */
+		schedule_work(&ds3232->work);
+
+		irq_set_irq_wake(client->irq, 0);
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops ds3232_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
+};
+
 static const struct i2c_device_id ds3232_id[] = {
 	{ "ds3232", 0 },
 	{ }
@@ -456,6 +503,7 @@ static struct i2c_driver ds3232_driver = {
 	.driver = {
 		.name = "rtc-ds3232",
 		.owner = THIS_MODULE,
+		.pm	= &ds3232_pm_ops,
 	},
 	.probe = ds3232_probe,
 	.remove = ds3232_remove,
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [rtc-linux] [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source
  2014-01-21  5:24 [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source Dongsheng Wang
@ 2014-02-25 22:07 ` Andrew Morton
  2014-02-26  3:09   ` Dongsheng.Wang
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2014-02-25 22:07 UTC (permalink / raw)
  To: rtc-linux; +Cc: a.zummo, linuxppc-dev, Dongsheng Wang, chenhui.zhao

On Tue, 21 Jan 2014 13:24:51 +0800 Dongsheng Wang <dongsheng.wang@freescale.com> wrote:

> From: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> Add suspend/resume and device_init_wakeup to enable ds3232 as
> wakeup source, /sys/class/rtc/rtcX/wakealarm for set wakeup alarm.
> 
> ...
> 
> @@ -411,23 +424,21 @@ static int ds3232_probe(struct i2c_client *client,
>  	if (ret)
>  		return ret;
>  
> -	ds3232->rtc = devm_rtc_device_register(&client->dev, client->name,
> -					  &ds3232_rtc_ops, THIS_MODULE);
> -	if (IS_ERR(ds3232->rtc)) {
> -		dev_err(&client->dev, "unable to register the class device\n");
> -		return PTR_ERR(ds3232->rtc);
> -	}
> -
> -	if (client->irq >= 0) {
> +	if (client->irq != NO_IRQ) {

x86_64 allmodconfig:

drivers/rtc/rtc-ds3232.c: In function 'ds3232_probe':
drivers/rtc/rtc-ds3232.c:427: error: 'NO_IRQ' undeclared (first use in this function)
drivers/rtc/rtc-ds3232.c:427: error: (Each undeclared identifier is reported only once
drivers/rtc/rtc-ds3232.c:427: error: for each function it appears in.)

Not all architectures implement NO_IRQ.

I think this should be 

	if (client->irq > 0) {

but I'm not sure - iirc, x86 (at least) treats zero as "not an IRQ". 
But I think some architectures permit IRQ 0.  There was discussion many
years ago but I don't think anything got resolved.


Help!  I think some ppc people will know what to do here?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [rtc-linux] [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source
  2014-02-25 22:07 ` [rtc-linux] " Andrew Morton
@ 2014-02-26  3:09   ` Dongsheng.Wang
  2014-02-26  3:20     ` Scott Wood
  0 siblings, 1 reply; 5+ messages in thread
From: Dongsheng.Wang @ 2014-02-26  3:09 UTC (permalink / raw)
  To: Andrew Morton, rtc-linux@googlegroups.com,
	benh@kernel.crashing.org
  Cc: Scott Wood, a.zummo@towertech.it, linuxppc-dev@lists.ozlabs.org,
	chenhui.zhao@freescale.com



> -----Original Message-----
> From: Andrew Morton [mailto:akpm@linux-foundation.org]
> Sent: Wednesday, February 26, 2014 6:07 AM
> To: rtc-linux@googlegroups.com
> Cc: Wang Dongsheng-B40534; a.zummo@towertech.it; Zhao Chenhui-B35336; lin=
uxppc-
> dev@lists.ozlabs.org
> Subject: Re: [rtc-linux] [PATCH] rtc/ds3232: Enable ds3232 to work as wak=
eup
> source
>=20
> On Tue, 21 Jan 2014 13:24:51 +0800 Dongsheng Wang <dongsheng.wang@freesca=
le.com>
> wrote:
>=20
> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >
> > Add suspend/resume and device_init_wakeup to enable ds3232 as
> > wakeup source, /sys/class/rtc/rtcX/wakealarm for set wakeup alarm.
> >
> > ...
> >
> > @@ -411,23 +424,21 @@ static int ds3232_probe(struct i2c_client *client=
,
> >  	if (ret)
> >  		return ret;
> >
> > -	ds3232->rtc =3D devm_rtc_device_register(&client->dev, client->name,
> > -					  &ds3232_rtc_ops, THIS_MODULE);
> > -	if (IS_ERR(ds3232->rtc)) {
> > -		dev_err(&client->dev, "unable to register the class device\n");
> > -		return PTR_ERR(ds3232->rtc);
> > -	}
> > -
> > -	if (client->irq >=3D 0) {
> > +	if (client->irq !=3D NO_IRQ) {
>=20
> x86_64 allmodconfig:
>=20
> drivers/rtc/rtc-ds3232.c: In function 'ds3232_probe':
> drivers/rtc/rtc-ds3232.c:427: error: 'NO_IRQ' undeclared (first use in th=
is
> function)
> drivers/rtc/rtc-ds3232.c:427: error: (Each undeclared identifier is repor=
ted
> only once
> drivers/rtc/rtc-ds3232.c:427: error: for each function it appears in.)
>=20
> Not all architectures implement NO_IRQ.
>=20
> I think this should be
>=20
> 	if (client->irq > 0) {
>=20
> but I'm not sure - iirc, x86 (at least) treats zero as "not an IRQ".
> But I think some architectures permit IRQ 0.  There was discussion many
> years ago but I don't think anything got resolved.
>=20
I think this is why NO_IRQ is defined in kernel, that should be resolved th=
is issue.

Sorry, I don't know why some architectures didn't define this macro?


Hi Ben,

Did you have some suggestion?

Thanks,
-Dongsheng

>=20
> Help!  I think some ppc people will know what to do here?
>=20

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [rtc-linux] [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source
  2014-02-26  3:09   ` Dongsheng.Wang
@ 2014-02-26  3:20     ` Scott Wood
  2014-02-26  3:26       ` Dongsheng.Wang
  0 siblings, 1 reply; 5+ messages in thread
From: Scott Wood @ 2014-02-26  3:20 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: a.zummo@towertech.it, Zhao Chenhui-B35336,
	rtc-linux@googlegroups.com, Andrew Morton,
	linuxppc-dev@lists.ozlabs.org

On Tue, 2014-02-25 at 21:09 -0600, Wang Dongsheng-B40534 wrote:
> 
> > -----Original Message-----
> > From: Andrew Morton [mailto:akpm@linux-foundation.org]
> > Sent: Wednesday, February 26, 2014 6:07 AM
> > To: rtc-linux@googlegroups.com
> > Cc: Wang Dongsheng-B40534; a.zummo@towertech.it; Zhao Chenhui-B35336; linuxppc-
> > dev@lists.ozlabs.org
> > Subject: Re: [rtc-linux] [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup
> > source
> > 
> > On Tue, 21 Jan 2014 13:24:51 +0800 Dongsheng Wang <dongsheng.wang@freescale.com>
> > wrote:
> > 
> > > +	if (client->irq != NO_IRQ) {
> > 
> > x86_64 allmodconfig:
> > 
> > drivers/rtc/rtc-ds3232.c: In function 'ds3232_probe':
> > drivers/rtc/rtc-ds3232.c:427: error: 'NO_IRQ' undeclared (first use in this
> > function)
> > drivers/rtc/rtc-ds3232.c:427: error: (Each undeclared identifier is reported
> > only once
> > drivers/rtc/rtc-ds3232.c:427: error: for each function it appears in.)
> > 
> > Not all architectures implement NO_IRQ.
> > 
> > I think this should be
> > 
> > 	if (client->irq > 0) {
> > 
> > but I'm not sure - iirc, x86 (at least) treats zero as "not an IRQ".
> > But I think some architectures permit IRQ 0.  There was discussion many
> > years ago but I don't think anything got resolved.
> > 
> I think this is why NO_IRQ is defined in kernel, that should be resolved this issue.
> 
> Sorry, I don't know why some architectures didn't define this macro?

NO_IRQ is deprecated (see "git log -SNO_IRQ" for the trend of removing
uses of it, as well as situations where it gives the wrong results).
"if (client->irq > 0)" is correct.

-Scott

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [rtc-linux] [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source
  2014-02-26  3:20     ` Scott Wood
@ 2014-02-26  3:26       ` Dongsheng.Wang
  0 siblings, 0 replies; 5+ messages in thread
From: Dongsheng.Wang @ 2014-02-26  3:26 UTC (permalink / raw)
  To: Scott Wood
  Cc: a.zummo@towertech.it, chenhui.zhao@freescale.com,
	rtc-linux@googlegroups.com, Andrew Morton,
	linuxppc-dev@lists.ozlabs.org

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV29vZCBTY290dC1CMDc0
MjENCj4gU2VudDogV2VkbmVzZGF5LCBGZWJydWFyeSAyNiwgMjAxNCAxMToyMSBBTQ0KPiBUbzog
V2FuZyBEb25nc2hlbmctQjQwNTM0DQo+IENjOiBBbmRyZXcgTW9ydG9uOyBydGMtbGludXhAZ29v
Z2xlZ3JvdXBzLmNvbTsgYmVuaEBrZXJuZWwuY3Jhc2hpbmcub3JnOw0KPiBhLnp1bW1vQHRvd2Vy
dGVjaC5pdDsgWmhhbyBDaGVuaHVpLUIzNTMzNjsgbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5v
cmcNCj4gU3ViamVjdDogUmU6IFtydGMtbGludXhdIFtQQVRDSF0gcnRjL2RzMzIzMjogRW5hYmxl
IGRzMzIzMiB0byB3b3JrIGFzIHdha2V1cA0KPiBzb3VyY2UNCj4gDQo+IE9uIFR1ZSwgMjAxNC0w
Mi0yNSBhdCAyMTowOSAtMDYwMCwgV2FuZyBEb25nc2hlbmctQjQwNTM0IHdyb3RlOg0KPiA+DQo+
ID4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+ID4gRnJvbTogQW5kcmV3IE1vcnRv
biBbbWFpbHRvOmFrcG1AbGludXgtZm91bmRhdGlvbi5vcmddDQo+ID4gPiBTZW50OiBXZWRuZXNk
YXksIEZlYnJ1YXJ5IDI2LCAyMDE0IDY6MDcgQU0NCj4gPiA+IFRvOiBydGMtbGludXhAZ29vZ2xl
Z3JvdXBzLmNvbQ0KPiA+ID4gQ2M6IFdhbmcgRG9uZ3NoZW5nLUI0MDUzNDsgYS56dW1tb0B0b3dl
cnRlY2guaXQ7IFpoYW8gQ2hlbmh1aS1CMzUzMzY7DQo+IGxpbnV4cHBjLQ0KPiA+ID4gZGV2QGxp
c3RzLm96bGFicy5vcmcNCj4gPiA+IFN1YmplY3Q6IFJlOiBbcnRjLWxpbnV4XSBbUEFUQ0hdIHJ0
Yy9kczMyMzI6IEVuYWJsZSBkczMyMzIgdG8gd29yayBhcyB3YWtldXANCj4gPiA+IHNvdXJjZQ0K
PiA+ID4NCj4gPiA+IE9uIFR1ZSwgMjEgSmFuIDIwMTQgMTM6MjQ6NTEgKzA4MDAgRG9uZ3NoZW5n
IFdhbmcNCj4gPGRvbmdzaGVuZy53YW5nQGZyZWVzY2FsZS5jb20+DQo+ID4gPiB3cm90ZToNCj4g
PiA+DQo+ID4gPiA+ICsJaWYgKGNsaWVudC0+aXJxICE9IE5PX0lSUSkgew0KPiA+ID4NCj4gPiA+
IHg4Nl82NCBhbGxtb2Rjb25maWc6DQo+ID4gPg0KPiA+ID4gZHJpdmVycy9ydGMvcnRjLWRzMzIz
Mi5jOiBJbiBmdW5jdGlvbiAnZHMzMjMyX3Byb2JlJzoNCj4gPiA+IGRyaXZlcnMvcnRjL3J0Yy1k
czMyMzIuYzo0Mjc6IGVycm9yOiAnTk9fSVJRJyB1bmRlY2xhcmVkIChmaXJzdCB1c2UgaW4gdGhp
cw0KPiA+ID4gZnVuY3Rpb24pDQo+ID4gPiBkcml2ZXJzL3J0Yy9ydGMtZHMzMjMyLmM6NDI3OiBl
cnJvcjogKEVhY2ggdW5kZWNsYXJlZCBpZGVudGlmaWVyIGlzIHJlcG9ydGVkDQo+ID4gPiBvbmx5
IG9uY2UNCj4gPiA+IGRyaXZlcnMvcnRjL3J0Yy1kczMyMzIuYzo0Mjc6IGVycm9yOiBmb3IgZWFj
aCBmdW5jdGlvbiBpdCBhcHBlYXJzIGluLikNCj4gPiA+DQo+ID4gPiBOb3QgYWxsIGFyY2hpdGVj
dHVyZXMgaW1wbGVtZW50IE5PX0lSUS4NCj4gPiA+DQo+ID4gPiBJIHRoaW5rIHRoaXMgc2hvdWxk
IGJlDQo+ID4gPg0KPiA+ID4gCWlmIChjbGllbnQtPmlycSA+IDApIHsNCj4gPiA+DQo+ID4gPiBi
dXQgSSdtIG5vdCBzdXJlIC0gaWlyYywgeDg2IChhdCBsZWFzdCkgdHJlYXRzIHplcm8gYXMgIm5v
dCBhbiBJUlEiLg0KPiA+ID4gQnV0IEkgdGhpbmsgc29tZSBhcmNoaXRlY3R1cmVzIHBlcm1pdCBJ
UlEgMC4gIFRoZXJlIHdhcyBkaXNjdXNzaW9uIG1hbnkNCj4gPiA+IHllYXJzIGFnbyBidXQgSSBk
b24ndCB0aGluayBhbnl0aGluZyBnb3QgcmVzb2x2ZWQuDQo+ID4gPg0KPiA+IEkgdGhpbmsgdGhp
cyBpcyB3aHkgTk9fSVJRIGlzIGRlZmluZWQgaW4ga2VybmVsLCB0aGF0IHNob3VsZCBiZSByZXNv
bHZlZCB0aGlzDQo+IGlzc3VlLg0KPiA+DQo+ID4gU29ycnksIEkgZG9uJ3Qga25vdyB3aHkgc29t
ZSBhcmNoaXRlY3R1cmVzIGRpZG4ndCBkZWZpbmUgdGhpcyBtYWNybz8NCj4gDQo+IE5PX0lSUSBp
cyBkZXByZWNhdGVkIChzZWUgImdpdCBsb2cgLVNOT19JUlEiIGZvciB0aGUgdHJlbmQgb2YgcmVt
b3ZpbmcNCj4gdXNlcyBvZiBpdCwgYXMgd2VsbCBhcyBzaXR1YXRpb25zIHdoZXJlIGl0IGdpdmVz
IHRoZSB3cm9uZyByZXN1bHRzKS4NCj4gImlmIChjbGllbnQtPmlycSA+IDApIiBpcyBjb3JyZWN0
Lg0KPiANClRoYW5rcy4NCg0KLURvbmdzaGVuZw0KDQo+IC1TY290dA0KPiANCg0K

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-02-26  3:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-21  5:24 [PATCH] rtc/ds3232: Enable ds3232 to work as wakeup source Dongsheng Wang
2014-02-25 22:07 ` [rtc-linux] " Andrew Morton
2014-02-26  3:09   ` Dongsheng.Wang
2014-02-26  3:20     ` Scott Wood
2014-02-26  3:26       ` Dongsheng.Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).