From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFC4BC433B4 for ; Wed, 19 May 2021 10:44:38 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3B50561355 for ; Wed, 19 May 2021 10:44:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3B50561355 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=LLGl2hNnrCJpAe5bHI4QPHUxIjiqN0k2e2KiobZZf6s=; b=d7kbSgCs1iIqEO/AxAlwE6ScnK NpMQHmsDontrK3zwO4bh0Bl3zbz/yX8QrOsHwx76veCsw9Lrs2OE8hjK3vKOTnE8tEW6wQK8d2Xhj 5J73zyNcJOXp20YvZZa762vfIqhJMmY0rU+BF9TJqLkIb3uLg8YvVf19eEPKdV+uFIE5tQfFnQWB/ hjVOeYQNoqdy6MHzjWlZpOlvt0QJ7WdoCsxKQOcQzr64QL0qyXG6nz3r5WUHKsaymqUCA7HPnGPap BofxxZzGpJQEOa5BrZ2eX2fePaDfxSvaYmoxkWoEdDA253v0coPF/p5BDDm2fzsASc85DS/iTbNHL 2W602wPw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1ljJfU-003cPW-K5; Wed, 19 May 2021 10:43:12 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ljJei-003cFV-J3 for linux-arm-kernel@desiato.infradead.org; Wed, 19 May 2021 10:42:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=PvfyG3hfKbnBbSFdMDecTOohUcuGOTnhPaocPK96+3s=; b=KVVne+TM2uMTC0/eRUplJfVDac Ma2IqaJ1AOh9W/XSa5kgaV8a3h/ja9q07AU87m9Y0+pCDd4tzpuudJE1ohNZIsJErlVk6x0ZWp94r 5sOUmF9Q6tWMwMA+sAlD6yTy2yjNJ/c8JQZiVyj4FFDtNEntrddJLlPJQWZC447Pm00oWx9YNB4MB GC21KuWEm5ZP13zLSY34dvcZqO+DIur+MObANnGWIdoo+q9eZ+/SLJP2bcwIlPs0bDVFwbW2bdexR 7eYmNvcBH0TMkXDdE5ycVrqWYXfjN9kMmoutW9vELKu09fZd4zeYStLhJlS3jAQ30egNaTups3CVB CtRmjVMA==; Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1ljJef-00FMSx-Q2 for linux-arm-kernel@lists.infradead.org; Wed, 19 May 2021 10:42:23 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4809314BF; Wed, 19 May 2021 03:42:17 -0700 (PDT) Received: from localhost.localdomain (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2CABC3F792; Wed, 19 May 2021 03:42:15 -0700 (PDT) From: Andre Przywara To: Maxime Ripard , Chen-Yu Tsai , Jernej Skrabec Cc: Rob Herring , Icenowy Zheng , Samuel Holland , Ondrej Jirman , linux-arm-kernel@lists.infradead.org, linux-sunxi@googlegroups.com, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, Alessandro Zummo , Alexandre Belloni , linux-rtc@vger.kernel.org Subject: [PATCH v6 04/17] rtc: sun6i: Add support for linear day storage Date: Wed, 19 May 2021 11:41:39 +0100 Message-Id: <20210519104152.21119-5-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20210519104152.21119-1-andre.przywara@arm.com> References: <20210519104152.21119-1-andre.przywara@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210519_034221_956577_9AD5ECCE X-CRM114-Status: GOOD ( 21.81 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Newer versions of the Allwinner RTC, as for instance found in the H616 SoC, no longer store a broken-down day/month/year representation in the RTC_DAY_REG, but just a linear day number. The user manual does not give any indication about the expected epoch time of this day count, but the BSP kernel uses the UNIX epoch, which allows easy support due to existing conversion functions in the kernel. Allow tagging a compatible string with a flag, and use that to mark those new RTCs. Then convert between a UNIX day number (converted into seconds) and the broken-down day representation using mktime64() and time64_to_tm() in the set_time/get_time functions. That enables support for the RTC in those new chips. Reviewed-by: Andre Przywara --- drivers/rtc/rtc-sun6i.c | 58 +++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index adec1b14a8de..0228e9dfd969 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -133,12 +133,15 @@ struct sun6i_rtc_clk_data { unsigned int has_auto_swt : 1; }; +#define RTC_LINEAR_DAY BIT(0) + struct sun6i_rtc_dev { struct rtc_device *rtc; const struct sun6i_rtc_clk_data *data; void __iomem *base; int irq; unsigned long alarm; + unsigned long flags; struct clk_hw hw; struct clk_hw *int_osc; @@ -471,17 +474,30 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_min = SUN6I_TIME_GET_MIN_VALUE(time); rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time); - rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date); - rtc_tm->tm_mon = SUN6I_DATE_GET_MON_VALUE(date); - rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date); - - rtc_tm->tm_mon -= 1; - - /* - * switch from (data_year->min)-relative offset to - * a (1900)-relative one - */ - rtc_tm->tm_year += SUN6I_YEAR_OFF; + if (chip->flags & RTC_LINEAR_DAY) { + struct tm tm; + + /* + * Newer chips store a linear day number, the manual + * does not mandate any epoch base. The BSP driver uses + * the UNIX epoch, let's just copy that, as it's the + * easiest anyway. + */ + time64_to_tm((date & 0xffff) * 3600ULL * 24, 0, &tm); + rtc_tm->tm_mday = tm.tm_mday; + rtc_tm->tm_mon = tm.tm_mon; + rtc_tm->tm_year = tm.tm_year; + } else { + rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date); + rtc_tm->tm_mon = SUN6I_DATE_GET_MON_VALUE(date) - 1; + rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date); + + /* + * switch from (data_year->min)-relative offset to + * a (1900)-relative one + */ + rtc_tm->tm_year += SUN6I_YEAR_OFF; + } return 0; } @@ -571,15 +587,21 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) u32 date = 0; u32 time = 0; - rtc_tm->tm_year -= SUN6I_YEAR_OFF; rtc_tm->tm_mon += 1; - date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | - SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | - SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year); + if (chip->flags & RTC_LINEAR_DAY) { + date = mktime64(rtc_tm->tm_year + 1900, rtc_tm->tm_mon, + rtc_tm->tm_mday, 0, 0, 0) / (3600ULL * 24); + } else { + rtc_tm->tm_year -= SUN6I_YEAR_OFF; + + date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | + SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | + SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year); - if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN)) - date |= SUN6I_LEAP_SET_VALUE(1); + if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN)) + date |= SUN6I_LEAP_SET_VALUE(1); + } time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min) | @@ -678,6 +700,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, chip); + chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev); + chip->irq = platform_get_irq(pdev, 0); if (chip->irq < 0) return chip->irq; -- 2.17.5 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel