[rtc-linux] [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

10 messages, 4 authors, 2017-02-12 · open the first message on its own page

[rtc-linux] [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: H Hartley Sweeten <hsweeten@visionengravers.com>
Date: 2017-02-10 18:12:36

This rtc driver is currently only used by the Technologic Systems TS-72xx
(arm/mach-ep93xx) and TS-78xx (arm/mach-orion5x) SBCs. These platforms use
static I/O mappings for the registers needed to access the index and data
registers of the chip.

On the TS-78xx there is one I/O mapping of SZ_1M for the entire FPGA address
space. The rtc index and data registers are located in that space along with
all the other FPGA devices.

On the TS-72xx the mapping is a bit uglier. That platform uses a CPLD to
access the rtc. The CPLD is connected to two chip select lines of the
processor and each chip select addresses 256 MiB. Address lines 25-22 and 0
are then decoded for the various devices. Since mapping the entire 256 MiB
for each address space would be _really_ ugly, a SZ_4K mapping is done for
each register that is needed.

This series does the following:
 1) Cleanup this driver to remove all the checkpatch.pl issues.
 2) Modify the probe to, optionally, ioremap the resources provided by the
    platform and handle the read/write operations internally.
 3) Add support for the NVRAM in the rtc.

With these changes the static I/O mappings for the rtc registers can be
removed from the ts-72xx platform.

Currently the ts78xx platform does some "probing" of the rtc NVRAM to see
if it is actually present before registering the rtc device. This "probing"
just checks if the NVRAM is present by reading/writing the last two bytes
of the NVRAM. I'm not sure if this is really necessary. If it can be removed
all the m48t86_ops stuff could also be removed from this driver, along with
platform_data/rtc-m48t86.h.

H Hartley Sweeten (3):
  rtc: m48t86: shorten register name defines
  rtc: m48t86: allow driver to manage it's resources
  rtc: m48t86: add NVRAM support

 drivers/rtc/rtc-m48t86.c | 247 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 169 insertions(+), 78 deletions(-)

-- 
2.10.0

-- 
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.

[rtc-linux] [PATCH 1/3] rtc: m48t86: shorten register name defines

From: H Hartley Sweeten <hsweeten@visionengravers.com>
Date: 2017-02-10 18:12:36

For asthetics. shorten all the register names by removing '_REG' from all of them.
This helps fix all the checkpatch.pl issues.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Alessandro Zummo <redacted>
Cc: Alexandre Belloni <redacted>
Cc: Alexander Clouter <alex@digriz.org.uk>
---
 drivers/rtc/rtc-m48t86.c | 127 +++++++++++++++++++++++------------------------
 1 file changed, 63 insertions(+), 64 deletions(-)
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 0eeb571..30648ea 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -19,25 +19,24 @@
 #include <linux/platform_data/rtc-m48t86.h>
 #include <linux/bcd.h>
 
-#define M48T86_REG_SEC		0x00
-#define M48T86_REG_SECALRM	0x01
-#define M48T86_REG_MIN		0x02
-#define M48T86_REG_MINALRM	0x03
-#define M48T86_REG_HOUR		0x04
-#define M48T86_REG_HOURALRM	0x05
-#define M48T86_REG_DOW		0x06 /* 1 = sunday */
-#define M48T86_REG_DOM		0x07
-#define M48T86_REG_MONTH	0x08 /* 1 - 12 */
-#define M48T86_REG_YEAR		0x09 /* 0 - 99 */
-#define M48T86_REG_A		0x0A
-#define M48T86_REG_B		0x0B
-#define M48T86_REG_C		0x0C
-#define M48T86_REG_D		0x0D
-
-#define M48T86_REG_B_H24	(1 << 1)
-#define M48T86_REG_B_DM		(1 << 2)
-#define M48T86_REG_B_SET	(1 << 7)
-#define M48T86_REG_D_VRT	(1 << 7)
+#define M48T86_SEC		0x00
+#define M48T86_SECALRM		0x01
+#define M48T86_MIN		0x02
+#define M48T86_MINALRM		0x03
+#define M48T86_HOUR		0x04
+#define M48T86_HOURALRM		0x05
+#define M48T86_DOW		0x06 /* 1 = sunday */
+#define M48T86_DOM		0x07
+#define M48T86_MONTH		0x08 /* 1 - 12 */
+#define M48T86_YEAR		0x09 /* 0 - 99 */
+#define M48T86_A		0x0a
+#define M48T86_B		0x0b
+#define M48T86_B_SET		BIT(7)
+#define M48T86_B_DM		BIT(2)
+#define M48T86_B_H24		BIT(1)
+#define M48T86_C		0x0c
+#define M48T86_D		0x0d
+#define M48T86_D_VRT		BIT(7)
 
 static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
