tty: serial_core: convert uart_open to use tty_port_open

tty_port_open handles much of the common parts of tty opening. Convert
uart_open to use it and move the serial_core specific parts into
tty_port.activate function. This will be needed to use tty_port functions
directly from in kernel clients.

The tricky part is uart_port_startup can return positive values to allow
setserial to configure the port. We now return the positive value to
tty_port_open so that the tty is not marked as initialized and then set the
return value in uart_open to 0.

Cc: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Rob Herring 2016-08-22 17:39:09 -05:00 committed by Greg Kroah-Hartman
parent ebaa81c728
commit b3b5764618
1 changed files with 27 additions and 51 deletions

View File

@ -235,18 +235,9 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state,
if (tty_port_initialized(port)) if (tty_port_initialized(port))
return 0; return 0;
/*
* Set the TTY IO error marker - we will only clear this
* once we have successfully opened the port.
*/
set_bit(TTY_IO_ERROR, &tty->flags);
retval = uart_port_startup(tty, state, init_hw); retval = uart_port_startup(tty, state, init_hw);
if (!retval) { if (retval)
tty_port_set_initialized(port, 1); set_bit(TTY_IO_ERROR, &tty->flags);
clear_bit(TTY_IO_ERROR, &tty->flags);
} else if (retval > 0)
retval = 0;
return retval; return retval;
} }
@ -972,8 +963,11 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
} }
uart_change_speed(tty, state, NULL); uart_change_speed(tty, state, NULL);
} }
} else } else {
retval = uart_startup(tty, state, 1); retval = uart_startup(tty, state, 1);
if (retval > 0)
retval = 0;
}
exit: exit:
return retval; return retval;
} }
@ -1139,6 +1133,8 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
uport->ops->config_port(uport, flags); uport->ops->config_port(uport, flags);
ret = uart_startup(tty, state, 1); ret = uart_startup(tty, state, 1);
if (ret > 0)
ret = 0;
} }
out: out:
mutex_unlock(&port->mutex); mutex_unlock(&port->mutex);
@ -1711,52 +1707,31 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
struct uart_driver *drv = tty->driver->driver_state; struct uart_driver *drv = tty->driver->driver_state;
int retval, line = tty->index; int retval, line = tty->index;
struct uart_state *state = drv->state + line; struct uart_state *state = drv->state + line;
struct tty_port *port = &state->port;
struct uart_port *uport;
pr_debug("uart_open(%d) called\n", line);
spin_lock_irq(&port->lock);
++port->count;
spin_unlock_irq(&port->lock);
/*
* We take the semaphore here to guarantee that we won't be re-entered
* while allocating the state structure, or while we request any IRQs
* that the driver may need. This also has the nice side-effect that
* it delays the action of uart_hangup, so we can guarantee that
* state->port.tty will always contain something reasonable.
*/
if (mutex_lock_interruptible(&port->mutex)) {
retval = -ERESTARTSYS;
goto end;
}
uport = uart_port_check(state);
if (!uport || uport->flags & UPF_DEAD) {
retval = -ENXIO;
goto err_unlock;
}
tty->driver_data = state; tty->driver_data = state;
uport->state = state;
retval = tty_port_open(&state->port, tty, filp);
if (retval > 0)
retval = 0;
return retval;
}
static int uart_port_activate(struct tty_port *port, struct tty_struct *tty)
{
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport;
uport = uart_port_check(state);
if (!uport || uport->flags & UPF_DEAD)
return -ENXIO;
port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0;
tty_port_tty_set(port, tty);
/* /*
* Start up the serial port. * Start up the serial port.
*/ */
retval = uart_startup(tty, state, 0); return uart_startup(tty, state, 0);
/*
* If we succeeded, wait until the port is ready.
*/
err_unlock:
mutex_unlock(&port->mutex);
if (retval == 0)
retval = tty_port_block_til_ready(port, tty, filp);
end:
return retval;
} }
static const char *uart_type(struct uart_port *port) static const char *uart_type(struct uart_port *port)
@ -2470,6 +2445,7 @@ static const struct tty_operations uart_ops = {
static const struct tty_port_operations uart_port_ops = { static const struct tty_port_operations uart_port_ops = {
.carrier_raised = uart_carrier_raised, .carrier_raised = uart_carrier_raised,
.dtr_rts = uart_dtr_rts, .dtr_rts = uart_dtr_rts,
.activate = uart_port_activate,
}; };
/** /**