2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-05-08 17:06:52 +04:00
/*
* Generic MMIO clocksource support
*/
# include <linux/clocksource.h>
# include <linux/errno.h>
# include <linux/init.h>
# include <linux/slab.h>
struct clocksource_mmio {
void __iomem * reg ;
struct clocksource clksrc ;
} ;
static inline struct clocksource_mmio * to_mmio_clksrc ( struct clocksource * c )
{
return container_of ( c , struct clocksource_mmio , clksrc ) ;
}
2016-12-21 22:32:01 +03:00
u64 clocksource_mmio_readl_up ( struct clocksource * c )
2011-05-08 17:06:52 +04:00
{
2016-12-21 22:32:01 +03:00
return ( u64 ) readl_relaxed ( to_mmio_clksrc ( c ) - > reg ) ;
2011-05-08 17:06:52 +04:00
}
2016-12-21 22:32:01 +03:00
u64 clocksource_mmio_readl_down ( struct clocksource * c )
2011-05-08 17:06:52 +04:00
{
2016-12-21 22:32:01 +03:00
return ~ ( u64 ) readl_relaxed ( to_mmio_clksrc ( c ) - > reg ) & c - > mask ;
2011-05-08 17:06:52 +04:00
}
2016-12-21 22:32:01 +03:00
u64 clocksource_mmio_readw_up ( struct clocksource * c )
2011-05-08 17:06:52 +04:00
{
2016-12-21 22:32:01 +03:00
return ( u64 ) readw_relaxed ( to_mmio_clksrc ( c ) - > reg ) ;
2011-05-08 17:06:52 +04:00
}
2016-12-21 22:32:01 +03:00
u64 clocksource_mmio_readw_down ( struct clocksource * c )
2011-05-08 17:06:52 +04:00
{
2016-12-21 22:32:01 +03:00
return ~ ( u64 ) readw_relaxed ( to_mmio_clksrc ( c ) - > reg ) & c - > mask ;
2011-05-08 17:06:52 +04:00
}
/**
* clocksource_mmio_init - Initialize a simple mmio based clocksource
* @ base : Virtual address of the clock readout register
* @ name : Name of the clocksource
* @ hz : Frequency of the clocksource in Hz
* @ rating : Rating of the clocksource
* @ bits : Number of valid bits
* @ read : One of clocksource_mmio_read * ( ) above
*/
int __init clocksource_mmio_init ( void __iomem * base , const char * name ,
unsigned long hz , int rating , unsigned bits ,
2016-12-21 22:32:01 +03:00
u64 ( * read ) ( struct clocksource * ) )
2011-05-08 17:06:52 +04:00
{
struct clocksource_mmio * cs ;
2015-12-10 20:21:41 +03:00
if ( bits > 64 | | bits < 16 )
2011-05-08 17:06:52 +04:00
return - EINVAL ;
cs = kzalloc ( sizeof ( struct clocksource_mmio ) , GFP_KERNEL ) ;
if ( ! cs )
return - ENOMEM ;
cs - > reg = base ;
cs - > clksrc . name = name ;
cs - > clksrc . rating = rating ;
cs - > clksrc . read = read ;
cs - > clksrc . mask = CLOCKSOURCE_MASK ( bits ) ;
cs - > clksrc . flags = CLOCK_SOURCE_IS_CONTINUOUS ;
return clocksource_register_hz ( & cs - > clksrc , hz ) ;
}