linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Alessandro Zummo <a.zummo@towertech.it>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Matt Fleming <matt@console-pimps.org>,
	Matthew Garrett <matthew.garrett@nebula.com>
Cc: Elliott@hp.com, samer.el-haj-mahmoud@hp.com,
	Oliver Neukum <oneukum@suse.de>,
	werner@suse.com, trenn@suse.de, JBeulich@suse.com,
	linux-kernel@vger.kernel.org, rtc-linux@googlegroups.com,
	x86@kernel.org,
	"linux-efi@vger.kernel.org" <linux-efi@vger.kernel.org>,
	linux-acpi@vger.kernel.org, "Lee, Chun-Yi" <jlee@suse.com>
Subject: [RFC PATCH 07/14] rtc-efi: add GMTOFF support to rtc_efi
Date: Thu, 19 Dec 2013 15:51:48 +0800	[thread overview]
Message-ID: <1387439515-8926-8-git-send-email-jlee@suse.com> (raw)
In-Reply-To: <1387439515-8926-1-git-send-email-jlee@suse.com>

Per UEFI 2.3.1 spec, we can use SetTime() to store the timezone value to
BIOS and get it back by GetTime(). It's good for installation system to
gain the default timezone setting from BIOS that was set by
manufacturer.

This patch adds 2 new iotrl: RTC_RD_GMTOFF and RTC_SET_GMTOFF to rtc_efi
support get/set gmt offset that mapping to the GUN's tm_gmtoff extension
(Seconds east of UTC).
Due the timezone definition of UEFI is "Localtime = UTC - TimeZone",
rtc_efi driver will transfer the format between GNU and EFI.

The logic of timezone only affect on x86 architecture and keep the
original EFI_UNSPECIFIED_TIMEZONE value on IA64.

Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 drivers/rtc/rtc-efi.c |  100 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 99 insertions(+), 1 deletions(-)

diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
index c4c3843..e0e3c7e 100644
--- a/drivers/rtc/rtc-efi.c
+++ b/drivers/rtc/rtc-efi.c
@@ -75,7 +75,10 @@ convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft)
 	eft->second	= wtime->tm_sec;
 	eft->nanosecond = 0;
 	eft->daylight	= wtime->tm_isdst ? EFI_ISDST : 0;
+#ifdef CONFIG_IA64
+	/* avoid overwrite timezone on non-IA64 platform. e.g. x86_64 */
 	eft->timezone	= EFI_UNSPECIFIED_TIMEZONE;
+#endif
 }
 
 static void
@@ -108,6 +111,84 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
 	}
 }
 
