From ef89af1f4380b922bdadd31c9e49829a022f55ae Mon Sep 17 00:00:00 2001 From: Yanchang Li Date: Tue, 11 Nov 2014 20:42:52 +0800 Subject: clocksource: sirf: Remove hard-coded clock rate The customers may want to adjust the whole PLL and dividers according to different user scenerios, and this causes the parent clock of sirf clocksource not be divided exactly by the current hard-coded 1MHz clock rate. This patch removes the hard-coded rate and makes the clocksource driver more adaptive to the external changes. Signed-off-by: Yanchang Li Signed-off-by: Barry Song Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-marco.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c index caf7a2030461..361a789d4bee 100644 --- a/drivers/clocksource/timer-marco.c +++ b/drivers/clocksource/timer-marco.c @@ -20,8 +20,6 @@ #include #include -#define MARCO_CLOCK_FREQ 1000000 - #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 #define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004 #define SIRFSOC_TIMER_MATCH_0 0x0018 @@ -40,6 +38,8 @@ #define SIRFSOC_TIMER_REG_CNT 6 +static unsigned long marco_timer_rate; + static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = { SIRFSOC_TIMER_WATCHDOG_EN, SIRFSOC_TIMER_32COUNTER_0_CTRL, @@ -195,7 +195,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce) ce->rating = 200; ce->set_mode = sirfsoc_timer_set_mode; ce->set_next_event = sirfsoc_timer_set_next_event; - clockevents_calc_mult_shift(ce, MARCO_CLOCK_FREQ, 60); + clockevents_calc_mult_shift(ce, marco_timer_rate, 60); ce->max_delta_ns = clockevent_delta2ns(-2, ce); ce->min_delta_ns = clockevent_delta2ns(2, ce); ce->cpumask = cpumask_of(cpu); @@ -257,7 +257,6 @@ static void __init sirfsoc_clockevent_init(void) /* initialize the kernel jiffy timer source */ static void __init sirfsoc_marco_timer_init(struct device_node *np) { - unsigned long rate; u32 timer_div; struct clk *clk; @@ -266,16 +265,12 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np) BUG_ON(clk_prepare_enable(clk)); - rate = clk_get_rate(clk); - - BUG_ON(rate < MARCO_CLOCK_FREQ); - BUG_ON(rate % MARCO_CLOCK_FREQ); + marco_timer_rate = clk_get_rate(clk); - /* Initialize the timer dividers */ - timer_div = rate / MARCO_CLOCK_FREQ - 1; - writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); - writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); - writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL); + /* timer dividers: 0, not divided */ + writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); + writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); + writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL); /* Initialize timer counters to 0 */ writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO); @@ -288,7 +283,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np) /* Clear all interrupts */ writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); - BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, MARCO_CLOCK_FREQ)); + BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, marco_timer_rate)); sirfsoc_clockevent_init(); } -- cgit v1.2.3 From fa5635a277171021d364f6a3fab4addce8f358d2 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:58 -0700 Subject: MIPS: Move GIC clocksource driver to drivers/clocksource/ Move the GIC clocksource driver to drivers/clocksource/mips-gic-timer.c. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8133/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 8 ++------ arch/mips/kernel/Makefile | 1 - arch/mips/kernel/csrc-gic.c | 32 -------------------------------- arch/mips/mti-malta/malta-time.c | 2 +- drivers/clocksource/Kconfig | 4 ++++ drivers/clocksource/Makefile | 1 + drivers/clocksource/mips-gic-timer.c | 32 ++++++++++++++++++++++++++++++++ drivers/irqchip/irq-mips-gic.c | 2 +- 8 files changed, 41 insertions(+), 41 deletions(-) delete mode 100644 arch/mips/kernel/csrc-gic.c create mode 100644 drivers/clocksource/mips-gic-timer.c (limited to 'drivers/clocksource') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3afb795c0125..5b690cf0fec7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -342,7 +342,7 @@ config MIPS_MALTA select BOOT_RAW select CEVT_R4K select CSRC_R4K - select CSRC_GIC + select CLKSRC_MIPS_GIC select DMA_MAYBE_COHERENT select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM @@ -385,7 +385,7 @@ config MIPS_SEAD3 select BUILTIN_DTB select CEVT_R4K select CSRC_R4K - select CSRC_GIC + select CLKSRC_MIPS_GIC select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI select DMA_NONCOHERENT @@ -954,10 +954,6 @@ config CSRC_IOASIC config CSRC_R4K bool -config CSRC_GIC - select MIPS_CM - bool - config CSRC_SB1250 bool diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 0945d804ec3a..1aedbf5e4232 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o -obj-$(CONFIG_CSRC_GIC) += csrc-gic.o obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c deleted file mode 100644 index 0bf28e6aca7a..000000000000 --- a/arch/mips/kernel/csrc-gic.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include -#include - -static cycle_t gic_hpt_read(struct clocksource *cs) -{ - return gic_read_count(); -} - -static struct clocksource gic_clocksource = { - .name = "GIC", - .read = gic_hpt_read, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -void __init gic_clocksource_init(unsigned int frequency) -{ - /* Set clocksource mask. */ - gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); - - /* Calculate a somewhat reasonable rating value. */ - gic_clocksource.rating = 200 + frequency / 10000000; - - clocksource_register_hz(&gic_clocksource, frequency); -} diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 608655f8e6dd..028fae077001 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -183,7 +183,7 @@ void __init plat_time_init(void) freq = freqround(gic_frequency, 5000); printk("GIC frequency %d.%02d MHz\n", freq/1000000, (freq%1000000)*100/1000000); -#ifdef CONFIG_CSRC_GIC +#ifdef CONFIG_CLKSRC_MIPS_GIC gic_clocksource_init(gic_frequency); #endif } diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 90420600e1eb..cb7e7f417a60 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -223,4 +223,8 @@ config CLKSRC_VERSATILE ARM Versatile, RealView and Versatile Express reference platforms. +config CLKSRC_MIPS_GIC + bool + depends on MIPS_GIC + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 756f6f10efa0..e23fc2d5fc27 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -46,3 +46,4 @@ obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o +obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c new file mode 100644 index 000000000000..0bf28e6aca7a --- /dev/null +++ b/drivers/clocksource/mips-gic-timer.c @@ -0,0 +1,32 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include +#include + +static cycle_t gic_hpt_read(struct clocksource *cs) +{ + return gic_read_count(); +} + +static struct clocksource gic_clocksource = { + .name = "GIC", + .read = gic_hpt_read, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void __init gic_clocksource_init(unsigned int frequency) +{ + /* Set clocksource mask. */ + gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); + + /* Calculate a somewhat reasonable rating value. */ + gic_clocksource.rating = 200 + frequency / 10000000; + + clocksource_register_hz(&gic_clocksource, frequency); +} diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index fbe2ceda4928..035d5ad435f9 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -103,7 +103,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); } -#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) +#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC) cycle_t gic_read_count(void) { unsigned int hi, hi2, lo; -- cgit v1.2.3 From a331ce63c85080f554e0a19fc4189a520c65267b Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:59 -0700 Subject: clocksource: mips-gic: Combine with GIC clockevent driver Combine the GIC clocksource driver with the GIC clockevent driver from arch/mips/kernel/cevt-gic.c and remove the clockevent driver's separate Kconfig symbol. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8132/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 13 ----- arch/mips/include/asm/time.h | 2 +- arch/mips/kernel/Makefile | 1 - arch/mips/kernel/cevt-gic.c | 103 ----------------------------------- drivers/clocksource/mips-gic-timer.c | 90 ++++++++++++++++++++++++++++++ drivers/irqchip/irq-mips-gic.c | 2 +- 6 files changed, 92 insertions(+), 119 deletions(-) delete mode 100644 arch/mips/kernel/cevt-gic.c (limited to 'drivers/clocksource') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5b690cf0fec7..97bbb3b09d4b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -935,10 +935,6 @@ config CEVT_GT641XX config CEVT_R4K bool -config CEVT_GIC - select MIPS_CM - bool - config CEVT_SB1250 bool @@ -1911,15 +1907,6 @@ config FORCE_MAX_ZONEORDER The page size is not necessarily 4KB. Keep this in mind when choosing a value for this option. -config CEVT_GIC - bool "Use GIC global counter for clock events" - depends on MIPS_GIC && !MIPS_SEAD3 - help - Use the GIC global counter for the clock events. The R4K clock - event driver is always present, so if the platform ends up not - detecting a GIC, it will fall back to the R4K timer for the - generation of clock events. - config BOARD_SCACHE bool diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 7969933ba89a..5f30aabbb598 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -57,7 +57,7 @@ extern int gic_clockevent_init(void); static inline int mips_clockevent_init(void) { -#if defined(CONFIG_CEVT_GIC) +#if defined(CONFIG_CLKSRC_MIPS_GIC) return (gic_clockevent_init() | r4k_clockevent_init()); #elif defined(CONFIG_CEVT_R4K) return r4k_clockevent_init(); diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 1aedbf5e4232..92987d1bbe5f 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -19,7 +19,6 @@ endif obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o -obj-$(CONFIG_CEVT_GIC) += cevt-gic.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c deleted file mode 100644 index 9caa68a2bcdc..000000000000 --- a/arch/mips/kernel/cevt-gic.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2013 Imagination Technologies Ltd. - */ -#include -#include -#include -#include -#include -#include - -#include -#include - -DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); -int gic_timer_irq_installed; - - -static int gic_next_event(unsigned long delta, struct clock_event_device *evt) -{ - u64 cnt; - int res; - - cnt = gic_read_count(); - cnt += (u64)delta; - gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); - res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; - return res; -} - -void gic_set_clock_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - /* Nothing to do ... */ -} - -irqreturn_t gic_compare_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *cd; - int cpu = smp_processor_id(); - - gic_write_compare(gic_read_compare()); - cd = &per_cpu(gic_clockevent_device, cpu); - cd->event_handler(cd); - return IRQ_HANDLED; -} - -struct irqaction gic_compare_irqaction = { - .handler = gic_compare_interrupt, - .flags = IRQF_PERCPU | IRQF_TIMER, - .name = "timer", -}; - - -void gic_event_handler(struct clock_event_device *dev) -{ -} - -int gic_clockevent_init(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - unsigned int irq; - - if (!cpu_has_counter || !gic_frequency) - return -ENXIO; - - irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); - - cd = &per_cpu(gic_clockevent_device, cpu); - - cd->name = "MIPS GIC"; - cd->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_C3STOP; - - clockevent_set_clock(cd, gic_frequency); - - /* Calculate the min / max delta */ - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - - cd->rating = 300; - cd->irq = irq; - cd->cpumask = cpumask_of(cpu); - cd->set_next_event = gic_next_event; - cd->set_mode = gic_set_clock_mode; - cd->event_handler = gic_event_handler; - - clockevents_register_device(cd); - - if (!gic_timer_irq_installed) { - setup_percpu_irq(irq, &gic_compare_irqaction); - gic_timer_irq_installed = 1; - } - - enable_percpu_irq(irq, IRQ_TYPE_NONE); - - - return 0; -} diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 0bf28e6aca7a..3cf5912c4054 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -5,10 +5,100 @@ * * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ +#include #include +#include #include +#include +#include #include +#include + +DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); +int gic_timer_irq_installed; + +static int gic_next_event(unsigned long delta, struct clock_event_device *evt) +{ + u64 cnt; + int res; + + cnt = gic_read_count(); + cnt += (u64)delta; + gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); + res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; + return res; +} + +void gic_set_clock_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + /* Nothing to do ... */ +} + +irqreturn_t gic_compare_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd; + int cpu = smp_processor_id(); + + gic_write_compare(gic_read_compare()); + cd = &per_cpu(gic_clockevent_device, cpu); + cd->event_handler(cd); + return IRQ_HANDLED; +} + +struct irqaction gic_compare_irqaction = { + .handler = gic_compare_interrupt, + .flags = IRQF_PERCPU | IRQF_TIMER, + .name = "timer", +}; + +void gic_event_handler(struct clock_event_device *dev) +{ +} + +int gic_clockevent_init(void) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + unsigned int irq; + + if (!cpu_has_counter || !gic_frequency) + return -ENXIO; + + irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); + + cd = &per_cpu(gic_clockevent_device, cpu); + + cd->name = "MIPS GIC"; + cd->features = CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_C3STOP; + + clockevent_set_clock(cd, gic_frequency); + + /* Calculate the min / max delta */ + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + + cd->rating = 300; + cd->irq = irq; + cd->cpumask = cpumask_of(cpu); + cd->set_next_event = gic_next_event; + cd->set_mode = gic_set_clock_mode; + cd->event_handler = gic_event_handler; + + clockevents_register_device(cd); + + if (!gic_timer_irq_installed) { + setup_percpu_irq(irq, &gic_compare_irqaction); + gic_timer_irq_installed = 1; + } + + enable_percpu_irq(irq, IRQ_TYPE_NONE); + + return 0; +} + static cycle_t gic_hpt_read(struct clocksource *cs) { return gic_read_count(); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 035d5ad435f9..cb674696810d 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -103,7 +103,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); } -#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC) +#ifdef CONFIG_CLKSRC_MIPS_GIC cycle_t gic_read_count(void) { unsigned int hi, hi2, lo; -- cgit v1.2.3 From 5fee56e0ddac14511a4dd33f1240a0f0b94a9d08 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:00 -0700 Subject: clocksource: mips-gic: Staticize local symbols There are a number of variables and functions which are unnecessarily global. Mark them static. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8135/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 3cf5912c4054..2603f50e5706 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -15,8 +15,8 @@ #include -DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); -int gic_timer_irq_installed; +static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); +static int gic_timer_irq_installed; static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { @@ -30,13 +30,13 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt) return res; } -void gic_set_clock_mode(enum clock_event_mode mode, +static void gic_set_clock_mode(enum clock_event_mode mode, struct clock_event_device *evt) { /* Nothing to do ... */ } -irqreturn_t gic_compare_interrupt(int irq, void *dev_id) +static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) { struct clock_event_device *cd; int cpu = smp_processor_id(); @@ -53,7 +53,7 @@ struct irqaction gic_compare_irqaction = { .name = "timer", }; -void gic_event_handler(struct clock_event_device *dev) +static void gic_event_handler(struct clock_event_device *dev) { } -- cgit v1.2.3 From b0854514537e4e2f0a599ca05d18fe95dcd3ee42 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:01 -0700 Subject: clocksource: mips-gic: Move gic_frequency to clocksource driver There's no reason for gic_frequency to be global any more and it certainly doesn't belong in the GIC irqchip driver, so move it to the GIC clocksource driver. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8137/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-time.c | 2 ++ drivers/clocksource/mips-gic-timer.c | 3 +++ drivers/irqchip/irq-mips-gic.c | 1 - include/linux/irqchip/mips-gic.h | 1 - 4 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/clocksource') diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 028fae077001..ce02dbdedc62 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -46,6 +46,8 @@ static int mips_cpu_timer_irq; static int mips_cpu_perf_irq; extern int cp0_perfcount_irq; +static unsigned int gic_frequency; + static void mips_timer_dispatch(void) { do_IRQ(mips_cpu_timer_irq); diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 2603f50e5706..bced17d2d2c1 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -17,6 +17,7 @@ static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); static int gic_timer_irq_installed; +static unsigned int gic_frequency; static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { @@ -112,6 +113,8 @@ static struct clocksource gic_clocksource = { void __init gic_clocksource_init(unsigned int frequency) { + gic_frequency = frequency; + /* Set clocksource mask. */ gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index cb674696810d..7ec3c18f1330 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -18,7 +18,6 @@ #include #include -unsigned int gic_frequency; unsigned int gic_present; struct gic_pcpu_mask { diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index 0350effb7ccc..420f77b34d02 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h @@ -230,7 +230,6 @@ #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) extern unsigned int gic_present; -extern unsigned int gic_frequency; extern void gic_init(unsigned long gic_base_addr, unsigned long gic_addrspace_size, unsigned int cpu_vec, -- cgit v1.2.3 From 001f5fe72cf6434f00fccf2b628f6843de1c3d4f Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:02 -0700 Subject: clocksource: mips-gic: Remove gic_event_handler Remove gic_event_handler since it is completely unnecessary. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8136/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index bced17d2d2c1..763aa1c9130f 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -54,10 +54,6 @@ struct irqaction gic_compare_irqaction = { .name = "timer", }; -static void gic_event_handler(struct clock_event_device *dev) -{ -} - int gic_clockevent_init(void) { unsigned int cpu = smp_processor_id(); @@ -86,7 +82,6 @@ int gic_clockevent_init(void) cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; - cd->event_handler = gic_event_handler; clockevents_register_device(cd); -- cgit v1.2.3 From f7ea3060b60a8f32794aa094f9216b198083d232 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:03 -0700 Subject: clocksource: mips-gic: Use percpu_dev_id Since the GIC timer IRQ is a percpu IRQ, we can use percpu_dev_id to pass the IRQ handler the correct clock_event_device. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8138/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 763aa1c9130f..05bdfe1e3e03 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -39,17 +39,16 @@ static void gic_set_clock_mode(enum clock_event_mode mode, static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) { - struct clock_event_device *cd; - int cpu = smp_processor_id(); + struct clock_event_device *cd = dev_id; gic_write_compare(gic_read_compare()); - cd = &per_cpu(gic_clockevent_device, cpu); cd->event_handler(cd); return IRQ_HANDLED; } struct irqaction gic_compare_irqaction = { .handler = gic_compare_interrupt, + .percpu_dev_id = &gic_clockevent_device, .flags = IRQF_PERCPU | IRQF_TIMER, .name = "timer", }; -- cgit v1.2.3 From e4752dbbc300939e14029583ba2a0b235b147649 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:04 -0700 Subject: clocksource: mips-gic: Use CPU notifiers to setup the timer Instead of requiring an explicit call to gic_clockevent_init in the SMP startup path, use CPU notifiers to register and enable the GIC timer on CPU startup. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8139/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/time.h | 5 +-- drivers/clocksource/mips-gic-timer.c | 60 ++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 20 deletions(-) (limited to 'drivers/clocksource') diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 5f30aabbb598..8ab2874225c4 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -53,13 +53,10 @@ extern int __weak get_c0_perfcount_int(void); */ extern unsigned int __weak get_c0_compare_int(void); extern int r4k_clockevent_init(void); -extern int gic_clockevent_init(void); static inline int mips_clockevent_init(void) { -#if defined(CONFIG_CLKSRC_MIPS_GIC) - return (gic_clockevent_init() | r4k_clockevent_init()); -#elif defined(CONFIG_CEVT_R4K) +#ifdef CONFIG_CEVT_R4K return r4k_clockevent_init(); #else return -ENXIO; diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 05bdfe1e3e03..3ce992bc574f 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -6,9 +6,11 @@ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ #include +#include #include #include #include +#include #include #include #include @@ -16,7 +18,7 @@ #include static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); -static int gic_timer_irq_installed; +static int gic_timer_irq; static unsigned int gic_frequency; static int gic_next_event(unsigned long delta, struct clock_event_device *evt) @@ -53,18 +55,9 @@ struct irqaction gic_compare_irqaction = { .name = "timer", }; -int gic_clockevent_init(void) +static void gic_clockevent_cpu_init(struct clock_event_device *cd) { unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - unsigned int irq; - - if (!cpu_has_counter || !gic_frequency) - return -ENXIO; - - irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); - - cd = &per_cpu(gic_clockevent_device, cpu); cd->name = "MIPS GIC"; cd->features = CLOCK_EVT_FEAT_ONESHOT | @@ -77,19 +70,52 @@ int gic_clockevent_init(void) cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; - cd->irq = irq; + cd->irq = gic_timer_irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; clockevents_register_device(cd); - if (!gic_timer_irq_installed) { - setup_percpu_irq(irq, &gic_compare_irqaction); - gic_timer_irq_installed = 1; + enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE); +} + +static void gic_clockevent_cpu_exit(struct clock_event_device *cd) +{ + disable_percpu_irq(gic_timer_irq); +} + +static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, + void *data) +{ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); + break; + case CPU_DYING: + gic_clockevent_cpu_exit(this_cpu_ptr(&gic_clockevent_device)); + break; } - enable_percpu_irq(irq, IRQ_TYPE_NONE); + return NOTIFY_OK; +} + +static struct notifier_block gic_cpu_nb = { + .notifier_call = gic_cpu_notifier, +}; + +static int gic_clockevent_init(void) +{ + if (!cpu_has_counter || !gic_frequency) + return -ENXIO; + + gic_timer_irq = MIPS_GIC_IRQ_BASE + + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); + setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); + + register_cpu_notifier(&gic_cpu_nb); + + gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); return 0; } @@ -116,4 +142,6 @@ void __init gic_clocksource_init(unsigned int frequency) gic_clocksource.rating = 200 + frequency / 10000000; clocksource_register_hz(&gic_clocksource, frequency); + + gic_clockevent_init(); } -- cgit v1.2.3 From b695d8e6ad6fba3d72b309b0d62128b04cf57160 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:05 -0700 Subject: clocksource: mips-gic: Use clockevents_config_and_register Use clockevents_config_and_register to setup the clock_event_device based on frequency and min/max ticks instead of doing it ourselves. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8140/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 3ce992bc574f..84fbb7ae4db2 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -15,8 +15,6 @@ #include #include -#include - static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); static int gic_timer_irq; static unsigned int gic_frequency; @@ -63,19 +61,13 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd) cd->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; - clockevent_set_clock(cd, gic_frequency); - - /* Calculate the min / max delta */ - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - cd->rating = 300; cd->irq = gic_timer_irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; - clockevents_register_device(cd); + clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff); enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE); } -- cgit v1.2.3 From a45da5659852bd4cbe453b49f5b26def65f5a6bf Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:06 -0700 Subject: clocksource: mips-gic: Bump up rating of GIC timer Bump up the rating of the GIC timer so that it gets prioritized over the CP0 timer. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8141/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 84fbb7ae4db2..a749c812e255 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -61,7 +61,7 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd) cd->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; - cd->rating = 300; + cd->rating = 350; cd->irq = gic_timer_irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; -- cgit v1.2.3 From e12aa828ff42bae894e4eb7350d4dbf46eb19084 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Wed, 12 Nov 2014 11:43:39 -0800 Subject: clocksource: mips-gic: Add device-tree support Parse the GIC timer frequency and interrupt from the device-tree. Signed-off-by: Andrew Bresticker Acked-by: Arnd Bergmann Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Thomas Gleixner Cc: Jason Cooper Cc: Daniel Lezcano Cc: John Crispin Cc: David Daney Cc: Qais Yousef Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8421/ Signed-off-by: Ralf Baechle --- drivers/clocksource/Kconfig | 1 + drivers/clocksource/mips-gic-timer.c | 41 ++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cb7e7f417a60..89836dc7cf66 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -226,5 +226,6 @@ config CLKSRC_VERSATILE config CLKSRC_MIPS_GIC bool depends on MIPS_GIC + select CLKSRC_OF endmenu diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index a749c812e255..3bd31b1321f6 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -101,8 +102,6 @@ static int gic_clockevent_init(void) if (!cpu_has_counter || !gic_frequency) return -ENXIO; - gic_timer_irq = MIPS_GIC_IRQ_BASE + - GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); register_cpu_notifier(&gic_cpu_nb); @@ -123,17 +122,45 @@ static struct clocksource gic_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -void __init gic_clocksource_init(unsigned int frequency) +static void __init __gic_clocksource_init(void) { - gic_frequency = frequency; - /* Set clocksource mask. */ gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); /* Calculate a somewhat reasonable rating value. */ - gic_clocksource.rating = 200 + frequency / 10000000; + gic_clocksource.rating = 200 + gic_frequency / 10000000; - clocksource_register_hz(&gic_clocksource, frequency); + clocksource_register_hz(&gic_clocksource, gic_frequency); gic_clockevent_init(); } + +void __init gic_clocksource_init(unsigned int frequency) +{ + gic_frequency = frequency; + gic_timer_irq = MIPS_GIC_IRQ_BASE + + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); + + __gic_clocksource_init(); +} + +static void __init gic_clocksource_of_init(struct device_node *node) +{ + if (WARN_ON(!gic_present || !node->parent || + !of_device_is_compatible(node->parent, "mti,gic"))) + return; + + if (of_property_read_u32(node, "clock-frequency", &gic_frequency)) { + pr_err("GIC frequency not specified.\n"); + return; + } + gic_timer_irq = irq_of_parse_and_map(node, 0); + if (!gic_timer_irq) { + pr_err("GIC timer IRQ not specified.\n"); + return; + } + + __gic_clocksource_init(); +} +CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", + gic_clocksource_of_init); -- cgit v1.2.3 From 551f2fd5c6f34945e2daa3abb547f81f5576facb Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 4 Nov 2014 10:21:31 -0300 Subject: clocksource: armada-370-xp: Add missing clock enable This commit makes sure the timer clock is prepared and enabled before retrieving its rate. Acked-by: Jason Cooper Acked-by: Gregory CLEMENT Acked-by: Wim Van Sebroeck Reviewed-by: Thomas Petazzoni Tested-by: Thomas Petazzoni Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano --- drivers/clocksource/time-armada-370-xp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 0451e62fac7a..d8555f9edc50 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -293,6 +293,7 @@ static void __init armada_xp_timer_init(struct device_node *np) /* The 25Mhz fixed clock is mandatory, and must always be available */ BUG_ON(IS_ERR(clk)); + clk_prepare_enable(clk); timer_clk = clk_get_rate(clk); armada_370_xp_timer_common_init(np); @@ -305,6 +306,7 @@ static void __init armada_370_timer_init(struct device_node *np) struct clk *clk = of_clk_get(np, 0); BUG_ON(IS_ERR(clk)); + clk_prepare_enable(clk); timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; timer25Mhz = false; -- cgit v1.2.3 From 4a22d9c93af1f2b2c40354c4bc59fd007f33f05e Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 4 Nov 2014 10:21:33 -0300 Subject: clocksource: armada-370-xp: Use the reference clock on A375 SoC The 25 MHz reference clock has better stability so its use is preferred over the core clock. This commit takes advantage of the already introduced Armada 375 devicetree compatible string and adds a new timer initialization. If available, the timer will use the reference clock (named as 'fixed'). Otherwise, it falls back to the previous behavior. Acked-by: Jason Cooper Acked-by: Gregory CLEMENT Acked-by: Wim Van Sebroeck Reviewed-by: Thomas Petazzoni Tested-by: Thomas Petazzoni Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano --- .../bindings/timer/marvell,armada-370-xp-timer.txt | 9 ++++--- drivers/clocksource/time-armada-370-xp.c | 28 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'drivers/clocksource') diff --git a/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt b/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt index f455182b1086..e9c78ce880e6 100644 --- a/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt +++ b/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt @@ -2,8 +2,10 @@ Marvell Armada 370 and Armada XP Timers --------------------------------------- Required properties: -- compatible: Should be either "marvell,armada-370-timer" or - "marvell,armada-xp-timer" as appropriate. +- compatible: Should be one of the following + "marvell,armada-370-timer", + "marvell,armada-375-timer", + "marvell,armada-xp-timer". - interrupts: Should contain the list of Global Timer interrupts and then local timer interrupts - reg: Should contain location and length for timers register. First @@ -13,7 +15,8 @@ Required properties: Clocks required for compatible = "marvell,armada-370-timer": - clocks : Must contain a single entry describing the clock input -Clocks required for compatible = "marvell,armada-xp-timer": +Clocks required for compatibles = "marvell,armada-xp-timer", + "marvell,armada-375-timer": - clocks : Must contain an entry for each entry in clock-names. - clock-names : Must include the following entries: "nbclk" (L2/coherency fabric clock), diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index d8555f9edc50..3a0704b0d739 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -301,6 +301,34 @@ static void __init armada_xp_timer_init(struct device_node *np) CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", armada_xp_timer_init); +static void __init armada_375_timer_init(struct device_node *np) +{ + struct clk *clk; + + clk = of_clk_get_by_name(np, "fixed"); + if (!IS_ERR(clk)) { + clk_prepare_enable(clk); + timer_clk = clk_get_rate(clk); + } else { + + /* + * This fallback is required in order to retain proper + * devicetree backwards compatibility. + */ + clk = of_clk_get(np, 0); + + /* Must have at least a clock */ + BUG_ON(IS_ERR(clk)); + clk_prepare_enable(clk); + timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; + timer25Mhz = false; + } + + armada_370_xp_timer_common_init(np); +} +CLOCKSOURCE_OF_DECLARE(armada_375, "marvell,armada-375-timer", + armada_375_timer_init); + static void __init armada_370_timer_init(struct device_node *np) { struct clk *clk = of_clk_get(np, 0); -- cgit v1.2.3