aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 08:17:14 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:07 -0500
commit568aafc627e2978509e8a80c640ba534d1e843cc (patch)
tree1a24c5c0fc3a56054fa054a0255c04e5b7848daa
parent338818fd802a6baacb7e5b6910d52c8996ca6d28 (diff)
tty: tty_port: Add a kref object to the tty port
Users of tty port need a way to refcount ports when hotplugging is involved. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/char/tty_port.c18
-rw-r--r--include/linux/tty.h12
2 files changed, 30 insertions, 0 deletions
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 84006de2900f..be492dd66437 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -29,6 +29,7 @@ void tty_port_init(struct tty_port *port)
29 spin_lock_init(&port->lock); 29 spin_lock_init(&port->lock);
30 port->close_delay = (50 * HZ) / 100; 30 port->close_delay = (50 * HZ) / 100;
31 port->closing_wait = (3000 * HZ) / 100; 31 port->closing_wait = (3000 * HZ) / 100;
32 kref_init(&port->kref);
32} 33}
33EXPORT_SYMBOL(tty_port_init); 34EXPORT_SYMBOL(tty_port_init);
34 35
@@ -56,6 +57,23 @@ void tty_port_free_xmit_buf(struct tty_port *port)
56} 57}
57EXPORT_SYMBOL(tty_port_free_xmit_buf); 58EXPORT_SYMBOL(tty_port_free_xmit_buf);
58 59
60static void tty_port_destructor(struct kref *kref)
61{
62 struct tty_port *port = container_of(kref, struct tty_port, kref);
63 if (port->xmit_buf)
64 free_page((unsigned long)port->xmit_buf);
65 if (port->ops->destruct)
66 port->ops->destruct(port);
67 else
68 kfree(port);
69}
70
71void tty_port_put(struct tty_port *port)
72{
73 if (port)
74 kref_put(&port->kref, tty_port_destructor);
75}
76EXPORT_SYMBOL(tty_port_put);
59 77
60/** 78/**
61 * tty_port_tty_get - get a tty reference 79 * tty_port_tty_get - get a tty reference
diff --git a/include/linux/tty.h b/include/linux/tty.h
index e9269ca1542a..e6da667ba34d 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -199,6 +199,8 @@ struct tty_port_operations {
199 /* FIXME: long term getting the tty argument *out* of this would be 199 /* FIXME: long term getting the tty argument *out* of this would be
200 good for consoles */ 200 good for consoles */
201 int (*activate)(struct tty_port *port, struct tty_struct *tty); 201 int (*activate)(struct tty_port *port, struct tty_struct *tty);
202 /* Called on the final put of a port */
203 void (*destruct)(struct tty_port *port);
202}; 204};
203 205
204struct tty_port { 206struct tty_port {
@@ -219,6 +221,7 @@ struct tty_port {
219 int drain_delay; /* Set to zero if no pure time 221 int drain_delay; /* Set to zero if no pure time
220 based drain is needed else 222 based drain is needed else
221 set to size of fifo */ 223 set to size of fifo */
224 struct kref kref; /* Ref counter */
222}; 225};
223 226
224/* 227/*
@@ -461,6 +464,15 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay);
461extern void tty_port_init(struct tty_port *port); 464extern void tty_port_init(struct tty_port *port);
462extern int tty_port_alloc_xmit_buf(struct tty_port *port); 465extern int tty_port_alloc_xmit_buf(struct tty_port *port);
463extern void tty_port_free_xmit_buf(struct tty_port *port); 466extern void tty_port_free_xmit_buf(struct tty_port *port);
467extern void tty_port_put(struct tty_port *port);
468
469extern inline struct tty_port *tty_port_get(struct tty_port *port)
470{
471 if (port)
472 kref_get(&port->kref);
473 return port;
474}
475
464extern struct tty_struct *tty_port_tty_get(struct tty_port *port); 476extern struct tty_struct *tty_port_tty_get(struct tty_port *port);
465extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); 477extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty);
466extern int tty_port_carrier_raised(struct tty_port *port); 478extern int tty_port_carrier_raised(struct tty_port *port);