Commit 2cd9fa25 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

TTY: hvcs, use kref from tty_port

A simple switch. Except we convert destroy_hvcs_struct to be
tty_port_operations->destruct...
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1997cf04
...@@ -290,12 +290,11 @@ struct hvcs_struct { ...@@ -290,12 +290,11 @@ struct hvcs_struct {
int chars_in_buffer; int chars_in_buffer;
/* /*
* Any variable below the kref is valid before a tty is connected and * Any variable below is valid before a tty is connected and
* stays valid after the tty is disconnected. These shouldn't be * stays valid after the tty is disconnected. These shouldn't be
* whacked until the kobject refcount reaches zero though some entries * whacked until the kobject refcount reaches zero though some entries
* may be changed via sysfs initiatives. * may be changed via sysfs initiatives.
*/ */
struct kref kref; /* ref count & hvcs_struct lifetime */
int connected; /* is the vty-server currently connected to a vty? */ int connected; /* is the vty-server currently connected to a vty? */
uint32_t p_unit_address; /* partner unit address */ uint32_t p_unit_address; /* partner unit address */
uint32_t p_partition_ID; /* partner partition ID */ uint32_t p_partition_ID; /* partner partition ID */
...@@ -304,9 +303,6 @@ struct hvcs_struct { ...@@ -304,9 +303,6 @@ struct hvcs_struct {
struct vio_dev *vdev; struct vio_dev *vdev;
}; };
/* Required to back map a kref to its containing object */
#define from_kref(k) container_of(k, struct hvcs_struct, kref)
static LIST_HEAD(hvcs_structs); static LIST_HEAD(hvcs_structs);
static DEFINE_SPINLOCK(hvcs_structs_lock); static DEFINE_SPINLOCK(hvcs_structs_lock);
static DEFINE_MUTEX(hvcs_init_mutex); static DEFINE_MUTEX(hvcs_init_mutex);
...@@ -701,10 +697,9 @@ static void hvcs_return_index(int index) ...@@ -701,10 +697,9 @@ static void hvcs_return_index(int index)
hvcs_index_list[index] = -1; hvcs_index_list[index] = -1;
} }
/* callback when the kref ref count reaches zero */ static void hvcs_destruct_port(struct tty_port *p)
static void destroy_hvcs_struct(struct kref *kref)
{ {
struct hvcs_struct *hvcsd = from_kref(kref); struct hvcs_struct *hvcsd = container_of(p, struct hvcs_struct, port);
struct vio_dev *vdev; struct vio_dev *vdev;
unsigned long flags; unsigned long flags;
...@@ -741,6 +736,10 @@ static void destroy_hvcs_struct(struct kref *kref) ...@@ -741,6 +736,10 @@ static void destroy_hvcs_struct(struct kref *kref)
kfree(hvcsd); kfree(hvcsd);
} }
static const struct tty_port_operations hvcs_port_ops = {
.destruct = hvcs_destruct_port,
};
static int hvcs_get_index(void) static int hvcs_get_index(void)
{ {
int i; int i;
...@@ -790,9 +789,8 @@ static int __devinit hvcs_probe( ...@@ -790,9 +789,8 @@ static int __devinit hvcs_probe(
return -ENODEV; return -ENODEV;
tty_port_init(&hvcsd->port); tty_port_init(&hvcsd->port);
hvcsd->port.ops = &hvcs_port_ops;
spin_lock_init(&hvcsd->lock); spin_lock_init(&hvcsd->lock);
/* Automatically incs the refcount the first time */
kref_init(&hvcsd->kref);
hvcsd->vdev = dev; hvcsd->vdev = dev;
dev_set_drvdata(&dev->dev, hvcsd); dev_set_drvdata(&dev->dev, hvcsd);
...@@ -860,7 +858,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev) ...@@ -860,7 +858,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
* Let the last holder of this object cause it to be removed, which * Let the last holder of this object cause it to be removed, which
* would probably be tty_hangup below. * would probably be tty_hangup below.
*/ */
kref_put(&hvcsd->kref, destroy_hvcs_struct); tty_port_put(&hvcsd->port);
/* /*
* The hangup is a scheduled function which will auto chain call * The hangup is a scheduled function which will auto chain call
...@@ -1094,7 +1092,7 @@ static struct hvcs_struct *hvcs_get_by_index(int index) ...@@ -1094,7 +1092,7 @@ static struct hvcs_struct *hvcs_get_by_index(int index)
list_for_each_entry(hvcsd, &hvcs_structs, next) { list_for_each_entry(hvcsd, &hvcs_structs, next) {
spin_lock_irqsave(&hvcsd->lock, flags); spin_lock_irqsave(&hvcsd->lock, flags);
if (hvcsd->index == index) { if (hvcsd->index == index) {
kref_get(&hvcsd->kref); tty_port_get(&hvcsd->port);
spin_unlock_irqrestore(&hvcsd->lock, flags); spin_unlock_irqrestore(&hvcsd->lock, flags);
spin_unlock(&hvcs_structs_lock); spin_unlock(&hvcs_structs_lock);
return hvcsd; return hvcsd;
...@@ -1160,7 +1158,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) ...@@ -1160,7 +1158,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
* and will grab the spinlock and free the connection if it fails. * and will grab the spinlock and free the connection if it fails.
*/ */
if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) { if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) {
kref_put(&hvcsd->kref, destroy_hvcs_struct); tty_port_put(&hvcsd->port);
printk(KERN_WARNING "HVCS: enable device failed.\n"); printk(KERN_WARNING "HVCS: enable device failed.\n");
return rc; return rc;
} }
...@@ -1171,7 +1169,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) ...@@ -1171,7 +1169,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
hvcsd = tty->driver_data; hvcsd = tty->driver_data;
spin_lock_irqsave(&hvcsd->lock, flags); spin_lock_irqsave(&hvcsd->lock, flags);
kref_get(&hvcsd->kref); tty_port_get(&hvcsd->port);
hvcsd->port.count++; hvcsd->port.count++;
hvcsd->todo_mask |= HVCS_SCHED_READ; hvcsd->todo_mask |= HVCS_SCHED_READ;
spin_unlock_irqrestore(&hvcsd->lock, flags); spin_unlock_irqrestore(&hvcsd->lock, flags);
...@@ -1186,7 +1184,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) ...@@ -1186,7 +1184,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
error_release: error_release:
spin_unlock_irqrestore(&hvcsd->lock, flags); spin_unlock_irqrestore(&hvcsd->lock, flags);
kref_put(&hvcsd->kref, destroy_hvcs_struct); tty_port_put(&hvcsd->port);
printk(KERN_WARNING "HVCS: partner connect failed.\n"); printk(KERN_WARNING "HVCS: partner connect failed.\n");
return retval; return retval;
...@@ -1240,7 +1238,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) ...@@ -1240,7 +1238,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
tty->driver_data = NULL; tty->driver_data = NULL;
free_irq(irq, hvcsd); free_irq(irq, hvcsd);
kref_put(&hvcsd->kref, destroy_hvcs_struct); tty_port_put(&hvcsd->port);
return; return;
} else if (hvcsd->port.count < 0) { } else if (hvcsd->port.count < 0) {
printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
...@@ -1249,7 +1247,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) ...@@ -1249,7 +1247,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
} }
spin_unlock_irqrestore(&hvcsd->lock, flags); spin_unlock_irqrestore(&hvcsd->lock, flags);
kref_put(&hvcsd->kref, destroy_hvcs_struct); tty_port_put(&hvcsd->port);
} }
static void hvcs_hangup(struct tty_struct * tty) static void hvcs_hangup(struct tty_struct * tty)
...@@ -1301,7 +1299,7 @@ static void hvcs_hangup(struct tty_struct * tty) ...@@ -1301,7 +1299,7 @@ static void hvcs_hangup(struct tty_struct * tty)
* NOTE: If this hangup was signaled from user space then the * NOTE: If this hangup was signaled from user space then the
* final put will never happen. * final put will never happen.
*/ */
kref_put(&hvcsd->kref, destroy_hvcs_struct); tty_port_put(&hvcsd->port);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment