From patchwork Sat Oct 10 10:46:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?5q2m5b2m?= X-Patchwork-Id: 11830119 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 87BBD109B for ; Sat, 10 Oct 2020 10:47:37 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 4E5D9206A5 for ; Sat, 10 Oct 2020 10:47:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="mKNiK/6y" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4E5D9206A5 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=allwinnertech.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=uOA5J9huFzFR7qIDXi4iuySvl9VX8bosvJCIoYBbS0E=; b=mKNiK/6yCpckwRt2840MQ0iQMx StJ0hLMZl1el1bbnSWh60iv0VHyl0QCBxeRRDKFPuvOC/oh22P6PlRGlQA2mvGq1GJIz+aAbhzOLw TJbmoI0LcyvmjojwKKea+4LHj9kejtWJSVo3Jl0ha/dGxCP7kCQ37iwZMobD+J/K0jlKWw8zQj97Q 3sFWA4TJYlsGL/9OeKLK/+c+obltPF2TsGRVbE71ecKaWoFDRJgwNw0VtqD9Z17PFeJdkYgn4ZbsH iHziOyUzA9PkAIaiA3FkDmGXOkCCQ6SFvESOgnE5xgKfBIj8dUY7SLJZvqpe0STfkXK/FfaFqi0DA pB9y2Uiw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kRCPJ-0001Bj-E1; Sat, 10 Oct 2020 10:47:21 +0000 Received: from smtp2207-205.mail.aliyun.com ([121.197.207.205]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kRCPF-0001BC-Qm for linux-arm-kernel@lists.infradead.org; Sat, 10 Oct 2020 10:47:20 +0000 X-Alimail-AntiSpam: AC=CONTINUE; BC=0.08021393|-1; BR=01201311R741ec; CH=green; DM=|CONTINUE|false|; DS=AD|ad_normal|0.405721-0.378217-0.216062; FP=0|0|0|0|0|-1|-1|-1; HT=ay29a033018047193; MF=wuyan@allwinnertech.com; NM=1; PH=DS; RN=8; RT=8; SR=0; TI=SMTPD_---.IhS2RTr_1602326823; Received: from localhost.localdomain(mailfrom:wuyan@allwinnertech.com fp:SMTPD_---.IhS2RTr_1602326823) by smtp.aliyun-inc.com(10.147.42.198); Sat, 10 Oct 2020 18:47:10 +0800 From: wuyan To: daniel.lezcano@linaro.org, tglx@linutronix.de, mripard@kernel.org, wens@csie.org Subject: [PATCH 1/1] clocksource: sun4i: Save and restore timer registers before and after sleeping Date: Sat, 10 Oct 2020 18:46:03 +0800 Message-Id: <20201010104603.26646-1-wuyan@allwinnertech.com> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201010_064719_040229_DA2E1138 X-CRM114-Status: GOOD ( 13.54 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [121.197.207.205 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay lines X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: wuyan , frank@allwinnertech.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Signed-off-by: wuyan Change-Id: I7edbc00fd0968d0301757f5a75dbd6f53d6a7cd7 --- drivers/clocksource/timer-sun4i.c | 45 +++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/timer-sun4i.c b/drivers/clocksource/timer-sun4i.c index 0ba8155b8287..49fb6b90ec15 100644 --- a/drivers/clocksource/timer-sun4i.c +++ b/drivers/clocksource/timer-sun4i.c @@ -29,6 +29,7 @@ #define TIMER_IRQ_EN_REG 0x00 #define TIMER_IRQ_EN(val) BIT(val) #define TIMER_IRQ_ST_REG 0x04 +#define TIMER_IRQ_CLEAR(val) BIT(val) #define TIMER_CTL_REG(val) (0x10 * val + 0x10) #define TIMER_CTL_ENABLE BIT(0) #define TIMER_CTL_RELOAD BIT(1) @@ -41,6 +42,19 @@ #define TIMER_SYNC_TICKS 3 +/* Registers which needs to be saved and restored before and after sleeping */ +static u32 regs_offset[] = { + TIMER_IRQ_EN_REG, + TIMER_IRQ_ST_REG, + TIMER_CTL_REG(0), + TIMER_INTVAL_REG(0), + TIMER_CNTVAL_REG(0), + TIMER_CTL_REG(1), + TIMER_INTVAL_REG(1), + TIMER_CNTVAL_REG(1), +}; +static u32 regs_backup[ARRAY_SIZE(regs_offset)]; + /* * When we disable a timer, we need to wait at least for 2 cycles of * the timer source clock. We will use for that the clocksource timer @@ -82,10 +96,37 @@ static void sun4i_clkevt_time_start(void __iomem *base, u8 timer, base + TIMER_CTL_REG(timer)); } +static inline void save_regs(void __iomem *base) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(regs_offset); i++) + regs_backup[i] = readl(base + regs_offset[i]); +} + +static inline void restore_regs(void __iomem *base) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(regs_offset); i++) + writel(regs_backup[i], base + regs_offset[i]); +} + static int sun4i_clkevt_shutdown(struct clock_event_device *evt) { struct timer_of *to = to_timer_of(evt); + save_regs(timer_of_base(to)); + sun4i_clkevt_time_stop(timer_of_base(to), 0); + + return 0; +} + +static int sun4i_tick_resume(struct clock_event_device *evt) +{ + struct timer_of *to = to_timer_of(evt); + + restore_regs(timer_of_base(to)); sun4i_clkevt_time_stop(timer_of_base(to), 0); return 0; @@ -126,7 +167,7 @@ static int sun4i_clkevt_next_event(unsigned long evt, static void sun4i_timer_clear_interrupt(void __iomem *base) { - writel(TIMER_IRQ_EN(0), base + TIMER_IRQ_ST_REG); + writel(TIMER_IRQ_CLEAR(0), base + TIMER_IRQ_ST_REG); } static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id) @@ -150,7 +191,7 @@ static struct timer_of to = { .set_state_shutdown = sun4i_clkevt_shutdown, .set_state_periodic = sun4i_clkevt_set_periodic, .set_state_oneshot = sun4i_clkevt_set_oneshot, - .tick_resume = sun4i_clkevt_shutdown, + .tick_resume = sun4i_tick_resume, .set_next_event = sun4i_clkevt_next_event, .cpumask = cpu_possible_mask, },