diff options
-rw-r--r-- | arch/arm/mach-picoxcell/common.h | 2 | ||||
-rw-r--r-- | drivers/clocksource/dw_apb_timer.c | 6 | ||||
-rw-r--r-- | drivers/clocksource/dw_apb_timer_of.c | 52 | ||||
-rw-r--r-- | include/linux/dw_apb_timer.h | 6 |
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 | ||
15 | extern 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 | ||
58 | static void __iomem *sched_io_base; | ||
59 | |||
60 | /* This is actually same as __apbt_read_clocksource(), but with | ||
61 | different interface */ | ||
62 | static u32 read_sched_clock_sptimer(void) | ||
63 | { | ||
64 | return ~__raw_readl(sched_io_base + APBTMR_N_CURRENT_VALUE); | ||
65 | } | ||
66 | |||
67 | static void add_clocksource(struct device_node *source_timer) | 58 | static 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; | 74 | static void __iomem *sched_io_base; |
83 | setup_sched_clock(read_sched_clock_sptimer, 32, rate); | 75 | |
76 | static u32 read_sched_clock(void) | ||
77 | { | ||
78 | return __raw_readl(sched_io_base); | ||
84 | } | 79 | } |
85 | 80 | ||
86 | static const struct of_device_id osctimer_ids[] __initconst = { | 81 | static 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 | /* | 87 | static 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 | |||
102 | static const struct of_device_id osctimer_ids[] __initconst = { | ||
103 | { .compatible = "picochip,pc3x2-timer" }, | ||
104 | { .compatible = "snps,dw-apb-timer-osc" }, | ||
105 | {}, | ||
106 | }; | ||
102 | 107 | ||
103 | void __init dw_apb_timer_init(void) | 108 | void __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 | ||
28 | struct dw_apb_timer { | 22 | struct dw_apb_timer { |