* [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion
@ 2009-11-25 16:32 Johannes Weiner
2009-11-25 16:32 ` [patch 2/3] rtc-x1205: reset clock to sane state after power failure Johannes Weiner
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Johannes Weiner @ 2009-11-25 16:32 UTC (permalink / raw)
To: Alessandro Zummo, Paul Gortmaker; +Cc: Andrew Morton, rtc-linux, linux-kernel
The possible CCR_Y2K register values are 19 or 20 and struct
rtc_time's tm_year is in years since 1900.
The function translating rtc_time to register values assumes tm_year
to be years since first christmas, though, and we end up storing 0 or
1 in the CCR_Y2K register, which the hardware does not refuse to do.
A subsequent probing of the clock fails due to the invalid value range
in the register, though.
[ And if it didn't, reading the clock would yield a bogus year because
the function translating registers to tm_year is assuming a register
value of 19 or 20. ]
This fixes the conversion from years since 1900 in tm_year to the
corresponding CCR_Y2K value of 19 or 20.
Signed-off-by: Johannes Weiner <jw@emlix.com>
---
drivers/rtc/rtc-x1205.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 310c107..cc9ba47 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -195,7 +195,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
/* year, since the rtc epoch*/
buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
buf[CCR_WDAY] = tm->tm_wday & 0x07;
- buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
+ buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
}
/* If writing alarm registers, set compare bits on registers 0-4 */
--
1.6.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [patch 2/3] rtc-x1205: reset clock to sane state after power failure 2009-11-25 16:32 [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Johannes Weiner @ 2009-11-25 16:32 ` Johannes Weiner 2009-11-25 16:32 ` [patch 3/3] rtc-x1205: unconditionally set date when setting clock Johannes Weiner 2009-11-25 22:11 ` [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Andrew Morton 2 siblings, 0 replies; 6+ messages in thread From: Johannes Weiner @ 2009-11-25 16:32 UTC (permalink / raw) To: Alessandro Zummo, Paul Gortmaker; +Cc: Andrew Morton, rtc-linux, linux-kernel When detecting power failure, the probe function would reset the clock time to defined state. However, the clock's _date_ might still be bogus and a subsequent probe fails when sanity-checking these values. Change the power-failure fixup code to do a full setting of rtc_time, including a valid date. Signed-off-by: Johannes Weiner <jw@emlix.com> --- drivers/rtc/rtc-x1205.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index cc9ba47..6583c1a 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -280,9 +280,9 @@ static int x1205_fix_osc(struct i2c_client *client) int err; struct rtc_time tm; - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + memset(&tm, 0, sizeof(tm)); - err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE, 0); + err = x1205_set_datetime(client, &tm, 1, X1205_CCR_BASE, 0); if (err < 0) dev_err(&client->dev, "unable to restart the oscillator\n"); -- 1.6.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [patch 3/3] rtc-x1205: unconditionally set date when setting clock 2009-11-25 16:32 [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Johannes Weiner 2009-11-25 16:32 ` [patch 2/3] rtc-x1205: reset clock to sane state after power failure Johannes Weiner @ 2009-11-25 16:32 ` Johannes Weiner 2009-11-25 22:11 ` [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Andrew Morton 2 siblings, 0 replies; 6+ messages in thread From: Johannes Weiner @ 2009-11-25 16:32 UTC (permalink / raw) To: Alessandro Zummo, Paul Gortmaker; +Cc: Andrew Morton, rtc-linux, linux-kernel All callsites of x1205_set_datetime() want the date to be set as well, so remove the flag parameter and set it unconditionally. Signed-off-by: Johannes Weiner <jw@emlix.com> --- drivers/rtc/rtc-x1205.c | 53 ++++++++++++++++------------------------------- 1 files changed, 18 insertions(+), 35 deletions(-) diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 6583c1a..9aae491 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -155,11 +155,11 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr) } static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, - int datetoo, u8 reg_base, unsigned char alm_enable) + u8 reg_base, unsigned char alm_enable) { - int i, xfer, nbytes; - unsigned char buf[8]; + int i, xfer; unsigned char rdata[10] = { 0, reg_base }; + unsigned char *buf = rdata + 2; static const unsigned char wel[3] = { 0, X1205_REG_SR, X1205_SR_WEL }; @@ -170,9 +170,9 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 }; dev_dbg(&client->dev, - "%s: secs=%d, mins=%d, hours=%d\n", - __func__, - tm->tm_sec, tm->tm_min, tm->tm_hour); + "%s: sec=%d min=%d hour=%d mday=%d mon=%d year=%d wday=%d\n", + __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, + tm->tm_mon, tm->tm_year, tm->tm_wday); buf[CCR_SEC] = bin2bcd(tm->tm_sec); buf[CCR_MIN] = bin2bcd(tm->tm_min); @@ -180,23 +180,15 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, /* set hour and 24hr bit */ buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL; - /* should we also set the date? */ - if (datetoo) { - dev_dbg(&client->dev, - "%s: mday=%d, mon=%d, year=%d, wday=%d\n", - __func__, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + buf[CCR_MDAY] = bin2bcd(tm->tm_mday); - buf[CCR_MDAY] = bin2bcd(tm->tm_mday); + /* month, 1 - 12 */ + buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1); - /* month, 1 - 12 */ - buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1); - - /* year, since the rtc epoch*/ - buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100); - buf[CCR_WDAY] = tm->tm_wday & 0x07; - buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100); - } + /* year, since the rtc epoch*/ + buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100); + buf[CCR_WDAY] = tm->tm_wday & 0x07; + buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100); /* If writing alarm registers, set compare bits on registers 0-4 */ if (reg_base < X1205_CCR_BASE) @@ -214,17 +206,8 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, return -EIO; } - - /* write register's data */ - if (datetoo) - nbytes = 8; - else - nbytes = 3; - for (i = 0; i < nbytes; i++) - rdata[2+i] = buf[i]; - - xfer = i2c_master_send(client, rdata, nbytes+2); - if (xfer != nbytes+2) { + xfer = i2c_master_send(client, rdata, sizeof(rdata)); + if (xfer != sizeof(rdata)) { dev_err(&client->dev, "%s: result=%d addr=%02x, data=%02x\n", __func__, @@ -282,7 +265,7 @@ static int x1205_fix_osc(struct i2c_client *client) memset(&tm, 0, sizeof(tm)); - err = x1205_set_datetime(client, &tm, 1, X1205_CCR_BASE, 0); + err = x1205_set_datetime(client, &tm, X1205_CCR_BASE, 0); if (err < 0) dev_err(&client->dev, "unable to restart the oscillator\n"); @@ -481,7 +464,7 @@ static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int x1205_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { return x1205_set_datetime(to_i2c_client(dev), - &alrm->time, 1, X1205_ALM0_BASE, alrm->enabled); + &alrm->time, X1205_ALM0_BASE, alrm->enabled); } static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -493,7 +476,7 @@ static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm) static int x1205_rtc_set_time(struct device *dev, struct rtc_time *tm) { return x1205_set_datetime(to_i2c_client(dev), - tm, 1, X1205_CCR_BASE, 0); + tm, X1205_CCR_BASE, 0); } static int x1205_rtc_proc(struct device *dev, struct seq_file *seq) -- 1.6.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion 2009-11-25 16:32 [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Johannes Weiner 2009-11-25 16:32 ` [patch 2/3] rtc-x1205: reset clock to sane state after power failure Johannes Weiner 2009-11-25 16:32 ` [patch 3/3] rtc-x1205: unconditionally set date when setting clock Johannes Weiner @ 2009-11-25 22:11 ` Andrew Morton 2009-11-26 1:02 ` Johannes Weiner 2 siblings, 1 reply; 6+ messages in thread From: Andrew Morton @ 2009-11-25 22:11 UTC (permalink / raw) To: Johannes Weiner; +Cc: Alessandro Zummo, Paul Gortmaker, rtc-linux, linux-kernel I'm thinking that patches 1 and 2 are 2.6.32 material? ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion 2009-11-25 22:11 ` [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Andrew Morton @ 2009-11-26 1:02 ` Johannes Weiner 2009-11-26 21:40 ` Alessandro Zummo 0 siblings, 1 reply; 6+ messages in thread From: Johannes Weiner @ 2009-11-26 1:02 UTC (permalink / raw) To: Andrew Morton; +Cc: Alessandro Zummo, Paul Gortmaker, rtc-linux, linux-kernel On Wed, Nov 25, 2009 at 02:11:00PM -0800, Andrew Morton wrote: > I'm thinking that patches 1 and 2 are 2.6.32 material? Yeah, I think so too, although I hope we can get feedback from the authors beforehand. Because #1 looks obvious to me and makes the driver at all usable for me but the code has been like that since the initial merge in 2006. So either a) nobody ever set the date with this thing, b) every embedded linux company has its own private patch or c) I am missing something, where likelyhood is in reverse order. That makes me feel slightly uncomfortable. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion 2009-11-26 1:02 ` Johannes Weiner @ 2009-11-26 21:40 ` Alessandro Zummo 0 siblings, 0 replies; 6+ messages in thread From: Alessandro Zummo @ 2009-11-26 21:40 UTC (permalink / raw) To: Johannes Weiner; +Cc: Andrew Morton, Paul Gortmaker, rtc-linux, linux-kernel On Thu, 26 Nov 2009 02:02:34 +0100 Johannes Weiner <jw@emlix.com> wrote: > eah, I think so too, although I hope we can get feedback from the > authors beforehand. > > Because #1 looks obvious to me and makes the driver at all usable for > me but the code has been like that since the initial merge in 2006. > So either > > a) nobody ever set the date with this thing, > b) every embedded linux company has its own private patch or > c) I am missing something, > > where likelyhood is in reverse order. That makes me feel slightly > uncomfortable. The last time I used an x1205 it worked nicely. It's been two or three years since. However the datasheet says 0x19 o 0x20 so your patch looks good. -- Best regards, Alessandro Zummo, Tower Technologies - Torino, Italy http://www.towertech.it ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-11-26 21:40 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-25 16:32 [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Johannes Weiner 2009-11-25 16:32 ` [patch 2/3] rtc-x1205: reset clock to sane state after power failure Johannes Weiner 2009-11-25 16:32 ` [patch 3/3] rtc-x1205: unconditionally set date when setting clock Johannes Weiner 2009-11-25 22:11 ` [patch 1/3] rtc-x1205: fix rtc_time to y2k register value conversion Andrew Morton 2009-11-26 1:02 ` Johannes Weiner 2009-11-26 21:40 ` Alessandro Zummo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox