csrc-ioasic.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * DEC I/O ASIC's counter clocksource
  4. *
  5. * Copyright (C) 2008 Yoichi Yuasa <[email protected]>
  6. */
  7. #include <linux/clocksource.h>
  8. #include <linux/sched_clock.h>
  9. #include <linux/init.h>
  10. #include <asm/ds1287.h>
  11. #include <asm/time.h>
  12. #include <asm/dec/ioasic.h>
  13. #include <asm/dec/ioasic_addrs.h>
  14. static u64 dec_ioasic_hpt_read(struct clocksource *cs)
  15. {
  16. return ioasic_read(IO_REG_FCTR);
  17. }
  18. static struct clocksource clocksource_dec = {
  19. .name = "dec-ioasic",
  20. .read = dec_ioasic_hpt_read,
  21. .mask = CLOCKSOURCE_MASK(32),
  22. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  23. };
  24. static u64 notrace dec_ioasic_read_sched_clock(void)
  25. {
  26. return ioasic_read(IO_REG_FCTR);
  27. }
  28. int __init dec_ioasic_clocksource_init(void)
  29. {
  30. unsigned int freq;
  31. u32 start, end;
  32. int i = HZ / 8;
  33. ds1287_timer_state();
  34. while (!ds1287_timer_state())
  35. ;
  36. start = dec_ioasic_hpt_read(&clocksource_dec);
  37. while (i--)
  38. while (!ds1287_timer_state())
  39. ;
  40. end = dec_ioasic_hpt_read(&clocksource_dec);
  41. freq = (end - start) * 8;
  42. /* An early revision of the I/O ASIC didn't have the counter. */
  43. if (!freq)
  44. return -ENXIO;
  45. printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
  46. clocksource_dec.rating = 200 + freq / 10000000;
  47. clocksource_register_hz(&clocksource_dec, freq);
  48. sched_clock_register(dec_ioasic_read_sched_clock, 32, freq);
  49. return 0;
  50. }