+static int efi_read_gmtoff(struct device *dev, long int *arg)
+{
+	efi_status_t status;
+	efi_time_t eft;
+	efi_time_cap_t cap;
+	s16 timezone;
+
+	status = efi.get_time(&eft, &cap);
+
+	if (status != EFI_SUCCESS) {
+		/* should never happen */
+		pr_err("efitime: can't read time\n");
+		return -EINVAL;
+	}
+
+	timezone = (s16)le16_to_cpu(eft.timezone);
+	*arg = EFI_UNSPECIFIED_TIMEZONE * 60;
+	if (abs(timezone) != EFI_UNSPECIFIED_TIMEZONE &&
+	    abs(timezone) <= 1440)
+		*arg = timezone * 60 * -1;
+
+	return 0;
+}
+
+static int efi_set_gmtoff(struct device *dev, long int arg)
+{
+	efi_status_t status;
+	efi_time_t eft;
+	efi_time_cap_t cap;
+	s16 timezone;
+
+	/* transfer seconds east of UTC to minutes for ACPI */
+	timezone = arg / 60 * -1;
+	if (abs(timezone) > 1440 &&
+	    abs(timezone) != EFI_UNSPECIFIED_TIMEZONE)
+		return -EINVAL;
+
+	/* can not use -2047 */
+	if (timezone == EFI_UNSPECIFIED_TIMEZONE * -1)
+		timezone = EFI_UNSPECIFIED_TIMEZONE;
+
+	status = efi.get_time(&eft, &cap);
+
+	if (status != EFI_SUCCESS) {
+		pr_err("efitime: can't read time\n");
+		return -EINVAL;
+	}
+
+	eft.timezone = (s16)cpu_to_le16(timezone);
+	status = efi.set_time(&eft);
+	if (status != EFI_SUCCESS) {
+		pr_err("efitime: can't set timezone\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int efi_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	long int gmtoff;
+	int err;
+
+	switch (cmd) {
+	case RTC_RD_GMTOFF:
+		err = efi_read_gmtoff(dev, &gmtoff);
+		if (err)
+			return err;
+		return put_user(gmtoff, (unsigned long __user *)arg);
+	case RTC_SET_GMTOFF:
+		return efi_set_gmtoff(dev, arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
 static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
 	efi_time_t eft;
@@ -172,6 +253,17 @@ static int efi_set_time(struct device *dev, struct rtc_time *tm)
 {
 	efi_status_t status;
 	efi_time_t eft;
+#ifdef CONFIG_X86
+	efi_time_cap_t cap;
+
+	/* read time for grab timezone to avoid overwrite it */
+	status = efi.get_time(&eft, &cap);
+
+	if (status != EFI_SUCCESS) {
+		pr_err("efitime: can't read time\n");
+		return -EINVAL;
+	}
+#endif
 
 	convert_to_efi_time(tm, &eft);
 
@@ -181,13 +273,16 @@ static int efi_set_time(struct device *dev, struct rtc_time *tm)
 }
 
 static const struct rtc_class_ops efi_rtc_ops = {
+#ifdef CONFIG_X86
+	.ioctl = efi_rtc_ioctl,
+#endif
 	.read_time = efi_read_time,
 	.set_time = efi_set_time,
 	.read_alarm = efi_read_alarm,
 	.set_alarm = efi_set_alarm,
 };
 
-static int __init efi_rtc_probe(struct platform_device *dev)
+static int efi_rtc_probe(struct platform_device *dev)
 {
 	struct rtc_device *rtc;
 
@@ -196,6 +291,8 @@ static int __init efi_rtc_probe(struct platform_device *dev)
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
 
+	rtc->caps = (RTC_TZ_CAP | RTC_DST_CAP);
+
 	platform_set_drvdata(dev, rtc);
 
 	return 0;
@@ -213,3 +310,4 @@ module_platform_driver_probe(efi_rtc_driver, efi_rtc_probe);
 MODULE_AUTHOR("dann frazier <dannf@hp.com>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("EFI RTC driver");
+MODULE_ALIAS("platform:rtc-efi");
-- 
1.6.4.2

  parent reply	other threads:[~2013-12-19  7:51 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-19  7:51 [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME Lee, Chun-Yi
2013-12-19  7:51 ` [PATCH 01/14] rtc-efi: fix decrease day twice when computing year days Lee, Chun-Yi
     [not found] ` <1387439515-8926-1-git-send-email-jlee-IBi9RG/b67k@public.gmane.org>
2013-12-19  7:51   ` [PATCH 03/14] rtc: block registration of rtc-cmos when CMOS RTC Not Present Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 04/14] ACPI: Add ACPI 5.0 Time and Alarm Device driver Lee, Chun-Yi
     [not found]   ` <1387439515-8926-5-git-send-email-jlee-IBi9RG/b67k@public.gmane.org>
2013-12-19 15:22     ` H. Peter Anvin
     [not found]       ` <52B30F43.1060306-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2013-12-20  5:41         ` joeyli
     [not found]           ` <1387518099.3539.4453.camel-ONCj+Eqt86TasUa73XJKwA@public.gmane.org>
2014-01-01  0:42             ` H. Peter Anvin
     [not found]               ` <52C3647B.7000708-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2014-01-06  8:58                 ` joeyli
2014-01-07  5:37                   ` H. Peter Anvin
2014-01-07 10:40                     ` joeyli
2014-01-07 16:35                       ` H. Peter Anvin
2014-01-08 14:59                         ` joeyli
     [not found]                           ` <1389193142.3539.6123.camel-ONCj+Eqt86TasUa73XJKwA@public.gmane.org>
2014-01-08 17:56                             ` H. Peter Anvin
     [not found]                               ` <52CD9139.2070302-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2014-01-09  3:47                                 ` joeyli
     [not found]                                   ` <1389239259.24105.2.camel-ONCj+Eqt86TasUa73XJKwA@public.gmane.org>
2014-01-09  4:00                                     ` H. Peter Anvin
2014-01-09 12:16                                   ` Rafael J. Wysocki
2014-01-02  8:09     ` Lan Tianyu
2014-01-06  9:20       ` joeyli
2013-12-19  7:51 ` [RFC PATCH 05/14] rtc: Add RTC driver of ACPI Time and Alarm Device Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 06/14] rtc-efi: register rtc-efi device when EFI enabled Lee, Chun-Yi
2013-12-19 14:09   ` Matt Fleming
2013-12-20  4:24     ` joeyli
     [not found]       ` <1387513491.3539.4345.camel-ONCj+Eqt86TasUa73XJKwA@public.gmane.org>
2013-12-20  4:30         ` H. Peter Anvin
2013-12-20 10:37           ` Borislav Petkov
     [not found]             ` <20131220103755.GA14784-fF5Pk5pvG8Y@public.gmane.org>
2013-12-20 15:14               ` Matthew Garrett
2013-12-20 21:04                 ` H. Peter Anvin
     [not found]                   ` <52B4B0ED.7030600-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2013-12-21  1:24                     ` joeyli
2013-12-21  1:51                       ` H. Peter Anvin
2013-12-21 15:34                         ` joeyli
2013-12-20 16:48               ` H. Peter Anvin
2013-12-19  7:51 ` Lee, Chun-Yi [this message]
     [not found]   ` <1387439515-8926-8-git-send-email-jlee-IBi9RG/b67k@public.gmane.org>
2013-12-20 15:11     ` [RFC PATCH 07/14] rtc-efi: add GMTOFF support to rtc_efi Matthew Garrett
2013-12-21  3:56       ` joeyli
2013-12-19  7:51 ` [RFC PATCH 08/14] rtc-efi: set uie_unsupported for indicate rtc-efi doesn't support UIE mode Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 09/14] efi: move functions of access efi time to header file for sharing Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 10/14] rtc: improve and move week day computing function to rtc header Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 11/14] rtc: switch to get/set rtc time to efi functions if CMOS RTC Not Present git set Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 12/14] efi: adjust system time base on timezone from EFI time services Lee, Chun-Yi
2013-12-19  7:51 ` [RFC PATCH 13/14] Documentation/RTC: add document of ACPI TAD and EFI TIME driver Lee, Chun-Yi
2013-12-19  7:51 ` [TEST PATCH 14/14] acpi: add early parameter to set CMOS RTC Not Present bit for testing Lee, Chun-Yi
     [not found] ` <1387448416-11672-1-git-send-email-jlee@suse.com>
     [not found]   ` <1387448416-11672-1-git-send-email-jlee-IBi9RG/b67k@public.gmane.org>
2013-12-19 10:49     ` [PATCH 02/14] x86-64/efi: Use EFI to deal with platform wall clock (again) Matt Fleming
     [not found]       ` <20131219104908.GE3145-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-12-19 13:32         ` joeyli
     [not found]           ` <1387459939.3539.4092.camel-ONCj+Eqt86TasUa73XJKwA@public.gmane.org>
2013-12-20 11:29             ` One Thousand Gnomes
2013-12-23 23:25               ` H. Peter Anvin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1387439515-8926-8-git-send-email-jlee@suse.com \
    --to=joeyli.kernel@gmail.com \
    --cc=Elliott@hp.com \
    --cc=JBeulich@suse.com \
    --cc=a.zummo@towertech.it \
    --cc=hpa@zytor.com \
    --cc=jlee@suse.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matt@console-pimps.org \
    --cc=matthew.garrett@nebula.com \
    --cc=oneukum@suse.de \
    --cc=rjw@rjwysocki.net \
    --cc=rtc-linux@googlegroups.com \
    --cc=samer.el-haj-mahmoud@hp.com \
    --cc=trenn@suse.de \
    --cc=werner@suse.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).