diff mbox series

[1/2] clocksource: Add Ralink System Tick Counter driver

Message ID 20240920075306.704665-2-sergio.paracuellos@gmail.com (mailing list archive)
State New
Headers show
Series clocksource: move System Tick Counter from 'arch/mips/ralink' | expand

Commit Message

Sergio Paracuellos Sept. 20, 2024, 7:53 a.m. UTC
System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
driver has been in 'arch/mips/ralink' directory since the beggining of
Ralink architecture support. However, it can be moved into a more proper
place in 'drivers/clocksource'. Hence add it here adding also support for
compile test targets.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/clocksource/Kconfig        |  10 ++
 drivers/clocksource/Makefile       |   1 +
 drivers/clocksource/timer-ralink.c | 150 +++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/clocksource/timer-ralink.c

Comments

Daniel Lezcano Oct. 28, 2024, 4:29 p.m. UTC | #1
On 20/09/2024 09:53, Sergio Paracuellos wrote:
> System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
> driver has been in 'arch/mips/ralink' directory since the beggining of
> Ralink architecture support. However, it can be moved into a more proper
> place in 'drivers/clocksource'. Hence add it here adding also support for
> compile test targets.
> 
> Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
> ---
>   drivers/clocksource/Kconfig        |  10 ++
>   drivers/clocksource/Makefile       |   1 +
>   drivers/clocksource/timer-ralink.c | 150 +++++++++++++++++++++++++++++
>   3 files changed, 161 insertions(+)
>   create mode 100644 drivers/clocksource/timer-ralink.c
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 95dd4660b5b6..50339f4d3201 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -753,4 +753,14 @@ config EP93XX_TIMER
>   	  Enables support for the Cirrus Logic timer block
>   	  EP93XX.
>   
> +config CLKSRC_RALINK

It is a timer

	RALINK_TIMER

> +	bool "Ralink System Tick Counter"

Silent option please if possible.

Let the platform Kconfig selects the driver

> +	depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
> +	default y if SOC_RT305X || SOC_MT7620

You should have something similar the RISCV option, no default option

> +	select CLKSRC_MMIO
> +	select TIMER_OF
> +	help
> +	  Enables support for system tick counter present on
> +	  Ralink SoCs RT3352 and MT7620.
> +
>   endmenu
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 22743785299e..c9214afcb712 100644
> --- a/drivers/clocksource/Makefile

You should use git mv

Otherwise the code is like submitting a new driver
Sergio Paracuellos Oct. 28, 2024, 6:04 p.m. UTC | #2
Hi Daniel,

Thanks for reviewing this.

On Mon, Oct 28, 2024 at 5:29 PM Daniel Lezcano
<daniel.lezcano@linaro.org> wrote:
>
> On 20/09/2024 09:53, Sergio Paracuellos wrote:
> > System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
> > driver has been in 'arch/mips/ralink' directory since the beggining of
> > Ralink architecture support. However, it can be moved into a more proper
> > place in 'drivers/clocksource'. Hence add it here adding also support for
> > compile test targets.
> >
> > Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
> > ---
> >   drivers/clocksource/Kconfig        |  10 ++
> >   drivers/clocksource/Makefile       |   1 +
> >   drivers/clocksource/timer-ralink.c | 150 +++++++++++++++++++++++++++++
> >   3 files changed, 161 insertions(+)
> >   create mode 100644 drivers/clocksource/timer-ralink.c
> >
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index 95dd4660b5b6..50339f4d3201 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -753,4 +753,14 @@ config EP93XX_TIMER
> >         Enables support for the Cirrus Logic timer block
> >         EP93XX.
> >
> > +config CLKSRC_RALINK
>
> It is a timer
>
>         RALINK_TIMER

Sure, I will change to RALINK_TIMER instead.

>
> > +     bool "Ralink System Tick Counter"
>
> Silent option please if possible.
>
> Let the platform Kconfig selects the driver
>
> > +     depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
> > +     default y if SOC_RT305X || SOC_MT7620
>
> You should have something similar the RISCV option, no default option

Sorry, I am not the best with Kconfig so I am not sure what you are
exactly expecting here.
Does the following work for you?

config RALINK_TIMER
   bool "Ralink System Tick Counter" if COMPILE_TEST
   depends on SOC_RT305X || SOC_MT7620
   select CLKSRC_MMIO
   select TIMER_OF
   help
     Enables support for system tick counter present on
     Ralink SoCs RT3352 and MT7620.


>
> > +     select CLKSRC_MMIO
> > +     select TIMER_OF
> > +     help
> > +       Enables support for system tick counter present on
> > +       Ralink SoCs RT3352 and MT7620.
> > +
> >   endmenu
> > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> > index 22743785299e..c9214afcb712 100644
> > --- a/drivers/clocksource/Makefile
>
> You should use git mv
>
> Otherwise the code is like submitting a new driver

Ok, i will squash two patches in one performing the git mv then.

Thanks,
    Sergio Paracuellos
>
>
>
> --
> <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
Daniel Lezcano Oct. 28, 2024, 6:44 p.m. UTC | #3
On 28/10/2024 19:04, Sergio Paracuellos wrote:
> Hi Daniel,
> 
> Thanks for reviewing this.
> 
> On Mon, Oct 28, 2024 at 5:29 PM Daniel Lezcano
> <daniel.lezcano@linaro.org> wrote:
>>
>> On 20/09/2024 09:53, Sergio Paracuellos wrote:
>>> System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
>>> driver has been in 'arch/mips/ralink' directory since the beggining of
>>> Ralink architecture support. However, it can be moved into a more proper
>>> place in 'drivers/clocksource'. Hence add it here adding also support for
>>> compile test targets.
>>>
>>> Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
>>> ---
>>>    drivers/clocksource/Kconfig        |  10 ++
>>>    drivers/clocksource/Makefile       |   1 +
>>>    drivers/clocksource/timer-ralink.c | 150 +++++++++++++++++++++++++++++
>>>    3 files changed, 161 insertions(+)
>>>    create mode 100644 drivers/clocksource/timer-ralink.c
>>>
>>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>>> index 95dd4660b5b6..50339f4d3201 100644
>>> --- a/drivers/clocksource/Kconfig
>>> +++ b/drivers/clocksource/Kconfig
>>> @@ -753,4 +753,14 @@ config EP93XX_TIMER
>>>          Enables support for the Cirrus Logic timer block
>>>          EP93XX.
>>>
>>> +config CLKSRC_RALINK
>>
>> It is a timer
>>
>>          RALINK_TIMER
> 
> Sure, I will change to RALINK_TIMER instead.
> 
>>
>>> +     bool "Ralink System Tick Counter"
>>
>> Silent option please if possible.
>>
>> Let the platform Kconfig selects the driver
>>
>>> +     depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
>>> +     default y if SOC_RT305X || SOC_MT7620
>>
>> You should have something similar the RISCV option, no default option
> 
> Sorry, I am not the best with Kconfig so I am not sure what you are
> exactly expecting here.MT7620
> Does the following work for you?
> 
> config RALINK_TIMER
>     bool "Ralink System Tick Counter" if COMPILE_TEST
>     depends on SOC_RT305X || SOC_MT7620
>     select CLKSRC_MMIO
>     select TIMER_OF
>     help
>       Enables support for system tick counter present on
>       Ralink SoCs RT3352 and MT7620.

Basically the idea is to have the platform's Kconfig selecting the 
RALINK_TIMER. If I'm not wrong the Kconfig in arch/riscv/ralink should 
select RALINK_TIMER under the "config SOC_RT305X" and "config 
SOC_MT7620". The block "config CLKEVT_RT3352" has to be removed.

Then this (clocksource) Kconfig option is a silent option. The user 
won't have to figure out which option to enable because that will be 
done directly when selecting RT305X or MT7620.

The only reason to not have it silent is if you really want to opt-out 
this timer because it is not present on a different version of RT305X or 
MT7620.

IOW, this option should be:

config RALINK_TIMER
      bool "Ralink System Tick Counter" if COMPILE_TEST
      select CLKSRC_MMIO
      select TIMER_OF
      help
        Enables support for system tick counter present on
        Ralink SoCs RT3352 and MT7620.

