From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Sender: rtc-linux@googlegroups.com Received: from na01-bl2-obe.outbound.protection.outlook.com (mail-bl2on0141.outbound.protection.outlook.com. [65.55.169.141]) by gmr-mx.google.com with ESMTPS id h76si708491ywc.7.2016.06.20.09.06.46 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 20 Jun 2016 09:06:46 -0700 (PDT) To: "linux-kernel@vger.kernel.org" , CC: Alexandre Belloni , Alessandro Zummo , Joe Lawrence From: Joe Lawrence Subject: [rtc-linux] __rtc_read_alarm missing month/year field bug? Message-ID: <5768148E.8090304@stratus.com> Date: Mon, 20 Jun 2016 12:06:38 -0400 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Reply-To: rtc-linux@googlegroups.com List-ID: List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Hello Alessandro and Alexandre, I noticed an interesting cmos_rtc.rtc.aie_timer on a Stratus machine running the 4.6 kernel, with an expiration time that puts the alarm way out into next year. This is easily reproducible on this machine by setting a wakealarm sometime in the near future, then rebooting. >>From a fresh boot: % cat /proc/driver/rtc rtc_time : 17:55:10 rtc_date : 2016-06-09 alrm_time : 14:04:37 alrm_date : 2017-06-09 << 2017 ? alarm_IRQ : no alrm_pending : no update IRQ enabled : no periodic IRQ enabled : no periodic IRQ frequency : 1024 max user IRQ frequency : 64 24hr : yes periodic_IRQ : no update_IRQ : no HPET_emulated : yes BCD : yes DST_enable : no periodic_freq : 1024 batt_status : okay I added some debugging code to the kernel, saw this on the next boot: __rtc_read_alarm: A - alarm->time.tm_year = -1, missing = 0 __rtc_read_alarm: B - alarm->time.tm_year = 116, missing = 3 __rtc_read_alarm: C - alarm->time.tm_year = 117 Corresponding to these parts of __rtc_read_alarm: int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ... enum { none, day, month, year } missing = none; ... err = rtc_read_alarm_internal(rtc, alarm); ... /* Fill in the missing alarm fields using the timestamp; we * know there's at least one since alarm->time is invalid. */ ... [A] if (alarm->time.tm_year == -1) { alarm->time.tm_year = now.tm_year; if (missing == none) missing = year; } [B] ... switch (missing) { ... /* Year rollover ... easy except for leap years! */ case year: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); do { alarm->time.tm_year++; } while (!is_leap_year(alarm->time.tm_year + 1900) && rtc_valid_tm(&alarm->time) != 0); [C] break; I noticed that the missing year and month cases increment their respective time units inside a do ... while (condition) loop, pushing the default 'filled-in' values to now + 1. Should this 'roll-over' code check for a valid date before incrementing the alarm time? (See attached patch.) I think this might also apply to a missing month field as well. (After the patch + reboot): % cat /proc/driver/rtc rtc_time : 18:24:02 rtc_date : 2016-06-09 alrm_time : 14:04:37 alrm_date : 2016-06-09 alarm_IRQ : no alrm_pending : no update IRQ enabled : no periodic IRQ enabled : no periodic IRQ frequency : 1024 max user IRQ frequency : 64 24hr : yes periodic_IRQ : no update_IRQ : no HPET_emulated : yes BCD : yes DST_enable : no periodic_freq : 1024 batt_status : okay -- >8 -- >>From d6feacf20b312c8ebfee902b8b84f68c1a82f035 Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Thu, 9 Jun 2016 14:52:28 -0400 Subject: [PATCH] rtc: check filled-in alarm values before incrementing In __rtc_read_alarm, check filled-in alarm->time.tm_year values (those not returned by the RTC and defaulted to now.tm_year) before incrementing them in the rollover handling case. Signed-off-by: Joe Lawrence --- drivers/rtc/interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9ef5f6f89f98..3098ce4167ef 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -258,10 +258,10 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) /* Year rollover ... easy except for leap years! */ case year: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); - do { + while (!is_leap_year(alarm->time.tm_year + 1900) + && rtc_valid_tm(&alarm->time) != 0) { alarm->time.tm_year++; - } while (!is_leap_year(alarm->time.tm_year + 1900) - && rtc_valid_tm(&alarm->time) != 0); + } break; default: -- 1.8.3.1 -- 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. From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754906AbcFTQXt (ORCPT ); Mon, 20 Jun 2016 12:23:49 -0400 Received: from mail-bn1bon0135.outbound.protection.outlook.com ([157.56.111.135]:56173 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751577AbcFTQXc (ORCPT ); Mon, 20 Jun 2016 12:23:32 -0400 X-Greylist: delayed 989 seconds by postgrey-1.27 at vger.kernel.org; Mon, 20 Jun 2016 12:23:17 EDT Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Joe.Lawrence@stratus.com; To: "linux-kernel@vger.kernel.org" , CC: Alexandre Belloni , Alessandro Zummo , Joe Lawrence From: Joe Lawrence Subject: __rtc_read_alarm missing month/year field bug? Message-ID: <5768148E.8090304@stratus.com> Date: Mon, 20 Jun 2016 12:06:38 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [198.97.42.5] X-ClientProxiedBy: DM2PR10CA0086.namprd10.prod.outlook.com (10.162.31.12) To SN2PR0801MB2254.namprd08.prod.outlook.com (10.167.19.10) X-MS-Office365-Filtering-Correlation-Id: 6fa25d09-3748-40bf-1d9d-08d39924e06a X-Microsoft-Exchange-Diagnostics: 1;SN2PR0801MB2254;2:q8kCEZOVcdm7wvx7PC8ixDEtxbPq9mUKP92xPQJgJsLhue+f8EfsXmm6p1OnwfEiSd6yIE7dARK8kTkwq7nTFlEbBj54xiwaSc5R9WtqFf6l1msZ/BKem49QoWnisvWyKbF1x8h0G2/DgBL4DTstBrkK0FRsvNzRKnnfXDcoesED26Hsu1JgkSicUjCM4LqG;3:czQZgeiNBY+S9132MSqDT124uylGOriVm0HqiaHq364TyazoF1IVWnwQe3Vwti+B1W7MwB0K8rX8FVR5hfr59/Qk8QGCphfYdEd5RTS9LmK/7tbb6U76BuR8YjALSrW2;25:f+Oh5wGA557hYxxBVyZ7wc20rqSI3uTbq/qnSvGIea43zkSdMXXWRcVn5/5lyhXMGt+3e2MubIFb52Dhd+qtoakxwYiSgHnCIHoDoudDlpjZLhCTCwFfST5vMHnEQtqibnzOvPqmE07jAWHVd9egqoVizoFDJsjIUhRumf3741JtyfEv+O1nqh6bXjJn4nBDLZ8j8mR6a8NNmSDNFcQ6dpiTbKGkAe/jB2I/oiVvp8i/TUA+4JIjblIOw9fVNspJ3ymO8jRLwOW8UaRQ8o6VRaz7E4aD2KuN/o/0Y2Sc1NFkStd6GO4SQWl4F2/G9NwmPL+/nJAIuoh36LrDVRnDeFcp+w8NO+g416CAQOID8q2HwpePB0TWiO3treJ7amCML7BVzca9hYiTKTnjhwQ78sPu5DrrLumy8R/uFU2feyI= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN2PR0801MB2254; X-Microsoft-Exchange-Diagnostics: 1;SN2PR0801MB2254;20:w4sSfILHhix/AAUHFZ25X8l9q93asUXOqqknoJYOs6RkuRE5i09aauNHaERhUjVutHP2KukyLhc699oosbjgKPuHvr44ICgSxYVkopW5QJ/7Yt5oSm7zKctOjTxJAwj1QHpv7AH0CYB8Ntx3m8kyfvOHKk/2SKe/M5Cl4nWCFLAG9b1MTw6F8DHVpeJNPTq7FhgNaSDeEenfNfOSIhjIdBPDHhpSSWa4LR//g6AXPHQV580wwZ80xuhRzGv8WJhi0FuymmbtXBls+ArqAR8S8WKgeGqdW8FQm+Lq+7CU05FCgPJ/0dM/4Lb/ebh3YBVTpcqIGXPXuw0+1GXD4xki5D2ygvulGE/LEqfA5I3yH7H27p9fBMAszZsXoGbxKBX9ANHeX4mWr/IHQJ64kdZ16YECSWGeN9pjDTsWY1FZ0x3PjbCtVnFulb9sWVffUS0lqK6LSAtXfG1UIA+yruJwQBZE7BpakcSeXYHBw3s8Rv31lWJjApDZRVJQ5pgzNq1z;4:xv3sZu4/EWpdYo2n+h1MBYT+FcFZaQuz53HggkKVOyDMutHY7pJJmnOHczKcItLk/kx3cMo/tlFS8IBPd71P0xeJR0h1ffnoTXS0vop2bjiY3yEuX7IrJoPI2dPIS7/76wCn9HFQBWAVrvrxRdqD2eqkb7FFn4F0++Niua+gUhyJBrxmuE8ocNJw/uXgwCQLbDqdX40POadaOnHe18xSKIEzGAq/GyIBVnl320/WXWh6ZgUMC6JdKRrHSOn03HrXgtTQGyAltnfX7YrjGDzHFnePTcr457t1CKffYe8OJvo3Hlo1ytl0vYs1ZnliWGw70y8/HCPXIguw7wFx5jKiuIROb/a/PawCYDx+88pDjzy44SPzYS5bLE7vLfLWU6D9gY+t1PfVBdSyOBF4iokWD2/PLuQOQRm/puVlPJzdqVY= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(17755550239193); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001);SRVR:SN2PR0801MB2254;BCL:0;PCL:0;RULEID:;SRVR:SN2PR0801MB2254; X-Forefront-PRVS: 09796A1B83 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(377424004)(36756003)(99136001)(86362001)(4001430100002)(87266999)(230700001)(65816999)(80316001)(83506001)(42186005)(64126003)(229853001)(77096005)(54356999)(19580405001)(50986999)(59896002)(19580395003)(68736007)(97736004)(50466002)(5001770100001)(66066001)(23676002)(106356001)(47776003)(81166006)(101416001)(81156014)(105586002)(2501003)(8676002)(4001350100001)(3846002)(2906002)(189998001)(586003)(33656002)(6116002)(4326007)(107886002)(5890100001)(65806001)(7846002)(65956001)(92566002)(7736002);DIR:OUT;SFP:1102;SCL:1;SRVR:SN2PR0801MB2254;H:jlaw-desktop.mno.stratus.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjJQUjA4MDFNQjIyNTQ7MjM6MU1FMmxKZVVTM3A3TWZMenEvL2ZONjN2?= =?utf-8?B?WW1QQ1orenovK2dhL0dZQ2xZZ3BZVC9GN2tlR1Jrb0FSblNZY2hqcldnMzBm?= =?utf-8?B?RnEvVlR2UmlObm13bHlmRjl5eGVzVzhNTUc3ZFdQbjhFQ1hqbEhGTEtWS1Rk?= =?utf-8?B?cjZ5Mml5Vm9INzdBTXkyK0VIWVI5RkNxK1JIZzEvMUdRU0t3TThVdTlIZ0tM?= =?utf-8?B?Q1NEem9KZjN5dFJ1d0xIK0tLbnpPVTFOc3pCbytYWE94allrTEswenArQzBM?= =?utf-8?B?TTl2N2Q0UGo5TFZyL0ZDQXZ2TmFIaGg2ZnBsdndPZFFGYXVyV056WUdQMnJU?= =?utf-8?B?Szc3VDNMQzhBSyt2QUhmaVMwYWhqZFEreml2azdUU3BHSjNGLzgwM05qYlE1?= =?utf-8?B?aHBmOGRVVys1WHNTY0plcWxUOWlJUUtQdC9GZEhBZ0ZoeHd1RTR5Y0F4RzBZ?= =?utf-8?B?QmcyRjAwRmFvNWFsT1N3cm5GdzlrbWtKVXZMc25FL2V4SDEycVA4dTN1bzZj?= =?utf-8?B?S3ltRDJzT2hvWDBoZTdvRm04KzdUT3JnOFBZbWJoeWNFOVNNQ0UvcUo4SGZt?= =?utf-8?B?U1Y0VUVxYXJPbXc4enJ6a2ZmcDZyRXQxd3BZQVhoa2pnMzkyeHNXeEVRdk1m?= =?utf-8?B?ekRwMmhJSnFabmtEYk5vdW9UV3c4NFN6L2M0RTdScWhka1FCZURHS1RyS1No?= =?utf-8?B?bEg5bGJlTEhJUUw1V21Mb0F6TDlUeWtHNnpjb0F6SlJsaEg2dUtiK2hibnpa?= =?utf-8?B?RG1mK1VEV0dqY2VZb1Q1WXlsTE1PczhKbmkzS1kxcTg1b28wRTlOaVpEbEN0?= =?utf-8?B?V051bloyN1M3SU9ZZ1JyVHFzTldyc3JuQ0hSWCsxRlhQbXNQSFBNTlZUNG5n?= =?utf-8?B?OThGaTdoWVVxaWVEcVViYmJWcDN3dXVBMU1HMlZ0RmpBMmhxcElmMXdGcTlk?= =?utf-8?B?NTIybUpEeW1zTTRxc0kyeHA0VCtTNEgyeU9VMVZzd1ZLUExFRWJqNXhzOEps?= =?utf-8?B?YnNicGhLOEtIeTJQYTNMSTdYMHlSMGlZQVVyY3luRFM5cG12cHVldnA2akpa?= =?utf-8?B?LzVrZnFqcEttK1pkVUdaaENVaVZSUWFWT1Y0NDJOaHJFdVVacHJzTjArTnNE?= =?utf-8?B?SDJCNVR6eGx6cHh1dTZrd2JIOGFiVHBBUFArRnZHMWlQeS9jL3Q1MUVteHZP?= =?utf-8?B?WTJwQlMzdmhXMDRBQUxxQkhDTWtwaE9pc0d1amlLMU9rbVZPTHBkL1V5ZnJO?= =?utf-8?B?ckJodnRTY1F5eHRtaTA0YmM5QWQ5Z2czRjNqNmVDb0dnMlZmR2ZmZ0J6cG5m?= =?utf-8?B?NjRmOUFkWmFlOWY4TWpqaFU0dlhqTHpQOHNGZHNxa3IzTGJSL3F2ZUdkbmVV?= =?utf-8?B?NnBMV0ZnSFQrSUJDTTlOTUM5cTczUkJRN2FiMkJjV3RsRnp5eEUwZ3BPcWF6?= =?utf-8?B?UWg2UHlIUkpTbitNUEJHQUI5eDdpL2R1YndpZWhDbVJ2aVZkUmlBUmlqNWZH?= =?utf-8?B?ZGp0ZmhuNFVxY0Vad0tXdllOZE1CTXllUGlUOGtjTFBTVEI0Y0NUaW9ZUW52?= =?utf-8?B?UjluSDZEeVIyT1FIM3FLRzVPU1BwaWl2SnY5T1hzVU4zUnRYTWVQZHhQR2F5?= =?utf-8?B?aWZEOTRyNURHOWk0RXAzbGRoMStmUXhkcUZscjg4N3Z4elNpTFV1TDFPS0RR?= =?utf-8?B?Q0EvbU9TbmMwT1d0QU1lNFdrS1BzNTROdCs0enRBTlBnbWtsRzFucHpaclpG?= =?utf-8?B?UEl5VDhsWVB1RWhmWGt2bTRQMUlZUG1RbVdXa3ZLR3ZMWW5oMEtLbWZPVVhv?= =?utf-8?Q?I6LOit7qJvEb7AM?= X-Microsoft-Exchange-Diagnostics: 1;SN2PR0801MB2254;6:h1JD1Ec2dGHgPEUKJvVwYiVm9RIAubfy3tSdUfy/n+NF1fLeFZ/Hc0Jz2Qa/O+/Hsc0qfVS9XtPyLkeJ4fPC+7BhurbHnc/GgG73tHCti4wZbB25MZF6PQ4TfiNca/eDc0XNcdBSHhEQwjqF2IAOn+sjKdcpVJZ5aJX6dDC93RzeBDAbnrAWbrhi+Tykvf7pqGvokpbGxPAoZd4m7gdtRA/c1RT0fYZG6aV17elp1WfLHoOBvLjgafWtdqnKYOix6+d68eYPbdyNygvGfESHqoMcfgvf3NJCMbkIrhdRYdk=;5:o/nQRDcWRYwS9UHKPEZujsFYGp6ZF+bK2f2VLlxCNK9enEs/eoaT69bw3FQmpPrCiwXGM/xUWZ/HtppkMz2AudsBwP/ml49MacaGp7H5ZOfVJDqseRvMz+nJJoZPP5TPGHQJOxXIs0vGYxQDImk97A==;24:CXRZ1ctW+8XkCFvZ1EZ+0XBThWYUsPmSeP/+J0JgV0dhrAEvBdelMmhgySJcx4PPFvU6QBdy48uX0BQiS/+SPGugj7gCpVi6ux09F8y3JN8=;7:H+Ypkm/BgNtDujTqyIicklwpjqcZhenOZ3K/SeDdIZD7WR/5wmg3OJX/fsuIZKksBYT6puOKKEMK3EX3sE4++LdpD6XDBot/70/Y1iutz07k849d+bZlihSETDQ9VyAeIHsaTI+/NySA2XVy9CWhdOl6i/QxPD5RGGHpEeHAIf/9T2ozqylLLCnkwGiRdmVe1JFFM2GKl/9BU83+rv3KFk6qlKe1PO+G80VRfc8whyWRB2ZlnCyd35Vutw8+m/l/ SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN2PR0801MB2254;20:sEAfgjORh6yxZojyydY3GLz4NQeaorQBMRuFz/AxIJL1NPXAValHNx8isc9GObxqu24R1ScWO1GoQIT3Y/6vQHtFYZ2jctyZUBdqQNoof94id3Cyr12p4dEg9981XDXR9F1vk0W4vwLq5WzREbDuqoruztKuqMRDLJkUrmr6eHM= X-OriginatorOrg: stratus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Jun 2016 16:06:44.6890 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN2PR0801MB2254 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello Alessandro and Alexandre, I noticed an interesting cmos_rtc.rtc.aie_timer on a Stratus machine running the 4.6 kernel, with an expiration time that puts the alarm way out into next year. This is easily reproducible on this machine by setting a wakealarm sometime in the near future, then rebooting. >>From a fresh boot: % cat /proc/driver/rtc rtc_time : 17:55:10 rtc_date : 2016-06-09 alrm_time : 14:04:37 alrm_date : 2017-06-09 << 2017 ? alarm_IRQ : no alrm_pending : no update IRQ enabled : no periodic IRQ enabled : no periodic IRQ frequency : 1024 max user IRQ frequency : 64 24hr : yes periodic_IRQ : no update_IRQ : no HPET_emulated : yes BCD : yes DST_enable : no periodic_freq : 1024 batt_status : okay I added some debugging code to the kernel, saw this on the next boot: __rtc_read_alarm: A - alarm->time.tm_year = -1, missing = 0 __rtc_read_alarm: B - alarm->time.tm_year = 116, missing = 3 __rtc_read_alarm: C - alarm->time.tm_year = 117 Corresponding to these parts of __rtc_read_alarm: int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ... enum { none, day, month, year } missing = none; ... err = rtc_read_alarm_internal(rtc, alarm); ... /* Fill in the missing alarm fields using the timestamp; we * know there's at least one since alarm->time is invalid. */ ... [A] if (alarm->time.tm_year == -1) { alarm->time.tm_year = now.tm_year; if (missing == none) missing = year; } [B] ... switch (missing) { ... /* Year rollover ... easy except for leap years! */ case year: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); do { alarm->time.tm_year++; } while (!is_leap_year(alarm->time.tm_year + 1900) && rtc_valid_tm(&alarm->time) != 0); [C] break; I noticed that the missing year and month cases increment their respective time units inside a do ... while (condition) loop, pushing the default 'filled-in' values to now + 1. Should this 'roll-over' code check for a valid date before incrementing the alarm time? (See attached patch.) I think this might also apply to a missing month field as well. (After the patch + reboot): % cat /proc/driver/rtc rtc_time : 18:24:02 rtc_date : 2016-06-09 alrm_time : 14:04:37 alrm_date : 2016-06-09 alarm_IRQ : no alrm_pending : no update IRQ enabled : no periodic IRQ enabled : no periodic IRQ frequency : 1024 max user IRQ frequency : 64 24hr : yes periodic_IRQ : no update_IRQ : no HPET_emulated : yes BCD : yes DST_enable : no periodic_freq : 1024 batt_status : okay -- >8 -- >>From d6feacf20b312c8ebfee902b8b84f68c1a82f035 Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Thu, 9 Jun 2016 14:52:28 -0400 Subject: [PATCH] rtc: check filled-in alarm values before incrementing In __rtc_read_alarm, check filled-in alarm->time.tm_year values (those not returned by the RTC and defaulted to now.tm_year) before incrementing them in the rollover handling case. Signed-off-by: Joe Lawrence --- drivers/rtc/interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9ef5f6f89f98..3098ce4167ef 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -258,10 +258,10 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) /* Year rollover ... easy except for leap years! */ case year: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); - do { + while (!is_leap_year(alarm->time.tm_year + 1900) + && rtc_valid_tm(&alarm->time) != 0) { alarm->time.tm_year++; - } while (!is_leap_year(alarm->time.tm_year + 1900) - && rtc_valid_tm(&alarm->time) != 0); + } break; default: -- 1.8.3.1