Subject: [PATCH 2/5] clocksource: Add Allwinner SoCs HS timers driver

From: [email-masked] (Maxime Ripard)
Date: Thu, 26 Sep 2013 15:58:52 +0300

Hi Stephen,

On Wed, Sep 25, 2013 at 04:16:14PM -0700, Stephen Boyd wrote:
> On 09/25/13 07:03, Maxime Ripard wrote:
> > diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
> > new file mode 100644
> > index 0000000..b1f81e9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
> > @@ -0,0 +1,22 @@
> > +Allwinner SoCs High Speed Timer Controller
> > +
> > +Required properties:
> > +
> > +- compatible :	should be "allwinner,sun5i-a13-hstimer" or
> > +		"allwinner,sun7i-a20-hstimer"
> > +- reg : Specifies base physical address and size of the registers.
> > +- interrupts :	The interrupts of these timers (2 for the sun5i IP, 4 for the sun7i
> > +		one)
> > +- clocks: phandle to the source clock (usually the AHB clock)
> > +
> > +Example:
> > +
> > +hstimer at 01c60000 {
> 
> This should just be 'timer at 1c60000'

Ok.

> > +	compatible = "allwinner,sun7i-a20-hstimer";
> > +        reg = <0x01c60000 0x1000>;
> > +        interrupts = <0 51 1>,
> > +                     <0 52 1>,
> > +                     <0 53 1>,
> > +                     <0 54 1>;
> > +        clocks = <&ahb1_gates 19>;
> > +};
> 
> Weird mix of tabs and spaces here.

Right.

> > +
> > +static void __iomem *timer_base;
> > +static u32 ticks_per_jiffy;
> > +
> > +/*
> > + * 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
> > + * that is already setup and runs at the same frequency than the other
> > + * timers, and we never will be disabled.
> > + */
> > +static void sun5i_clkevt_sync(void)
> > +{
> > +	u32 old = readl(timer_base + TIMER_CNTVAL_LO_REG(1));
> > +
> > +	while ((old - readl(timer_base + TIMER_CNTVAL_LO_REG(1))) < 3)
> > +		cpu_relax();
> > +}
> > +
> [...]
> > +
> > +static int sun5i_clkevt_next_event(unsigned long evt,
> > +				   struct clock_event_device *unused)
> > +{
> > +	sun5i_clkevt_time_stop(0);
> > +	sun5i_clkevt_time_setup(0, evt);
> > +	sun5i_clkevt_time_start(0, false);
> 
> I suppose the min delta wants to be 3 instead of 1 because if we program
> an evt one tick in the future first we'll wait for two ticks (or is that
> three?) while we stop the timer and then program the timer to fire one
> tick after that. Perhaps we should subtract two ticks from the evt as
> well when we program it here?

Hmmm, indeed.

> > +
> > +	return 0;
> > +}
> > +
> > +static struct clock_event_device sun5i_clockevent = {
> > +	.name = "sun5i_tick",
> > +	.rating = 350,
> > +	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> > +	.set_mode = sun5i_clkevt_mode,
> > +	.set_next_event = sun5i_clkevt_next_event,
> > +};
> > +
> > +
> > +static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
> > +{
> > +	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
> > +
> > +	writel(0x1, timer_base + TIMER_IRQ_ST_REG);
> > +	evt->event_handler(evt);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static struct irqaction sun5i_timer_irq = {
> > +	.name = "sun5i_timer0",
> > +	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> 
> IRQF_DISABLED is a no-op and can be dropped.

Right.

> > +
> > +static u32 sun5i_timer_sched_read(void)
> > +{
> > +	return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1));
> > +}
> > +
> > +static void __init sun5i_timer_init(struct device_node *node)
> > +{
> [...]
> > +
> > +	sun5i_clockevent.cpumask = cpumask_of(0);
> 
> Can this timer interrupt any CPU or is it hardwired to CPU0? If the
> interrupt can go to any CPU this should be cpu_possible_mask instead.

This is an interrupt that can interrupt any CPU available on the system,
so yes, cpu_possible_mask would make sense.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130926/593567ba/attachment-0001.sig>