@@ -45,33 +44,33 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct m48t86_ops *ops = dev_get_platdata(&pdev->dev);
 
-	reg = ops->readbyte(M48T86_REG_B);
+	reg = ops->readbyte(M48T86_B);
 
-	if (reg & M48T86_REG_B_DM) {
+	if (reg & M48T86_B_DM) {
 		/* data (binary) mode */
-		tm->tm_sec	= ops->readbyte(M48T86_REG_SEC);
-		tm->tm_min	= ops->readbyte(M48T86_REG_MIN);
-		tm->tm_hour	= ops->readbyte(M48T86_REG_HOUR) & 0x3F;
-		tm->tm_mday	= ops->readbyte(M48T86_REG_DOM);
+		tm->tm_sec	= ops->readbyte(M48T86_SEC);
+		tm->tm_min	= ops->readbyte(M48T86_MIN);
+		tm->tm_hour	= ops->readbyte(M48T86_HOUR) & 0x3f;
+		tm->tm_mday	= ops->readbyte(M48T86_DOM);
 		/* tm_mon is 0-11 */
-		tm->tm_mon	= ops->readbyte(M48T86_REG_MONTH) - 1;
-		tm->tm_year	= ops->readbyte(M48T86_REG_YEAR) + 100;
-		tm->tm_wday	= ops->readbyte(M48T86_REG_DOW);
+		tm->tm_mon	= ops->readbyte(M48T86_MONTH) - 1;
+		tm->tm_year	= ops->readbyte(M48T86_YEAR) + 100;
+		tm->tm_wday	= ops->readbyte(M48T86_DOW);
 	} else {
 		/* bcd mode */
-		tm->tm_sec	= bcd2bin(ops->readbyte(M48T86_REG_SEC));
-		tm->tm_min	= bcd2bin(ops->readbyte(M48T86_REG_MIN));
-		tm->tm_hour	= bcd2bin(ops->readbyte(M48T86_REG_HOUR) & 0x3F);
-		tm->tm_mday	= bcd2bin(ops->readbyte(M48T86_REG_DOM));
+		tm->tm_sec	= bcd2bin(ops->readbyte(M48T86_SEC));
+		tm->tm_min	= bcd2bin(ops->readbyte(M48T86_MIN));
+		tm->tm_hour	= bcd2bin(ops->readbyte(M48T86_HOUR) & 0x3f);
+		tm->tm_mday	= bcd2bin(ops->readbyte(M48T86_DOM));
 		/* tm_mon is 0-11 */
-		tm->tm_mon	= bcd2bin(ops->readbyte(M48T86_REG_MONTH)) - 1;
-		tm->tm_year	= bcd2bin(ops->readbyte(M48T86_REG_YEAR)) + 100;
-		tm->tm_wday	= bcd2bin(ops->readbyte(M48T86_REG_DOW));
+		tm->tm_mon	= bcd2bin(ops->readbyte(M48T86_MONTH)) - 1;
+		tm->tm_year	= bcd2bin(ops->readbyte(M48T86_YEAR)) + 100;
+		tm->tm_wday	= bcd2bin(ops->readbyte(M48T86_DOW));
 	}
 
 	/* correct the hour if the clock is in 12h mode */
-	if (!(reg & M48T86_REG_B_H24))
-		if (ops->readbyte(M48T86_REG_HOUR) & 0x80)
+	if (!(reg & M48T86_B_H24))
+		if (ops->readbyte(M48T86_HOUR) & 0x80)
 			tm->tm_hour += 12;
 
 	return rtc_valid_tm(tm);
@@ -83,35 +82,35 @@ static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct m48t86_ops *ops = dev_get_platdata(&pdev->dev);
 
-	reg = ops->readbyte(M48T86_REG_B);
+	reg = ops->readbyte(M48T86_B);
 
 	/* update flag and 24h mode */
-	reg |= M48T86_REG_B_SET | M48T86_REG_B_H24;
-	ops->writebyte(reg, M48T86_REG_B);
+	reg |= M48T86_B_SET | M48T86_B_H24;
+	ops->writebyte(reg, M48T86_B);
 
-	if (reg & M48T86_REG_B_DM) {
+	if (reg & M48T86_B_DM) {
 		/* data (binary) mode */
-		ops->writebyte(tm->tm_sec, M48T86_REG_SEC);
-		ops->writebyte(tm->tm_min, M48T86_REG_MIN);
-		ops->writebyte(tm->tm_hour, M48T86_REG_HOUR);
-		ops->writebyte(tm->tm_mday, M48T86_REG_DOM);
-		ops->writebyte(tm->tm_mon + 1, M48T86_REG_MONTH);
-		ops->writebyte(tm->tm_year % 100, M48T86_REG_YEAR);
-		ops->writebyte(tm->tm_wday, M48T86_REG_DOW);
+		ops->writebyte(tm->tm_sec, M48T86_SEC);
+		ops->writebyte(tm->tm_min, M48T86_MIN);
+		ops->writebyte(tm->tm_hour, M48T86_HOUR);
+		ops->writebyte(tm->tm_mday, M48T86_DOM);
+		ops->writebyte(tm->tm_mon + 1, M48T86_MONTH);
+		ops->writebyte(tm->tm_year % 100, M48T86_YEAR);
+		ops->writebyte(tm->tm_wday, M48T86_DOW);
 	} else {
 		/* bcd mode */
-		ops->writebyte(bin2bcd(tm->tm_sec), M48T86_REG_SEC);
-		ops->writebyte(bin2bcd(tm->tm_min), M48T86_REG_MIN);
-		ops->writebyte(bin2bcd(tm->tm_hour), M48T86_REG_HOUR);
-		ops->writebyte(bin2bcd(tm->tm_mday), M48T86_REG_DOM);
-		ops->writebyte(bin2bcd(tm->tm_mon + 1), M48T86_REG_MONTH);
-		ops->writebyte(bin2bcd(tm->tm_year % 100), M48T86_REG_YEAR);
-		ops->writebyte(bin2bcd(tm->tm_wday), M48T86_REG_DOW);
+		ops->writebyte(bin2bcd(tm->tm_sec), M48T86_SEC);
+		ops->writebyte(bin2bcd(tm->tm_min), M48T86_MIN);
+		ops->writebyte(bin2bcd(tm->tm_hour), M48T86_HOUR);
+		ops->writebyte(bin2bcd(tm->tm_mday), M48T86_DOM);
+		ops->writebyte(bin2bcd(tm->tm_mon + 1), M48T86_MONTH);
+		ops->writebyte(bin2bcd(tm->tm_year % 100), M48T86_YEAR);
+		ops->writebyte(bin2bcd(tm->tm_wday), M48T86_DOW);
 	}
 
 	/* update ended */
-	reg &= ~M48T86_REG_B_SET;
-	ops->writebyte(reg, M48T86_REG_B);
+	reg &= ~M48T86_B_SET;
+	ops->writebyte(reg, M48T86_B);
 
 	return 0;
 }
@@ -122,15 +121,15 @@ static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct m48t86_ops *ops = dev_get_platdata(&pdev->dev);
 
-	reg = ops->readbyte(M48T86_REG_B);
+	reg = ops->readbyte(M48T86_B);
 
 	seq_printf(seq, "mode\t\t: %s\n",
-		 (reg & M48T86_REG_B_DM) ? "binary" : "bcd");
+		   (reg & M48T86_B_DM) ? "binary" : "bcd");
 
