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

Commit 33dd474a authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

tty: kref nozomi



Update the nozomi driver to use krefs

Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c9f19e96
Loading
Loading
Loading
Loading
+45 −40
Original line number Original line Diff line number Diff line
@@ -353,6 +353,7 @@ struct ctrl_ul {


/* This holds all information that is needed regarding a port */
/* This holds all information that is needed regarding a port */
struct port {
struct port {
	struct tty_port port;
	u8 update_flow_control;
	u8 update_flow_control;
	struct ctrl_ul ctrl_ul;
	struct ctrl_ul ctrl_ul;
	struct ctrl_dl ctrl_dl;
	struct ctrl_dl ctrl_dl;
@@ -365,8 +366,6 @@ struct port {
	u8 toggle_ul;
	u8 toggle_ul;
	u16 token_dl;
	u16 token_dl;


	struct tty_struct *tty;
	int tty_open_count;
	/* mutex to ensure one access patch to this port */
	/* mutex to ensure one access patch to this port */
	struct mutex tty_sem;
	struct mutex tty_sem;
	wait_queue_head_t tty_wait;
	wait_queue_head_t tty_wait;
@@ -788,14 +787,14 @@ static void disable_transmit_dl(enum port_type port, struct nozomi *dc)
 * Return 1 - send buffer to card and ack.
 * Return 1 - send buffer to card and ack.
 * Return 0 - don't ack, don't send buffer to card.
 * Return 0 - don't ack, don't send buffer to card.
 */
 */
static int send_data(enum port_type index, const struct nozomi *dc)
static int send_data(enum port_type index, struct nozomi *dc)
{
{
	u32 size = 0;
	u32 size = 0;
	const struct port *port = &dc->port[index];
	struct port *port = &dc->port[index];
	const u8 toggle = port->toggle_ul;
	const u8 toggle = port->toggle_ul;
	void __iomem *addr = port->ul_addr[toggle];
	void __iomem *addr = port->ul_addr[toggle];
	const u32 ul_size = port->ul_size[toggle];
	const u32 ul_size = port->ul_size[toggle];
	struct tty_struct *tty = port->tty;
	struct tty_struct *tty = tty_port_tty_get(&port->port);


	/* Get data from tty and place in buf for now */
	/* Get data from tty and place in buf for now */
	size = __kfifo_get(port->fifo_ul, dc->send_buf,
	size = __kfifo_get(port->fifo_ul, dc->send_buf,
@@ -803,6 +802,7 @@ static int send_data(enum port_type index, const struct nozomi *dc)


	if (size == 0) {
	if (size == 0) {
		DBG4("No more data to send, disable link:");
		DBG4("No more data to send, disable link:");
		tty_kref_put(tty);
		return 0;
		return 0;
	}
	}


@@ -815,6 +815,7 @@ static int send_data(enum port_type index, const struct nozomi *dc)
	if (tty)
	if (tty)
		tty_wakeup(tty);
		tty_wakeup(tty);


	tty_kref_put(tty);
	return 1;
	return 1;
}
}


@@ -826,7 +827,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
	u32 offset = 4;
	u32 offset = 4;
	struct port *port = &dc->port[index];
	struct port *port = &dc->port[index];
	void __iomem *addr = port->dl_addr[port->toggle_dl];
	void __iomem *addr = port->dl_addr[port->toggle_dl];
	struct tty_struct *tty = port->tty;
	struct tty_struct *tty = tty_port_tty_get(&port->port);
	int i;
	int i;


	if (unlikely(!tty)) {
	if (unlikely(!tty)) {
@@ -870,7 +871,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
	}
	}


	set_bit(index, &dc->flip);
	set_bit(index, &dc->flip);

	tty_kref_put(tty);
	return 1;
	return 1;
}
}


@@ -1276,9 +1277,15 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id)


exit_handler:
exit_handler:
	spin_unlock(&dc->spin_mutex);
	spin_unlock(&dc->spin_mutex);
	for (a = 0; a < NOZOMI_MAX_PORTS; a++)
	for (a = 0; a < NOZOMI_MAX_PORTS; a++) {
		if (test_and_clear_bit(a, &dc->flip))
		struct tty_struct *tty;
			tty_flip_buffer_push(dc->port[a].tty);
		if (test_and_clear_bit(a, &dc->flip)) {
			tty = tty_port_tty_get(&dc->port[a].port);
			if (tty)
				tty_flip_buffer_push(tty);
			tty_kref_put(tty);
		}
	}
	return IRQ_HANDLED;
	return IRQ_HANDLED;
none:
none:
	spin_unlock(&dc->spin_mutex);
	spin_unlock(&dc->spin_mutex);
@@ -1453,12 +1460,10 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,


	for (i = 0; i < MAX_PORT; i++) {
	for (i = 0; i < MAX_PORT; i++) {
		mutex_init(&dc->port[i].tty_sem);
		mutex_init(&dc->port[i].tty_sem);
		dc->port[i].tty_open_count = 0;
		tty_port_init(&dc->port[i].port);
		dc->port[i].tty = NULL;
		tty_register_device(ntty_driver, dc->index_start + i,
		tty_register_device(ntty_driver, dc->index_start + i,
							&pdev->dev);
							&pdev->dev);
	}
	}

	return 0;
	return 0;


err_free_sbuf:
err_free_sbuf:
@@ -1482,14 +1487,16 @@ static void __devexit tty_exit(struct nozomi *dc)


	flush_scheduled_work();
	flush_scheduled_work();


	for (i = 0; i < MAX_PORT; ++i)
	for (i = 0; i < MAX_PORT; ++i) {
		if (dc->port[i].tty && \
		struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port);
				list_empty(&dc->port[i].tty->hangup_work.entry))
		if (tty && list_empty(&tty->hangup_work.entry))
			tty_hangup(dc->port[i].tty);
			tty_hangup(tty);

		tty_kref_put(tty);
	}
	/* Racy below - surely should wait for scheduled work to be done or
	   complete off a hangup method ? */
	while (dc->open_ttys)
	while (dc->open_ttys)
		msleep(1);
		msleep(1);

	for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
	for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
		tty_unregister_device(ntty_driver, i);
		tty_unregister_device(ntty_driver, i);
}
}
@@ -1579,23 +1586,22 @@ static int ntty_open(struct tty_struct *tty, struct file *file)
	if (mutex_lock_interruptible(&port->tty_sem))
	if (mutex_lock_interruptible(&port->tty_sem))
		return -ERESTARTSYS;
		return -ERESTARTSYS;


	port->tty_open_count++;
	port->port.count++;
	dc->open_ttys++;
	dc->open_ttys++;


	/* Enable interrupt downlink for channel */
	/* Enable interrupt downlink for channel */
	if (port->tty_open_count == 1) {
	if (port->port.count == 1) {
		/* FIXME: is this needed now ? */
		tty->low_latency = 1;
		tty->low_latency = 1;
		tty->driver_data = port;
		tty->driver_data = port;
		port->tty = tty;
		tty_port_tty_set(&port->port, tty);
		DBG1("open: %d", port->token_dl);
		DBG1("open: %d", port->token_dl);
		spin_lock_irqsave(&dc->spin_mutex, flags);
		spin_lock_irqsave(&dc->spin_mutex, flags);
		dc->last_ier = dc->last_ier | port->token_dl;
		dc->last_ier = dc->last_ier | port->token_dl;
		writew(dc->last_ier, dc->reg_ier);
		writew(dc->last_ier, dc->reg_ier);
		spin_unlock_irqrestore(&dc->spin_mutex, flags);
		spin_unlock_irqrestore(&dc->spin_mutex, flags);
	}
	}

	mutex_unlock(&port->tty_sem);
	mutex_unlock(&port->tty_sem);

	return 0;
	return 0;
}
}


@@ -1606,31 +1612,30 @@ static int ntty_open(struct tty_struct *tty, struct file *file)
static void ntty_close(struct tty_struct *tty, struct file *file)
static void ntty_close(struct tty_struct *tty, struct file *file)
{
{
	struct nozomi *dc = get_dc_by_tty(tty);
	struct nozomi *dc = get_dc_by_tty(tty);
	struct port *port = tty->driver_data;
	struct port *nport = tty->driver_data;
	struct tty_port *port = &nport->port;
	unsigned long flags;
	unsigned long flags;


	if (!dc || !port)
	if (!dc || !nport)
		return;
		return;


	if (mutex_lock_interruptible(&port->tty_sem))
	/* Users cannot interrupt a close */
		return;
	mutex_lock(&nport->tty_sem);


	if (!port->tty_open_count)
	WARN_ON(!port->count);
		goto exit;


	dc->open_ttys--;
	dc->open_ttys--;
	port->tty_open_count--;
	port->count--;
	tty_port_tty_set(port, NULL);


	if (port->tty_open_count == 0) {
	if (port->count == 0) {
		DBG1("close: %d", port->token_dl);
		DBG1("close: %d", nport->token_dl);
		spin_lock_irqsave(&dc->spin_mutex, flags);
		spin_lock_irqsave(&dc->spin_mutex, flags);
		dc->last_ier &= ~(port->token_dl);
		dc->last_ier &= ~(nport->token_dl);
		writew(dc->last_ier, dc->reg_ier);
		writew(dc->last_ier, dc->reg_ier);
		spin_unlock_irqrestore(&dc->spin_mutex, flags);
		spin_unlock_irqrestore(&dc->spin_mutex, flags);
	}
	}

	mutex_unlock(&nport->tty_sem);
exit:
	mutex_unlock(&port->tty_sem);
}
}


/*
/*
@@ -1660,7 +1665,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
		return -EAGAIN;
		return -EAGAIN;
	}
	}


	if (unlikely(!port->tty_open_count)) {
	if (unlikely(!port->port.count)) {
		DBG1(" ");
		DBG1(" ");
		goto exit;
		goto exit;
	}
	}
@@ -1710,7 +1715,7 @@ static int ntty_write_room(struct tty_struct *tty)
	if (!mutex_trylock(&port->tty_sem))
	if (!mutex_trylock(&port->tty_sem))
		return 0;
		return 0;


	if (!port->tty_open_count)
	if (!port->port.count)
		goto exit;
		goto exit;


	room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
	room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
@@ -1866,7 +1871,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
		goto exit_in_buffer;
		goto exit_in_buffer;
	}
	}


	if (unlikely(!port->tty_open_count)) {
	if (unlikely(!port->port.count)) {
		dev_err(&dc->pdev->dev, "No tty open?\n");
		dev_err(&dc->pdev->dev, "No tty open?\n");
		rval = -ENODEV;
		rval = -ENODEV;
		goto exit_in_buffer;
		goto exit_in_buffer;