[LinuxPPS] [PATCH] New tty source registration method

Rodolfo Giometti giometti at enneenne.com
Thu Dec 14 15:12:00 CET 2006


Hi,

here the patch that _should_ resolve the problem regarding ttySx
sources registration.

Please note that you have to update your linux configuration before
recompiling! So use the sequence:

   make menuconfig (or similar)

to rebuild kernel configuration, and then:

   make

Bernhard, please, try it on your system with 8250_PNP hardware.

Udo, please, do the same on your system _after_ you have resolved your
current problem.

After positive feedback I'll update the GIT repository and produce a
new patch.

Thanks,

Rodolfo

-- 

GNU/Linux Solutions                  e-mail:    giometti at enneenne.com
Linux Device Driver                             giometti at gnudd.com
Embedded Systems                     		giometti at linux.it
UNIX programming                     phone:     +39 349 2432127
-------------- next part --------------
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig
index 5bd6273..1e6e489 100644
--- a/drivers/pps/clients/Kconfig
+++ b/drivers/pps/clients/Kconfig
@@ -15,9 +15,9 @@ config PPS_CLIENT_KTIMER
 	  This driver can also be built as a module.  If so, the module
 	  will be called ktimer.o.
 
-config PPS_CLIENT_8250
-	bool "8250 serial support"
-	depends on PPS && SERIAL_8250 && ! ( PPS = m && SERIAL_8250 = y ) && EXPERIMENTAL
+config PPS_CLIENT_UART
+	bool "UART serial support"
+	depends on PPS && SERIAL_CORE && ! ( PPS = SERIAL_CORE ) && EXPERIMENTAL
 	help
 	  If you say yes here you get support for a PPS source connected
-	  with the CD (Carrier Detect) pin of your 8250 serial line chip.
+	  with the CD (Carrier Detect) pin of your UART serial line chip.
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 589bf11..f1a3f3f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -44,11 +44,6 @@ #include <linux/mutex.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#ifdef CONFIG_PPS_CLIENT_8250
-#include <linux/timepps.h>
-#include <linux/pps.h>
-#endif
-
 #include "8250.h"
 
 /*
@@ -125,10 +120,6 @@ struct uart_8250_port {
 	struct uart_port	port;
 	struct timer_list	timer;		/* "no irq" timer */
 	struct list_head	list;		/* ports on this IRQ */
-#ifdef CONFIG_PPS_CLIENT_8250
-	struct linuxpps_source_info_s linuxpps_8250_info;
-	int source;
-#endif
 	unsigned short		capabilities;	/* port capabilities */
 	unsigned short		bugs;		/* port bugs */
 	unsigned int		tx_loadsz;	/* transmit fifo load size */