-	reg = ops->readbyte(M48T86_REG_D);
+	reg = ops->readbyte(M48T86_D);
 
 	seq_printf(seq, "battery\t\t: %s\n",
-		 (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted");
+		   (reg & M48T86_D_VRT) ? "ok" : "exhausted");
 
 	return 0;
 }
@@ -148,7 +147,7 @@ static int m48t86_rtc_probe(struct platform_device *dev)
 	struct rtc_device *rtc;
 
 	rtc = devm_rtc_device_register(&dev->dev, "m48t86",
-				&m48t86_rtc_ops, THIS_MODULE);
+				       &m48t86_rtc_ops, THIS_MODULE);
 
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
@@ -156,9 +155,9 @@ static int m48t86_rtc_probe(struct platform_device *dev)
 	platform_set_drvdata(dev, rtc);
 
 	/* read battery status */
-	reg = ops->readbyte(M48T86_REG_D);
+	reg = ops->readbyte(M48T86_D);
 	dev_info(&dev->dev, "battery %s\n",
-		(reg & M48T86_REG_D_VRT) ? "ok" : "exhausted");
+		 (reg & M48T86_D_VRT) ? "ok" : "exhausted");
 
 	return 0;
 }
-- 
2.10.0

-- 
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.

[rtc-linux] [PATCH 3/3] rtc: m48t86: add NVRAM support

From: H Hartley Sweeten <hsweeten@visionengravers.com>
Date: 2017-02-10 18:12:36

