All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RTC/PCF85063: fix reading/setting time/date
@ 2015-12-07 13:49 ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

The PCF85063 RTC needs special treatment while setting or reading the
time/date:

 - while reading the 7 time/date registers they are blocked from updating by
   the one second pulse internally. So reading all time/date registers should
   happen in one turn to ensure reading is an atomic operation

 - to let setting the time/date be an atomic operation as well, the clock
   dividers must be kept in reset state to avoid a one second pulse during
   writing the 7 time/date registers

Patch 1 and 2 change reading the time/date. I have kept them separately for
easier review. Squasching both into one patch render it more or less
unreadable.
Patch 3 changes setting the time/date.

Comments are welcome
Juergen

Please keep me on CC as I'm not subscribed to the list.


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

* [rtc-linux] [PATCH] RTC/PCF85063: fix reading/setting time/date
@ 2015-12-07 13:49 ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

The PCF85063 RTC needs special treatment while setting or reading the
time/date:

 - while reading the 7 time/date registers they are blocked from updating by
   the one second pulse internally. So reading all time/date registers should
   happen in one turn to ensure reading is an atomic operation

 - to let setting the time/date be an atomic operation as well, the clock
   dividers must be kept in reset state to avoid a one second pulse during
   writing the 7 time/date registers

Patch 1 and 2 change reading the time/date. I have kept them separately for
easier review. Squasching both into one patch render it more or less
unreadable.
Patch 3 changes setting the time/date.

Comments are welcome
Juergen

Please keep me on CC as I'm not subscribed to the list.

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH 1/3] RTC/PCF85063: fix time/date reading (part 1)
  2015-12-07 13:49 ` [rtc-linux] " Juergen Borleis
@ 2015-12-07 13:49   ` Juergen Borleis
  -1 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

When reading the seconds register, all time/date registers are frozen
until the year register is read. So, read all time/date registers in one
turn.

Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
---
 drivers/rtc/rtc-pcf85063.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 63334cb..75f2866 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -39,6 +39,38 @@ struct pcf85063 {
 	int voltage_low; /* indicates if a low_voltage was detected */
 };
 
