pps_gen-dummy.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * PPS dummy generator
  4. *
  5. * Copyright (C) 2024 Rodolfo Giometti <giometti@enneenne.com>
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/init.h>
  10. #include <linux/time.h>
  11. #include <linux/timer.h>
  12. #include <linux/random.h>
  13. #include <linux/pps_gen_kernel.h>
  14. static struct pps_gen_device *pps_gen;
  15. static struct timer_list ktimer;
  16. static unsigned int get_random_delay(void)
  17. {
  18. unsigned int delay = get_random_u8() & 0x0f;
  19. return (delay + 1) * HZ;
  20. }
  21. /*
  22. * The kernel timer
  23. */
  24. static void pps_gen_ktimer_event(struct timer_list *unused)
  25. {
  26. pps_gen_event(pps_gen, PPS_GEN_EVENT_MISSEDPULSE, NULL);
  27. }
  28. /*
  29. * PPS Generator methods
  30. */
  31. static int pps_gen_dummy_get_time(struct pps_gen_device *pps_gen,
  32. struct timespec64 *time)
  33. {
  34. struct system_time_snapshot snap;
  35. ktime_get_snapshot(&snap);
  36. *time = ktime_to_timespec64(snap.real);
  37. return 0;
  38. }
  39. static int pps_gen_dummy_enable(struct pps_gen_device *pps_gen, bool enable)
  40. {
  41. if (enable)
  42. mod_timer(&ktimer, jiffies + get_random_delay());
  43. else
  44. timer_delete_sync(&ktimer);
  45. return 0;
  46. }
  47. /*
  48. * The PPS info struct
  49. */
  50. static const struct pps_gen_source_info pps_gen_dummy_info = {
  51. .use_system_clock = true,
  52. .get_time = pps_gen_dummy_get_time,
  53. .enable = pps_gen_dummy_enable,
  54. };
  55. /*
  56. * Module staff
  57. */
  58. static void __exit pps_gen_dummy_exit(void)
  59. {
  60. timer_delete_sync(&ktimer);
  61. pps_gen_unregister_source(pps_gen);
  62. }
  63. static int __init pps_gen_dummy_init(void)
  64. {
  65. pps_gen = pps_gen_register_source(&pps_gen_dummy_info);
  66. if (IS_ERR(pps_gen))
  67. return PTR_ERR(pps_gen);
  68. timer_setup(&ktimer, pps_gen_ktimer_event, 0);
  69. return 0;
  70. }
  71. module_init(pps_gen_dummy_init);
  72. module_exit(pps_gen_dummy_exit);
  73. MODULE_AUTHOR("Rodolfo Giometti <giometti@enneenne.com>");
  74. MODULE_DESCRIPTION("LinuxPPS dummy generator");
  75. MODULE_LICENSE("GPL");