This RTC has 114 bytes of NVRAM. Provide access to it via a biniary
sysfs 'nvram' attribute file.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Alessandro Zummo <redacted>
Cc: Alexandre Belloni <redacted>
Cc: Alexander Clouter <alex@digriz.org.uk>
---
 drivers/rtc/rtc-m48t86.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 4dcdbd2..4dc4af4 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -38,6 +38,8 @@
 #define M48T86_C		0x0c
 #define M48T86_D		0x0d
 #define M48T86_D_VRT		BIT(7)
+#define M48T86_NVRAM(x)		(0x0e + (x))
+#define M48T86_NVRAM_LEN	114
 
 struct m48t86_rtc_info {
 	void __iomem *index_reg;
@@ -170,6 +172,35 @@ static const struct rtc_class_ops m48t86_rtc_ops = {
 	.proc		= m48t86_rtc_proc,
 };
 
+static ssize_t m48t86_nvram_read(struct file *filp, struct kobject *kobj,
+				 struct bin_attribute *attr,
+				 char *buf, loff_t off, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	unsigned int i;
+
+	for (i = 0; i < count; i++)
+		buf[i] = m48t86_readb(dev, M48T86_NVRAM(off + i));
+
+	return count;
+}
+
+static ssize_t m48t86_nvram_write(struct file *filp, struct kobject *kobj,
+				  struct bin_attribute *attr,
+				  char *buf, loff_t off, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	unsigned int i;
+
+	for (i = 0; i < count; i++)
+		m48t86_writeb(dev, buf[i], M48T86_NVRAM(off + i));
+
+	return count;
+}
+
+static BIN_ATTR(nvram, 0644, m48t86_nvram_read, m48t86_nvram_write,
+		M48T86_NVRAM_LEN);
+
 static int m48t86_rtc_probe(struct platform_device *pdev)
 {
 	struct m48t86_rtc_info *info;
@@ -210,6 +241,15 @@ static int m48t86_rtc_probe(struct platform_device *pdev)
 	dev_info(&pdev->dev, "battery %s\n",
 		 (reg & M48T86_D_VRT) ? "ok" : "exhausted");
 
+	if (device_create_bin_file(&pdev->dev, &bin_attr_nvram))
+		dev_err(&pdev->dev, "failed to create nvram sysfs entry\n");
+
+	return 0;
+}
+
+static int m48t86_rtc_remove(struct platform_device *pdev)
+{
+	device_remove_bin_file(&pdev->dev, &bin_attr_nvram);
 	return 0;
 }
 
@@ -218,6 +258,7 @@ static struct platform_driver m48t86_rtc_platform_driver = {
 		.name	= "rtc-m48t86",
 	},
 	.probe		= m48t86_rtc_probe,
+	.remove		= m48t86_rtc_remove,
 };
 
 module_platform_driver(m48t86_rtc_platform_driver);
-- 
2.10.0

-- 
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.

[rtc-linux] [PATCH 2/3] rtc: m48t86: allow driver to manage it's resources

From: H Hartley Sweeten <hsweeten@visionengravers.com>
Date: 2017-02-10 18:12:36

Allow this driver to, optionally, manage it's own resources and do the
read/write operations if the platform does not provide them.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Alessandro Zummo <redacted>
Cc: Alexandre Belloni <redacted>
Cc: Alexander Clouter <alex@digriz.org.uk>
---
 drivers/rtc/rtc-m48t86.c | 153 +++++++++++++++++++++++++++++++----------------
 1 file changed, 102 insertions(+), 51 deletions(-)
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 30648ea..4dcdbd2 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_data/rtc-m48t86.h>
 #include <linux/bcd.h>
+#include <linux/io.h>
 
 #define M48T86_SEC		0x00
 #define M48T86_SECALRM		0x01
@@ -38,39 +39,72 @@
 #define M48T86_D		0x0d
 #define M48T86_D_VRT		BIT(7)
 
+struct m48t86_rtc_info {
+	void __iomem *index_reg;
+	void __iomem *data_reg;
+	struct rtc_device *rtc;
+	struct m48t86_ops *ops;
+};
+
+static unsigned char m48t86_readb(struct device *dev, unsigned long addr)
+{
+	struct m48t86_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char value;
+
+	if (info->ops) {
+		value = info->ops->readbyte(addr);
+	} else {
+		writeb(addr, info->index_reg);
+		value = readb(info->data_reg);
+	}
+	return value;
+}
+
+static void m48t86_writeb(struct device *dev,
+			  unsigned char value, unsigned long addr)
+{
+	struct m48t86_rtc_info *info = dev_get_drvdata(dev);
+
+	if (info->ops) {
+		info->ops->writebyte(value, addr);
+	} else {
+		writeb(addr, info->index_reg);
+		writeb(value, info->data_reg);
+	}
+}
+
 static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	unsigned char reg;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct m48t86_ops *ops = dev_get_platdata(&pdev->dev);
 
