linux/include/linux/pps_kernel.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * PPS API kernel header
   4 *
   5 * Copyright (C) 2009   Rodolfo Giometti <giometti@linux.it>
   6 */
   7
   8#ifndef LINUX_PPS_KERNEL_H
   9#define LINUX_PPS_KERNEL_H
  10
  11#include <linux/pps.h>
  12#include <linux/cdev.h>
  13#include <linux/device.h>
  14#include <linux/time.h>
  15
  16/*
  17 * Global defines
  18 */
  19
  20struct pps_device;
  21
  22/* The specific PPS source info */
  23struct pps_source_info {
  24        char name[PPS_MAX_NAME_LEN];            /* symbolic name */
  25        char path[PPS_MAX_NAME_LEN];            /* path of connected device */
  26        int mode;                               /* PPS allowed mode */
  27
  28        void (*echo)(struct pps_device *pps,
  29                        int event, void *data); /* PPS echo function */
  30
  31        struct module *owner;
  32        struct device *dev;             /* Parent device for device_create */
  33};
  34
  35struct pps_event_time {
  36#ifdef CONFIG_NTP_PPS
  37        struct timespec64 ts_raw;
  38#endif /* CONFIG_NTP_PPS */
  39        struct timespec64 ts_real;
  40};
  41
  42/* The main struct */
  43struct pps_device {
  44        struct pps_source_info info;            /* PSS source info */
  45
  46        struct pps_kparams params;              /* PPS current params */
  47
  48        __u32 assert_sequence;                  /* PPS assert event seq # */
  49        __u32 clear_sequence;                   /* PPS clear event seq # */
  50        struct pps_ktime assert_tu;
  51        struct pps_ktime clear_tu;
  52        int current_mode;                       /* PPS mode at event time */
  53
  54        unsigned int last_ev;                   /* last PPS event id */
  55        wait_queue_head_t queue;                /* PPS event queue */
  56
  57        unsigned int id;                        /* PPS source unique ID */
  58        void const *lookup_cookie;              /* For pps_lookup_dev() only */
  59        struct cdev cdev;
  60        struct device *dev;
  61        struct fasync_struct *async_queue;      /* fasync method */
  62        spinlock_t lock;
  63};
  64
  65/*
  66 * Global variables
  67 */
  68
  69extern const struct attribute_group *pps_groups[];
  70
  71/*
  72 * Internal functions.
  73 *
  74 * These are not actually part of the exported API, but this is a
  75 * convenient header file to put them in.
  76 */
  77
  78extern int pps_register_cdev(struct pps_device *pps);
  79extern void pps_unregister_cdev(struct pps_device *pps);
  80
  81/*
  82 * Exported functions
  83 */
  84
  85extern struct pps_device *pps_register_source(
  86                struct pps_source_info *info, int default_params);
  87extern void pps_unregister_source(struct pps_device *pps);
  88extern void pps_event(struct pps_device *pps,
  89                struct pps_event_time *ts, int event, void *data);
  90/* Look up a pps_device by magic cookie */
  91struct pps_device *pps_lookup_dev(void const *cookie);
  92
  93static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
  94                struct timespec64 ts)
  95{
  96        kt->sec = ts.tv_sec;
  97        kt->nsec = ts.tv_nsec;
  98}
  99
 100static inline void pps_get_ts(struct pps_event_time *ts)
 101{
 102        struct system_time_snapshot snap;
 103
 104        ktime_get_snapshot(&snap);
 105        ts->ts_real = ktime_to_timespec64(snap.real);
 106#ifdef CONFIG_NTP_PPS
 107        ts->ts_raw = ktime_to_timespec64(snap.raw);
 108#endif
 109}
 110
 111/* Subtract known time delay from PPS event time(s) */
 112static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec64 delta)
 113{
 114        ts->ts_real = timespec64_sub(ts->ts_real, delta);
 115#ifdef CONFIG_NTP_PPS
 116        ts->ts_raw = timespec64_sub(ts->ts_raw, delta);
 117#endif
 118}
 119
 120#endif /* LINUX_PPS_KERNEL_H */
 121