+static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
+{
+	int rc;
+	u8 clk_ctrl = PCF85063_REG_SC;
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.len = sizeof(clk_ctrl),
+			.buf = &clk_ctrl,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = size,
+			.buf = buf
+		},
+	};
+
+	/*
+	 * while reading the time/date registers are blocked and not updated
+	 * anymore until the access is finished. To not lose a second
+	 * event, the access must be finished within one second. So, read all
+	 * time/date registers in one turn.
+	 */
+	rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (rc != ARRAY_SIZE(msgs)) {
+		dev_err(&client->dev, "date/time register read error\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /*
  * In the routines that deal directly with the pcf85063 hardware, we use
  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
-- 
2.6.2


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

* [rtc-linux] [PATCH 1/3] RTC/PCF85063: fix time/date reading (part 1)
@ 2015-12-07 13:49   ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

When reading the seconds register, all time/date registers are frozen
until the year register is read. So, read all time/date registers in one
turn.

Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
---
 drivers/rtc/rtc-pcf85063.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 63334cb..75f2866 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -39,6 +39,38 @@ struct pcf85063 {
 	int voltage_low; /* indicates if a low_voltage was detected */
 };
 
+static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
+{
+	int rc;
+	u8 clk_ctrl = PCF85063_REG_SC;
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.len = sizeof(clk_ctrl),
+			.buf = &clk_ctrl,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = size,
+			.buf = buf
+		},
+	};
+
+	/*
+	 * while reading the time/date registers are blocked and not updated
+	 * anymore until the access is finished. To not lose a second
+	 * event, the access must be finished within one second. So, read all
+	 * time/date registers in one turn.
+	 */
+	rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (rc != ARRAY_SIZE(msgs)) {
+		dev_err(&client->dev, "date/time register read error\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /*
  * In the routines that deal directly with the pcf85063 hardware, we use
  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
-- 
2.6.2

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
  2015-12-07 13:49 ` [rtc-linux] " Juergen Borleis
@ 2015-12-07 13:49   ` Juergen Borleis
  -1 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

Use the function to read the whole time/date register in one turn and now
check if the RTC signals an invalid time/date (due to a battery power loss
for example). In this case ignore the time/date until it is really set
again.

Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
---
 drivers/rtc/rtc-pcf85063.c | 45 +++++++++++++++++++--------------------------
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 75f2866..abed934 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -22,6 +22,7 @@
 #define PCF85063_REG_CTRL2		0x01
 
 #define PCF85063_REG_SC			0x04 /* datetime */
+#define PCF85063_REG_SC_OS		0x80
 #define PCF85063_REG_MN			0x05
 #define PCF85063_REG_HR			0x06
 #define PCF85063_REG_DM			0x07
@@ -77,39 +78,31 @@ static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
  */
 static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
+	int rc;
 	struct pcf85063 *pcf85063 = i2c_get_clientdata(client);
-	unsigned char buf[13] = { PCF85063_REG_CTRL1 };
-	struct i2c_msg msgs[] = {
-		{/* setup read ptr */
-			.addr = client->addr,
-			.len = 1,
-			.buf = buf
-		},
-		{/* read status + date */
-			.addr = client->addr,
-			.flags = I2C_M_RD,
-			.len = 13,
-			.buf = buf
-		},
-	};
+	u8 regs[7];
 
-	/* read registers */
-	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
-		dev_err(&client->dev, "%s: read error\n", __func__);
-		return -EIO;
+	rc = pcf85063_read_time(client, regs, sizeof(regs));
+	if (rc < 0)
+		return rc;
+
+	/* if the clock has lost its power it makes no sense to use its time */
+	if (regs[0] & PCF85063_REG_SC_OS) {
+		dev_warn(&client->dev, "Power loss detected, invalid time\n");
+		return -EINVAL;
 	}
 
-	tm->tm_sec = bcd2bin(buf[PCF85063_REG_SC] & 0x7F);
-	tm->tm_min = bcd2bin(buf[PCF85063_REG_MN] & 0x7F);
-	tm->tm_hour = bcd2bin(buf[PCF85063_REG_HR] & 0x3F); /* rtc hr 0-23 */
-	tm->tm_mday = bcd2bin(buf[PCF85063_REG_DM] & 0x3F);
-	tm->tm_wday = buf[PCF85063_REG_DW] & 0x07;
-	tm->tm_mon = bcd2bin(buf[PCF85063_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
-	tm->tm_year = bcd2bin(buf[PCF85063_REG_YR]);
+	tm->tm_sec = bcd2bin(regs[0] & 0x7F);
+	tm->tm_min = bcd2bin(regs[1] & 0x7F);
+	tm->tm_hour = bcd2bin(regs[2] & 0x3F); /* rtc hr 0-23 */
+	tm->tm_mday = bcd2bin(regs[3] & 0x3F);
+	tm->tm_wday = regs[4] & 0x07;
+	tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */
+	tm->tm_year = bcd2bin(regs[6]);
 	if (tm->tm_year < 70)
 		tm->tm_year += 100;	/* assume we are in 1970...2069 */
 	/* detect the polarity heuristically. see note above. */
-	pcf85063->c_polarity = (buf[PCF85063_REG_MO] & PCF85063_MO_C) ?
+	pcf85063->c_polarity = (regs[5] & PCF85063_MO_C) ?
 		(tm->tm_year >= 100) : (tm->tm_year < 100);
 
 	return rtc_valid_tm(tm);
-- 
2.6.2


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

* [rtc-linux] [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
@ 2015-12-07 13:49   ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

Use the function to read the whole time/date register in one turn and now
check if the RTC signals an invalid time/date (due to a battery power loss
for example). In this case ignore the time/date until it is really set
again.

Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
---
 drivers/rtc/rtc-pcf85063.c | 45 +++++++++++++++++++--------------------------
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 75f2866..abed934 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -22,6 +22,7 @@
 #define PCF85063_REG_CTRL2		0x01
 
 #define PCF85063_REG_SC			0x04 /* datetime */
+#define PCF85063_REG_SC_OS		0x80
 #define PCF85063_REG_MN			0x05
 #define PCF85063_REG_HR			0x06
 #define PCF85063_REG_DM			0x07
@@ -77,39 +78,31 @@ static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
  */
 static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
+	int rc;
 	struct pcf85063 *pcf85063 = i2c_get_clientdata(client);
-	unsigned char buf[13] = { PCF85063_REG_CTRL1 };
-	struct i2c_msg msgs[] = {
-		{/* setup read ptr */
-			.addr = client->addr,
-			.len = 1,
-			.buf = buf
-		},
-		{/* read status + date */
-			.addr = client->addr,
-			.flags = I2C_M_RD,
-			.len = 13,
-			.buf = buf
-		},
-	};
+	u8 regs[7];
 
-	/* read registers */
-	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
-		dev_err(&client->dev, "%s: read error\n", __func__);
-		return -EIO;
+	rc = pcf85063_read_time(client, regs, sizeof(regs));
+	if (rc < 0)
+		return rc;
+
+	/* if the clock has lost its power it makes no sense to use its time */
+	if (regs[0] & PCF85063_REG_SC_OS) {
+		dev_warn(&client->dev, "Power loss detected, invalid time\n");
+		return -EINVAL;
 	}
 
-	tm->tm_sec = bcd2bin(buf[PCF85063_REG_SC] & 0x7F);
-	tm->tm_min = bcd2bin(buf[PCF85063_REG_MN] & 0x7F);
-	tm->tm_hour = bcd2bin(buf[PCF85063_REG_HR] & 0x3F); /* rtc hr 0-23 */
-	tm->tm_mday = bcd2bin(buf[PCF85063_REG_DM] & 0x3F);
-	tm->tm_wday = buf[PCF85063_REG_DW] & 0x07;
-	tm->tm_mon = bcd2bin(buf[PCF85063_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
-	tm->tm_year = bcd2bin(buf[PCF85063_REG_YR]);
+	tm->tm_sec = bcd2bin(regs[0] & 0x7F);
+	tm->tm_min = bcd2bin(regs[1] & 0x7F);
+	tm->tm_hour = bcd2bin(regs[2] & 0x3F); /* rtc hr 0-23 */
+	tm->tm_mday = bcd2bin(regs[3] & 0x3F);
+	tm->tm_wday = regs[4] & 0x07;
+	tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */
+	tm->tm_year = bcd2bin(regs[6]);
 	if (tm->tm_year < 70)
 		tm->tm_year += 100;	/* assume we are in 1970...2069 */
 	/* detect the polarity heuristically. see note above. */
-	pcf85063->c_polarity = (buf[PCF85063_REG_MO] & PCF85063_MO_C) ?
+	pcf85063->c_polarity = (regs[5] & PCF85063_MO_C) ?
 		(tm->tm_year >= 100) : (tm->tm_year < 100);
 
 	return rtc_valid_tm(tm);
-- 
2.6.2

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH 3/3] RTC/PCF85063: fix time/date setting
  2015-12-07 13:49 ` [rtc-linux] " Juergen Borleis
@ 2015-12-07 13:49   ` Juergen Borleis
  -1 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

When setting a new time/date the RTC's clock must be stopped first, in
order to write the time/date registers in an atomic manner.
So, this change stops the clock first and then writes the time/date
registers and the clock control register (to re-enable the clock) in one
turn.

Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
---
 drivers/rtc/rtc-pcf85063.c | 96 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 73 insertions(+), 23 deletions(-)

diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index abed934..0150e93 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -19,6 +19,7 @@
 #define DRV_VERSION "0.0.1"
 
 #define PCF85063_REG_CTRL1		0x00 /* status */
+#define PCF85063_REG_CTRL1_STOP		BIT(5)
 #define PCF85063_REG_CTRL2		0x01
 
 #define PCF85063_REG_SC			0x04 /* datetime */
@@ -72,6 +73,47 @@ static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
 	return 0;
 }
 
+static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1)
+{
+	int rc;
+	u8 clk_ctrl[2] = { PCF85063_REG_CTRL1, };
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.len = 1,
+			.buf = &clk_ctrl[0],
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = &clk_ctrl[1],
+		}, {
+			.addr = client->addr,
+			.len = sizeof(clk_ctrl),
+			.buf = &clk_ctrl[0],
+		},
+	};
+
+	rc = i2c_transfer(client->adapter, &msgs[0], 2);
+	if (rc != 2) {
+		dev_err(&client->dev, "Failing to stop the clock\n");
+		return -EIO;
+	}
+
+	/* stop the clock */
+	clk_ctrl[1] |= PCF85063_REG_CTRL1_STOP;
+
+	rc = i2c_transfer(client->adapter, &msgs[2], 1);
+	if (rc != 1) {
+		dev_err(&client->dev, "Failing to stop the clock\n");
+		return -EIO;
+	}
+
+	*ctrl1 = clk_ctrl[1];
+
+	return 0;
+}
+
 /*
  * In the routines that deal directly with the pcf85063 hardware, we use
  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -110,41 +152,49 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 
 static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
-	int i = 0, err = 0;
-	unsigned char buf[11];
+	int rc;
+	u8 regs[9];
 
-	/* Control & status */
-	buf[PCF85063_REG_CTRL1] = 0;
-	buf[PCF85063_REG_CTRL2] = 5;
+	/*
+	 * to accurately set the time, reset the divider chain and keep it in
+	 * reset state until all time/date registers are written
+	 */
+	rc = pcf85063_stop_clock(client, &regs[8]);
+	if (rc != 0)
+		return rc;
 
+	/* write start register */
+	regs[0] = PCF85063_REG_SC;
 	/* hours, minutes and seconds */
-	buf[PCF85063_REG_SC] = bin2bcd(tm->tm_sec) & 0x7F;
+	regs[1] = bin2bcd(tm->tm_sec) & 0x7F; /* clear OS flag */
 
-	buf[PCF85063_REG_MN] = bin2bcd(tm->tm_min);
-	buf[PCF85063_REG_HR] = bin2bcd(tm->tm_hour);
+	regs[2] = bin2bcd(tm->tm_min);
+	regs[3] = bin2bcd(tm->tm_hour);
 
 	/* Day of month, 1 - 31 */
-	buf[PCF85063_REG_DM] = bin2bcd(tm->tm_mday);
+	regs[4] = bin2bcd(tm->tm_mday);
 
 	/* Day, 0 - 6 */
-	buf[PCF85063_REG_DW] = tm->tm_wday & 0x07;
+	regs[5] = tm->tm_wday & 0x07;
 
 	/* month, 1 - 12 */
-	buf[PCF85063_REG_MO] = bin2bcd(tm->tm_mon + 1);
+	regs[6] = bin2bcd(tm->tm_mon + 1);
 
 	/* year and century */
-	buf[PCF85063_REG_YR] = bin2bcd(tm->tm_year % 100);
-
-	/* write register's data */
-	for (i = 0; i < sizeof(buf); i++) {
-		unsigned char data[2] = { i, buf[i] };
-
-		err = i2c_master_send(client, data, sizeof(data));
-		if (err != sizeof(data)) {
-			dev_err(&client->dev, "%s: err=%d addr=%02x, data=%02x\n",
-					__func__, err, data[0], data[1]);
-			return -EIO;
-		}
+	regs[7] = bin2bcd(tm->tm_year % 100);
+
+	/*
+	 * after all time/date registers are written, let the address auto
+	 * increment wrap around and write register CTRL1 to re-enable the
+	 * clock divider chain again
+	 */
+	regs[8] &= ~PCF85063_REG_CTRL1_STOP;
+
+	/* write all registers at once */
+	rc = i2c_master_send(client, regs, sizeof(regs));
+	if (rc != sizeof(regs)) {
+		dev_err(&client->dev, "date/time register write error\n");
+		return -EIO;
 	}
 
 	return 0;
-- 
2.6.2


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

* [rtc-linux] [PATCH 3/3] RTC/PCF85063: fix time/date setting
@ 2015-12-07 13:49   ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2015-12-07 13:49 UTC (permalink / raw)
  To: rtc-linux; +Cc: Alessandro Zummo, Alexandre Belloni, linux-kernel, kernel

When setting a new time/date the RTC's clock must be stopped first, in
order to write the time/date registers in an atomic manner.
So, this change stops the clock first and then writes the time/date
registers and the clock control register (to re-enable the clock) in one
turn.

Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
---
 drivers/rtc/rtc-pcf85063.c | 96 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 73 insertions(+), 23 deletions(-)

diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index abed934..0150e93 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -19,6 +19,7 @@
 #define DRV_VERSION "0.0.1"
 
 #define PCF85063_REG_CTRL1		0x00 /* status */
+#define PCF85063_REG_CTRL1_STOP		BIT(5)
 #define PCF85063_REG_CTRL2		0x01
 
 #define PCF85063_REG_SC			0x04 /* datetime */
@@ -72,6 +73,47 @@ static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
 	return 0;
 }
 
+static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1)
+{
+	int rc;
+	u8 clk_ctrl[2] = { PCF85063_REG_CTRL1, };
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.len = 1,
+			.buf = &clk_ctrl[0],
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = &clk_ctrl[1],
+		}, {
+			.addr = client->addr,
+			.len = sizeof(clk_ctrl),
+			.buf = &clk_ctrl[0],
+		},
+	};
+
+	rc = i2c_transfer(client->adapter, &msgs[0], 2);
+	if (rc != 2) {
+		dev_err(&client->dev, "Failing to stop the clock\n");
+		return -EIO;
+	}
+
+	/* stop the clock */
+	clk_ctrl[1] |= PCF85063_REG_CTRL1_STOP;
+
+	rc = i2c_transfer(client->adapter, &msgs[2], 1);
+	if (rc != 1) {
+		dev_err(&client->dev, "Failing to stop the clock\n");
+		return -EIO;
+	}
+
+	*ctrl1 = clk_ctrl[1];
+
+	return 0;
+}
+
 /*
  * In the routines that deal directly with the pcf85063 hardware, we use
  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -110,41 +152,49 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 
 static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
-	int i = 0, err = 0;
-	unsigned char buf[11];
+	int rc;
+	u8 regs[9];
 
-	/* Control & status */
-	buf[PCF85063_REG_CTRL1] = 0;
-	buf[PCF85063_REG_CTRL2] = 5;
+	/*
+	 * to accurately set the time, reset the divider chain and keep it in
+	 * reset state until all time/date registers are written
+	 */
+	rc = pcf85063_stop_clock(client, &regs[8]);
+	if (rc != 0)
+		return rc;
 