-	reg = ops->readbyte(M48T86_B);
+	reg = m48t86_readb(dev, M48T86_B);
 
 	if (reg & M48T86_B_DM) {
 		/* data (binary) mode */
-		tm->tm_sec	= ops->readbyte(M48T86_SEC);
-		tm->tm_min	= ops->readbyte(M48T86_MIN);
-		tm->tm_hour	= ops->readbyte(M48T86_HOUR) & 0x3f;
-		tm->tm_mday	= ops->readbyte(M48T86_DOM);
+		tm->tm_sec	= m48t86_readb(dev, M48T86_SEC);
+		tm->tm_min	= m48t86_readb(dev, M48T86_MIN);
+		tm->tm_hour	= m48t86_readb(dev, M48T86_HOUR) & 0x3f;
+		tm->tm_mday	= m48t86_readb(dev, M48T86_DOM);
 		/* tm_mon is 0-11 */
-		tm->tm_mon	= ops->readbyte(M48T86_MONTH) - 1;
-		tm->tm_year	= ops->readbyte(M48T86_YEAR) + 100;
-		tm->tm_wday	= ops->readbyte(M48T86_DOW);
+		tm->tm_mon	= m48t86_readb(dev, M48T86_MONTH) - 1;
+		tm->tm_year	= m48t86_readb(dev, M48T86_YEAR) + 100;
+		tm->tm_wday	= m48t86_readb(dev, M48T86_DOW);
 	} else {
 		/* bcd mode */
-		tm->tm_sec	= bcd2bin(ops->readbyte(M48T86_SEC));
-		tm->tm_min	= bcd2bin(ops->readbyte(M48T86_MIN));
-		tm->tm_hour	= bcd2bin(ops->readbyte(M48T86_HOUR) & 0x3f);
-		tm->tm_mday	= bcd2bin(ops->readbyte(M48T86_DOM));
+		tm->tm_sec	= bcd2bin(m48t86_readb(dev, M48T86_SEC));
+		tm->tm_min	= bcd2bin(m48t86_readb(dev, M48T86_MIN));
+		tm->tm_hour	= bcd2bin(m48t86_readb(dev, M48T86_HOUR) &
+					  0x3f);
+		tm->tm_mday	= bcd2bin(m48t86_readb(dev, M48T86_DOM));
 		/* tm_mon is 0-11 */
-		tm->tm_mon	= bcd2bin(ops->readbyte(M48T86_MONTH)) - 1;
-		tm->tm_year	= bcd2bin(ops->readbyte(M48T86_YEAR)) + 100;
-		tm->tm_wday	= bcd2bin(ops->readbyte(M48T86_DOW));
+		tm->tm_mon	= bcd2bin(m48t86_readb(dev, M48T86_MONTH)) - 1;
+		tm->tm_year	= bcd2bin(m48t86_readb(dev, M48T86_YEAR)) + 100;
+		tm->tm_wday	= bcd2bin(m48t86_readb(dev, M48T86_DOW));
 	}
 
 	/* correct the hour if the clock is in 12h mode */
 	if (!(reg & M48T86_B_H24))
-		if (ops->readbyte(M48T86_HOUR) & 0x80)
+		if (m48t86_readb(dev, M48T86_HOUR) & 0x80)
 			tm->tm_hour += 12;
 
 	return rtc_valid_tm(tm);
@@ -79,38 +113,36 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	unsigned char reg;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct m48t86_ops *ops = dev_get_platdata(&pdev->dev);
 
-	reg = ops->readbyte(M48T86_B);
+	reg = m48t86_readb(dev, M48T86_B);
 
 	/* update flag and 24h mode */
 	reg |= M48T86_B_SET | M48T86_B_H24;
