aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Bresticker <abrestic@chromium.org>2014-10-20 15:03:59 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-11-24 01:45:15 -0500
commita331ce63c85080f554e0a19fc4189a520c65267b (patch)
treebe84ac9416e957f7d601337f0f17bf327aebf80c
parentfa5635a277171021d364f6a3fab4addce8f358d2 (diff)
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 <abrestic@chromium.org> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Andrew Bresticker <abrestic@chromium.org> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Qais Yousef <qais.yousef@imgtec.com> Cc: John Crispin <blogic@openwrt.org> 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 <ralf@linux-mips.org>
-rw-r--r--arch/mips/Kconfig13
-rw-r--r--arch/mips/include/asm/time.h2
-rw-r--r--arch/mips/kernel/Makefile1
-rw-r--r--arch/mips/kernel/cevt-gic.c103
-rw-r--r--drivers/clocksource/mips-gic-timer.c90
-rw-r--r--drivers/irqchip/irq-mips-gic.c2
6 files changed, 92 insertions, 119 deletions
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
935config CEVT_R4K 935config CEVT_R4K
936 bool 936 bool
937 937
938config CEVT_GIC
939 select MIPS_CM
940 bool
941
942config CEVT_SB1250 938config CEVT_SB1250
943 bool 939 bool
944 940
@@ -1911,15 +1907,6 @@ config FORCE_MAX_ZONEORDER
1911 The page size is not necessarily 4KB. Keep this in mind 1907 The page size is not necessarily 4KB. Keep this in mind
1912 when choosing a value for this option. 1908 when choosing a value for this option.
1913 1909
1914config CEVT_GIC
1915 bool "Use GIC global counter for clock events"
1916 depends on MIPS_GIC && !MIPS_SEAD3
1917 help
1918 Use the GIC global counter for the clock events. The R4K clock
1919 event driver is always present, so if the platform ends up not
1920 detecting a GIC, it will fall back to the R4K timer for the
1921 generation of clock events.
1922
1923config BOARD_SCACHE 1910config BOARD_SCACHE
1924 bool 1911 bool
1925 1912
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);
57 57
58static inline int mips_clockevent_init(void) 58static inline int mips_clockevent_init(void)
59{ 59{
60#if defined(CONFIG_CEVT_GIC) 60#if defined(CONFIG_CLKSRC_MIPS_GIC)
61 return (gic_clockevent_init() | r4k_clockevent_init()); 61 return (gic_clockevent_init() | r4k_clockevent_init());
62#elif defined(CONFIG_CEVT_R4K) 62#elif defined(CONFIG_CEVT_R4K)
63 return r4k_clockevent_init(); 63 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
19obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o 19obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
20obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 20obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
21obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o 21obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
22obj-$(CONFIG_CEVT_GIC) += cevt-gic.o
23obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o 22obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
24obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o 23obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
25obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o 24obj-$(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 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2013 Imagination Technologies Ltd.
7 */
8#include <linux/clockchips.h>
9#include <linux/interrupt.h>
10#include <linux/percpu.h>
11#include <linux/smp.h>
12#include <linux/irq.h>
13#include <linux/irqchip/mips-gic.h>
14
15#include <asm/time.h>
16#include <asm/mips-boards/maltaint.h>
17
18DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
19int gic_timer_irq_installed;
20
21
22static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
23{
24 u64 cnt;
25 int res;
26
27 cnt = gic_read_count();
28 cnt += (u64)delta;
29 gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
30 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
31 return res;
32}
33
34void gic_set_clock_mode(enum clock_event_mode mode,
35 struct clock_event_device *evt)
36{
37 /* Nothing to do ... */
38}
39
40irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
41{
42 struct clock_event_device *cd;
43 int cpu = smp_processor_id();
44
45 gic_write_compare(gic_read_compare());
46 cd = &per_cpu(gic_clockevent_device, cpu);
47 cd->event_handler(cd);
48 return IRQ_HANDLED;
49}
50
51struct irqaction gic_compare_irqaction = {
52 .handler = gic_compare_interrupt,
53 .flags = IRQF_PERCPU | IRQF_TIMER,
54 .name = "timer",
55};
56
57
58void gic_event_handler(struct clock_event_device *dev)
59{
60}
61
62int gic_clockevent_init(void)
63{
64 unsigned int cpu = smp_processor_id();
65 struct clock_event_device *cd;
66 unsigned int irq;
67
68 if (!cpu_has_counter || !gic_frequency)
69 return -ENXIO;
70
71 irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
72
73 cd = &per_cpu(gic_clockevent_device, cpu);
74
75 cd->name = "MIPS GIC";
76 cd->features = CLOCK_EVT_FEAT_ONESHOT |
77 CLOCK_EVT_FEAT_C3STOP;
78
79 clockevent_set_clock(cd, gic_frequency);
80
81 /* Calculate the min / max delta */
82 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
83 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
84
85 cd->rating = 300;
86 cd->irq = irq;
87 cd->cpumask = cpumask_of(cpu);
88 cd->set_next_event = gic_next_event;
89 cd->set_mode = gic_set_clock_mode;
90 cd->event_handler = gic_event_handler;
91
92 clockevents_register_device(cd);
93
94 if (!gic_timer_irq_installed) {
95 setup_percpu_irq(irq, &gic_compare_irqaction);
96 gic_timer_irq_installed = 1;
97 }
98
99 enable_percpu_irq(irq, IRQ_TYPE_NONE);
100
101
102 return 0;
103}
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 @@
5 * 5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */ 7 */
8#include <linux/clockchips.h>
8#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/interrupt.h>
9#include <linux/irqchip/mips-gic.h> 11#include <linux/irqchip/mips-gic.h>
12#include <linux/percpu.h>
13#include <linux/smp.h>
10#include <linux/time.h> 14#include <linux/time.h>
11 15
16#include <asm/time.h>
17
18DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
19int gic_timer_irq_installed;
20
21static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
22{
23 u64 cnt;
24 int res;
25
26 cnt = gic_read_count();
27 cnt += (u64)delta;
28 gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
29 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
30 return res;
31}
32
33void gic_set_clock_mode(enum clock_event_mode mode,
34 struct clock_event_device *evt)
35{
36 /* Nothing to do ... */
37}
38
39irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
40{
41 struct clock_event_device *cd;
42 int cpu = smp_processor_id();
43
44 gic_write_compare(gic_read_compare());
45 cd = &per_cpu(gic_clockevent_device, cpu);
46 cd->event_handler(cd);
47 return IRQ_HANDLED;
48}
49
50struct irqaction gic_compare_irqaction = {
51 .handler = gic_compare_interrupt,
52 .flags = IRQF_PERCPU | IRQF_TIMER,
53 .name = "timer",
54};
55
56void gic_event_handler(struct clock_event_device *dev)
57{
58}
59
60int gic_clockevent_init(void)
61{
62 unsigned int cpu = smp_processor_id();
63 struct clock_event_device *cd;
64 unsigned int irq;
65
66 if (!cpu_has_counter || !gic_frequency)
67 return -ENXIO;
68
69 irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
70
71 cd = &per_cpu(gic_clockevent_device, cpu);
72
73 cd->name = "MIPS GIC";
74 cd->features = CLOCK_EVT_FEAT_ONESHOT |
75 CLOCK_EVT_FEAT_C3STOP;
76
77 clockevent_set_clock(cd, gic_frequency);
78
79 /* Calculate the min / max delta */
80 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
81 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
82
83 cd->rating = 300;
84 cd->irq = irq;
85 cd->cpumask = cpumask_of(cpu);
86 cd->set_next_event = gic_next_event;
87 cd->set_mode = gic_set_clock_mode;
88 cd->event_handler = gic_event_handler;
89
90 clockevents_register_device(cd);
91
92 if (!gic_timer_irq_installed) {
93 setup_percpu_irq(irq, &gic_compare_irqaction);
94 gic_timer_irq_installed = 1;
95 }
96
97 enable_percpu_irq(irq, IRQ_TYPE_NONE);
98
99 return 0;
100}
101
12static cycle_t gic_hpt_read(struct clocksource *cs) 102static cycle_t gic_hpt_read(struct clocksource *cs)
13{ 103{
14 return gic_read_count(); 104 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)
103 GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); 103 GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
104} 104}
105 105
106#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC) 106#ifdef CONFIG_CLKSRC_MIPS_GIC
107cycle_t gic_read_count(void) 107cycle_t gic_read_count(void)
108{ 108{
109 unsigned int hi, hi2, lo; 109 unsigned int hi, hi2, lo;