mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects - Introduce wrappers for some optional functions to get consistent behaviour - Wrap put_char which used to be patched by the tty layer - Document which functions are needed/optional - Make put_char report success/fail - Cache the driver->ops pointer in the tty as tty->ops - Remove various surplus lock calls we no longer need - Remove proc_write method as noted by Alexey Dobriyan - Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present [[email protected]: fix fs/compat_ioctl.c build] [[email protected]: fix isicom] [[email protected]: fix arch/ia64/hp/sim/simserial.c build] [[email protected]: fix kgdb] Signed-off-by: Alan Cox <[email protected]> Acked-by: Greg Kroah-Hartman <[email protected]> Cc: Jason Wessel <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
251b8dd7ee
commit
f34d7a5b70
30 changed files with 537 additions and 664 deletions
|
|
@ -96,12 +96,14 @@ static void cleanup_kgdboc(void)
|
|||
|
||||
static int kgdboc_get_char(void)
|
||||
{
|
||||
return kgdb_tty_driver->poll_get_char(kgdb_tty_driver, kgdb_tty_line);
|
||||
return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
|
||||
kgdb_tty_line);
|
||||
}
|
||||
|
||||
static void kgdboc_put_char(u8 chr)
|
||||
{
|
||||
kgdb_tty_driver->poll_put_char(kgdb_tty_driver, kgdb_tty_line, chr);
|
||||
kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
|
||||
kgdb_tty_line, chr);
|
||||
}
|
||||
|
||||
static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
|
||||
|
|
|
|||
|
|
@ -532,15 +532,25 @@ uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
|
|||
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)
|
||||
|
|
@ -622,6 +632,11 @@ static int uart_get_info(struct uart_state *state,
|
|||
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;
|
||||
|
|
@ -641,6 +656,8 @@ static int uart_get_info(struct uart_state *state,
|
|||
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;
|
||||
|
|
@ -918,14 +935,12 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
|
|||
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)
|
||||
|
|
@ -1074,7 +1089,6 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
|
|||
int ret = -ENOIOCTLCMD;
|
||||
|
||||
|
||||
lock_kernel();
|
||||
/*
|
||||
* These ioctls don't rely on the hardware to be present.
|
||||
*/
|
||||
|
|
@ -1144,10 +1158,9 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
|
|||
break;
|
||||
}
|
||||
}
|
||||
out_up:
|
||||
out_up:
|
||||
mutex_unlock(&state->mutex);
|
||||
out:
|
||||
unlock_kernel();
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1173,7 +1186,6 @@ static void uart_set_termios(struct tty_struct *tty,
|
|||
return;
|
||||
}
|
||||
|
||||
lock_kernel();
|
||||
uart_change_speed(state, old_termios);
|
||||
|
||||
/* Handle transition to B0 status */
|
||||
|
|
@ -1206,7 +1218,6 @@ static void uart_set_termios(struct tty_struct *tty,
|
|||
}
|
||||
spin_unlock_irqrestore(&state->port->lock, flags);
|
||||
}
|
||||
unlock_kernel();
|
||||
#if 0
|
||||
/*
|
||||
* No need to wake up processes in open wait, since they
|
||||
|
|
@ -1322,11 +1333,11 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
|||
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
|
||||
|
|
@ -1372,6 +1383,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
|||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING); /* might not be needed */
|
||||
unlock_kernel();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2085,7 +2097,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
|
|||
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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue