All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Laurent Vivier <laurent@vivier.eu>, linux-kernel@vger.kernel.org
Cc: linux-rtc@vger.kernel.org,
	Alessandro Zummo <a.zummo@towertech.it>,
	Jiaxun Yang <jiaxun.yang@flygoat.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	linux-m68k@lists.linux-m68k.org, Arnd Bergmann <arnd@arndb.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Stephen Boyd <sboyd@kernel.org>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	John Stultz <john.stultz@linaro.org>
Subject: Re: [PATCH v12 4/5] clocksource/drivers: Add a goldfish-timer clocksource
Date: Wed, 26 Jan 2022 12:55:05 +0100	[thread overview]
Message-ID: <2dc495b0-b9a1-e493-ddeb-d966afd624c0@linaro.org> (raw)
In-Reply-To: <20220121200738.2577697-5-laurent@vivier.eu>


Hi Laurent,

On 21/01/2022 21:07, Laurent Vivier wrote:
> Add a clocksource based on the goldfish-rtc device.

As a first submission, please provide a more detailed description of the
timer.

> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  drivers/clocksource/Kconfig          |   7 ++
>  drivers/clocksource/Makefile         |   1 +
>  drivers/clocksource/timer-goldfish.c | 163 +++++++++++++++++++++++++++
>  include/clocksource/timer-goldfish.h |  11 ++
>  4 files changed, 182 insertions(+)
>  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..4c670a1aea16
> --- /dev/null
> +++ b/drivers/clocksource/timer-goldfish.c
> @@ -0,0 +1,163 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/interrupt.h>
> +#include <linux/ioport.h>
> +#include <linux/clocksource.h>
> +#include <linux/clockchips.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/goldfish.h>
> +#include <clocksource/timer-goldfish.h>
> +
> +#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   */

Thanks for the comments giving the update details of the register.
However the format is not very easy to read. I suggest to add these
information in the log or above the macros being a bit more verbose

/*
 * bla bla
 */

> +#define TIMER_IRQ_ENABLED	0x10
> +#define TIMER_CLEAR_ALARM	0x14
> +#define TIMER_ALARM_STATUS	0x18
> +#define TIMER_CLEAR_INTERRUPT	0x1c
> +
> +struct goldfish_timer {
> +	struct clocksource cs;
> +	struct clock_event_device ced;
> +	struct resource res;
> +	void __iomem *base;
> +	int irq;

'res' and 'irq' can be local variable in the init function, they are not
used anywhere else

> +};
> +
> +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 golfish_timer_tick(int irq, void *dev_id)

"timer_tick" will be confusing with "scheduler timer tick". Please
rename it to (eg. goldfish_timer_irq)

Note: the function name 'golfish' instead of 'goldfish'

> +{
> +	struct clock_event_device *evt = dev_id;
> +	struct goldfish_timer *timerdrv = ced_to_gf(evt);
> +	void __iomem *base = timerdrv->base;
> +
> +	gf_iowrite32(1, base + TIMER_CLEAR_INTERRUPT);
> +
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +void __init goldfish_timer_init(int irq, void __iomem *base)

Error handling please

int __init goldfish_timer_init(...)

> +{
> +	struct goldfish_timer *timerdrv;
> +	int ret;
> +
> +	timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL);
> +	if (!timerdrv)
> +		return;
> +
> +	timerdrv->base = base;
> +	timerdrv->irq = irq;

Not needed

> +	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,
> +	};

nit: add CR

> +	timerdrv->res = (struct resource){
> +		.name  = "goldfish_timer",
> +		.start = (unsigned long)base,
> +		.end   = (unsigned long)base + 0xfff,
> +	};

Could be a local variable, no?

> +	if (request_resource(&iomem_resource, &timerdrv->res)) {
> +		pr_err("Cannot allocate goldfish-timer resource\n");

nit: pr_err("Cannot allocate '%s' resource\n", res.name);

> +		return;
> +	}
> +
> +	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(timerdrv->irq, golfish_timer_tick, IRQF_TIMER,
> +			  "goldfish_timer", &timerdrv->ced);

Why not pass directly 'timerdrv' ?

> +	if (ret) {
> +		pr_err("Couldn't register goldfish-timer interrupt\n");
> +		return;
> +	}
> +
> +	clockevents_config_and_register(&timerdrv->ced, NSEC_PER_SEC,
> +					1, 0xffffffff);
> +}
> diff --git a/include/clocksource/timer-goldfish.h b/include/clocksource/timer-goldfish.h
> new file mode 100644
> index 000000000000..b237267844f1
> --- /dev/null
> +++ b/include/clocksource/timer-goldfish.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * goldfish-timer clocksource
> + */
> +
> +#ifndef _CLOCKSOURCE_GOLDFISH_TIMER_H
> +#define _CLOCKSOURCE_GOLDFISH_TIMER_H
> +
> +extern void goldfish_timer_init(int irq, void __iomem *base);
> +
> +#endif /* _CLOCKSOURCE_GOLDFISH_TIMER_H */
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

  reply	other threads:[~2022-01-26 11:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-21 20:07 [PATCH v12 0/5] m68k: Add Virtual M68k Machine Laurent Vivier
2022-01-21 20:07 ` [PATCH v12 1/5] m68k: add asm/config.h Laurent Vivier
2022-01-21 20:07 ` [PATCH v12 2/5] tty: goldfish: introduce gf_ioread32()/gf_iowrite32() Laurent Vivier
2022-01-26 13:41   ` Greg KH
2022-01-26 14:15     ` Arnd Bergmann
2022-01-26 17:32     ` Laurent Vivier
2022-01-21 20:07 ` [PATCH v12 3/5] rtc: goldfish: use gf_ioread32()/gf_iowrite32() Laurent Vivier
2022-01-21 20:07 ` [PATCH v12 4/5] clocksource/drivers: Add a goldfish-timer clocksource Laurent Vivier
2022-01-26 11:55   ` Daniel Lezcano [this message]
2022-01-26 17:14     ` Laurent Vivier
2022-01-26 17:25       ` Daniel Lezcano
2022-01-21 20:07 ` [PATCH v12 5/5] m68k: introduce a virtual m68k machine Laurent Vivier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2dc495b0-b9a1-e493-ddeb-d966afd624c0@linaro.org \
    --to=daniel.lezcano@linaro.org \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@bootlin.com \
    --cc=arnd@arndb.de \
    --cc=geert@linux-m68k.org \
    --cc=jiaxun.yang@flygoat.com \
    --cc=john.stultz@linaro.org \
    --cc=laurent@vivier.eu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=sboyd@kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.