Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030720AbbKDPhP (ORCPT ); Wed, 4 Nov 2015 10:37:15 -0500 Received: from mail-pa0-f54.google.com ([209.85.220.54]:34715 "EHLO mail-pa0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030696AbbKDPhM (ORCPT ); Wed, 4 Nov 2015 10:37:12 -0500 From: Joshua Clayton To: Alessandro Zummo , Alexandre Belloni Cc: rtc-linux@googlegroups.com, linux-kernel@vger.kernel.org, Joshua Clayton Subject: [PATCH 6/9] rtc-pcf2123: avoid resetting the clock if possible Date: Wed, 4 Nov 2015 07:36:37 -0800 Message-Id: X-Mailer: git-send-email 2.5.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2595 Lines: 85 pcf2123 data sheet recommends a software reset when the chip is first powered on. This change avoids resetting the chip every time the driver is loaded, which has some negative effects. There are several registers including a clock rate adjustment that really should survive a reload of the driver (or reboot). In addition, stopping and restarting the clock to verify the chip is there is not a good thing once the time is set. According to the data sheet, the seconds register has a 1 in the high bit when the voltage has gotten low. We check for this condition, as well as whether the time retrieved from the chip is valid. We reset the rtc only if the time is not reliable and valid. This is sufficient for checking for the presence of the chip, as either all zeros or all 0xff will result in an invalid time/date Signed-off-by: Joshua Clayton --- drivers/rtc/rtc-pcf2123.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index d3c1447..4964d5c 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -260,6 +260,33 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) return 0; } +static bool pcf2123_time_valid(struct device *dev) +{ + u8 seconds; + struct rtc_time tm; + int ret; + + ret = pcf2123_read(dev, PCF2123_REG_SC, &seconds, 1); + if (ret < 0) + return false; + + if (seconds & OSC_HAS_STOPPED) { + dev_info(dev, "clock was stopped. seconds: 0x%02X\n", seconds); + return false; + } + + ret = pcf2123_rtc_read_time(dev, &tm); + if (ret < 0) + return false; + + if (rtc_valid_tm(&tm) < 0) { + dev_err(dev, "retrieved date/time is not valid.\n"); + return false; + } + + return true; +} + static int pcf2123_reset(struct device *dev) { int ret; @@ -311,10 +338,12 @@ static int pcf2123_probe(struct spi_device *spi) return -ENOMEM; spi->dev.platform_data = pdata; - ret = pcf2123_reset(&spi->dev); - if (ret < 0) { - dev_err(&spi->dev, "chip not found\n"); - goto kfree_exit; + if (!pcf2123_time_valid(&spi->dev)) { + ret = pcf2123_reset(&spi->dev); + if (ret < 0) { + dev_err(&spi->dev, "chip not found\n"); + goto kfree_exit; + } } dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/