The option COMPILE_TEST is to compile on different platforms, thus 
increasing the compilation test coverage. At the first glance, the 
driver does not seem to pull arch dependent code except definitions 
which look compatible with other archs, so it should be fine.


>>> +     select CLKSRC_MMIO
>>> +     select TIMER_OF
>>> +     help
>>> +       Enables support for system tick counter present on
>>> +       Ralink SoCs RT3352 and MT7620.
>>> +
>>>    endmenu
>>> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
>>> index 22743785299e..c9214afcb712 100644
>>> --- a/drivers/clocksource/Makefile
>>
>> You should use git mv
>>
>> Otherwise the code is like submitting a new driver
> 
> Ok, i will squash two patches in one performing the git mv then.
> 
> Thanks,
>      Sergio Paracuellos
>>
>>
>>
>> --
>> <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
Sergio Paracuellos Oct. 28, 2024, 7:02 p.m. UTC | #4
Hi Daniel,

Thanks a lot for the detailed explanation. It was really helpful.

On Mon, Oct 28, 2024 at 7:44 PM Daniel Lezcano
<daniel.lezcano@linaro.org> wrote:
>
> On 28/10/2024 19:04, Sergio Paracuellos wrote:
> > Hi Daniel,
> >
> > Thanks for reviewing this.
> >
> > On Mon, Oct 28, 2024 at 5:29 PM Daniel Lezcano
> > <daniel.lezcano@linaro.org> wrote:
> >>
> >> On 20/09/2024 09:53, Sergio Paracuellos wrote:
> >>> System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
> >>> driver has been in 'arch/mips/ralink' directory since the beggining of
> >>> Ralink architecture support. However, it can be moved into a more proper
> >>> place in 'drivers/clocksource'. Hence add it here adding also support for
> >>> compile test targets.
> >>>
> >>> Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
> >>> ---
> >>>    drivers/clocksource/Kconfig        |  10 ++
> >>>    drivers/clocksource/Makefile       |   1 +
> >>>    drivers/clocksource/timer-ralink.c | 150 +++++++++++++++++++++++++++++
> >>>    3 files changed, 161 insertions(+)
> >>>    create mode 100644 drivers/clocksource/timer-ralink.c
> >>>
> >>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> >>> index 95dd4660b5b6..50339f4d3201 100644
> >>> --- a/drivers/clocksource/Kconfig
> >>> +++ b/drivers/clocksource/Kconfig
> >>> @@ -753,4 +753,14 @@ config EP93XX_TIMER
> >>>          Enables support for the Cirrus Logic timer block
> >>>          EP93XX.
> >>>
> >>> +config CLKSRC_RALINK
> >>
> >> It is a timer
> >>
> >>          RALINK_TIMER
> >
> > Sure, I will change to RALINK_TIMER instead.
> >
> >>
> >>> +     bool "Ralink System Tick Counter"
> >>
> >> Silent option please if possible.
> >>
> >> Let the platform Kconfig selects the driver
> >>
> >>> +     depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
> >>> +     default y if SOC_RT305X || SOC_MT7620
> >>
> >> You should have something similar the RISCV option, no default option
> >
> > Sorry, I am not the best with Kconfig so I am not sure what you are
> > exactly expecting here.MT7620
> > Does the following work for you?
> >
> > config RALINK_TIMER
> >     bool "Ralink System Tick Counter" if COMPILE_TEST
> >     depends on SOC_RT305X || SOC_MT7620
> >     select CLKSRC_MMIO
> >     select TIMER_OF
> >     help
> >       Enables support for system tick counter present on
> >       Ralink SoCs RT3352 and MT7620.
>
> Basically the idea is to have the platform's Kconfig selecting the
> RALINK_TIMER. If I'm not wrong the Kconfig in arch/riscv/ralink should
> select RALINK_TIMER under the "config SOC_RT305X" and "config
> SOC_MT7620". The block "config CLKEVT_RT3352" has to be removed.
>
> Then this (clocksource) Kconfig option is a silent option. The user
> won't have to figure out which option to enable because that will be
> done directly when selecting RT305X or MT7620.
>
> The only reason to not have it silent is if you really want to opt-out
> this timer because it is not present on a different version of RT305X or
> MT7620.

