aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-picoxcell/common.h2
-rw-r--r--drivers/clocksource/dw_apb_timer.c6
-rw-r--r--drivers/clocksource/dw_apb_timer_of.c52
-rw-r--r--include/linux/dw_apb_timer.h6
4 files changed, 37 insertions, 29 deletions
diff --git a/arch/arm/mach-picoxcell/common.h b/arch/arm/mach-picoxcell/common.h
index 237fb3bcbd04..481b42a4ef15 100644
--- a/arch/arm/mach-picoxcell/common.h
+++ b/arch/arm/mach-picoxcell/common.h
@@ -12,4 +12,6 @@
12 12
13#include <asm/mach/time.h> 13#include <asm/mach/time.h>
14 14
15extern void dw_apb_timer_init(void);
16
15#endif /* __PICOXCELL_COMMON_H__ */ 17#endif /* __PICOXCELL_COMMON_H__ */
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c
index e7042bc5c7d2..e54ca1062d8e 100644
--- a/drivers/clocksource/dw_apb_timer.c
+++ b/drivers/clocksource/dw_apb_timer.c
@@ -21,6 +21,12 @@
21#define APBT_MIN_PERIOD 4 21#define APBT_MIN_PERIOD 4
22#define APBT_MIN_DELTA_USEC 200 22#define APBT_MIN_DELTA_USEC 200
23 23
24#define APBTMR_N_LOAD_COUNT 0x00
25#define APBTMR_N_CURRENT_VALUE 0x04
26#define APBTMR_N_CONTROL 0x08
27#define APBTMR_N_EOI 0x0c
28#define APBTMR_N_INT_STATUS 0x10
29
24#define APBTMRS_INT_STATUS 0xa0 30#define APBTMRS_INT_STATUS 0xa0
25#define APBTMRS_EOI 0xa4 31#define APBTMRS_EOI 0xa4
26#define APBTMRS_RAW_INT_STATUS 0xa8 32#define APBTMRS_RAW_INT_STATUS 0xa8
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
index a97b4065dacf..d9a1e8d51751 100644
--- a/drivers/clocksource/dw_apb_timer_of.c
+++ b/drivers/clocksource/dw_apb_timer_of.c
@@ -55,15 +55,6 @@ static void add_clockevent(struct device_node *event_timer)
55 dw_apb_clockevent_register(ced); 55 dw_apb_clockevent_register(ced);
56} 56}
57 57
58static void __iomem *sched_io_base;
59
60/* This is actually same as __apbt_read_clocksource(), but with
61 different interface */
62static u32 read_sched_clock_sptimer(void)
63{
64 return ~__raw_readl(sched_io_base + APBTMR_N_CURRENT_VALUE);
65}
66
67static void add_clocksource(struct device_node *source_timer) 58static void add_clocksource(struct device_node *source_timer)
68{ 59{
69 void __iomem *iobase; 60 void __iomem *iobase;
@@ -78,27 +69,41 @@ static void add_clocksource(struct device_node *source_timer)
78 69
79 dw_apb_clocksource_start(cs); 70 dw_apb_clocksource_start(cs);
80 dw_apb_clocksource_register(cs); 71 dw_apb_clocksource_register(cs);
72}
81 73
82 sched_io_base = iobase; 74static void __iomem *sched_io_base;
83 setup_sched_clock(read_sched_clock_sptimer, 32, rate); 75
76static u32 read_sched_clock(void)
77{
78 return __raw_readl(sched_io_base);
84} 79}
85 80
86static const struct of_device_id osctimer_ids[] __initconst = { 81static const struct of_device_id sptimer_ids[] __initconst = {
87 { .compatible = "picochip,pc3x2-timer" }, 82 { .compatible = "picochip,pc3x2-rtc" },
88 { .compatible = "snps,dw-apb-timer-osc" },
89 { .compatible = "snps,dw-apb-timer-sp" }, 83 { .compatible = "snps,dw-apb-timer-sp" },
90 { /* Sentinel */ }, 84 { /* Sentinel */ },
91}; 85};
92 86
93/* 87static void init_sched_clock(void)
94 You don't have to use dw_apb_timer for scheduler clock, 88{
95 this should also work fine on arm: 89 struct device_node *sched_timer;
90 u32 rate;
96 91
97 twd_local_timer_of_register(); 92 sched_timer = of_find_matching_node(NULL, sptimer_ids);
98 arch_timer_of_register(); 93 if (!sched_timer)
99 arch_timer_sched_clock_init(); 94 panic("No RTC for sched clock to use");
100*/
101 95
96 timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
97 of_node_put(sched_timer);
98
99 setup_sched_clock(read_sched_clock, 32, rate);
100}
101
102static const struct of_device_id osctimer_ids[] __initconst = {
103 { .compatible = "picochip,pc3x2-timer" },
104 { .compatible = "snps,dw-apb-timer-osc" },
105 {},
106};
102 107
103void __init dw_apb_timer_init(void) 108void __init dw_apb_timer_init(void)
104{ 109{
@@ -114,6 +119,7 @@ void __init dw_apb_timer_init(void)
114 panic("No timer for clocksource"); 119 panic("No timer for clocksource");
115 add_clocksource(source_timer); 120 add_clocksource(source_timer);
116 121
117 of_node_put(event_timer);
118 of_node_put(source_timer); 122 of_node_put(source_timer);
123
124 init_sched_clock();
119} 125}
diff --git a/include/linux/dw_apb_timer.h b/include/linux/dw_apb_timer.h
index de0904e38f33..b1cd9597c241 100644
--- a/include/linux/dw_apb_timer.h
+++ b/include/linux/dw_apb_timer.h
@@ -17,12 +17,6 @@
17#include <linux/clocksource.h> 17#include <linux/clocksource.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19 19
20#define APBTMR_N_LOAD_COUNT 0x00
21#define APBTMR_N_CURRENT_VALUE 0x04
22#define APBTMR_N_CONTROL 0x08
23#define APBTMR_N_EOI 0x0c
24#define APBTMR_N_INT_STATUS 0x10
25
26#define APBTMRS_REG_SIZE 0x14 20#define APBTMRS_REG_SIZE 0x14
27 21
28struct dw_apb_timer { 22struct dw_apb_timer {