2015-10-09 16:59:18 +02:00
# include <linux/clocksource.h>
# include <linux/sched_clock.h>
# include <linux/of_address.h>
# include <linux/printk.h>
# include <linux/delay.h>
# include <linux/init.h>
# include <linux/clk.h>
static void __iomem * xtal_in_cnt ;
static struct delay_timer delay_timer ;
static unsigned long notrace read_xtal_counter ( void )
{
return readl_relaxed ( xtal_in_cnt ) ;
}
static u64 notrace read_sched_clock ( void )
{
return read_xtal_counter ( ) ;
}
2016-06-06 17:59:24 +02:00
static int __init tango_clocksource_init ( struct device_node * np )
2015-10-09 16:59:18 +02:00
{
struct clk * clk ;
int xtal_freq , ret ;
xtal_in_cnt = of_iomap ( np , 0 ) ;
if ( xtal_in_cnt = = NULL ) {
2017-07-18 16:42:53 -05:00
pr_err ( " %pOF: invalid address \n " , np ) ;
2016-06-06 17:59:24 +02:00
return - ENXIO ;
2015-10-09 16:59:18 +02:00
}
clk = of_clk_get ( np , 0 ) ;
if ( IS_ERR ( clk ) ) {
2017-07-18 16:42:53 -05:00
pr_err ( " %pOF: invalid clock \n " , np ) ;
2016-06-06 17:59:24 +02:00
return PTR_ERR ( clk ) ;
2015-10-09 16:59:18 +02:00
}
xtal_freq = clk_get_rate ( clk ) ;
delay_timer . freq = xtal_freq ;
delay_timer . read_current_timer = read_xtal_counter ;
2015-11-13 10:44:38 +01:00
ret = clocksource_mmio_init ( xtal_in_cnt , " tango-xtal " , xtal_freq , 350 ,
32 , clocksource_mmio_readl_up ) ;
2016-04-19 15:43:02 +02:00
if ( ret ) {
2017-07-18 16:42:53 -05:00
pr_err ( " %pOF: registration failed \n " , np ) ;
2016-06-06 17:59:24 +02:00
return ret ;
2015-10-09 16:59:18 +02:00
}
sched_clock_register ( read_sched_clock , 32 , xtal_freq ) ;
register_current_timer_delay ( & delay_timer ) ;
2016-06-06 17:59:24 +02:00
return 0 ;
2015-10-09 16:59:18 +02:00
}
2017-05-26 16:56:11 +02:00
TIMER_OF_DECLARE ( tango , " sigma,tick-counter " , tango_clocksource_init ) ;