+	/* write start register */
+	regs[0] = PCF85063_REG_SC;
 	/* hours, minutes and seconds */
-	buf[PCF85063_REG_SC] = bin2bcd(tm->tm_sec) & 0x7F;
+	regs[1] = bin2bcd(tm->tm_sec) & 0x7F; /* clear OS flag */
 
-	buf[PCF85063_REG_MN] = bin2bcd(tm->tm_min);
-	buf[PCF85063_REG_HR] = bin2bcd(tm->tm_hour);
+	regs[2] = bin2bcd(tm->tm_min);
+	regs[3] = bin2bcd(tm->tm_hour);
 
 	/* Day of month, 1 - 31 */
-	buf[PCF85063_REG_DM] = bin2bcd(tm->tm_mday);
+	regs[4] = bin2bcd(tm->tm_mday);
 
 	/* Day, 0 - 6 */
-	buf[PCF85063_REG_DW] = tm->tm_wday & 0x07;
+	regs[5] = tm->tm_wday & 0x07;
 
 	/* month, 1 - 12 */
-	buf[PCF85063_REG_MO] = bin2bcd(tm->tm_mon + 1);
+	regs[6] = bin2bcd(tm->tm_mon + 1);
 
 	/* year and century */
-	buf[PCF85063_REG_YR] = bin2bcd(tm->tm_year % 100);
-
-	/* write register's data */
-	for (i = 0; i < sizeof(buf); i++) {
-		unsigned char data[2] = { i, buf[i] };
-
-		err = i2c_master_send(client, data, sizeof(data));
-		if (err != sizeof(data)) {
-			dev_err(&client->dev, "%s: err=%d addr=%02x, data=%02x\n",
-					__func__, err, data[0], data[1]);
-			return -EIO;
-		}
+	regs[7] = bin2bcd(tm->tm_year % 100);
+
+	/*
+	 * after all time/date registers are written, let the address auto
+	 * increment wrap around and write register CTRL1 to re-enable the
+	 * clock divider chain again
+	 */
+	regs[8] &= ~PCF85063_REG_CTRL1_STOP;
+
+	/* write all registers at once */
+	rc = i2c_master_send(client, regs, sizeof(regs));
+	if (rc != sizeof(regs)) {
+		dev_err(&client->dev, "date/time register write error\n");
+		return -EIO;
 	}
 
 	return 0;
-- 
2.6.2

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
  2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
@ 2015-12-20 11:35     ` Alexandre Belloni
  -1 siblings, 0 replies; 18+ messages in thread
From: Alexandre Belloni @ 2015-12-20 11:35 UTC (permalink / raw)
  To: Juergen Borleis; +Cc: rtc-linux, Alessandro Zummo, linux-kernel, kernel

Hi,

On 07/12/2015 at 14:49:33 +0100, Juergen Borleis wrote :
> Use the function to read the whole time/date register in one turn and now
> check if the RTC signals an invalid time/date (due to a battery power loss
> for example). In this case ignore the time/date until it is really set
> again.
> 
> Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
> ---
>  drivers/rtc/rtc-pcf85063.c | 45 +++++++++++++++++++--------------------------
>  1 file changed, 19 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
> index 75f2866..abed934 100644
> --- a/drivers/rtc/rtc-pcf85063.c
> +++ b/drivers/rtc/rtc-pcf85063.c
> @@ -22,6 +22,7 @@
>  #define PCF85063_REG_CTRL2		0x01
>  
>  #define PCF85063_REG_SC			0x04 /* datetime */
> +#define PCF85063_REG_SC_OS		0x80
>  #define PCF85063_REG_MN			0x05
>  #define PCF85063_REG_HR			0x06
>  #define PCF85063_REG_DM			0x07
> @@ -77,39 +78,31 @@ static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
>   */
>  static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
>  {
> +	int rc;
>  	struct pcf85063 *pcf85063 = i2c_get_clientdata(client);
> -	unsigned char buf[13] = { PCF85063_REG_CTRL1 };
> -	struct i2c_msg msgs[] = {
> -		{/* setup read ptr */
> -			.addr = client->addr,
> -			.len = 1,
> -			.buf = buf
> -		},
> -		{/* read status + date */
> -			.addr = client->addr,
> -			.flags = I2C_M_RD,
> -			.len = 13,
> -			.buf = buf
> -		},
> -	};
> +	u8 regs[7];
>  
> -	/* read registers */
> -	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
> -		dev_err(&client->dev, "%s: read error\n", __func__);
> -		return -EIO;

Isn't that already reading the time and date register in one block? I'd
say you are simply reading less registers. Also, maybe you could use
i2c_smbus_read_block_data?


> +	rc = pcf85063_read_time(client, regs, sizeof(regs));
> +	if (rc < 0)
> +		return rc;
> +
> +	/* if the clock has lost its power it makes no sense to use its time */
> +	if (regs[0] & PCF85063_REG_SC_OS) {
> +		dev_warn(&client->dev, "Power loss detected, invalid time\n");
> +		return -EINVAL;
>  	}

That part is more useful and as I understand it is what you are trying
to fix.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [rtc-linux] Re: [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
@ 2015-12-20 11:35     ` Alexandre Belloni
  0 siblings, 0 replies; 18+ messages in thread
From: Alexandre Belloni @ 2015-12-20 11:35 UTC (permalink / raw)
  To: Juergen Borleis; +Cc: rtc-linux, Alessandro Zummo, linux-kernel, kernel

Hi,

On 07/12/2015 at 14:49:33 +0100, Juergen Borleis wrote :
> Use the function to read the whole time/date register in one turn and now
> check if the RTC signals an invalid time/date (due to a battery power loss
> for example). In this case ignore the time/date until it is really set
> again.
> 
> Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
> ---
>  drivers/rtc/rtc-pcf85063.c | 45 +++++++++++++++++++--------------------------
>  1 file changed, 19 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
> index 75f2866..abed934 100644
> --- a/drivers/rtc/rtc-pcf85063.c
> +++ b/drivers/rtc/rtc-pcf85063.c
> @@ -22,6 +22,7 @@
>  #define PCF85063_REG_CTRL2		0x01
>  
>  #define PCF85063_REG_SC			0x04 /* datetime */
> +#define PCF85063_REG_SC_OS		0x80
>  #define PCF85063_REG_MN			0x05
>  #define PCF85063_REG_HR			0x06
>  #define PCF85063_REG_DM			0x07
> @@ -77,39 +78,31 @@ static int pcf85063_read_time(struct i2c_client *client, u8 *buf, u16 size)
>   */
>  static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm)
>  {
> +	int rc;
>  	struct pcf85063 *pcf85063 = i2c_get_clientdata(client);
> -	unsigned char buf[13] = { PCF85063_REG_CTRL1 };
> -	struct i2c_msg msgs[] = {
> -		{/* setup read ptr */
> -			.addr = client->addr,
> -			.len = 1,
> -			.buf = buf
> -		},
> -		{/* read status + date */
> -			.addr = client->addr,
> -			.flags = I2C_M_RD,
> -			.len = 13,
> -			.buf = buf
> -		},
> -	};
> +	u8 regs[7];
>  
> -	/* read registers */
> -	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
> -		dev_err(&client->dev, "%s: read error\n", __func__);
> -		return -EIO;

Isn't that already reading the time and date register in one block? I'd
say you are simply reading less registers. Also, maybe you could use
i2c_smbus_read_block_data?


> +	rc = pcf85063_read_time(client, regs, sizeof(regs));
> +	if (rc < 0)
> +		return rc;
> +
> +	/* if the clock has lost its power it makes no sense to use its time */
> +	if (regs[0] & PCF85063_REG_SC_OS) {
> +		dev_warn(&client->dev, "Power loss detected, invalid time\n");
> +		return -EINVAL;
>  	}

That part is more useful and as I understand it is what you are trying
to fix.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 3/3] RTC/PCF85063: fix time/date setting
  2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
