rtc: hctosys: move hctosys functionality to rtc_device_register

Message ID 14cc1b9c-66af-2e09-1ca5-07aa55025beb@gmail.com
State New
Headers show

Commit Message

Heiner Kallweit March 7, 2017, 7:10 p.m.
It's a little annoying that rtc driver plus all drivers it depends on
(e.g. I2C) have to be compiled into the kernel to be used with hctosys.

I think it would be more logical to set the system clock once the
rtc driver has been registered. Therefore move the hctosys
functionality to the end of rtc_device_register.

Works perfectly fine here.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/rtc/Makefile  |  1 -
 drivers/rtc/class.c   | 38 ++++++++++++++++++++++++++++
 drivers/rtc/hctosys.c | 70 ---------------------------------------------------
 3 files changed, 38 insertions(+), 71 deletions(-)
 delete mode 100644 drivers/rtc/hctosys.c

Comments

Heiner Kallweit July 6, 2017, 8:15 p.m. | #1
Am 07.03.2017 um 20:10 schrieb Heiner Kallweit:
> It's a little annoying that rtc driver plus all drivers it depends on
> (e.g. I2C) have to be compiled into the kernel to be used with hctosys.
> 
> I think it would be more logical to set the system clock once the
> rtc driver has been registered. Therefore move the hctosys
> functionality to the end of rtc_device_register.
> 
> Works perfectly fine here.
> 
Do you have an opinion on this one?

Rgds, Heiner


> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
>  drivers/rtc/Makefile  |  1 -
>  drivers/rtc/class.c   | 38 ++++++++++++++++++++++++++++
>  drivers/rtc/hctosys.c | 70 ---------------------------------------------------
>  3 files changed, 38 insertions(+), 71 deletions(-)
>  delete mode 100644 drivers/rtc/hctosys.c
> 
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index f07297b1..f1d57b06 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -5,7 +5,6 @@
>  ccflags-$(CONFIG_RTC_DEBUG)	:= -DDEBUG
>  
>  obj-$(CONFIG_RTC_LIB)		+= rtc-lib.o
> -obj-$(CONFIG_RTC_HCTOSYS)	+= hctosys.o
>  obj-$(CONFIG_RTC_SYSTOHC)	+= systohc.o
>  obj-$(CONFIG_RTC_CLASS)		+= rtc-core.o
>  obj-$(CONFIG_RTC_MC146818_LIB)	+= rtc-mc146818-lib.o
> diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
> index 74fd9746..dcfd2e64 100644
> --- a/drivers/rtc/class.c
> +++ b/drivers/rtc/class.c
> @@ -168,6 +168,13 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
>  	struct rtc_wkalrm alrm;
>  	int of_id = -1, id = -1, err;
>  
> +#if IS_ENABLED(CONFIG_RTC_HCTOSYS)
> +	struct rtc_time tm;
> +	struct timespec64 tv64 = {
> +		.tv_nsec = NSEC_PER_SEC >> 1,
> +	};
> +#endif
> +
>  	if (dev->of_node)
>  		of_id = of_alias_get_id(dev->of_node, "rtc");
>  	else if (dev->parent && dev->parent->of_node)
> @@ -246,6 +253,37 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
>  	dev_info(dev, "rtc core: registered %s as %s\n",
>  			rtc->name, dev_name(&rtc->dev));
>  
> +#if IS_ENABLED(CONFIG_RTC_HCTOSYS)
> +/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
> + * whether it stores the most close value or the value with partial
> + * seconds truncated. However, it is important that we use it to store
> + * the truncated value. This is because otherwise it is necessary,
> + * in an rtc sync function, to read both xtime.tv_sec and
> + * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
> + * of >32bits is not possible. So storing the most close value would
> + * slow down the sync API. So here we have the truncated value and
> + * the best guess is to add 0.5s.
> + */
> +	if (!strcmp(CONFIG_RTC_HCTOSYS_DEVICE, dev_name(&rtc->dev))) {
> +		err = rtc_read_time(rtc, &tm);
> +		if (err) {
> +			dev_err(dev, "hctosys: unable to read the hardware clock\n");
> +			goto hctosys_out;
> +		}
> +
> +		tv64.tv_sec = rtc_tm_to_time64(&tm);
> +
> +		err = do_settimeofday64(&tv64);
> +
> +		dev_info(dev, "setting system clock to %d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
> +			 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
> +			 tm.tm_hour, tm.tm_min, tm.tm_sec,
> +			 (long long) tv64.tv_sec);
> +hctosys_out:
> +		rtc_hctosys_ret = err;
> +	}
> +#endif
> +
>  	return rtc;
>  
>  exit_ida:
> diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
> deleted file mode 100644
> index e1cfa068..00000000
> --- a/drivers/rtc/hctosys.c
> +++ /dev/null
> @@ -1,70 +0,0 @@
> -/*
> - * RTC subsystem, initialize system time on startup
> - *
> - * Copyright (C) 2005 Tower Technologies
> - * Author: Alessandro Zummo <a.zummo@towertech.it>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> -*/
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> -
> -#include <linux/rtc.h>
> -
> -/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
> - * whether it stores the most close value or the value with partial
> - * seconds truncated. However, it is important that we use it to store
> - * the truncated value. This is because otherwise it is necessary,
> - * in an rtc sync function, to read both xtime.tv_sec and
> - * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
> - * of >32bits is not possible. So storing the most close value would
> - * slow down the sync API. So here we have the truncated value and
> - * the best guess is to add 0.5s.
> - */
> -
> -static int __init rtc_hctosys(void)
> -{
> -	int err = -ENODEV;
> -	struct rtc_time tm;
> -	struct timespec64 tv64 = {
> -		.tv_nsec = NSEC_PER_SEC >> 1,
> -	};
> -	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
> -
> -	if (rtc == NULL) {
> -		pr_info("unable to open rtc device (%s)\n",
> -			CONFIG_RTC_HCTOSYS_DEVICE);
> -		goto err_open;
> -	}
> -
> -	err = rtc_read_time(rtc, &tm);
> -	if (err) {
> -		dev_err(rtc->dev.parent,
> -			"hctosys: unable to read the hardware clock\n");
> -		goto err_read;
> -
> -	}
> -
> -	tv64.tv_sec = rtc_tm_to_time64(&tm);
> -
> -	err = do_settimeofday64(&tv64);
> -
> -	dev_info(rtc->dev.parent,
> -		"setting system clock to "
> -		"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
> -		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
> -		tm.tm_hour, tm.tm_min, tm.tm_sec,
> -		(long long) tv64.tv_sec);
> -
> -err_read:
> -	rtc_class_close(rtc);
> -
> -err_open:
> -	rtc_hctosys_ret = err;
> -
> -	return err;
> -}
> -
> -late_initcall(rtc_hctosys);
>

Patch

diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index f07297b1..f1d57b06 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -5,7 +5,6 @@ 
 ccflags-$(CONFIG_RTC_DEBUG)	:= -DDEBUG
 
 obj-$(CONFIG_RTC_LIB)		+= rtc-lib.o
