diff options
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/dw_apb_timer.c | 6 | ||||
-rw-r--r-- | drivers/clocksource/dw_apb_timer_of.c | 52 |
2 files changed, 35 insertions, 23 deletions
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index e7042bc..e54ca10 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 a97b406..d9a1e8d 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(); } |