Ok, then I don't want to silence it since those ralink's platform
SOC_RT305X and SOC_MT7620 includes other SoCs models that do not have
this timer (rt3050, mt7628 for example). Only models
rt3352 and mt7620 include this. So I guess having this is the correct
thing to do:

config RALINK_TIMER
    bool "Ralink System Tick Counter" if COMPILE_TEST
    depends on SOC_RT305X || SOC_MT7620
    select CLKSRC_MMIO
    select TIMER_OF
    help
       Enables support for system tick counter present on
       Ralink SoCs RT3352 and MT7620.

Are you ok with this?

>
> IOW, this option should be:
>
> config RALINK_TIMER
>       bool "Ralink System Tick Counter" if COMPILE_TEST
>       select CLKSRC_MMIO
>       select TIMER_OF
>       help
>         Enables support for system tick counter present on
>         Ralink SoCs RT3352 and MT7620.
>
> The option COMPILE_TEST is to compile on different platforms, thus
> increasing the compilation test coverage. At the first glance, the
> driver does not seem to pull arch dependent code except definitions
> which look compatible with other archs, so it should be fine.

Yes, there is no arch dependencies since the only include which was
dependent was not really needed and I already got rid of it when I
performed the git mv. I already checked
that the driver is properly compiled for allyesconfig target.

Thanks,
    Sergio Paracuellos

>
>
> >>> +     select CLKSRC_MMIO
> >>> +     select TIMER_OF
> >>> +     help
> >>> +       Enables support for system tick counter present on
> >>> +       Ralink SoCs RT3352 and MT7620.
> >>> +
> >>>    endmenu
> >>> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> >>> index 22743785299e..c9214afcb712 100644
> >>> --- a/drivers/clocksource/Makefile
> >>
> >> You should use git mv
> >>
> >> Otherwise the code is like submitting a new driver
> >
> > Ok, i will squash two patches in one performing the git mv then.
> >
> > Thanks,
> >      Sergio Paracuellos
> >>
> >>
> >>
> >> --
> >> <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
>
>
> --
> <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
Daniel Lezcano Oct. 28, 2024, 7:40 p.m. UTC | #5
On 28/10/2024 20:02, Sergio Paracuellos wrote:
> Hi Daniel,
> 
> Thanks a lot for the detailed explanation. It was really helpful.
> 
> On Mon, Oct 28, 2024 at 7:44 PM Daniel Lezcano
> <daniel.lezcano@linaro.org> wrote:
>>
>> On 28/10/2024 19:04, Sergio Paracuellos wrote:
>>> Hi Daniel,
>>>
>>> Thanks for reviewing this.
>>>
>>> On Mon, Oct 28, 2024 at 5:29 PM Daniel Lezcano
>>> <daniel.lezcano@linaro.org> wrote:
>>>>
>>>> On 20/09/2024 09:53, Sergio Paracuellos wrote:
>>>>> System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
>>>>> driver has been in 'arch/mips/ralink' directory since the beggining of
>>>>> Ralink architecture support. However, it can be moved into a more proper
>>>>> place in 'drivers/clocksource'. Hence add it here adding also support for
>>>>> compile test targets.
>>>>>
>>>>> Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
>>>>> ---
>>>>>     drivers/clocksource/Kconfig        |  10 ++
>>>>>     drivers/clocksource/Makefile       |   1 +
>>>>>     drivers/clocksource/timer-ralink.c | 150 +++++++++++++++++++++++++++++
>>>>>     3 files changed, 161 insertions(+)
>>>>>     create mode 100644 drivers/clocksource/timer-ralink.c
>>>>>
>>>>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>>>>> index 95dd4660b5b6..50339f4d3201 100644
>>>>> --- a/drivers/clocksource/Kconfig
>>>>> +++ b/drivers/clocksource/Kconfig
>>>>> @@ -753,4 +753,14 @@ config EP93XX_TIMER
>>>>>           Enables support for the Cirrus Logic timer block
>>>>>           EP93XX.
>>>>>
>>>>> +config CLKSRC_RALINK
>>>>
>>>> It is a timer
>>>>
>>>>           RALINK_TIMER
>>>
>>> Sure, I will change to RALINK_TIMER instead.
>>>
>>>>
>>>>> +     bool "Ralink System Tick Counter"
>>>>
>>>> Silent option please if possible.
>>>>
>>>> Let the platform Kconfig selects the driver
>>>>
>>>>> +     depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
>>>>> +     default y if SOC_RT305X || SOC_MT7620
>>>>
>>>> You should have something similar the RISCV option, no default option
>>>
>>> Sorry, I am not the best with Kconfig so I am not sure what you are
>>> exactly expecting here.MT7620
>>> Does the following work for you?
>>>
>>> config RALINK_TIMER
>>>      bool "Ralink System Tick Counter" if COMPILE_TEST
>>>      depends on SOC_RT305X || SOC_MT7620
>>>      select CLKSRC_MMIO
>>>      select TIMER_OF
>>>      help
>>>        Enables support for system tick counter present on
>>>        Ralink SoCs RT3352 and MT7620.
>>
>> Basically the idea is to have the platform's Kconfig selecting the
>> RALINK_TIMER. If I'm not wrong the Kconfig in arch/riscv/ralink should
>> select RALINK_TIMER under the "config SOC_RT305X" and "config
>> SOC_MT7620". The block "config CLKEVT_RT3352" has to be removed.
>>
>> Then this (clocksource) Kconfig option is a silent option. The user
>> won't have to figure out which option to enable because that will be
>> done directly when selecting RT305X or MT7620.
>>
>> The only reason to not have it silent is if you really want to opt-out
>> this timer because it is not present on a different version of RT305X or
>> MT7620.
> 
> Ok, then I don't want to silence it since those ralink's platform
> SOC_RT305X and SOC_MT7620 includes other SoCs models that do not have
> this timer (rt3050, mt7628 for example). Only models
> rt3352 and mt7620 include this. So I guess having this is the correct
> thing to do:
> 
> config RALINK_TIMER
>      bool "Ralink System Tick Counter" if COMPILE_TEST
>      depends on SOC_RT305X || SOC_MT7620
>      select CLKSRC_MMIO
>      select TIMER_OF
>      help
>         Enables support for system tick counter present on
>         Ralink SoCs RT3352 and MT7620.
> 
> Are you ok with this?


