[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