mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-24 18:38:38 +00:00
serial: replace the state mutex with the tty port mutex
They cover essentially the same stuff and we can therefore fold it into the tty_port one. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
a03006860d
commit
a2bceae065
@ -1645,7 +1645,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
|
|||||||
state = pmz_uart_reg.state + uap->port.line;
|
state = pmz_uart_reg.state + uap->port.line;
|
||||||
|
|
||||||
mutex_lock(&pmz_irq_mutex);
|
mutex_lock(&pmz_irq_mutex);
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->port.mutex);
|
||||||
|
|
||||||
spin_lock_irqsave(&uap->port.lock, flags);
|
spin_lock_irqsave(&uap->port.lock, flags);
|
||||||
|
|
||||||
@ -1676,7 +1676,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
|
|||||||
/* Shut the chip down */
|
/* Shut the chip down */
|
||||||
pmz_set_scc_power(uap, 0);
|
pmz_set_scc_power(uap, 0);
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->port.mutex);
|
||||||
mutex_unlock(&pmz_irq_mutex);
|
mutex_unlock(&pmz_irq_mutex);
|
||||||
|
|
||||||
pmz_debug("suspend, switching complete\n");
|
pmz_debug("suspend, switching complete\n");
|
||||||
@ -1705,7 +1705,7 @@ static int pmz_resume(struct macio_dev *mdev)
|
|||||||
state = pmz_uart_reg.state + uap->port.line;
|
state = pmz_uart_reg.state + uap->port.line;
|
||||||
|
|
||||||
mutex_lock(&pmz_irq_mutex);
|
mutex_lock(&pmz_irq_mutex);
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->port.mutex);
|
||||||
|
|
||||||
spin_lock_irqsave(&uap->port.lock, flags);
|
spin_lock_irqsave(&uap->port.lock, flags);
|
||||||
if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
|
if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
|
||||||
@ -1737,7 +1737,7 @@ static int pmz_resume(struct macio_dev *mdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->port.mutex);
|
||||||
mutex_unlock(&pmz_irq_mutex);
|
mutex_unlock(&pmz_irq_mutex);
|
||||||
|
|
||||||
/* Right now, we deal with delay by blocking here, I'll be
|
/* Right now, we deal with delay by blocking here, I'll be
|
||||||
|
@ -633,35 +633,36 @@ static void uart_unthrottle(struct tty_struct *tty)
|
|||||||
static int uart_get_info(struct uart_state *state,
|
static int uart_get_info(struct uart_state *state,
|
||||||
struct serial_struct __user *retinfo)
|
struct serial_struct __user *retinfo)
|
||||||
{
|
{
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
struct serial_struct tmp;
|
struct serial_struct tmp;
|
||||||
|
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
|
|
||||||
/* Ensure the state we copy is consistent and no hardware changes
|
/* Ensure the state we copy is consistent and no hardware changes
|
||||||
occur as we go */
|
occur as we go */
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
tmp.type = port->type;
|
tmp.type = uport->type;
|
||||||
tmp.line = port->line;
|
tmp.line = uport->line;
|
||||||
tmp.port = port->iobase;
|
tmp.port = uport->iobase;
|
||||||
if (HIGH_BITS_OFFSET)
|
if (HIGH_BITS_OFFSET)
|
||||||
tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
|
tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET;
|
||||||
tmp.irq = port->irq;
|
tmp.irq = uport->irq;
|
||||||
tmp.flags = port->flags;
|
tmp.flags = uport->flags;
|
||||||
tmp.xmit_fifo_size = port->fifosize;
|
tmp.xmit_fifo_size = uport->fifosize;
|
||||||
tmp.baud_base = port->uartclk / 16;
|
tmp.baud_base = uport->uartclk / 16;
|
||||||
tmp.close_delay = state->port.close_delay / 10;
|
tmp.close_delay = port->close_delay / 10;
|
||||||
tmp.closing_wait = state->port.closing_wait == USF_CLOSING_WAIT_NONE ?
|
tmp.closing_wait = port->closing_wait == USF_CLOSING_WAIT_NONE ?
|
||||||
ASYNC_CLOSING_WAIT_NONE :
|
ASYNC_CLOSING_WAIT_NONE :
|
||||||
state->port.closing_wait / 10;
|
port->closing_wait / 10;
|
||||||
tmp.custom_divisor = port->custom_divisor;
|
tmp.custom_divisor = uport->custom_divisor;
|
||||||
tmp.hub6 = port->hub6;
|
tmp.hub6 = uport->hub6;
|
||||||
tmp.io_type = port->iotype;
|
tmp.io_type = uport->iotype;
|
||||||
tmp.iomem_reg_shift = port->regshift;
|
tmp.iomem_reg_shift = uport->regshift;
|
||||||
tmp.iomem_base = (void *)(unsigned long)port->mapbase;
|
tmp.iomem_base = (void *)(unsigned long)uport->mapbase;
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
|
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -699,7 +700,7 @@ static int uart_set_info(struct uart_state *state,
|
|||||||
* module insertion/removal doesn't change anything
|
* module insertion/removal doesn't change anything
|
||||||
* under us.
|
* under us.
|
||||||
*/
|
*/
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
change_irq = !(uport->flags & UPF_FIXED_PORT)
|
change_irq = !(uport->flags & UPF_FIXED_PORT)
|
||||||
&& new_serial.irq != uport->irq;
|
&& new_serial.irq != uport->irq;
|
||||||
@ -867,7 +868,7 @@ static int uart_set_info(struct uart_state *state,
|
|||||||
} else
|
} else
|
||||||
retval = uart_startup(state, 1);
|
retval = uart_startup(state, 1);
|
||||||
exit:
|
exit:
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,10 +903,11 @@ static int uart_get_lsr_info(struct uart_state *state,
|
|||||||
static int uart_tiocmget(struct tty_struct *tty, struct file *file)
|
static int uart_tiocmget(struct tty_struct *tty, struct file *file)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
struct uart_port *uport = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
int result = -EIO;
|
int result = -EIO;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
if ((!file || !tty_hung_up_p(file)) &&
|
if ((!file || !tty_hung_up_p(file)) &&
|
||||||
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
||||||
result = uport->mctrl;
|
result = uport->mctrl;
|
||||||
@ -914,7 +916,7 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
|
|||||||
result |= uport->ops->get_mctrl(uport);
|
result |= uport->ops->get_mctrl(uport);
|
||||||
spin_unlock_irq(&uport->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -925,35 +927,38 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
|
|||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *uport = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
if ((!file || !tty_hung_up_p(file)) &&
|
if ((!file || !tty_hung_up_p(file)) &&
|
||||||
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
||||||
uart_update_mctrl(uport, set, clear);
|
uart_update_mctrl(uport, set, clear);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
struct uart_port *uport = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
if (uport->type != PORT_UNKNOWN)
|
if (uport->type != PORT_UNKNOWN)
|
||||||
uport->ops->break_ctl(uport, break_state);
|
uport->ops->break_ctl(uport, break_state);
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uart_do_autoconfig(struct uart_state *state)
|
static int uart_do_autoconfig(struct uart_state *state)
|
||||||
{
|
{
|
||||||
struct uart_port *uport = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
int flags, ret;
|
int flags, ret;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
@ -964,7 +969,7 @@ static int uart_do_autoconfig(struct uart_state *state)
|
|||||||
* changing, and hence any extra opens of the port while
|
* changing, and hence any extra opens of the port while
|
||||||
* we're auto-configuring.
|
* we're auto-configuring.
|
||||||
*/
|
*/
|
||||||
if (mutex_lock_interruptible(&state->mutex))
|
if (mutex_lock_interruptible(&port->mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
@ -990,7 +995,7 @@ static int uart_do_autoconfig(struct uart_state *state)
|
|||||||
|
|
||||||
ret = uart_startup(state, 1);
|
ret = uart_startup(state, 1);
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,6 +1098,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
|
|||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
void __user *uarg = (void __user *)arg;
|
void __user *uarg = (void __user *)arg;
|
||||||
int ret = -ENOIOCTLCMD;
|
int ret = -ENOIOCTLCMD;
|
||||||
|
|
||||||
@ -1143,7 +1149,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
|
|||||||
if (ret != -ENOIOCTLCMD)
|
if (ret != -ENOIOCTLCMD)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
if (tty_hung_up_p(filp)) {
|
if (tty_hung_up_p(filp)) {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
@ -1167,7 +1173,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_up:
|
out_up:
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1266,7 +1272,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
|||||||
|
|
||||||
pr_debug("uart_close(%d) called\n", uport->line);
|
pr_debug("uart_close(%d) called\n", uport->line);
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
if (tty_hung_up_p(filp))
|
if (tty_hung_up_p(filp))
|
||||||
goto done;
|
goto done;
|
||||||
@ -1340,7 +1346,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
|||||||
wake_up_interruptible(&port->open_wait);
|
wake_up_interruptible(&port->open_wait);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||||
@ -1416,7 +1422,7 @@ static void uart_hangup(struct tty_struct *tty)
|
|||||||
BUG_ON(!kernel_locked());
|
BUG_ON(!kernel_locked());
|
||||||
pr_debug("uart_hangup(%d)\n", state->uart_port->line);
|
pr_debug("uart_hangup(%d)\n", state->uart_port->line);
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
if (port->flags & ASYNC_NORMAL_ACTIVE) {
|
if (port->flags & ASYNC_NORMAL_ACTIVE) {
|
||||||
uart_flush_buffer(tty);
|
uart_flush_buffer(tty);
|
||||||
uart_shutdown(state);
|
uart_shutdown(state);
|
||||||
@ -1426,7 +1432,7 @@ static void uart_hangup(struct tty_struct *tty)
|
|||||||
wake_up_interruptible(&port->open_wait);
|
wake_up_interruptible(&port->open_wait);
|
||||||
wake_up_interruptible(&state->delta_msr_wait);
|
wake_up_interruptible(&state->delta_msr_wait);
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1528,9 +1534,9 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
|||||||
if (mctrl & TIOCM_CAR)
|
if (mctrl & TIOCM_CAR)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
schedule();
|
schedule();
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
break;
|
break;
|
||||||
@ -1553,15 +1559,17 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
|||||||
static struct uart_state *uart_get(struct uart_driver *drv, int line)
|
static struct uart_state *uart_get(struct uart_driver *drv, int line)
|
||||||
{
|
{
|
||||||
struct uart_state *state;
|
struct uart_state *state;
|
||||||
|
struct tty_port *port;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
state = drv->state + line;
|
state = drv->state + line;
|
||||||
if (mutex_lock_interruptible(&state->mutex)) {
|
port = &state->port;
|
||||||
|
if (mutex_lock_interruptible(&port->mutex)) {
|
||||||
ret = -ERESTARTSYS;
|
ret = -ERESTARTSYS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->port.count++;
|
port->count++;
|
||||||
if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
|
if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
goto err_unlock;
|
goto err_unlock;
|
||||||
@ -1569,8 +1577,8 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
|
|||||||
return state;
|
return state;
|
||||||
|
|
||||||
err_unlock:
|
err_unlock:
|
||||||
state->port.count--;
|
port->count--;
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
err:
|
err:
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
@ -1636,7 +1644,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||||||
if (tty_hung_up_p(filp)) {
|
if (tty_hung_up_p(filp)) {
|
||||||
retval = -EAGAIN;
|
retval = -EAGAIN;
|
||||||
port->count--;
|
port->count--;
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1656,7 +1664,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||||||
*/
|
*/
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
retval = uart_block_til_ready(filp, state);
|
retval = uart_block_til_ready(filp, state);
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is the first open to succeed, adjust things to suit.
|
* If this is the first open to succeed, adjust things to suit.
|
||||||
@ -1667,7 +1675,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||||||
uart_update_termios(state);
|
uart_update_termios(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1689,57 +1697,58 @@ static const char *uart_type(struct uart_port *port)
|
|||||||
static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
|
static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
|
||||||
{
|
{
|
||||||
struct uart_state *state = drv->state + i;
|
struct uart_state *state = drv->state + i;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
int pm_state;
|
int pm_state;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
char stat_buf[32];
|
char stat_buf[32];
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
int mmio;
|
int mmio;
|
||||||
|
|
||||||
if (!port)
|
if (!uport)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mmio = port->iotype >= UPIO_MEM;
|
mmio = uport->iotype >= UPIO_MEM;
|
||||||
seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
|
seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
|
||||||
port->line, uart_type(port),
|
uport->line, uart_type(uport),
|
||||||
mmio ? "mmio:0x" : "port:",
|
mmio ? "mmio:0x" : "port:",
|
||||||
mmio ? (unsigned long long)port->mapbase
|
mmio ? (unsigned long long)uport->mapbase
|
||||||
: (unsigned long long) port->iobase,
|
: (unsigned long long)uport->iobase,
|
||||||
port->irq);
|
uport->irq);
|
||||||
|
|
||||||
if (port->type == PORT_UNKNOWN) {
|
if (uport->type == PORT_UNKNOWN) {
|
||||||
seq_putc(m, '\n');
|
seq_putc(m, '\n');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (capable(CAP_SYS_ADMIN)) {
|
if (capable(CAP_SYS_ADMIN)) {
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
pm_state = state->pm_state;
|
pm_state = state->pm_state;
|
||||||
if (pm_state)
|
if (pm_state)
|
||||||
uart_change_pm(state, 0);
|
uart_change_pm(state, 0);
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
status = port->ops->get_mctrl(port);
|
status = uport->ops->get_mctrl(uport);
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
if (pm_state)
|
if (pm_state)
|
||||||
uart_change_pm(state, pm_state);
|
uart_change_pm(state, pm_state);
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
seq_printf(m, " tx:%d rx:%d",
|
seq_printf(m, " tx:%d rx:%d",
|
||||||
port->icount.tx, port->icount.rx);
|
uport->icount.tx, uport->icount.rx);
|
||||||
if (port->icount.frame)
|
if (uport->icount.frame)
|
||||||
seq_printf(m, " fe:%d",
|
seq_printf(m, " fe:%d",
|
||||||
port->icount.frame);
|
uport->icount.frame);
|
||||||
if (port->icount.parity)
|
if (uport->icount.parity)
|
||||||
seq_printf(m, " pe:%d",
|
seq_printf(m, " pe:%d",
|
||||||
port->icount.parity);
|
uport->icount.parity);
|
||||||
if (port->icount.brk)
|
if (uport->icount.brk)
|
||||||
seq_printf(m, " brk:%d",
|
seq_printf(m, " brk:%d",
|
||||||
port->icount.brk);
|
uport->icount.brk);
|
||||||
if (port->icount.overrun)
|
if (uport->icount.overrun)
|
||||||
seq_printf(m, " oe:%d",
|
seq_printf(m, " oe:%d",
|
||||||
port->icount.overrun);
|
uport->icount.overrun);
|
||||||
|
|
||||||
#define INFOBIT(bit, str) \
|
#define INFOBIT(bit, str) \
|
||||||
if (port->mctrl & (bit)) \
|
if (uport->mctrl & (bit)) \
|
||||||
strncat(stat_buf, (str), sizeof(stat_buf) - \
|
strncat(stat_buf, (str), sizeof(stat_buf) - \
|
||||||
strlen(stat_buf) - 2)
|
strlen(stat_buf) - 2)
|
||||||
#define STATBIT(bit, str) \
|
#define STATBIT(bit, str) \
|
||||||
@ -1991,11 +2000,11 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|||||||
struct device *tty_dev;
|
struct device *tty_dev;
|
||||||
struct uart_match match = {uport, drv};
|
struct uart_match match = {uport, drv};
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
if (!console_suspend_enabled && uart_console(uport)) {
|
if (!console_suspend_enabled && uart_console(uport)) {
|
||||||
/* we're going to avoid suspending serial console */
|
/* we're going to avoid suspending serial console */
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2003,7 +2012,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|||||||
if (device_may_wakeup(tty_dev)) {
|
if (device_may_wakeup(tty_dev)) {
|
||||||
enable_irq_wake(uport->irq);
|
enable_irq_wake(uport->irq);
|
||||||
put_device(tty_dev);
|
put_device(tty_dev);
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uport->suspended = 1;
|
uport->suspended = 1;
|
||||||
@ -2045,7 +2054,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|||||||
|
|
||||||
uart_change_pm(state, 3);
|
uart_change_pm(state, 3);
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2057,18 +2066,18 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
|
|||||||
struct device *tty_dev;
|
struct device *tty_dev;
|
||||||
struct uart_match match = {uport, drv};
|
struct uart_match match = {uport, drv};
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
|
|
||||||
if (!console_suspend_enabled && uart_console(uport)) {
|
if (!console_suspend_enabled && uart_console(uport)) {
|
||||||
/* no need to resume serial console, it wasn't suspended */
|
/* no need to resume serial console, it wasn't suspended */
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
|
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
|
||||||
if (!uport->suspended && device_may_wakeup(tty_dev)) {
|
if (!uport->suspended && device_may_wakeup(tty_dev)) {
|
||||||
disable_irq_wake(uport->irq);
|
disable_irq_wake(uport->irq);
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uport->suspended = 0;
|
uport->suspended = 0;
|
||||||
@ -2124,7 +2133,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
|
|||||||
clear_bit(ASYNCB_SUSPENDED, &port->flags);
|
clear_bit(ASYNCB_SUSPENDED, &port->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2364,12 +2373,11 @@ int uart_register_driver(struct uart_driver *drv)
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < drv->nr; i++) {
|
for (i = 0; i < drv->nr; i++) {
|
||||||
struct uart_state *state = drv->state + i;
|
struct uart_state *state = drv->state + i;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
|
|
||||||
mutex_init(&state->mutex);
|
tty_port_init(port);
|
||||||
|
port->close_delay = 500; /* .5 seconds */
|
||||||
tty_port_init(&state->port);
|
port->closing_wait = 30000; /* 30 seconds */
|
||||||
state->port.close_delay = 500; /* .5 seconds */
|
|
||||||
state->port.closing_wait = 30000; /* 30 seconds */
|
|
||||||
init_waitqueue_head(&state->delta_msr_wait);
|
init_waitqueue_head(&state->delta_msr_wait);
|
||||||
tasklet_init(&state->tlet, uart_tasklet_action,
|
tasklet_init(&state->tlet, uart_tasklet_action,
|
||||||
(unsigned long)state);
|
(unsigned long)state);
|
||||||
@ -2419,62 +2427,64 @@ struct tty_driver *uart_console_device(struct console *co, int *index)
|
|||||||
* level uart drivers to expand uart_port, rather than having yet
|
* level uart drivers to expand uart_port, rather than having yet
|
||||||
* more levels of structures.
|
* more levels of structures.
|
||||||
*/
|
*/
|
||||||
int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
|
int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
|
||||||
{
|
{
|
||||||
struct uart_state *state;
|
struct uart_state *state;
|
||||||
|
struct tty_port *port;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct device *tty_dev;
|
struct device *tty_dev;
|
||||||
|
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
|
|
||||||
if (port->line >= drv->nr)
|
if (uport->line >= drv->nr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
state = drv->state + port->line;
|
state = drv->state + uport->line;
|
||||||
|
port = &state->port;
|
||||||
|
|
||||||
mutex_lock(&port_mutex);
|
mutex_lock(&port_mutex);
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
if (state->uart_port) {
|
if (state->uart_port) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->uart_port = port;
|
state->uart_port = uport;
|
||||||
state->pm_state = -1;
|
state->pm_state = -1;
|
||||||
|
|
||||||
port->cons = drv->cons;
|
uport->cons = drv->cons;
|
||||||
port->state = state;
|
uport->state = state;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this port is a console, then the spinlock is already
|
* If this port is a console, then the spinlock is already
|
||||||
* initialised.
|
* initialised.
|
||||||
*/
|
*/
|
||||||
if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) {
|
if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) {
|
||||||
spin_lock_init(&port->lock);
|
spin_lock_init(&uport->lock);
|
||||||
lockdep_set_class(&port->lock, &port_lock_key);
|
lockdep_set_class(&uport->lock, &port_lock_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_configure_port(drv, state, port);
|
uart_configure_port(drv, state, uport);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the port whether it's detected or not. This allows
|
* Register the port whether it's detected or not. This allows
|
||||||
* setserial to be used to alter this ports parameters.
|
* setserial to be used to alter this ports parameters.
|
||||||
*/
|
*/
|
||||||
tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev);
|
tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);
|
||||||
if (likely(!IS_ERR(tty_dev))) {
|
if (likely(!IS_ERR(tty_dev))) {
|
||||||
device_init_wakeup(tty_dev, 1);
|
device_init_wakeup(tty_dev, 1);
|
||||||
device_set_wakeup_enable(tty_dev, 0);
|
device_set_wakeup_enable(tty_dev, 0);
|
||||||
} else
|
} else
|
||||||
printk(KERN_ERR "Cannot register tty device on line %d\n",
|
printk(KERN_ERR "Cannot register tty device on line %d\n",
|
||||||
port->line);
|
uport->line);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure UPF_DEAD is not set.
|
* Ensure UPF_DEAD is not set.
|
||||||
*/
|
*/
|
||||||
port->flags &= ~UPF_DEAD;
|
uport->flags &= ~UPF_DEAD;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
mutex_unlock(&port_mutex);
|
mutex_unlock(&port_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -2489,15 +2499,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
|
|||||||
* core driver. No further calls will be made to the low-level code
|
* core driver. No further calls will be made to the low-level code
|
||||||
* for this port.
|
* for this port.
|
||||||
*/
|
*/
|
||||||
int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
|
int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
|
||||||
{
|
{
|
||||||
struct uart_state *state = drv->state + port->line;
|
struct uart_state *state = drv->state + uport->line;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
|
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
|
|
||||||
if (state->uart_port != port)
|
if (state->uart_port != uport)
|
||||||
printk(KERN_ALERT "Removing wrong port: %p != %p\n",
|
printk(KERN_ALERT "Removing wrong port: %p != %p\n",
|
||||||
state->uart_port, port);
|
state->uart_port, uport);
|
||||||
|
|
||||||
mutex_lock(&port_mutex);
|
mutex_lock(&port_mutex);
|
||||||
|
|
||||||
@ -2505,28 +2516,28 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
|
|||||||
* Mark the port "dead" - this prevents any opens from
|
* Mark the port "dead" - this prevents any opens from
|
||||||
* succeeding while we shut down the port.
|
* succeeding while we shut down the port.
|
||||||
*/
|
*/
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&port->mutex);
|
||||||
port->flags |= UPF_DEAD;
|
uport->flags |= UPF_DEAD;
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&port->mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove the devices from the tty layer
|
* Remove the devices from the tty layer
|
||||||
*/
|
*/
|
||||||
tty_unregister_device(drv->tty_driver, port->line);
|
tty_unregister_device(drv->tty_driver, uport->line);
|
||||||
|
|
||||||
if (state->port.tty)
|
if (port->tty)
|
||||||
tty_vhangup(state->port.tty);
|
tty_vhangup(port->tty);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free the port IO and memory resources, if any.
|
* Free the port IO and memory resources, if any.
|
||||||
*/
|
*/
|
||||||
if (port->type != PORT_UNKNOWN)
|
if (uport->type != PORT_UNKNOWN)
|
||||||
port->ops->release_port(port);
|
uport->ops->release_port(uport);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Indicate that there isn't a port here anymore.
|
* Indicate that there isn't a port here anymore.
|
||||||
*/
|
*/
|
||||||
port->type = PORT_UNKNOWN;
|
uport->type = PORT_UNKNOWN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kill the tasklet, and free resources.
|
* Kill the tasklet, and free resources.
|
||||||
|
@ -351,8 +351,6 @@ struct uart_state {
|
|||||||
struct tasklet_struct tlet;
|
struct tasklet_struct tlet;
|
||||||
wait_queue_head_t delta_msr_wait;
|
wait_queue_head_t delta_msr_wait;
|
||||||
struct uart_port *uart_port;
|
struct uart_port *uart_port;
|
||||||
|
|
||||||
struct mutex mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UART_XMIT_SIZE PAGE_SIZE
|
#define UART_XMIT_SIZE PAGE_SIZE
|
||||||
|
Loading…
Reference in New Issue
Block a user