1 // SPDX-License-Identifier: GPL-2.0-only
3 * Generic MMIO clocksource support
5 #include <linux/clocksource.h>
6 #include <linux/errno.h>
7 #include <linux/init.h>
8 #include <linux/slab.h>
10 struct clocksource_mmio
{
12 struct clocksource clksrc
;
15 static inline struct clocksource_mmio
*to_mmio_clksrc(struct clocksource
*c
)
17 return container_of(c
, struct clocksource_mmio
, clksrc
);
20 u64
clocksource_mmio_readl_up(struct clocksource
*c
)
22 return (u64
)readl_relaxed(to_mmio_clksrc(c
)->reg
);
25 u64
clocksource_mmio_readl_down(struct clocksource
*c
)
27 return ~(u64
)readl_relaxed(to_mmio_clksrc(c
)->reg
) & c
->mask
;
30 u64
clocksource_mmio_readw_up(struct clocksource
*c
)
32 return (u64
)readw_relaxed(to_mmio_clksrc(c
)->reg
);
35 u64
clocksource_mmio_readw_down(struct clocksource
*c
)
37 return ~(u64
)readw_relaxed(to_mmio_clksrc(c
)->reg
) & c
->mask
;
41 * clocksource_mmio_init - Initialize a simple mmio based clocksource
42 * @base: Virtual address of the clock readout register
43 * @name: Name of the clocksource
44 * @hz: Frequency of the clocksource in Hz
45 * @rating: Rating of the clocksource
46 * @bits: Number of valid bits
47 * @read: One of clocksource_mmio_read*() above
49 int __init
clocksource_mmio_init(void __iomem
*base
, const char *name
,
50 unsigned long hz
, int rating
, unsigned bits
,
51 u64 (*read
)(struct clocksource
*))
53 struct clocksource_mmio
*cs
;
55 if (bits
> 64 || bits
< 16)
58 cs
= kzalloc(sizeof(struct clocksource_mmio
), GFP_KERNEL
);
63 cs
->clksrc
.name
= name
;
64 cs
->clksrc
.rating
= rating
;
65 cs
->clksrc
.read
= read
;
66 cs
->clksrc
.mask
= CLOCKSOURCE_MASK(bits
);
67 cs
->clksrc
.flags
= CLOCK_SOURCE_IS_CONTINUOUS
;
69 return clocksource_register_hz(&cs
->clksrc
, hz
);