|
|
Log in / Subscribe / Register

Re: [PATCH 3/9] clocksource: dw_apb_timer: quirk for variants with 64bit counter

From:  Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ-AT-public.gmane.org>
To:  Heiko Stübner <heiko-4mtYJXux2i+zQB+pC5nmwQ-AT-public.gmane.org>
Subject:  Re: [PATCH 3/9] clocksource: dw_apb_timer: quirk for variants with 64bit counter
Date:  Sat, 6 Jul 2013 01:45:09 +0200 (CEST)
Message-ID:  <alpine.DEB.2.02.1307060129340.32106@ionos.tec.linutronix.de>
Cc:  devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ-AT-public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA-AT-public.gmane.org, Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ-AT-public.gmane.org>, John Stultz <john.stultz-QSEj5FYQhm4dnm+yROfE0A-AT-public.gmane.org>, Grant Likely <grant.likely-QSEj5FYQhm4dnm+yROfE0A-AT-public.gmane.org>, Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ-AT-public.gmane.org>, Ulrich Prinz <ulrich.prinz-gM/Ye1E23mwN+BqQ9rBEUg-AT-public.gmane.org>, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r-AT-public.gmane.org
Archive‑link:  Article

On Sat, 6 Jul 2013, Heiko Stübner wrote:

> This adds a quirk for IP variants containing two load_count and value
> registers that are used to provide 64bit accuracy on 32bit systems.
> 
> The added accuracy is currently not used, the driver is only adapted to
> handle the different register layout and make it work on affected devices.
> 
> Signed-off-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
> ---
>  drivers/clocksource/dw_apb_timer.c |   27 +++++++++++++++++++++++++++
>  include/linux/dw_apb_timer.h       |    6 ++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c
> index f5e7be8..bd45351 100644
> --- a/drivers/clocksource/dw_apb_timer.c
> +++ b/drivers/clocksource/dw_apb_timer.c
> @@ -56,6 +56,17 @@ static void apbt_init_regs(struct dw_apb_timer *timer, int quirks)
>  	timer->reg_control = APBTMR_N_CONTROL;
>  	timer->reg_eoi = APBTMR_N_EOI;
>  	timer->reg_int_status = APBTMR_N_INT_STATUS;
> +
> +	/*
> +	 * On variants with 64bit counters some registers are
> +	 * moved further down.
> +	 */
> +	if (quirks & APBTMR_QUIRK_64BIT_COUNTER) {
> +		timer->reg_current_value += 0x4;
> +		timer->reg_control += 0x8;
> +		timer->reg_eoi += 0x8;
> +		timer->reg_int_status += 0x8;
> +	}
>  }

Oh, no. this is not how we handle these things.

1) We want proper constants for this 64bit IP block 

2) This is not a quirk, it's a property of that particular IP block

You already made the register offsets a part of the timer structure,
so why don't you supply a proper structure filled with that values to
the init function?

That's what we do all over the place. Either we instantiate those
structs at compile time or runtime fed by device tree or any other
configuration mechanism.
  
>  static unsigned long apbt_readl(struct dw_apb_timer *timer, unsigned long offs)
> @@ -145,6 +156,10 @@ static void apbt_set_mode(enum clock_event_mode mode,
>  		udelay(1);
>  		pr_debug("Setting clock period %lu for HZ %d\n", period, HZ);
>  		apbt_writel(timer, period, timer->reg_load_count);
> +
> +		if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
> +			apbt_writel(timer, 0, timer->reg_load_count + 0x4);
> +

No. We are not adding such conditional constructs when we can deal
with them just by providing a proper set of function pointers. And
definitely not with hardcoded magic 0x4 constants involved.

     timer->load_count(timer, value);

Provide a 32 bit and a 64 bit version of that function and be done
with it.

>  		ctrl |= APBTMR_CONTROL_ENABLE;
>  		apbt_writel(timer, ctrl, timer->reg_control);
>  		break;
> @@ -168,6 +183,10 @@ static void apbt_set_mode(enum clock_event_mode mode,
>  		 * running mode.
>  		 */
>  		apbt_writel(timer, ~0, timer->reg_load_count);
> +
> +		if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
> +			apbt_writel(timer, 0, timer->reg_load_count + 0x4);
> +

Makes this copy go away.

>  		ctrl &= ~APBTMR_CONTROL_INT;
>  		ctrl |= APBTMR_CONTROL_ENABLE;
>  		apbt_writel(timer, ctrl, timer->reg_control);
> @@ -199,6 +218,10 @@ static int apbt_next_event(unsigned long delta,
>  	apbt_writel(timer, ctrl, timer->reg_control);
>  	/* write new count */
>  	apbt_writel(timer, delta, timer->reg_load_count);
> +
> +	if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
> +		apbt_writel(timer, 0, timer->reg_load_count + 0x4);
> +

And this one as well.

>  	ctrl |= APBTMR_CONTROL_ENABLE;
>  	apbt_writel(timer, ctrl, timer->reg_control);
>  
> @@ -325,6 +348,10 @@ void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
>  	ctrl &= ~APBTMR_CONTROL_ENABLE;
>  	apbt_writel(timer, ctrl, timer->reg_control);
>  	apbt_writel(timer, ~0, timer->reg_load_count);
> +
> +	if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
> +		apbt_writel(timer, 0, timer->reg_load_count + 0x4);
> +

Copy and paste is a conveniant thing, right? It just should have a pop
up window assigned which asks at the second instance of copying the
same thing whether you really thought about it.

Thanks,

	tglx_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss



to post comments

Re: [PATCH 3/9] clocksource: dw_apb_timer: quirk for variants with 64bit counter

Posted Jul 13, 2013 5:03 UTC (Sat) by willp (guest, #52971) [Link]

awesome. i never thought about it before. a whole category of anti-pattern that is fixable at the UI layer!

another option would be to clear the paste buffer when a user pastes. where's the petition i can sign for this? :-)

<INSERT snarky comment about some horrible PHP project codebase HERE>


Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds