162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * pps-ktimer.c -- kernel timer test client 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2005-2006 Rodolfo Giometti <giometti@linux.it> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/time.h> 1462306a36Sopenharmony_ci#include <linux/timer.h> 1562306a36Sopenharmony_ci#include <linux/pps_kernel.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * Global variables 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic struct pps_device *pps; 2262306a36Sopenharmony_cistatic struct timer_list ktimer; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* 2562306a36Sopenharmony_ci * The kernel timer 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void pps_ktimer_event(struct timer_list *unused) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci struct pps_event_time ts; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci /* First of all we get the time stamp... */ 3362306a36Sopenharmony_ci pps_get_ts(&ts); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci pps_event(pps, &ts, PPS_CAPTUREASSERT, NULL); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci mod_timer(&ktimer, jiffies + HZ); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* 4162306a36Sopenharmony_ci * The PPS info struct 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic struct pps_source_info pps_ktimer_info = { 4562306a36Sopenharmony_ci .name = "ktimer", 4662306a36Sopenharmony_ci .path = "", 4762306a36Sopenharmony_ci .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | 4862306a36Sopenharmony_ci PPS_ECHOASSERT | 4962306a36Sopenharmony_ci PPS_CANWAIT | PPS_TSFMT_TSPEC, 5062306a36Sopenharmony_ci .owner = THIS_MODULE, 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * Module staff 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic void __exit pps_ktimer_exit(void) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci dev_info(pps->dev, "ktimer PPS source unregistered\n"); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci del_timer_sync(&ktimer); 6262306a36Sopenharmony_ci pps_unregister_source(pps); 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic int __init pps_ktimer_init(void) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci pps = pps_register_source(&pps_ktimer_info, 6862306a36Sopenharmony_ci PPS_CAPTUREASSERT | PPS_OFFSETASSERT); 6962306a36Sopenharmony_ci if (IS_ERR(pps)) { 7062306a36Sopenharmony_ci pr_err("cannot register PPS source\n"); 7162306a36Sopenharmony_ci return PTR_ERR(pps); 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci timer_setup(&ktimer, pps_ktimer_event, 0); 7562306a36Sopenharmony_ci mod_timer(&ktimer, jiffies + HZ); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci dev_info(pps->dev, "ktimer PPS source registered\n"); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci return 0; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cimodule_init(pps_ktimer_init); 8362306a36Sopenharmony_cimodule_exit(pps_ktimer_exit); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciMODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); 8662306a36Sopenharmony_ciMODULE_DESCRIPTION("dummy PPS source by using a kernel timer (just for debug)"); 8762306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 88