@@ -1304,14 +1295,18 @@ static unsigned int check_modem_status(s
 		if (status & UART_MSR_DDSR)
 			up->port.icount.dsr++;
 		if (status & UART_MSR_DDCD) {
-#ifdef CONFIG_PPS_CLIENT_8250
+#ifdef CONFIG_PPS_CLIENT_UART
 			if (status & UART_MSR_DCD) {
-				linuxpps_event(up->source, PPS_CAPTUREASSERT);
-				dbg("serial8250: PPS assert event at %lu", jiffies);
+				linuxpps_event(up->port.pps_source,
+						PPS_CAPTUREASSERT);
+				dbg("serial8250: PPS assert event at %lu",
+						jiffies);
 			}
 			else {
-				linuxpps_event(up->source, PPS_CAPTURECLEAR);
-				dbg("serial8250: PPS clear event at %lu", jiffies);
+				linuxpps_event(up->port.pps_source,
+						PPS_CAPTURECLEAR);
+				dbg("serial8250: PPS clear event at %lu",
+						jiffies);
 			}
 #endif
 			uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
@@ -1899,7 +1894,7 @@ #endif
 		up->ier |= UART_IER_MSI;
 	if (up->capabilities & UART_CAP_UUE)
 		up->ier |= UART_IER_UUE | UART_IER_RTOIE;
-#ifdef CONFIG_PPS_CLIENT_8250
+#ifdef CONFIG_PPS_CLIENT_UART
 	up->ier |= UART_IER_MSI;	/* enable interrupts */
 #endif
 
@@ -2218,7 +2213,6 @@ static void __init
 serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 {
 	int i;
-	int ret;
 
 	serial8250_isa_init_ports();
 
@@ -2226,31 +2220,7 @@ serial8250_register_ports(struct uart_dr
 		struct uart_8250_port *up = &serial8250_ports[i];
 
 		up->port.dev = dev;
-		ret = uart_add_one_port(drv, &up->port);
-#ifdef CONFIG_PPS_CLIENT_8250
-		if (ret == 0) {
-			snprintf(up->linuxpps_8250_info.name, 
-				LINUXPPS_MAX_NAME_LEN, "pps_8250_%d",
-				up->port.line);
-			snprintf(up->linuxpps_8250_info.path,
-				LINUXPPS_MAX_NAME_LEN, "/dev/ttyS%d",
-				up->port.line);
-			up->linuxpps_8250_info.mode = 
-				  PPS_CAPTUREBOTH|PPS_OFFSETASSERT|PPS_OFFSETCLEAR|
-	            		  PPS_CANWAIT|PPS_TSFMT_TSPEC;
-			ret = linuxpps_register_source(
-				&(up->linuxpps_8250_info),
-	    			PPS_CAPTUREBOTH|PPS_OFFSETASSERT|PPS_OFFSETCLEAR,
-				-1 /* is up to the system */);
-			if (ret >= 0) {
-				up->source = ret;
-				dbg("registered 8250 source %d at line %d",
-					up->source, up->port.line);
-			}
-			else
-				err("cannot register 8250 source at line %d", up->port.line);
-		}
-#endif
+		uart_add_one_port(drv, &up->port);
 	}
 }
 
@@ -2651,33 +2621,8 @@ int serial8250_register_port(struct uart
 			uart->port.dev = port->dev;
 
 		ret = uart_add_one_port(&serial8250_reg, &uart->port);
-		if (ret == 0) {
-#ifdef CONFIG_PPS_CLIENT_8250
-			snprintf(uart->linuxpps_8250_info.name, 
-				LINUXPPS_MAX_NAME_LEN, "pps_8250_%d",
-				uart->port.line);
-			snprintf(uart->linuxpps_8250_info.path,
-				LINUXPPS_MAX_NAME_LEN, "/dev/ttyS%d",
-				uart->port.line);
-			uart->linuxpps_8250_info.mode = 
-				  PPS_CAPTUREBOTH|PPS_OFFSETASSERT|PPS_OFFSETCLEAR|
-                		  PPS_CANWAIT|PPS_TSFMT_TSPEC;
-			ret = linuxpps_register_source(
-				&(uart->linuxpps_8250_info),
-	    			PPS_CAPTUREBOTH|PPS_OFFSETASSERT|PPS_OFFSETCLEAR,
-				-1 /* is up to the system */);
-			if (ret >= 0) {
-				uart->source = ret;
-				ret = uart->port.line;
-                                dbg("registered 8250 source %d at line %d", 
-					uart->source, uart->port.line);
-
-			} else
-				err("cannot register 8250 source at line %d", uart->port.line);
-#else
+		if (ret == 0)
 			ret = uart->port.line;
-#endif
-		}
 	}
 	mutex_unlock(&serial_mutex);
 
@@ -2698,11 +2643,6 @@ void serial8250_unregister_port(int line
 
 	mutex_lock(&serial_mutex);
 
-#ifdef CONFIG_PPS_CLIENT_8250
-	linuxpps_unregister_source(&(uart->linuxpps_8250_info));
-	dbg("unregistered 8250 source %d from line %d", uart->source, line);
-#endif
-
 	uart_remove_one_port(&serial8250_reg, &uart->port);
 	if (serial8250_isa_devs) {
 		uart->port.flags &= ~UPF_BOOT_AUTOCONF;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index c67b05e..c861d8d 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -37,6 +37,11 @@ #include <linux/mutex.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PPS_CLIENT_UART
+#include <linux/timepps.h>
+#include <linux/pps.h>
+#endif
+
 #undef	DEBUG
 #ifdef DEBUG
 #define DPRINTK(x...)	printk(x)
@@ -2076,6 +2081,7 @@ uart_configure_port(struct uart_driver *
 		    struct uart_port *port)
 {
 	unsigned int flags;
+	int retval;
 
 	/*
 	 * If there isn't a port here, don't do anything further.
@@ -2114,6 +2120,33 @@ uart_configure_port(struct uart_driver *
 		 */
 		if (!uart_console(port))
 			uart_change_pm(state, 3);
+
+#ifdef CONFIG_PPS_CLIENT_UART
+		/*
+		 * Add the PPS support for the probed port.
+		 */
+                snprintf(state->pps_info.name, LINUXPPS_MAX_NAME_LEN,
+				"%s%d", drv->driver_name, port->line);
+		snprintf(state->pps_info.path, LINUXPPS_MAX_NAME_LEN,
+				"/dev/%s%d", drv->dev_name, port->line);
+
+		state->pps_info.mode = PPS_CAPTUREBOTH | \
+				PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
+				PPS_CANWAIT | PPS_TSFMT_TSPEC;
+
+		retval = linuxpps_register_source(&state->pps_info,
+					PPS_CAPTUREBOTH | \
+					PPS_OFFSETASSERT |PPS_OFFSETCLEAR,
+					-1 /* PPS ID is up to the system */);
+		if (retval < 0) {
+			err("cannot register PPS source \"%s\"",
+				state->pps_info.path);
+			return;
+		}
+		port->pps_source = retval;
+		info("PPS source #%d \"%s\" added to the system ",
+			port->pps_source, state->pps_info.path);
+#endif
 	}
 }
 
@@ -2341,6 +2374,16 @@ int uart_remove_one_port(struct uart_dri
 	port->flags |= UPF_DEAD;
 	mutex_unlock(&state->mutex);
 
+#ifdef CONFIG_PPS_CLIENT_UART
+	/*
+	 * Remove the PPS support.
+	 */
+	if (port->type != PORT_UNKNOWN) {
+		linuxpps_unregister_source(&state->pps_info);
+		dbg("PPS source #%d \"%s\" removed from the system",
+		port->pps_source, state->pps_info.path);
+	}
+#endif
 	/*
 	 * Remove the devices from the tty layer
 	 */
diff --git a/include/linux/pps.h b/include/linux/pps.h
index 76c7271..4d69696 100644
--- a/include/linux/pps.h
+++ b/include/linux/pps.h
@@ -20,6 +20,9 @@
  */
 
 
+#ifndef _PPS_H_
+#define _PPS_H_
+
 /* ----- Misc macros -------------------------------------------------- */
 
 #define PPS_VERSION	"2.2.1"
@@ -101,3 +104,5 @@ extern int linuxpps_procfs_create_source
 extern void linuxpps_procfs_remove_source_entry(struct linuxpps_source_info_s *info, int id);
 extern int linuxpps_procfs_register(void);
 extern void linuxpps_procfs_unregister(void);
+
+#endif /* _PPS_H_ */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 463ab95..da6ffe7 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -143,6 +143,11 @@ #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/mutex.h>
 
+#ifdef CONFIG_PPS_CLIENT_UART
+#include <linux/timepps.h>
+#include <linux/pps.h>
+#endif
+
 struct uart_port;
 struct uart_info;
 struct serial_struct;
@@ -221,6 +226,9 @@ struct uart_port {
 	unsigned char		regshift;		/* reg offset shift */
 	unsigned char		iotype;			/* io access style */
 	unsigned char		unused1;
+#ifdef CONFIG_PPS_CLIENT_UART
+	int			pps_source;		/* PPS source ID */
+#endif
 
 #define UPIO_PORT		(0)
 #define UPIO_HUB6		(1)
@@ -293,6 +301,10 @@ #define USF_CLOSING_WAIT_NONE	(~0U)
 	struct uart_info	*info;
 	struct uart_port	*port;
 
+#ifdef CONFIG_PPS_CLIENT_UART
+        struct linuxpps_source_info_s pps_info;
+#endif
+
 	struct mutex		mutex;
 };
 


More information about the LinuxPPS mailing list