From nobody Sat Feb 7 15:10:14 2026 Received: from mail-dl1-f65.google.com (mail-dl1-f65.google.com [74.125.82.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3744B28850D for ; Fri, 23 Jan 2026 05:44:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769147070; cv=none; b=a748wbkmzahcL/tHIdgPPey8nCckIOiENUVL8X3q9MCs3I4SZQ2pmI/Jvv+4X78UoVEljwJ4sxsXRgESn4bGjCS7jqii0ttAARZhWk7PngF9aI9z25w5pwfyRZKTASLqc04Dq5ZLtUYmB/iBPIwKKf1Gr/pi+nyemN5+9RmjZLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769147070; c=relaxed/simple; bh=MbrZcFq/kjAHItmH/p3NlxoSi4iYQDMPCdIgam12/v4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=QCM6AyLe4zofApMFvOIT0lOXi8OtMuMRAK1xMjsJG2eBde/VOjunHS/fCBF+8t31Lmpet8HAs/xgfttpa76uVzRTWvCUTNbE8hwu8IOxdsiTnLxBdIFwbRLS0Xtbvp6Z5yzPxzjJQPXM3+BnYMydedKMRDjpsU1GyyfPmQC4xf4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hWU+AwNh; arc=none smtp.client-ip=74.125.82.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hWU+AwNh" Received: by mail-dl1-f65.google.com with SMTP id a92af1059eb24-12332910300so1361198c88.0 for ; Thu, 22 Jan 2026 21:44:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769147061; x=1769751861; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1+TYh8IrFMKjKZqlaMWZ/MSgPtaZ4028KCDnw1NyO2E=; b=hWU+AwNhXCqcvPGysixWegWYxaotkqzwqx5JOQWalMRFaaoUDOg5Kgaeg4qmdCTDaT c8Xx9szSsX0msU6xwpBqaAnfkMA1l4XV+W+rU0VBxdheqY6hip5AvnygVxbYd7Ps4wF/ dQGzi0FR5cB3GiW2itAfcVu+FlAnE85foFElB9IWfHAvLopfCJfq1iqsxEHgWuJYSDqP 8aixOOyEN6pPJj7Fy0joU+V7vE5NGj5mjvwfKsdIX1Z1cQhdeYjxdAtWW6PRN66Fplp/ 8XCr5NI8uSiypA640tTQeUcltsGeNl56+xvIegylYdrCzLn6+6PnkiVYEK9I5ItWXNlM 2MEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769147061; x=1769751861; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=1+TYh8IrFMKjKZqlaMWZ/MSgPtaZ4028KCDnw1NyO2E=; b=VmNHhdPZhPgZTVpEPPO6CHnPJwPk8KP4a740wAIb/3Igi/LE+qtHXRVmB69qDT6VU3 K0AVZz5aMAR6Xk03jkBq6m59HKM6lOCwgIVRvOYw3iUsD4x8ewZKHkxg31t4mi98Dqv/ h5yDzRV/5NEv6opa3hej+TwrTRaHgazhZqLt33DhHlfnp5FmHFBnFnEmCk/HuO7SOdWt ZahfxmUhHdPiaZSnOqHXJXCuLTv6+DCGMwkm+rqz7WQ7ct1VDg+mFBdxZ1XStN7Qsx+1 dHe2f1nE1bQBu1rvMVRuKZnBfUNIK9C03GfvF8eRidmije95L9Lp9CtnZMKN0ea5C//E ggCA== X-Gm-Message-State: AOJu0YxdkhhkVeh+C67INNOMNsAI5i0mdK3Gl5QbatacmtZ872fHvDFE DnsYMOZlnhOH3z2Dc/R8qKuOUBSzKJP7dIxiIS/NwOJ87Bq2ajO7J6PS3ZCclCWj X-Gm-Gg: AZuq6aLTndPGNd6wdysYI4R91qOYlm4JMqm4fw++I2XZPRtLf/5vjgpNAPXqMlv+YhI 2oWbWPHqrZjcv27ryED+cFXgRH8+N2+fDPUHnt2SW6tcJTg9q5FpfP8oSpPM/dcGT/rZ5gsWHYe aFClGRWYzdmHo4ig5B1/3jNMVnsuUtcZUlAq/ZTlHZbw8wy7rnj3f4jgTs9JWFbiP6/nCRoIQ4G wpzQrS2cUsyH/1GzdKx1lL1DdhHLr//IGS6x0UhRJietEuhPalxnlHekR4loobLwVWOROzgEi1b zSASRG4I3yL3L/VGDDp3AS3WCISE76+1TxyJCSVBHr0N7cTl1wjGPQ7Xn1jlib7O7W3kEr5hrW+ 0ugRDD0hF6Zz47SqHg15aPgIUno+BdQ+XNEbmWbZRv5y+xYDkMmBGYTecp0CDJV6YXB6XbmDGS+ hQOoG4omNje1LKcdLodAoHMYJRuYHuZFoiYjC2TyNOUs12F8/a6oNLgyl2qetBmthB/9P8JeH1X wL/Ex8ZDSXdTNvDrRXG+P5e/jfljD9a0rJW80GsdRbkQd/e4mj5zF2vq1ztL2VcsyVCndjauHtx kVsG X-Received: by 2002:a05:7300:5712:b0:2ae:5ffa:8da4 with SMTP id 5a478bee46e88-2b73995f1camr931830eec.1.1769140577098; Thu, 22 Jan 2026 19:56:17 -0800 (PST) Received: from ethan-latitude5420.. (host-127-24.cafrjco.fresno.ca.us.clients.pavlovmedia.net. [68.180.127.24]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b73aa2b656sm1643187eec.33.2026.01.22.19.56.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jan 2026 19:56:16 -0800 (PST) From: Ethan Nelson-Moore To: linux-kernel@vger.kernel.org Cc: Ethan Nelson-Moore , Rodolfo Giometti , Subramanian Mohan , Lakshmi Sowjanya D , Pandith N , Thejesh Reddy T R , Greg Kroah-Hartman , Christopher Hall , Nam Cao , Andy Shevchenko , Zack Rusin , Thomas Gleixner , Petr Mladek Subject: [PATCH] pps: generators: remove broken pps_gen_parport driver Date: Thu, 22 Jan 2026 19:55:47 -0800 Message-ID: <20260123035607.22340-1-enelsonmoore@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This driver was introduced in January 2011 and has been marked BROKEN for almost its entire existence, since commit 95b90afec301 ("pps: make pps_gen_parport depend on BROKEN") in March 2011. It is unlikely anyone will fix the driver at this point. Signed-off-by: Ethan Nelson-Moore Acked-by: Rodolfo Giometti --- drivers/pps/generators/Kconfig | 8 - drivers/pps/generators/Makefile | 1 - drivers/pps/generators/pps_gen_parport.c | 238 ----------------------- 3 files changed, 247 deletions(-) delete mode 100644 drivers/pps/generators/pps_gen_parport.c diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index b3f340ed3163..4ef02b3f2576 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -23,14 +23,6 @@ config PPS_GENERATOR_DUMMY This driver can also be built as a module. If so, the module will be called pps_gen-dummy. =20 -config PPS_GENERATOR_PARPORT - tristate "Parallel port PPS signal generator" - depends on PARPORT && BROKEN - help - If you say yes here you get support for a PPS signal generator which - utilizes STROBE pin of a parallel port to send PPS signals. It uses - parport abstraction layer and hrtimers to precisely control the signal. - config PPS_GENERATOR_TIO tristate "TIO PPS signal generator" depends on X86 && CPU_SUP_INTEL diff --git a/drivers/pps/generators/Makefile b/drivers/pps/generators/Makef= ile index e109920e8a2d..5d38774b4a56 100644 --- a/drivers/pps/generators/Makefile +++ b/drivers/pps/generators/Makefile @@ -7,7 +7,6 @@ pps_gen_core-y :=3D pps_gen.o sysfs.o obj-$(CONFIG_PPS_GENERATOR) :=3D pps_gen_core.o =20 obj-$(CONFIG_PPS_GENERATOR_DUMMY) +=3D pps_gen-dummy.o -obj-$(CONFIG_PPS_GENERATOR_PARPORT) +=3D pps_gen_parport.o obj-$(CONFIG_PPS_GENERATOR_TIO) +=3D pps_gen_tio.o =20 ccflags-$(CONFIG_PPS_DEBUG) :=3D -DDEBUG diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generat= ors/pps_gen_parport.c deleted file mode 100644 index 05bbf8d30ef1..000000000000 --- a/drivers/pps/generators/pps_gen_parport.c +++ /dev/null @@ -1,238 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pps_gen_parport.c -- kernel parallel port PPS signal generator - * - * Copyright (C) 2009 Alexander Gordeev - */ - - -/* - * TODO: - * fix issues when realtime clock is adjusted in a leap - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include - -#define SIGNAL 0 -#define NO_SIGNAL PARPORT_CONTROL_STROBE - -/* module parameters */ - -#define SEND_DELAY_MAX 100000 - -static unsigned int send_delay =3D 30000; -MODULE_PARM_DESC(delay, - "Delay between setting and dropping the signal (ns)"); -module_param_named(delay, send_delay, uint, 0); - - -#define SAFETY_INTERVAL 3000 /* set the hrtimer earlier for safety (ns) */ - -/* internal per port structure */ -struct pps_generator_pp { - struct pardevice *pardev; /* parport device */ - struct hrtimer timer; - long port_write_time; /* calibrated port write time (ns) */ -}; - -static struct pps_generator_pp device =3D { - .pardev =3D NULL, -}; - -static int attached; - -/* calibrated time between a hrtimer event and the reaction */ -static long hrtimer_error =3D SAFETY_INTERVAL; - -/* the kernel hrtimer event */ -static enum hrtimer_restart hrtimer_event(struct hrtimer *timer) -{ - struct timespec64 expire_time, ts1, ts2, ts3, dts; - struct pps_generator_pp *dev; - struct parport *port; - long lim, delta; - unsigned long flags; - - /* We have to disable interrupts here. The idea is to prevent - * other interrupts on the same processor to introduce random - * lags while polling the clock. ktime_get_real_ts64() takes <1us on - * most machines while other interrupt handlers can take much - * more potentially. - * - * NB: approx time with blocked interrupts =3D - * send_delay + 3 * SAFETY_INTERVAL - */ - local_irq_save(flags); - - /* first of all we get the time stamp... */ - ktime_get_real_ts64(&ts1); - expire_time =3D ktime_to_timespec64(hrtimer_get_softexpires(timer)); - dev =3D container_of(timer, struct pps_generator_pp, timer); - lim =3D NSEC_PER_SEC - send_delay - dev->port_write_time; - - /* check if we are late */ - if (expire_time.tv_sec !=3D ts1.tv_sec || ts1.tv_nsec > lim) { - local_irq_restore(flags); - pr_err("we are late this time %ptSp\n", &ts1); - goto done; - } - - /* busy loop until the time is right for an assert edge */ - do { - ktime_get_real_ts64(&ts2); - } while (expire_time.tv_sec =3D=3D ts2.tv_sec && ts2.tv_nsec < lim); - - /* set the signal */ - port =3D dev->pardev->port; - port->ops->write_control(port, SIGNAL); - - /* busy loop until the time is right for a clear edge */ - lim =3D NSEC_PER_SEC - dev->port_write_time; - do { - ktime_get_real_ts64(&ts2); - } while (expire_time.tv_sec =3D=3D ts2.tv_sec && ts2.tv_nsec < lim); - - /* unset the signal */ - port->ops->write_control(port, NO_SIGNAL); - - ktime_get_real_ts64(&ts3); - - local_irq_restore(flags); - - /* update calibrated port write time */ - dts =3D timespec64_sub(ts3, ts2); - dev->port_write_time =3D - (dev->port_write_time + timespec64_to_ns(&dts)) >> 1; - -done: - /* update calibrated hrtimer error */ - dts =3D timespec64_sub(ts1, expire_time); - delta =3D timespec64_to_ns(&dts); - /* If the new error value is bigger then the old, use the new - * value, if not then slowly move towards the new value. This - * way it should be safe in bad conditions and efficient in - * good conditions. - */ - if (delta >=3D hrtimer_error) - hrtimer_error =3D delta; - else - hrtimer_error =3D (3 * hrtimer_error + delta) >> 2; - - /* update the hrtimer expire time */ - hrtimer_set_expires(timer, - ktime_set(expire_time.tv_sec + 1, - NSEC_PER_SEC - (send_delay + - dev->port_write_time + SAFETY_INTERVAL + - 2 * hrtimer_error))); - - return HRTIMER_RESTART; -} - -/* calibrate port write time */ -#define PORT_NTESTS_SHIFT 5 -static void calibrate_port(struct pps_generator_pp *dev) -{ - struct parport *port =3D dev->pardev->port; - int i; - long acc =3D 0; - - for (i =3D 0; i < (1 << PORT_NTESTS_SHIFT); i++) { - struct timespec64 a, b; - unsigned long irq_flags; - - local_irq_save(irq_flags); - ktime_get_real_ts64(&a); - port->ops->write_control(port, NO_SIGNAL); - ktime_get_real_ts64(&b); - local_irq_restore(irq_flags); - - b =3D timespec64_sub(b, a); - acc +=3D timespec64_to_ns(&b); - } - - dev->port_write_time =3D acc >> PORT_NTESTS_SHIFT; - pr_info("port write takes %ldns\n", dev->port_write_time); -} - -static inline ktime_t next_intr_time(struct pps_generator_pp *dev) -{ - struct timespec64 ts; - - ktime_get_real_ts64(&ts); - - return ktime_set(ts.tv_sec + - ((ts.tv_nsec > 990 * NSEC_PER_MSEC) ? 1 : 0), - NSEC_PER_SEC - (send_delay + - dev->port_write_time + 3 * SAFETY_INTERVAL)); -} - -static void parport_attach(struct parport *port) -{ - struct pardev_cb pps_cb; - - if (send_delay > SEND_DELAY_MAX) { - pr_err("delay value should be not greater then %d\n", SEND_DELAY_MAX); - return; - } - - if (attached) { - /* we already have a port */ - return; - } - - memset(&pps_cb, 0, sizeof(pps_cb)); - pps_cb.private =3D &device; - pps_cb.flags =3D PARPORT_FLAG_EXCL; - device.pardev =3D parport_register_dev_model(port, KBUILD_MODNAME, - &pps_cb, 0); - if (!device.pardev) { - pr_err("couldn't register with %s\n", port->name); - return; - } - - if (parport_claim_or_block(device.pardev) < 0) { - pr_err("couldn't claim %s\n", port->name); - goto err_unregister_dev; - } - - pr_info("attached to %s\n", port->name); - attached =3D 1; - - calibrate_port(&device); - - hrtimer_setup(&device.timer, hrtimer_event, CLOCK_REALTIME, HRTIMER_MODE_= ABS); - hrtimer_start(&device.timer, next_intr_time(&device), HRTIMER_MODE_ABS); - - return; - -err_unregister_dev: - parport_unregister_device(device.pardev); -} - -static void parport_detach(struct parport *port) -{ - if (port->cad !=3D device.pardev) - return; /* not our port */ - - hrtimer_cancel(&device.timer); - parport_release(device.pardev); - parport_unregister_device(device.pardev); -} - -static struct parport_driver pps_gen_parport_driver =3D { - .name =3D KBUILD_MODNAME, - .match_port =3D parport_attach, - .detach =3D parport_detach, -}; -module_parport_driver(pps_gen_parport_driver); - -MODULE_AUTHOR("Alexander Gordeev "); -MODULE_DESCRIPTION("parallel port PPS signal generator"); -MODULE_LICENSE("GPL"); --=20 2.43.0