No because it is a compile test option only. You may want to do the same as:

https://lore.kernel.org/all/20241001-arm64-vexpress-sp804-v3-1-0a2d3f7883e4@kernel.org/

It should be:

config RALINK_TIMER
	bool "Ralink System Tick Counter"
	depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
	select CLKSRC_MMIO
	select TIMER_OF
	help
	  Enables support for system tick counter present on
	  Ralink SoCs RT3352 and MT7620.

so very similar to the initial patch except no default is needed as it 
should be set from SOC_RT305X or SOC_MT7620
diff mbox series

Patch

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 95dd4660b5b6..50339f4d3201 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -753,4 +753,14 @@  config EP93XX_TIMER
 	  Enables support for the Cirrus Logic timer block
 	  EP93XX.
 
+config CLKSRC_RALINK
+	bool "Ralink System Tick Counter"
+	depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
+	default y if SOC_RT305X || SOC_MT7620
+	select CLKSRC_MMIO
+	select TIMER_OF
+	help
+	  Enables support for system tick counter present on
+	  Ralink SoCs RT3352 and MT7620.
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 22743785299e..c9214afcb712 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -91,3 +91,4 @@  obj-$(CONFIG_GOLDFISH_TIMER)		+= timer-goldfish.o
 obj-$(CONFIG_GXP_TIMER)			+= timer-gxp.o
 obj-$(CONFIG_CLKSRC_LOONGSON1_PWM)	+= timer-loongson1-pwm.o
 obj-$(CONFIG_EP93XX_TIMER)		+= timer-ep93xx.o