@ 2015-12-20 11:46     ` Alexandre Belloni
  -1 siblings, 0 replies; 18+ messages in thread
From: Alexandre Belloni @ 2015-12-20 11:46 UTC (permalink / raw)
  To: Juergen Borleis; +Cc: rtc-linux, Alessandro Zummo, linux-kernel, kernel

On 07/12/2015 at 14:49:34 +0100, Juergen Borleis wrote :
> When setting a new time/date the RTC's clock must be stopped first, in
> order to write the time/date registers in an atomic manner.
> So, this change stops the clock first and then writes the time/date
> registers and the clock control register (to re-enable the clock) in one
> turn.
> 

I'd have the same comment for that patch. Using
i2c_smbus_write_byte_data and i2c_smbus_write_block_data would make the
code clearer and also more robust because it takes care of
retransmissions for example.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [rtc-linux] Re: [PATCH 3/3] RTC/PCF85063: fix time/date setting
@ 2015-12-20 11:46     ` Alexandre Belloni
  0 siblings, 0 replies; 18+ messages in thread
From: Alexandre Belloni @ 2015-12-20 11:46 UTC (permalink / raw)
  To: Juergen Borleis; +Cc: rtc-linux, Alessandro Zummo, linux-kernel, kernel

On 07/12/2015 at 14:49:34 +0100, Juergen Borleis wrote :
> When setting a new time/date the RTC's clock must be stopped first, in
> order to write the time/date registers in an atomic manner.
> So, this change stops the clock first and then writes the time/date
> registers and the clock control register (to re-enable the clock) in one
> turn.
> 

