From nobody Thu May 15 08:54:16 2025 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E14D238166 for <linux-kernel@vger.kernel.org>; Wed, 2 Apr 2025 12:06:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743595586; cv=none; b=tuEQVqVzFa1pR6d+MbnIDkfZqYbnaHaaGDqhyUjW+5HR0lq9kqHOcK7/rz6WT/ZYdbx8p7GHa05LSBnY0m4hR3Qx6K4OBQrOsxp5UhGAK/q6NYYHWqGGEPys4C2L6rsbyExwQR0npRVSqz02I1LAH3GGlqLejHBGD8os+yIHlmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743595586; c=relaxed/simple; bh=7swfiKnH8hrUC9s3SQdoobfGIfZ4drxEBqFdEd8mRQ0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZszQFDUc9wcAkQBjnJRW1aqXxXuCjrpoXzh9fxMQ4+E4YQCPRnHfIYVC4HkJrz07wuqLFPBAFe78OjSeXKbYZhusGUiz2V1JZr/5S6Yhy4pki1RtRX6S4qpFAC+MSMtgF5dJr2ZNQdrahcwiwaMBECObAZTNgT1kMz1emzCDQ68= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=mvista.com; spf=pass smtp.mailfrom=mvista.com; dkim=pass (1024-bit key) header.d=mvista.com header.i=@mvista.com header.b=ONw4wMCY; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=mvista.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mvista.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mvista.com header.i=@mvista.com header.b="ONw4wMCY" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-227aaa82fafso127842675ad.2 for <linux-kernel@vger.kernel.org>; Wed, 02 Apr 2025 05:06:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1743595583; x=1744200383; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kCigWhMrmcJBolyuUgV3lJ1qYbCm1dkqPLc5H/XoqqE=; b=ONw4wMCYvnabXnHu9xVJTe8LNJLzjU21VxG+3v49040zDt2maSNIvBIiQjB24kf81T EPlnTttvx04oeSx71Uol91DiTJvK58kq7jWpq4De2417pQMZUrlaBI4NiwGMXOO8BVoF MZYe52SfU27oZOrIJ99uTiNKw3uOTSc0AvQvQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743595584; x=1744200384; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kCigWhMrmcJBolyuUgV3lJ1qYbCm1dkqPLc5H/XoqqE=; b=DpQfo1P1RbpUlKWTdTrvyBJwOFCahrF16aSoKuFrvf9giYcRnEuVTaMxLgNdDnHH1i Q+RMtN15tDNpRY8SO/pmEPrdoW3x1n3hxy2hwj6ngo4UbV5ZCtK5pRf4zDROteqJioXe qwqHipj9gU3lCkgE5xKBBPU0UxCRzurafdtJr5bMFh/W24Sl5ItJyHNTt3bY8BwXFA1S zPkkYnfuVOGh6eQqiguXo8ug+Kj+vV5hR27pPb5cJxEwEYrlFHo6vwCwi8WGLI2hZeIt Mix9Chm6Ia5F5yepoyZAvxTrf3QHu/egP5+KDRL1ShT0QAytMkEvAM84wtEUkqA5Wo7k og2Q== X-Forwarded-Encrypted: i=1; AJvYcCWyEJZR/ePyY7zr16LIt/QlbSE+Q+DiBG1RjY5o7wZXvfVY6ySB0kX14spQsHA0X4RJC91I9z3k93PXPNY=@vger.kernel.org X-Gm-Message-State: AOJu0YzitNkTW1Gn6ZrRgojx7XxxN68brBB3aAPuabQhG8az81SfGIuJ No3V3EmYCQb7VhXdyB8jg68HCw3M9g+xKEJT7G6x1GIUautQ1aGB0z/PtzB1x7M= X-Gm-Gg: ASbGncucb/WB7I+uJLTYBQ4nGpnnPLBL7t3Asw8Kr3m7SxN4xB6TcM4SBNEMVs6hLYO lQkUVqACBgTuPwARX3UVHBj1DunNS5D4flvv3OrbWzDsRMIBQZ1AKlHLmJX5aNQm7Taps9/uCW8 O5Rv4VJ7TMD03ZVk3zCXPph/ZqX/ejbZgnBbYEBuyTP6jRUqIM+PouJacjYKIFPFHOvOS7V8IPS RbKjkIcskbGg+msEyf4tvSlZrhGP8eh/v55Cli20oMO696gryFLy3puDWTerv0LI3rNL7e4a8U0 /2R7D9xPJyulJGF41AI+Eukrp0j+GVU6kxpHlOkqDvANhkJn/5tphFcLfWg= X-Google-Smtp-Source: AGHT+IH7SJCT5w1JE7ro6lt0SJ18bG6a/eylqAKOqWZO3IB/4aC4Rj6hZeZDRT9PoKTBRqHp6AQqjQ== X-Received: by 2002:a17:902:e549:b0:224:a79:5fe4 with SMTP id d9443c01a7336-2292f942f58mr212724095ad.2.1743595583576; Wed, 02 Apr 2025 05:06:23 -0700 (PDT) Received: from niyas-desktop.mvista.com ([182.74.28.237]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2291eedd2bcsm106477375ad.65.2025.04.02.05.06.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Apr 2025 05:06:23 -0700 (PDT) From: nmydeen@mvista.com To: alexandre.belloni@bootlin.com Cc: linux-rtc@vger.kernel.org, linux-kernel@vger.kernel.org, cminyard@mvista.com, "A. Niyas Ahamed Mydeen" <nmydeen@mvista.com> Subject: [PATCH v2] rtc-m41t62: kickstart ocillator upon failure Date: Wed, 2 Apr 2025 17:35:46 +0530 Message-Id: <20250402120546.336657-2-nmydeen@mvista.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250402120546.336657-1-nmydeen@mvista.com> References: <20250401090454fb0ccf16@mail.local> <20250402120546.336657-1-nmydeen@mvista.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "A. Niyas Ahamed Mydeen" <nmydeen@mvista.com> The ocillator on the m41t62 (and other chips of this type) needs a kickstart upon a failure; the RTC read routine will notice the oscillator failure and fail reads. This is added in the RTC write routine; this allows the system to know that the time in the RTC is accurate. This is following the procedure described in section 3.11 of "https://www.st.com/resource/en/datasheet/m41t62.pdf" Signed-off-by: A. Niyas Ahamed Mydeen <nmydeen@mvista.com> Reviewed-by: Corey Minyard <cminyard@mvista.com> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com> --- drivers/rtc/rtc-m41t80.c | 68 ++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 1f58ae8b151e..7074d086f1c8 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/mutex.h> #include <linux/string.h> +#include <linux/delay.h> #ifdef CONFIG_RTC_DRV_M41T80_WDT #include <linux/fs.h> #include <linux/ioctl.h> @@ -204,7 +205,7 @@ static int m41t80_rtc_read_time(struct device *dev, str= uct rtc_time *tm) return flags; =20 if (flags & M41T80_FLAGS_OF) { - dev_err(&client->dev, "Oscillator failure, data is invalid.\n"); + dev_err(&client->dev, "Oscillator failure, time may not be accurate, wri= te time to RTC to fix it.\n"); return -EINVAL; } =20 @@ -227,21 +228,31 @@ static int m41t80_rtc_read_time(struct device *dev, s= truct rtc_time *tm) return 0; } =20 -static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) +static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *in_tm) { struct i2c_client *client =3D to_i2c_client(dev); struct m41t80_data *clientdata =3D i2c_get_clientdata(client); + struct rtc_time tm =3D *in_tm; unsigned char buf[8]; int err, flags; + time64_t time =3D 0; =20 + flags =3D i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (flags < 0) + return flags; + if (flags & M41T80_FLAGS_OF) { + /* add 4sec of oscillator stablize time otherwise we are behind 4sec */ + time =3D rtc_tm_to_time64(&tm); + rtc_time64_to_tm(time + 4, &tm); + } buf[M41T80_REG_SSEC] =3D 0; - buf[M41T80_REG_SEC] =3D bin2bcd(tm->tm_sec); - buf[M41T80_REG_MIN] =3D bin2bcd(tm->tm_min); - buf[M41T80_REG_HOUR] =3D bin2bcd(tm->tm_hour); - buf[M41T80_REG_DAY] =3D bin2bcd(tm->tm_mday); - buf[M41T80_REG_MON] =3D bin2bcd(tm->tm_mon + 1); - buf[M41T80_REG_YEAR] =3D bin2bcd(tm->tm_year - 100); - buf[M41T80_REG_WDAY] =3D tm->tm_wday; + buf[M41T80_REG_SEC] =3D bin2bcd(tm.tm_sec); + buf[M41T80_REG_MIN] =3D bin2bcd(tm.tm_min); + buf[M41T80_REG_HOUR] =3D bin2bcd(tm.tm_hour); + buf[M41T80_REG_DAY] =3D bin2bcd(tm.tm_mday); + buf[M41T80_REG_MON] =3D bin2bcd(tm.tm_mon + 1); + buf[M41T80_REG_YEAR] =3D bin2bcd(tm.tm_year - 100); + buf[M41T80_REG_WDAY] =3D tm.tm_wday; =20 /* If the square wave output is controlled in the weekday register */ if (clientdata->features & M41T80_FEATURE_SQ_ALT) { @@ -260,17 +271,34 @@ static int m41t80_rtc_set_time(struct device *dev, st= ruct rtc_time *tm) dev_err(&client->dev, "Unable to write to date registers\n"); return err; } - - /* Clear the OF bit of Flags Register */ - flags =3D i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); - if (flags < 0) - return flags; - - err =3D i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, - flags & ~M41T80_FLAGS_OF); - if (err < 0) { - dev_err(&client->dev, "Unable to write flags register\n"); - return err; + if (flags & M41T80_FLAGS_OF) { + /* OF cannot be immediately reset: oscillator has to be restarted. */ + dev_warn(&client->dev, "OF bit is still set, kickstarting clock.\n"); + err =3D i2c_smbus_write_byte_data(client, M41T80_REG_SEC, M41T80_SEC_ST); + if (err < 0) { + dev_err(&client->dev, "Can't set ST bit\n"); + return err; + } + err =3D i2c_smbus_write_byte_data(client, M41T80_REG_SEC, flags & ~M41T8= 0_SEC_ST); + if (err < 0) { + dev_err(&client->dev, "Can't clear ST bit\n"); + return err; + } + /* oscillator must run for 4sec before we attempt to reset OF bit */ + msleep(4000); + /* Clear the OF bit of Flags Register */ + err =3D i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, flags & ~M41= T80_FLAGS_OF); + if (err < 0) { + dev_err(&client->dev, "Unable to write flags register\n"); + return err; + } + flags =3D i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (flags < 0) { + return flags; + } else if (flags & M41T80_FLAGS_OF) { + dev_err(&client->dev, "Can't clear the OF bit check battery\n"); + return err; + } } =20 return err; --=20 2.34.1