+obj-$(CONFIG_CLKSRC_RALINK)		+= timer-ralink.o
diff --git a/drivers/clocksource/timer-ralink.c b/drivers/clocksource/timer-ralink.c
new file mode 100644
index 000000000000..6ecdb4228f76
--- /dev/null
+++ b/drivers/clocksource/timer-ralink.c
@@ -0,0 +1,150 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ralink System Tick Counter driver present on RT3352 and MT7620 SoCs.
+ *
+ * Copyright (C) 2013 by John Crispin <john@phrozen.org>
+ */
+
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/reset.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#define SYSTICK_FREQ		(50 * 1000)
+
+#define SYSTICK_CONFIG		0x00
+#define SYSTICK_COMPARE		0x04
+#define SYSTICK_COUNT		0x08
+
+/* route systick irq to mips irq 7 instead of the r4k-timer */
+#define CFG_EXT_STK_EN		0x2
+/* enable the counter */
+#define CFG_CNT_EN		0x1
+
+struct systick_device {
+	void __iomem *membase;
+	struct clock_event_device dev;
+	int irq_requested;
+	int freq_scale;
+};
+
+static int systick_set_oneshot(struct clock_event_device *evt);
+static int systick_shutdown(struct clock_event_device *evt);
+
+static int systick_next_event(unsigned long delta,
+			      struct clock_event_device *evt)
+{
+	struct systick_device *sdev;
+	u32 count;
+
+	sdev = container_of(evt, struct systick_device, dev);
+	count = ioread32(sdev->membase + SYSTICK_COUNT);
+	count = (count + delta) % SYSTICK_FREQ;
+	iowrite32(count, sdev->membase + SYSTICK_COMPARE);
+
+	return 0;
+}
+
+static void systick_event_handler(struct clock_event_device *dev)
+{
+	/* noting to do here */
+}
+
+static irqreturn_t systick_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *dev = (struct clock_event_device *)dev_id;
+
+	dev->event_handler(dev);
+
+	return IRQ_HANDLED;
+}
+
+static struct systick_device systick = {
+	.dev = {
+		/*
+		 * cevt-r4k uses 300, make sure systick
+		 * gets used if available
+		 */
+		.rating			= 310,
+		.features		= CLOCK_EVT_FEAT_ONESHOT,
+		.set_next_event		= systick_next_event,
+		.set_state_shutdown	= systick_shutdown,
+		.set_state_oneshot	= systick_set_oneshot,
+		.event_handler		= systick_event_handler,
+	},
+};
+
+static int systick_shutdown(struct clock_event_device *evt)
+{
+	struct systick_device *sdev;
+
+	sdev = container_of(evt, struct systick_device, dev);
+
+	if (sdev->irq_requested)
+		free_irq(systick.dev.irq, &systick.dev);
+	sdev->irq_requested = 0;
+	iowrite32(0, systick.membase + SYSTICK_CONFIG);
+
+	return 0;
+}
+
+static int systick_set_oneshot(struct clock_event_device *evt)
+{
+	const char *name = systick.dev.name;
+	struct systick_device *sdev;
+	int irq = systick.dev.irq;
+
+	sdev = container_of(evt, struct systick_device, dev);
+
+	if (!sdev->irq_requested) {
+		if (request_irq(irq, systick_interrupt,
+				IRQF_PERCPU | IRQF_TIMER, name, &systick.dev))
+			pr_err("Failed to request irq %d (%s)\n", irq, name);
+	}
+	sdev->irq_requested = 1;
+	iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
+		  systick.membase + SYSTICK_CONFIG);
+
+	return 0;
+}
+
+static int __init ralink_systick_init(struct device_node *np)
+{
+	int ret;
+
+	systick.membase = of_iomap(np, 0);
+	if (!systick.membase)
+		return -ENXIO;
+
+	systick.dev.name = np->name;
+	clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
+	systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
+	systick.dev.max_delta_ticks = 0x7fff;
+	systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
+	systick.dev.min_delta_ticks = 0x3;
+	systick.dev.irq = irq_of_parse_and_map(np, 0);
+	if (!systick.dev.irq) {
+		pr_err("%pOFn: request_irq failed", np);
+		return -EINVAL;
+	}
+
+	ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
+				    SYSTICK_FREQ, 301, 16,
+				    clocksource_mmio_readl_up);
+	if (ret)
+		return ret;
+
+	clockevents_register_device(&systick.dev);
+
+	pr_info("%pOFn: running - mult: %d, shift: %d\n",
+			np, systick.dev.mult, systick.dev.shift);
+
+	return 0;
+}
+
+TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);