I'd have the same comment for that patch. Using
i2c_smbus_write_byte_data and i2c_smbus_write_block_data would make the
code clearer and also more robust because it takes care of
retransmissions for example.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
  2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
@ 2016-01-07 10:12     ` Juergen Borleis
  -1 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2016-01-07 10:12 UTC (permalink / raw)
  To: kernel; +Cc: rtc-linux, Alessandro Zummo, Alexandre Belloni, linux-kernel

Hi Alexandre,

(please keep me on CC...)

> [...]
> > -	/* read registers */
> > -	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
> > -		dev_err(&client->dev, "%s: read error\n", __func__);
> > -		return -EIO;
>
> Isn't that already reading the time and date register in one block? I'd
> say you are simply reading less registers. Also, maybe you could use
> i2c_smbus_read_block_data?

Its just a "try" to make the code more readable, by a named subfunction and 
more comments why things must happen that way.
Will check for the suggested smbus function.

Regards,
Juergen

-- 
Pengutronix e.K.                              | Juergen Borleis             |
Industrial Linux Solutions                    | http://www.pengutronix.de/  |

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

* [rtc-linux] Re: [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
@ 2016-01-07 10:12     ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2016-01-07 10:12 UTC (permalink / raw)
  To: kernel; +Cc: rtc-linux, Alessandro Zummo, Alexandre Belloni, linux-kernel

Hi Alexandre,

(please keep me on CC...)

> [...]
> > -	/* read registers */
> > -	if ((i2c_transfer(client->adapter, msgs, 2)) !=3D 2) {
> > -		dev_err(&client->dev, "%s: read error\n", __func__);
> > -		return -EIO;
>
> Isn't that already reading the time and date register in one block? I'd
> say you are simply reading less registers. Also, maybe you could use
> i2c_smbus_read_block_data?

Its just a "try" to make the code more readable, by a named subfunction and=
=20
more comments why things must happen that way.
Will check for the suggested smbus function.

Regards,
Juergen

=2D-=20
Pengutronix e.K. =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0| Juergen Borleis =A0 =A0 =A0 =A0 =A0 =A0 |
Industrial Linux Solutions =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| http://=
www.pengutronix.de/ =A0|

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

* Re: [PATCH 3/3] RTC/PCF85063: fix time/date setting
  2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
@ 2016-01-07 10:13     ` Juergen Borleis
  -1 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2016-01-07 10:13 UTC (permalink / raw)
  To: kernel; +Cc: rtc-linux, Alessandro Zummo, Alexandre Belloni, linux-kernel

