Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * s390 PTP clock driver
  4 *
  5 */
  6
  7#include "ptp_private.h"
  8#include <linux/time.h>
  9#include <asm/stp.h>
 10
 11static struct ptp_clock *ptp_stcke_clock, *ptp_qpt_clock;
 12
 13static int ptp_s390_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 14{
 15	return -EOPNOTSUPP;
 16}
 17
 18static int ptp_s390_adjtime(struct ptp_clock_info *ptp, s64 delta)
 19{
 20	return -EOPNOTSUPP;
 21}
 22
 23static struct timespec64 eitod_to_timespec64(union tod_clock *clk)
 24{
 25	return ns_to_timespec64(eitod_to_ns(clk->eitod - TOD_UNIX_EPOCH));
 26}
 27
 28static struct timespec64 tod_to_timespec64(unsigned long tod)
 29{
 30	return ns_to_timespec64(tod_to_ns(tod - TOD_UNIX_EPOCH));
 31}
 32
 33static int ptp_s390_stcke_gettime(struct ptp_clock_info *ptp,
 34				  struct timespec64 *ts)
 35{
 36	union tod_clock tod;
 37
 38	if (!stp_enabled())
 39		return -EOPNOTSUPP;
 40
 41	store_tod_clock_ext(&tod);
 42	*ts = eitod_to_timespec64(&tod);
 43	return 0;
 44}
 45
 46static int ptp_s390_qpt_gettime(struct ptp_clock_info *ptp,
 47				struct timespec64 *ts)
 48{
 49	unsigned long tod;
 50
 51	ptff(&tod, sizeof(tod), PTFF_QPT);
 52	*ts = tod_to_timespec64(tod);
 53	return 0;
 54}
 55
 56static int ptp_s390_settime(struct ptp_clock_info *ptp,
 57			    const struct timespec64 *ts)
 58{
 59	return -EOPNOTSUPP;
 60}
 61
 62static int s390_arch_ptp_get_crosststamp(ktime_t *device_time,
 63					 struct system_counterval_t *system_counter,
 64					 void *ctx)
 65{
 66	union tod_clock clk;
 67
 68	store_tod_clock_ext(&clk);
 69	*device_time = ns_to_ktime(tod_to_ns(clk.tod - TOD_UNIX_EPOCH));
 70	system_counter->cycles = clk.tod;
 71	system_counter->cs_id = CSID_S390_TOD;
 72	return 0;
 73}
 74
 75static int ptp_s390_getcrosststamp(struct ptp_clock_info *ptp,
 76				   struct system_device_crosststamp *xtstamp)
 77{
 78	if (!stp_enabled())
 79		return -EOPNOTSUPP;
 80	return get_device_system_crosststamp(s390_arch_ptp_get_crosststamp, NULL, NULL, xtstamp);
 81}
 82
 83static struct ptp_clock_info ptp_s390_stcke_info = {
 84	.owner		= THIS_MODULE,
 85	.name		= "s390 STCKE Clock",
 86	.max_adj	= 0,
 87	.adjfine	= ptp_s390_adjfine,
 88	.adjtime	= ptp_s390_adjtime,
 89	.gettime64	= ptp_s390_stcke_gettime,
 90	.settime64	= ptp_s390_settime,
 91	.getcrosststamp = ptp_s390_getcrosststamp,
 92};
 93
 94static struct ptp_clock_info ptp_s390_qpt_info = {
 95	.owner		= THIS_MODULE,
 96	.name		= "s390 Physical Clock",
 97	.max_adj	= 0,
 98	.adjfine	= ptp_s390_adjfine,
 99	.adjtime	= ptp_s390_adjtime,
100	.gettime64	= ptp_s390_qpt_gettime,
101	.settime64	= ptp_s390_settime,
102};
103
104static __init int ptp_s390_init(void)
105{
106	ptp_stcke_clock = ptp_clock_register(&ptp_s390_stcke_info, NULL);
107	if (IS_ERR(ptp_stcke_clock))
108		return PTR_ERR(ptp_stcke_clock);
109
110	ptp_qpt_clock = ptp_clock_register(&ptp_s390_qpt_info, NULL);
111	if (IS_ERR(ptp_qpt_clock)) {
112		ptp_clock_unregister(ptp_stcke_clock);
113		return PTR_ERR(ptp_qpt_clock);
114	}
115	return 0;
116}
117
118static __exit void ptp_s390_exit(void)
119{
120	ptp_clock_unregister(ptp_qpt_clock);
121	ptp_clock_unregister(ptp_stcke_clock);
122}
123
124module_init(ptp_s390_init);
125module_exit(ptp_s390_exit);
126
127MODULE_AUTHOR("Sven Schnelle <svens@linux.ibm.com>");
128MODULE_DESCRIPTION("s390 Physical/STCKE Clock PtP Driver");
129MODULE_LICENSE("GPL");