-	ops->writebyte(reg, M48T86_B);
+	m48t86_writeb(dev, reg, M48T86_B);
 
 	if (reg & M48T86_B_DM) {
 		/* data (binary) mode */
-		ops->writebyte(tm->tm_sec, M48T86_SEC);
-		ops->writebyte(tm->tm_min, M48T86_MIN);
-		ops->writebyte(tm->tm_hour, M48T86_HOUR);
-		ops->writebyte(tm->tm_mday, M48T86_DOM);
-		ops->writebyte(tm->tm_mon + 1, M48T86_MONTH);
-		ops->writebyte(tm->tm_year % 100, M48T86_YEAR);
-		ops->writebyte(tm->tm_wday, M48T86_DOW);
+		m48t86_writeb(dev, tm->tm_sec, M48T86_SEC);
+		m48t86_writeb(dev, tm->tm_min, M48T86_MIN);
+		m48t86_writeb(dev, tm->tm_hour, M48T86_HOUR);
+		m48t86_writeb(dev, tm->tm_mday, M48T86_DOM);
+		m48t86_writeb(dev, tm->tm_mon + 1, M48T86_MONTH);
+		m48t86_writeb(dev, tm->tm_year % 100, M48T86_YEAR);
+		m48t86_writeb(dev, tm->tm_wday, M48T86_DOW);
 	} else {
 		/* bcd mode */
-		ops->writebyte(bin2bcd(tm->tm_sec), M48T86_SEC);
-		ops->writebyte(bin2bcd(tm->tm_min), M48T86_MIN);
-		ops->writebyte(bin2bcd(tm->tm_hour), M48T86_HOUR);
-		ops->writebyte(bin2bcd(tm->tm_mday), M48T86_DOM);
-		ops->writebyte(bin2bcd(tm->tm_mon + 1), M48T86_MONTH);
-		ops->writebyte(bin2bcd(tm->tm_year % 100), M48T86_YEAR);
-		ops->writebyte(bin2bcd(tm->tm_wday), M48T86_DOW);
+		m48t86_writeb(dev, bin2bcd(tm->tm_sec), M48T86_SEC);
+		m48t86_writeb(dev, bin2bcd(tm->tm_min), M48T86_MIN);
+		m48t86_writeb(dev, bin2bcd(tm->tm_hour), M48T86_HOUR);
+		m48t86_writeb(dev, bin2bcd(tm->tm_mday), M48T86_DOM);
+		m48t86_writeb(dev, bin2bcd(tm->tm_mon + 1), M48T86_MONTH);
+		m48t86_writeb(dev, bin2bcd(tm->tm_year % 100), M48T86_YEAR);
+		m48t86_writeb(dev, bin2bcd(tm->tm_wday), M48T86_DOW);
 	}
 
 	/* update ended */
 	reg &= ~M48T86_B_SET;
-	ops->writebyte(reg, M48T86_B);
+	m48t86_writeb(dev, reg, M48T86_B);
 
 	return 0;
 }
@@ -118,15 +150,13 @@ static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq)
 {
 	unsigned char reg;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct m48t86_ops *ops = dev_get_platdata(&pdev->dev);
 
-	reg = ops->readbyte(M48T86_B);
+	reg = m48t86_readb(dev, M48T86_B);
 
 	seq_printf(seq, "mode\t\t: %s\n",
 		   (reg & M48T86_B_DM) ? "binary" : "bcd");
 
-	reg = ops->readbyte(M48T86_D);
+	reg = m48t86_readb(dev, M48T86_D);
 
 	seq_printf(seq, "battery\t\t: %s\n",
 		   (reg & M48T86_D_VRT) ? "ok" : "exhausted");
@@ -140,23 +170,44 @@ static const struct rtc_class_ops m48t86_rtc_ops = {
 	.proc		= m48t86_rtc_proc,
 };
 
-static int m48t86_rtc_probe(struct platform_device *dev)
+static int m48t86_rtc_probe(struct platform_device *pdev)
 {
+	struct m48t86_rtc_info *info;
 	unsigned char reg;
-	struct m48t86_ops *ops = dev_get_platdata(&dev->dev);
-	struct rtc_device *rtc;
 
-	rtc = devm_rtc_device_register(&dev->dev, "m48t86",
-				       &m48t86_rtc_ops, THIS_MODULE);
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->ops = dev_get_platdata(&pdev->dev);
+	if (!info->ops) {
+		struct resource *res;
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!res)
+			return -ENODEV;
+		info->index_reg = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(info->index_reg))
+			return PTR_ERR(info->index_reg);
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		if (!res)
+			return -ENODEV;
+		info->data_reg = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(info->data_reg))
+			return PTR_ERR(info->data_reg);
+	}
 
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
+	dev_set_drvdata(&pdev->dev, info);
 
-	platform_set_drvdata(dev, rtc);
+	info->rtc = devm_rtc_device_register(&pdev->dev, "m48t86",
+					     &m48t86_rtc_ops, THIS_MODULE);
+	if (IS_ERR(info->rtc))
+		return PTR_ERR(info->rtc);
 
 	/* read battery status */