Hi Alexandre,

sorry, missed your comment. Please keep me on CC since I'm not subscribed to 
the list.

> > When setting a new time/date the RTC's clock must be stopped first, in
> > order to write the time/date registers in an atomic manner.
> > So, this change stops the clock first and then writes the time/date
> > registers and the clock control register (to re-enable the clock) in one
> > turn.
>
> I'd have the same comment for that patch. Using
> i2c_smbus_write_byte_data and i2c_smbus_write_block_data would make the
> code clearer and also more robust because it takes care of
> retransmissions for example.

Okay. Will have a look.

Regards,
Juergen

-- 
Pengutronix e.K.                              | Juergen Borleis             |
Industrial Linux Solutions                    | http://www.pengutronix.de/  |

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

* [rtc-linux] Re: [PATCH 3/3] RTC/PCF85063: fix time/date setting
@ 2016-01-07 10:13     ` Juergen Borleis
  0 siblings, 0 replies; 18+ messages in thread
From: Juergen Borleis @ 2016-01-07 10:13 UTC (permalink / raw)
  To: kernel; +Cc: rtc-linux, Alessandro Zummo, Alexandre Belloni, linux-kernel

Hi Alexandre,

sorry, missed your comment. Please keep me on CC since I'm not subscribed t=
o=20
the list.

> > When setting a new time/date the RTC's clock must be stopped first, in
> > order to write the time/date registers in an atomic manner.
> > So, this change stops the clock first and then writes the time/date
> > registers and the clock control register (to re-enable the clock) in one
> > turn.
>
> I'd have the same comment for that patch. Using
> i2c_smbus_write_byte_data and i2c_smbus_write_block_data would make the
> code clearer and also more robust because it takes care of
> retransmissions for example.

Okay. Will have a look.

Regards,
Juergen

=2D-=20
Pengutronix e.K. =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0| Juergen Borleis =A0 =A0 =A0 =A0 =A0 =A0 |
Industrial Linux Solutions =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| http://=
www.pengutronix.de/ =A0|

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

* Re: [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
  2016-01-07 10:12     ` [rtc-linux] " Juergen Borleis