-obj-$(CONFIG_RTC_HCTOSYS)	+= hctosys.o
 obj-$(CONFIG_RTC_SYSTOHC)	+= systohc.o
 obj-$(CONFIG_RTC_CLASS)		+= rtc-core.o
 obj-$(CONFIG_RTC_MC146818_LIB)	+= rtc-mc146818-lib.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 74fd9746..dcfd2e64 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -168,6 +168,13 @@  struct rtc_device *rtc_device_register(const char *name, struct device *dev,
 	struct rtc_wkalrm alrm;
 	int of_id = -1, id = -1, err;
 
+#if IS_ENABLED(CONFIG_RTC_HCTOSYS)
+	struct rtc_time tm;
+	struct timespec64 tv64 = {
+		.tv_nsec = NSEC_PER_SEC >> 1,
+	};
+#endif
+
 	if (dev->of_node)
 		of_id = of_alias_get_id(dev->of_node, "rtc");
 	else if (dev->parent && dev->parent->of_node)
@@ -246,6 +253,37 @@  struct rtc_device *rtc_device_register(const char *name, struct device *dev,
 	dev_info(dev, "rtc core: registered %s as %s\n",
 			rtc->name, dev_name(&rtc->dev));
 
+#if IS_ENABLED(CONFIG_RTC_HCTOSYS)
+/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
+ * whether it stores the most close value or the value with partial
+ * seconds truncated. However, it is important that we use it to store
+ * the truncated value. This is because otherwise it is necessary,
+ * in an rtc sync function, to read both xtime.tv_sec and
+ * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
+ * of >32bits is not possible. So storing the most close value would
+ * slow down the sync API. So here we have the truncated value and
+ * the best guess is to add 0.5s.
+ */
+	if (!strcmp(CONFIG_RTC_HCTOSYS_DEVICE, dev_name(&rtc->dev))) {
+		err = rtc_read_time(rtc, &tm);
+		if (err) {
+			dev_err(dev, "hctosys: unable to read the hardware clock\n");
+			goto hctosys_out;
+		}
+
+		tv64.tv_sec = rtc_tm_to_time64(&tm);
+
+		err = do_settimeofday64(&tv64);
+
+		dev_info(dev, "setting system clock to %d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
+			 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+			 tm.tm_hour, tm.tm_min, tm.tm_sec,
+			 (long long) tv64.tv_sec);
+hctosys_out:
+		rtc_hctosys_ret = err;
+	}
+#endif
+
 	return rtc;
 
 exit_ida:
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
deleted file mode 100644
index e1cfa068..00000000
--- a/drivers/rtc/hctosys.c
+++ /dev/null
@@ -1,70 +0,0 @@ 
-/*
- * RTC subsystem, initialize system time on startup
- *
- * Copyright (C) 2005 Tower Technologies
- * Author: Alessandro Zummo <a.zummo@towertech.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/rtc.h>
-
-/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
- * whether it stores the most close value or the value with partial
- * seconds truncated. However, it is important that we use it to store
- * the truncated value. This is because otherwise it is necessary,
- * in an rtc sync function, to read both xtime.tv_sec and
- * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
- * of >32bits is not possible. So storing the most close value would
- * slow down the sync API. So here we have the truncated value and
- * the best guess is to add 0.5s.
- */
-
-static int __init rtc_hctosys(void)
-{
-	int err = -ENODEV;
-	struct rtc_time tm;
-	struct timespec64 tv64 = {
-		.tv_nsec = NSEC_PER_SEC >> 1,
-	};
-	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-
-	if (rtc == NULL) {
-		pr_info("unable to open rtc device (%s)\n",
-			CONFIG_RTC_HCTOSYS_DEVICE);
-		goto err_open;
-	}
-
-	err = rtc_read_time(rtc, &tm);
-	if (err) {
-		dev_err(rtc->dev.parent,
-			"hctosys: unable to read the hardware clock\n");
-		goto err_read;
-
-	}
-
-	tv64.tv_sec = rtc_tm_to_time64(&tm);
-
-	err = do_settimeofday64(&tv64);
-
-	dev_info(rtc->dev.parent,
-		"setting system clock to "
-		"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
-		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-		tm.tm_hour, tm.tm_min, tm.tm_sec,
-		(long long) tv64.tv_sec);
-
-err_read:
-	rtc_class_close(rtc);
-
-err_open:
-	rtc_hctosys_ret = err;
-
-	return err;
-}
-
-late_initcall(rtc_hctosys);