mmio.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Generic MMIO clocksource support
  4. */
  5. #include <linux/clocksource.h>
  6. #include <linux/errno.h>
  7. #include <linux/init.h>
  8. #include <linux/slab.h>
  9. struct clocksource_mmio {
  10. void __iomem *reg;
  11. struct clocksource clksrc;
  12. };
  13. static inline struct clocksource_mmio *to_mmio_clksrc(struct clocksource *c)
  14. {
  15. return container_of(c, struct clocksource_mmio, clksrc);
  16. }
  17. u64 clocksource_mmio_readl_up(struct clocksource *c)
  18. {
  19. return (u64)readl_relaxed(to_mmio_clksrc(c)->reg);
  20. }
  21. EXPORT_SYMBOL_GPL(clocksource_mmio_readl_up);
  22. u64 clocksource_mmio_readl_down(struct clocksource *c)
  23. {
  24. return ~(u64)readl_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
  25. }
  26. u64 clocksource_mmio_readw_up(struct clocksource *c)
  27. {
  28. return (u64)readw_relaxed(to_mmio_clksrc(c)->reg);
  29. }
  30. u64 clocksource_mmio_readw_down(struct clocksource *c)
  31. {
  32. return ~(u64)readw_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
  33. }
  34. /**
  35. * clocksource_mmio_init - Initialize a simple mmio based clocksource
  36. * @base: Virtual address of the clock readout register
  37. * @name: Name of the clocksource
  38. * @hz: Frequency of the clocksource in Hz
  39. * @rating: Rating of the clocksource
  40. * @bits: Number of valid bits
  41. * @read: One of clocksource_mmio_read*() above
  42. */
  43. int clocksource_mmio_init(void __iomem *base, const char *name,
  44. unsigned long hz, int rating, unsigned bits,
  45. u64 (*read)(struct clocksource *))
  46. {
  47. struct clocksource_mmio *cs;
  48. if (bits > 64 || bits < 16)
  49. return -EINVAL;
  50. cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL);
  51. if (!cs)
  52. return -ENOMEM;
  53. cs->reg = base;
  54. cs->clksrc.name = name;
  55. cs->clksrc.rating = rating;
  56. cs->clksrc.read = read;
  57. cs->clksrc.mask = CLOCKSOURCE_MASK(bits);
  58. cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
  59. return clocksource_register_hz(&cs->clksrc, hz);
  60. }
  61. EXPORT_SYMBOL_GPL(clocksource_mmio_init);