@ 2016-01-21  0:04       ` Alexandre Belloni
  -1 siblings, 0 replies; 18+ messages in thread
From: Alexandre Belloni @ 2016-01-21  0:04 UTC (permalink / raw)
  To: Juergen Borleis
  Cc: kernel, rtc-linux, Alessandro Zummo, linux-kernel, Juergen Borleis

Hi Jurgen,

On 07/01/2016 at 11:12:52 +0100, Juergen Borleis wrote :
> Hi Alexandre,
> 
> (please keep me on CC...)
> 

I've just checked again and now I'm pretty sure you were in To:. Should
I also add you in Cc? Maybe you should check your filters ;)


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [rtc-linux] Re: [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II)
@ 2016-01-21  0:04       ` Alexandre Belloni
  0 siblings, 0 replies; 18+ messages in thread
From: Alexandre Belloni @ 2016-01-21  0:04 UTC (permalink / raw)
  To: Juergen Borleis
  Cc: kernel, rtc-linux, Alessandro Zummo, linux-kernel, Juergen Borleis

Hi Jurgen,

On 07/01/2016 at 11:12:52 +0100, Juergen Borleis wrote :
> Hi Alexandre,
> 
> (please keep me on CC...)
> 

I've just checked again and now I'm pretty sure you were in To:. Should
I also add you in Cc? Maybe you should check your filters ;)


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

