summaryrefslogtreecommitdiffstats
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 @@
#include <asm/mach/time.h>
+extern void dw_apb_timer_init(void);
+
#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 @@
#define APBT_MIN_PERIOD 4
#define APBT_MIN_DELTA_USEC 200
+#define APBTMR_N_LOAD_COUNT 0x00
+#define APBTMR_N_CURRENT_VALUE 0x04
+#define APBTMR_N_CONTROL 0x08
+#define APBTMR_N_EOI 0x0c
+#define APBTMR_N_INT_STATUS 0x10
+
#define APBTMRS_INT_STATUS 0xa0
#define APBTMRS_EOI 0xa4
#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)
dw_apb_clockevent_register(ced);
}
-static void __iomem *sched_io_base;
-
-/* This is actually same as __apbt_read_clocksource(), but with
- different interface */
-static u32 read_sched_clock_sptimer(void)
-{
- return ~__raw_readl(sched_io_base + APBTMR_N_CURRENT_VALUE);
-}
-
static void add_clocksource(struct device_node *source_timer)
{
void __iomem *iobase;
@@ -78,27 +69,41 @@ static void add_clocksource(struct device_node *source_timer)
dw_apb_clocksource_start(cs);
dw_apb_clocksource_register(cs);
+}
- sched_io_base = iobase;
- setup_sched_clock(read_sched_clock_sptimer, 32, rate);
+static void __iomem *sched_io_base;
+
+static u32 read_sched_clock(void)
+{
+ return __raw_readl(sched_io_base);
}
-static const struct of_device_id osctimer_ids[] __initconst = {
- { .compatible = "picochip,pc3x2-timer" },
- { .compatible = "snps,dw-apb-timer-osc" },
+static const struct of_device_id sptimer_ids[] __initconst = {
+ { .compatible = "picochip,pc3x2-rtc" },
{ .compatible = "snps,dw-apb-timer-sp" },
- { /* Sentinel */ },
+ { /* Sentinel */ },
};
-/*
- You don't have to use dw_apb_timer for scheduler clock,
- this should also work fine on arm:
+static void init_sched_clock(void)
+{
+ struct device_node *sched_timer;
+ u32 rate;
- twd_local_timer_of_register();
- arch_timer_of_register();
- arch_timer_sched_clock_init();
-*/
+ sched_timer = of_find_matching_node(NULL, sptimer_ids);
+ if (!sched_timer)
+ panic("No RTC for sched clock to use");
+ timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
+ of_node_put(sched_timer);
+
+ setup_sched_clock(read_sched_clock, 32, rate);
+}
+
+static const struct of_device_id osctimer_ids[] __initconst = {
+ { .compatible = "picochip,pc3x2-timer" },
+ { .compatible = "snps,dw-apb-timer-osc" },
+ {},
+};
void __init dw_apb_timer_init(void)
{
@@ -114,6 +119,7 @@ void __init dw_apb_timer_init(void)
panic("No timer for clocksource");
add_clocksource(source_timer);
- of_node_put(event_timer);
of_node_put(source_timer);
+
+ init_sched_clock();
}
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 @@
#include <linux/clocksource.h>
#include <linux/interrupt.h>
-#define APBTMR_N_LOAD_COUNT 0x00
-#define APBTMR_N_CURRENT_VALUE 0x04
-#define APBTMR_N_CONTROL 0x08
-#define APBTMR_N_EOI 0x0c
-#define APBTMR_N_INT_STATUS 0x10
-
#define APBTMRS_REG_SIZE 0x14
struct dw_apb_timer {