-	reg = ops->readbyte(M48T86_D);
-	dev_info(&dev->dev, "battery %s\n",
+	reg = m48t86_readb(&pdev->dev, M48T86_D);
+	dev_info(&pdev->dev, "battery %s\n",
 		 (reg & M48T86_D_VRT) ? "ok" : "exhausted");
 
 	return 0;
-- 
2.10.0

-- 
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.

[rtc-linux] Re: [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: Alexander Clouter <alex@digriz.org.uk>
Date: 2017-02-10 22:45:06

On Fri, Feb 10, 2017 at 11:11:54AM -0700, H Hartley Sweeten wrote:
Currently the ts78xx platform does some "probing" of the rtc NVRAM to see
if it is actually present before registering the rtc device. This "probing"
just checks if the NVRAM is present by reading/writing the last two bytes
of the NVRAM. I'm not sure if this is really necessary. If it can be removed
all the m48t86_ops stuff could also be removed from this driver, along with
platform_data/rtc-m48t86.h.
The RTC is an optional upgrade on the TS-7800[1].  Not sure what would happen 
if the RTC driver kicks in with no actual RTC being present?

If I was to do this over again, I probably would have the driver check that the 
HMS is actually incrementing after being instantiated, if it looks weird then 
to unbind its-self.

My TS-7800 is still clunking away in the corner though on an aging 2.6.32 
kernel.  I keep meaning to update it, might be some time before I can though.

Cheers

[1] https://www.embeddedarm.com/products/TS-7800 - 'Order' tab

-- 
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.

[rtc-linux] RE: [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: Hartley Sweeten <hidden>
Date: 2017-02-10 22:56:14

On Friday, February 10, 2017 3:45 PM, Alexander Clouter wrote:
On Fri, Feb 10, 2017 at 11:11:54AM -0700, H Hartley Sweeten wrote:
quoted
Currently the ts78xx platform does some "probing" of the rtc NVRAM to see
if it is actually present before registering the rtc device. This "probing"
just checks if the NVRAM is present by reading/writing the last two bytes
of the NVRAM. I'm not sure if this is really necessary. If it can be removed
all the m48t86_ops stuff could also be removed from this driver, along with
platform_data/rtc-m48t86.h.
The RTC is an optional upgrade on the TS-7800[1].  Not sure what would happen 
if the RTC driver kicks in with no actual RTC being present?
How about modifying the m48t86 probe so that it does the NVRAM check that
you are doing in the ts78xx platform code. If the NVRAM check fails the probe
will return -ENODEV. Reading the NVRAM to check the 0x55 0xaa signature in
the last locations might be adequate. Not sure if making sure they can be written
is necessary.

Then you can just register the driver and let it figure out if the rtc is actually there.
quoted
If I was to do this over again, I probably would have the driver check that the 
HMS is actually incrementing after being instantiated, if it looks weird then 
to unbind its-self.
Or the probe could do that check and return -ENODEV if it fails.
My TS-7800 is still clunking away in the corner though on an aging 2.6.32 
kernel.  I keep meaning to update it, might be some time before I can though.
I recently got a TS-7300 from them. It has an even older 2.4 kernel. I have it
booting 4.9.9 right now and I'm trying to cleanup some of the driver code it
uses.

Regards,
Hartley

-- 
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.

[rtc-linux] RE: [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: Hartley Sweeten <hidden>
Date: 2017-02-10 23:14:20

On Friday, February 10, 2017 3:45 PM, Alexander Clouter wrote:
The RTC is an optional upgrade on the TS-7800[1].  Not sure what would happen 
if the RTC driver kicks in with no actual RTC being present?
I think the only side-effect of the RTC not actually being present is that
rtc_valid_tm() will probably report an invalid time with the time is read
from the rtc.  The values read will probably just be random, unless the
board has pull-up/down resistors on the data bus....

Hartley



-- 
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.

Re: [rtc-linux] RE: [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: Alexandre Belloni <hidden>
Date: 2017-02-12 00:05:05

On 10/02/2017 at 22:56:12 +0000, Hartley Sweeten wrote:
On Friday, February 10, 2017 3:45 PM, Alexander Clouter wrote:
quoted
On Fri, Feb 10, 2017 at 11:11:54AM -0700, H Hartley Sweeten wrote:
quoted
Currently the ts78xx platform does some "probing" of the rtc NVRAM to see
if it is actually present before registering the rtc device. This "probing"
just checks if the NVRAM is present by reading/writing the last two bytes
of the NVRAM. I'm not sure if this is really necessary. If it can be removed
all the m48t86_ops stuff could also be removed from this driver, along with
platform_data/rtc-m48t86.h.
The RTC is an optional upgrade on the TS-7800[1].  Not sure what would happen 
if the RTC driver kicks in with no actual RTC being present?
How about modifying the m48t86 probe so that it does the NVRAM check that
you are doing in the ts78xx platform code. If the NVRAM check fails the probe
will return -ENODEV. Reading the NVRAM to check the 0x55 0xaa signature in
the last locations might be adequate. Not sure if making sure they can be written
is necessary.

Then you can just register the driver and let it figure out if the rtc is actually there.
quoted
quoted
If I was to do this over again, I probably would have the driver check that the 
HMS is actually incrementing after being instantiated, if it looks weird then 
to unbind its-self.
Or the probe could do that check and return -ENODEV if it fails.
If it is always incrementing, even when it has never been set (first
boot or battery is dead), then this can be done in the probe.

The other option would be to switch to DT but that's far from trivial,
especially seeing how they are connected ;)

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

Re: [rtc-linux] [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: Alexandre Belloni <hidden>
Date: 2017-02-12 00:10:18

On 10/02/2017 at 11:11:54 -0700, H Hartley Sweeten wrote:
This rtc driver is currently only used by the Technologic Systems TS-72xx
(arm/mach-ep93xx) and TS-78xx (arm/mach-orion5x) SBCs. These platforms use
static I/O mappings for the registers needed to access the index and data
registers of the chip.

On the TS-78xx there is one I/O mapping of SZ_1M for the entire FPGA address
space. The rtc index and data registers are located in that space along with
all the other FPGA devices.

On the TS-72xx the mapping is a bit uglier. That platform uses a CPLD to
access the rtc. The CPLD is connected to two chip select lines of the
processor and each chip select addresses 256 MiB. Address lines 25-22 and 0
are then decoded for the various devices. Since mapping the entire 256 MiB
for each address space would be _really_ ugly, a SZ_4K mapping is done for
each register that is needed.

This series does the following:
 1) Cleanup this driver to remove all the checkpatch.pl issues.
 2) Modify the probe to, optionally, ioremap the resources provided by the
    platform and handle the read/write operations internally.
 3) Add support for the NVRAM in the rtc.

With these changes the static I/O mappings for the rtc registers can be
removed from the ts-72xx platform.

Currently the ts78xx platform does some "probing" of the rtc NVRAM to see
if it is actually present before registering the rtc device. This "probing"
just checks if the NVRAM is present by reading/writing the last two bytes
of the NVRAM. I'm not sure if this is really necessary. If it can be removed
all the m48t86_ops stuff could also be removed from this driver, along with
platform_data/rtc-m48t86.h.

H Hartley Sweeten (3):
  rtc: m48t86: shorten register name defines
  rtc: m48t86: allow driver to manage it's resources
  rtc: m48t86: add NVRAM support

 drivers/rtc/rtc-m48t86.c | 247 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 169 insertions(+), 78 deletions(-)
All applied, thanks.


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

[rtc-linux] Re: [PATCH 0/3] rtc: m48t86: cleanup driver and add NVRAM support

From: Alexander Clouter <alex@digriz.org.uk>
Date: 2017-02-12 00:22:25

On Fri, Feb 10, 2017 at 10:56:12PM +0000, Hartley Sweeten wrote:
On Friday, February 10, 2017 3:45 PM, Alexander Clouter wrote:
quoted
On Fri, Feb 10, 2017 at 11:11:54AM -0700, H Hartley Sweeten wrote:
quoted
Currently the ts78xx platform does some "probing" of the rtc NVRAM to see
if it is actually present before registering the rtc device. This "probing"
just checks if the NVRAM is present by reading/writing the last two bytes
of the NVRAM. I'm not sure if this is really necessary. If it can be removed
all the m48t86_ops stuff could also be removed from this driver, along with
platform_data/rtc-m48t86.h.
The RTC is an optional upgrade on the TS-7800[1].  Not sure what would happen
if the RTC driver kicks in with no actual RTC being present?
How about modifying the m48t86 probe so that it does the NVRAM check that
you are doing in the ts78xx platform code. If the NVRAM check fails the probe
will return -ENODEV. Reading the NVRAM to check the 0x55 0xaa signature in
the last locations might be adequate. Not sure if making sure they can be written
is necessary.
Its not a signature, its just some spare usable bytes at the end of the NVRAM; 
I cribbed the probing routing from Technologic Systems[1].  They seem to use a 
similar routine[2] for the TS-7200 too.

Looks like it would be fine to move this all into the driver its-self.

Cheers

[1] ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7800-linux/samples/rtc7800.c
[2] ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7200-linux/sources/rtc.c

-- 
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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help