end of thread, other threads:[~2016-01-21  0:04 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-07 13:49 [PATCH] RTC/PCF85063: fix reading/setting time/date Juergen Borleis
2015-12-07 13:49 ` [rtc-linux] " Juergen Borleis
2015-12-07 13:49 ` [PATCH 1/3] RTC/PCF85063: fix time/date reading (part 1) Juergen Borleis
2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
2015-12-07 13:49 ` [PATCH 2/3] RTC/PCF85063: fix time/date reading (part II) Juergen Borleis
2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
2015-12-20 11:35   ` Alexandre Belloni
2015-12-20 11:35     ` [rtc-linux] " Alexandre Belloni
2016-01-07 10:12   ` Juergen Borleis
2016-01-07 10:12     ` [rtc-linux] " Juergen Borleis
2016-01-21  0:04     ` Alexandre Belloni
2016-01-21  0:04       ` [rtc-linux] " Alexandre Belloni
2015-12-07 13:49 ` [PATCH 3/3] RTC/PCF85063: fix time/date setting Juergen Borleis
2015-12-07 13:49   ` [rtc-linux] " Juergen Borleis
2015-12-20 11:46   ` Alexandre Belloni
2015-12-20 11:46     ` [rtc-linux] " Alexandre Belloni
2016-01-07 10:13   ` Juergen Borleis
2016-01-07 10:13     ` [rtc-linux] " Juergen Borleis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.