Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+16 −18
Original line number Original line Diff line number Diff line
@@ -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 {
	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)
		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)
	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(
		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)
	 * 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)
	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)
	 * 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)
	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)


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)
		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)
	}
	}


	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)
		 * 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);
	}
	}
}
}