Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp2034215pxb; Sat, 2 Apr 2022 12:38:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzb+0Mc5LzyTBDA4YO4Zm7fTl1upg0KdDx8lzSJazAnHBU5SF3ioJQfq5nQsV9VAc4Yn13X X-Received: by 2002:a17:907:2cc6:b0:6e0:3113:6e9a with SMTP id hg6-20020a1709072cc600b006e031136e9amr4874918ejc.519.1648928295869; Sat, 02 Apr 2022 12:38:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648928295; cv=none; d=google.com; s=arc-20160816; b=YXtETDSS/I7HDf/hp7mdJsWG4sQx8VW5waj/LaFJ8yPfCqqCrTveb5xyUS1E8J0bzO 4GA3keS+7dwXQUl3RNMN5JHcQ9DBL2MvbrSzCNh5vqkFhHJEz+KNsiv8/7CH8z19Y8cL 5A4qTvVAjCJlo/YobdwLPHzPsmhVNVE7wW+Xq7fnHHbovJ4RD8JbpQc8kp8wxhWNM0bP Yi/1aMh38O0fiwrnHszlNW+7iGg0Uvoq06VIq9h26oIzdW1JrTT/KTxNCPwsPK2F1K5m Qri6Qutj1YqEnxoecnplIwqIxlGX47QGDMmWMQMsk4oO6fuTDUeDWOza/6wlItUsoBD4 9Mng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id; bh=D97X3/RFniYvDfkXthxU3aHPEdNWL0E94VIJfwj5va4=; b=HqBUmqWtaTsYdvdEtuTgTe2IijezdefmEaQao2xIsR/D3T0kY1C1A2JxebGoWvz24K +6YqztKeNjwci2apZ+2QTaukeWjkM/Bn5uixrzDlaP73ICgi9FbeQDVZkTy+xOCUoDia ITqDJ2hlUDMatbLACfKlygtsO1rc0VXQuK2s3bhtcDD+AWmRTEPshwvez5bDqwilQx7z 2VYvchD+1v6DroUp60A38YDk7t+PcO25kx4c8BMK+TQJJZd/XyILoa/nnRThSRXKkcJt HlaTi17GfBvN5Bf9Pa5moHPhYbI7U+psm51ELxWzLXw7RlI9e3C14anSYcd/WiBr4hCX 4gYw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id eb14-20020a0564020d0e00b00419d4892ba7si4655933edb.343.2022.04.02.12.37.49; Sat, 02 Apr 2022 12:38:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245445AbiDAKWc (ORCPT + 99 others); Fri, 1 Apr 2022 06:22:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245363AbiDAKW3 (ORCPT ); Fri, 1 Apr 2022 06:22:29 -0400 Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.126.130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75B6F1C9B4B; Fri, 1 Apr 2022 03:20:38 -0700 (PDT) Received: from [192.168.100.1] ([82.142.17.26]) by mrelayeu.kundenserver.de (mreue010 [213.165.67.103]) with ESMTPSA (Nemesis) id 1MwQGj-1nqnji0vn3-00sLP0; Fri, 01 Apr 2022 12:20:19 +0200 Message-ID: Date: Fri, 1 Apr 2022 12:20:17 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: [PATCH v15 4/5] clocksource/drivers: Add a goldfish-timer clocksource Content-Language: fr To: Daniel Lezcano Cc: Jiaxun Yang , Alessandro Zummo , linux-rtc@vger.kernel.org, Stephen Boyd , Arnd Bergmann , Alexandre Belloni , linux-m68k@lists.linux-m68k.org, Geert Uytterhoeven , Thomas Gleixner , John Stultz , linux-kernel@vger.kernel.org References: <20220310090048.1933020-1-laurent@vivier.eu> <20220310090048.1933020-5-laurent@vivier.eu> From: Laurent Vivier In-Reply-To: <20220310090048.1933020-5-laurent@vivier.eu> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Provags-ID: V03:K1:u2d6Fo0vt2+bqXskDLHjOPdixCX4zsXvINJ2Jn19xWXsGKxPOxq 1XwntdfcPDTYVDrUzFjrILOv9jflp2j4a2oGsERZp+9tejRjCaycJ6O1Yycab2p5EowcobN T0u13sSkliObBT2/RnxUQzbB5k29damx0RxX+L9maHub8YvDC0cTgYOz96FnnKPeB3x6dYz EzHq5M4WG9LvBfStI4OcQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:81TbQ8LjB+A=:iWBIL0/kInar3gnkCke+Zr 1hCIlIlVcC9UMnvtMboWe8CGwxV0DUo7GT+iu7F8u2TdHo7z0jL5B2326hwgeun/hAW4ez8wy 4jZTWBArzyxChrRsmpsYwJWTuMqVB+9kruwFMnMMS5CWn0fo3f6wAxDCPV/yYIzSyMwZuy6f9 ZiwY5tFgKgC/l73lMi5ZLYj4L5n0VcPTpsqVlB06EcxaZ/YRZe0KP5uBOhFC334sgAkum6nx7 YqFgjlBONKLnqrara0ioZHauDHM2poIJ49KvtW35/3VQ+bIYZ914ymGUOZy/6LcbMbNTeL56o WDZDj/w2KaUp/uOnjBpM9N2mR8vsGszDcKb2ykCR5tPu3O44h9qNP+c1OHDn7SDw8qb3ekpqv QFRntqOEPVZqf21H3Um3A1G3+hmTY3nUxO4XLxCZ6Z9Uma2aGl46mQfAL2jQY8MxC8wPxwZQM xuPEdlTXyqS4Z2YzomRE+NNUDYN9cK1QVrQFYMzZn3Zkwg58GJArNxmUmvxRxf3q7PKLrrJoZ Ezw+YeX0pCkg94UBgOp4r2KtlKesysuI49SW/Wv7906ycsK4NGIRMXpYRiTyHpb8jBvvuooli ++TCDGbUuUdX5C7iXTiNvDZFhb8EHPE9SkUAluE45BcKrvEZctyo4Q0JEbkQxxSRJ+spVgkwK cLjmWNJSO/uuyAyj1IimeCkbWjqInmMvfbc/7TWdXINYKtauckME7QXwAlldSmmas3BI= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NICE_REPLY_A, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Daniel ? Thanks, Laurent Le 10/03/2022 à 10:00, Laurent Vivier a écrit : > Add a clocksource based on the goldfish-rtc device. > > Move the timer register definition to > > This kernel implementation is based on the QEMU upstream implementation: > > https://git.qemu.org/?p=qemu.git;a=blob_plain;f=hw/rtc/goldfish_rtc.c > > goldfish-timer is a high-precision signed 64-bit nanosecond timer. > It is part of the 'goldfish' virtual hardware platform used to run > some emulated Android systems under QEMU. > This timer only supports oneshot event. > > Signed-off-by: Laurent Vivier > --- > drivers/clocksource/Kconfig | 7 ++ > drivers/clocksource/Makefile | 1 + > drivers/clocksource/timer-goldfish.c | 153 +++++++++++++++++++++++++++ > drivers/rtc/rtc-goldfish.c | 13 +-- > include/clocksource/timer-goldfish.h | 31 ++++++ > 5 files changed, 193 insertions(+), 12 deletions(-) > create mode 100644 drivers/clocksource/timer-goldfish.c > create mode 100644 include/clocksource/timer-goldfish.h > > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig > index cfb8ea0df3b1..94f00374cebb 100644 > --- a/drivers/clocksource/Kconfig > +++ b/drivers/clocksource/Kconfig > @@ -721,4 +721,11 @@ config MICROCHIP_PIT64B > modes and high resolution. It is used as a clocksource > and a clockevent. > > +config GOLDFISH_TIMER > + bool "Clocksource using goldfish-rtc" > + depends on M68K || COMPILE_TEST > + depends on RTC_DRV_GOLDFISH > + help > + Support for the timer/counter of goldfish-rtc > + > endmenu > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile > index fa5f624eadb6..12f5d7e8cc2d 100644 > --- a/drivers/clocksource/Makefile > +++ b/drivers/clocksource/Makefile > @@ -89,3 +89,4 @@ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o > obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o > obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o > obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o > +obj-$(CONFIG_GOLDFISH_TIMER) += timer-goldfish.o > diff --git a/drivers/clocksource/timer-goldfish.c b/drivers/clocksource/timer-goldfish.c > new file mode 100644 > index 000000000000..0512d5eabc82 > --- /dev/null > +++ b/drivers/clocksource/timer-goldfish.c > @@ -0,0 +1,153 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct goldfish_timer { > + struct clocksource cs; > + struct clock_event_device ced; > + struct resource res; > + void __iomem *base; > +}; > + > +static struct goldfish_timer *ced_to_gf(struct clock_event_device *ced) > +{ > + return container_of(ced, struct goldfish_timer, ced); > +} > + > +static struct goldfish_timer *cs_to_gf(struct clocksource *cs) > +{ > + return container_of(cs, struct goldfish_timer, cs); > +} > + > +static u64 goldfish_timer_read(struct clocksource *cs) > +{ > + struct goldfish_timer *timerdrv = cs_to_gf(cs); > + void __iomem *base = timerdrv->base; > + u32 time_low, time_high; > + u64 ticks; > + > + /* > + * time_low: get low bits of current time and update time_high > + * time_high: get high bits of time at last time_low read > + */ > + time_low = gf_ioread32(base + TIMER_TIME_LOW); > + time_high = gf_ioread32(base + TIMER_TIME_HIGH); > + > + ticks = ((u64)time_high << 32) | time_low; > + > + return ticks; > +} > + > +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) > +{ > + struct goldfish_timer *timerdrv = ced_to_gf(evt); > + void __iomem *base = timerdrv->base; > + > + gf_iowrite32(0, base + TIMER_ALARM_HIGH); > + gf_iowrite32(0, base + TIMER_ALARM_LOW); > + gf_iowrite32(1, base + TIMER_IRQ_ENABLED); > + > + return 0; > +} > + > +static int goldfish_timer_shutdown(struct clock_event_device *evt) > +{ > + struct goldfish_timer *timerdrv = ced_to_gf(evt); > + void __iomem *base = timerdrv->base; > + > + gf_iowrite32(0, base + TIMER_IRQ_ENABLED); > + > + return 0; > +} > + > +static int goldfish_timer_next_event(unsigned long delta, > + struct clock_event_device *evt) > +{ > + struct goldfish_timer *timerdrv = ced_to_gf(evt); > + void __iomem *base = timerdrv->base; > + u64 now; > + > + now = goldfish_timer_read(&timerdrv->cs); > + > + now += delta; > + > + gf_iowrite32(upper_32_bits(now), base + TIMER_ALARM_HIGH); > + gf_iowrite32(lower_32_bits(now), base + TIMER_ALARM_LOW); > + > + return 0; > +} > + > +static irqreturn_t goldfish_timer_irq(int irq, void *dev_id) > +{ > + struct goldfish_timer *timerdrv = dev_id; > + struct clock_event_device *evt = &timerdrv->ced; > + void __iomem *base = timerdrv->base; > + > + gf_iowrite32(1, base + TIMER_CLEAR_INTERRUPT); > + > + evt->event_handler(evt); > + > + return IRQ_HANDLED; > +} > + > +int __init goldfish_timer_init(int irq, void __iomem *base) > +{ > + struct goldfish_timer *timerdrv; > + int ret; > + > + timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); > + if (!timerdrv) > + return -ENOMEM; > + > + timerdrv->base = base; > + > + timerdrv->ced = (struct clock_event_device){ > + .name = "goldfish_timer", > + .features = CLOCK_EVT_FEAT_ONESHOT, > + .set_state_shutdown = goldfish_timer_shutdown, > + .set_state_oneshot = goldfish_timer_set_oneshot, > + .set_next_event = goldfish_timer_next_event, > + }; > + > + timerdrv->res = (struct resource){ > + .name = "goldfish_timer", > + .start = (unsigned long)base, > + .end = (unsigned long)base + 0xfff, > + }; > + > + ret = request_resource(&iomem_resource, &timerdrv->res); > + if (ret) { > + pr_err("Cannot allocate '%s' resource\n", timerdrv->res.name); > + return ret; > + } > + > + timerdrv->cs = (struct clocksource){ > + .name = "goldfish_timer", > + .rating = 400, > + .read = goldfish_timer_read, > + .mask = CLOCKSOURCE_MASK(64), > + .flags = 0, > + .max_idle_ns = LONG_MAX, > + }; > + > + clocksource_register_hz(&timerdrv->cs, NSEC_PER_SEC); > + > + ret = request_irq(irq, goldfish_timer_irq, IRQF_TIMER, > + "goldfish_timer", timerdrv); > + if (ret) { > + pr_err("Couldn't register goldfish-timer interrupt\n"); > + return ret; > + } > + > + clockevents_config_and_register(&timerdrv->ced, NSEC_PER_SEC, > + 1, 0xffffffff); > + > + return 0; > +} > diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c > index eb1929b0cbb6..59c0f38cc08d 100644 > --- a/drivers/rtc/rtc-goldfish.c > +++ b/drivers/rtc/rtc-goldfish.c > @@ -11,18 +11,7 @@ > #include > #include > #include > - > -#define TIMER_TIME_LOW 0x00 /* get low bits of current time */ > - /* and update TIMER_TIME_HIGH */ > -#define TIMER_TIME_HIGH 0x04 /* get high bits of time at last */ > - /* TIMER_TIME_LOW read */ > -#define TIMER_ALARM_LOW 0x08 /* set low bits of alarm and */ > - /* activate it */ > -#define TIMER_ALARM_HIGH 0x0c /* set high bits of next alarm */ > -#define TIMER_IRQ_ENABLED 0x10 > -#define TIMER_CLEAR_ALARM 0x14 > -#define TIMER_ALARM_STATUS 0x18 > -#define TIMER_CLEAR_INTERRUPT 0x1c > +#include > > struct goldfish_rtc { > void __iomem *base; > diff --git a/include/clocksource/timer-goldfish.h b/include/clocksource/timer-goldfish.h > new file mode 100644 > index 000000000000..d39097729b1d > --- /dev/null > +++ b/include/clocksource/timer-goldfish.h > @@ -0,0 +1,31 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * goldfish-timer clocksource > + * Registers definition for the goldfish-timer device > + */ > + > +#ifndef _CLOCKSOURCE_TIMER_GOLDFISH_H > +#define _CLOCKSOURCE_TIMER_GOLDFISH_H > + > +/* > + * TIMER_TIME_LOW get low bits of current time and update TIMER_TIME_HIGH > + * TIMER_TIME_HIGH get high bits of time at last TIMER_TIME_LOW read > + * TIMER_ALARM_LOW set low bits of alarm and activate it > + * TIMER_ALARM_HIGH set high bits of next alarm > + * TIMER_IRQ_ENABLED enable alarm interrupt > + * TIMER_CLEAR_ALARM disarm an existin alarm > + * TIMER_ALARM_STATUS alarm status (running or not) > + * TIMER_CLEAR_INTERRUPT clear interrupt > + */ > +#define TIMER_TIME_LOW 0x00 > +#define TIMER_TIME_HIGH 0x04 > +#define TIMER_ALARM_LOW 0x08 > +#define TIMER_ALARM_HIGH 0x0c > +#define TIMER_IRQ_ENABLED 0x10 > +#define TIMER_CLEAR_ALARM 0x14 > +#define TIMER_ALARM_STATUS 0x18 > +#define TIMER_CLEAR_INTERRUPT 0x1c > + > +extern int goldfish_timer_init(int irq, void __iomem *base); > + > +#endif /* _CLOCKSOURCE_TIMER_GOLDFISH_H */