static int uart_write_room(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
+ unsigned long flags;
+ int ret;
- return uart_circ_chars_free(&state->info->xmit);
+ spin_lock_irqsave(&state->port->lock, flags);
+ ret = uart_circ_chars_free(&state->info->xmit);
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ return ret;
}
static int uart_chars_in_buffer(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
+ unsigned long flags;
+ int ret;
- return uart_circ_chars_pending(&state->info->xmit);
+ spin_lock_irqsave(&state->port->lock, flags);
+ ret = uart_circ_chars_pending(&state->info->xmit);
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ return ret;
}
static void uart_flush_buffer(struct tty_struct *tty)
struct serial_struct tmp;
memset(&tmp, 0, sizeof(tmp));
+
+ /* Ensure the state we copy is consistent and no hardware changes
+ occur as we go */
+ mutex_lock(&state->mutex);
+
tmp.type = port->type;
tmp.line = port->line;
tmp.port = port->iobase;
tmp.iomem_reg_shift = port->regshift;
tmp.iomem_base = (void *)(unsigned long)port->mapbase;
+ mutex_unlock(&state->mutex);
+
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
return 0;
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port;
- lock_kernel();
mutex_lock(&state->mutex);
if (port->type != PORT_UNKNOWN)
port->ops->break_ctl(port, break_state);
mutex_unlock(&state->mutex);
- unlock_kernel();
}
static int uart_do_autoconfig(struct uart_state *state)
int ret = -ENOIOCTLCMD;
- lock_kernel();
/*
* These ioctls don't rely on the hardware to be present.
*/
break;
}
}
- out_up:
+out_up:
mutex_unlock(&state->mutex);
- out:
- unlock_kernel();
+out:
return ret;
}
return;
}
- lock_kernel();
uart_change_speed(state, old_termios);
/* Handle transition to B0 status */
}
spin_unlock_irqrestore(&state->port->lock, flags);
}
- unlock_kernel();
#if 0
/*
* No need to wake up processes in open wait, since they
struct uart_port *port = state->port;
unsigned long char_time, expire;
- BUG_ON(!kernel_locked());
-
if (port->type == PORT_UNKNOWN || port->fifosize == 0)
return;
+ lock_kernel();
+
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
break;
}
set_current_state(TASK_RUNNING); /* might not be needed */
+ unlock_kernel();
}
/*
int ret;
uart_change_pm(state, 0);
+ spin_lock_irq(&port->lock);
ops->set_mctrl(port, 0);
+ spin_unlock_irq(&port->lock);
ret = ops->startup(port);
if (ret == 0) {
uart_change_speed(state, NULL);