mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branches 'sh/urgent', 'sh/core', 'sh/clockevents', 'sh/asm-generic' and 'sh/trivial' into sh-fixes-for-linus
This commit is contained in:
commit
380622e9ff
3984 changed files with 220830 additions and 106853 deletions
|
|
@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
|
|||
if (!retinfo)
|
||||
return -EFAULT;
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
tmp.line = tty->index;
|
||||
tmp.port = state->port;
|
||||
tmp.flags = state->tport.flags;
|
||||
|
|
@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
|
|||
tmp.close_delay = state->tport.close_delay;
|
||||
tmp.closing_wait = state->tport.closing_wait;
|
||||
tmp.custom_divisor = state->custom_divisor;
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
|
@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
|
|||
if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
|
||||
return -EFAULT;
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
|
||||
new_serial.custom_divisor != state->custom_divisor;
|
||||
if (new_serial.irq || new_serial.port != state->port ||
|
||||
new_serial.xmit_fifo_size != state->xmit_fifo_size) {
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
|
|||
(new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
|
||||
((new_serial.flags & ~ASYNC_USR_MASK) !=
|
||||
(port->flags & ~ASYNC_USR_MASK))) {
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return -EPERM;
|
||||
}
|
||||
port->flags = ((port->flags & ~ASYNC_USR_MASK) |
|
||||
|
|
@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
|
|||
}
|
||||
|
||||
if (new_serial.baud_base < 9600) {
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -1116,7 +1116,7 @@ check_and_exit:
|
|||
}
|
||||
} else
|
||||
retval = startup(tty, state);
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
|
|||
* If the port is the middle of closing, bail out now
|
||||
*/
|
||||
if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
|
||||
wait_event_interruptible_tty(tty, info->port.close_wait,
|
||||
wait_event_interruptible_tty(info->port.close_wait,
|
||||
!(info->port.flags & ASYNC_CLOSING));
|
||||
return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1065,8 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
|
|||
|
||||
TRACE_L("read()");
|
||||
|
||||
/* FIXME: should use a private lock */
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
|
||||
pClient = findClient(pInfo, task_pid(current));
|
||||
if (pClient) {
|
||||
|
|
@ -1078,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
|
|||
goto unlock;
|
||||
}
|
||||
/* block until there is a message: */
|
||||
wait_event_interruptible_tty(tty, pInfo->read_wait,
|
||||
wait_event_interruptible_tty(pInfo->read_wait,
|
||||
(pMsg = remove_msg(pInfo, pClient)));
|
||||
}
|
||||
|
||||
|
|
@ -1108,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
|
|||
}
|
||||
ret = -EPERM;
|
||||
unlock:
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1157,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
|
|||
pHeader->locks = 0;
|
||||
pHeader->owner = NULL;
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
|
||||
pClient = findClient(pInfo, task_pid(current));
|
||||
if (pClient) {
|
||||
|
|
@ -1176,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
|
|||
add_tx_queue(pInfo, pHeader);
|
||||
trigger_transmit(pInfo);
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
|
|||
wake_up_interruptible(&tty->read_wait);
|
||||
wake_up_interruptible(&tty->write_wait);
|
||||
tty->packet = 0;
|
||||
/* Review - krefs on tty_link ?? */
|
||||
if (!tty->link)
|
||||
return;
|
||||
tty->link->packet = 0;
|
||||
|
|
@ -63,9 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
|
|||
mutex_unlock(&devpts_mutex);
|
||||
}
|
||||
#endif
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
tty_vhangup(tty->link);
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -623,29 +622,26 @@ static int ptmx_open(struct inode *inode, struct file *filp)
|
|||
return retval;
|
||||
|
||||
/* find a device that is not in use. */
|
||||
mutex_lock(&devpts_mutex);
|
||||
tty_lock();
|
||||
index = devpts_new_index(inode);
|
||||
tty_unlock();
|
||||
if (index < 0) {
|
||||
retval = index;
|
||||
goto err_file;
|
||||
}
|
||||
|
||||
mutex_unlock(&devpts_mutex);
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
mutex_lock(&devpts_mutex);
|
||||
tty = tty_init_dev(ptm_driver, index);
|
||||
mutex_unlock(&devpts_mutex);
|
||||
tty_lock();
|
||||
mutex_unlock(&tty_mutex);
|
||||
|
||||
if (IS_ERR(tty)) {
|
||||
retval = PTR_ERR(tty);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* The tty returned here is locked so we can safely
|
||||
drop the mutex */
|
||||
mutex_unlock(&devpts_mutex);
|
||||
mutex_unlock(&tty_mutex);
|
||||
|
||||
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
|
||||
|
||||
tty_add_file(tty, filp);
|
||||
|
|
@ -658,17 +654,16 @@ static int ptmx_open(struct inode *inode, struct file *filp)
|
|||
if (retval)
|
||||
goto err_release;
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return 0;
|
||||
err_release:
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
tty_release(inode, filp);
|
||||
return retval;
|
||||
out:
|
||||
mutex_unlock(&tty_mutex);
|
||||
devpts_kill_index(inode, index);
|
||||
tty_unlock();
|
||||
err_file:
|
||||
mutex_unlock(&devpts_mutex);
|
||||
tty_free_file(filp);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
|
|||
*/
|
||||
if (tty_hung_up_p(filp) ||
|
||||
(info->flags & ASYNC_CLOSING)) {
|
||||
wait_event_interruptible_tty(tty, info->close_wait,
|
||||
wait_event_interruptible_tty(info->close_wait,
|
||||
!(info->flags & ASYNC_CLOSING));
|
||||
#ifdef SERIAL_DO_RESTART
|
||||
if (info->flags & ASYNC_HUP_NOTIFY)
|
||||
|
|
@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
|
|||
printk("block_til_ready blocking: ttyS%d, count = %d\n",
|
||||
info->line, info->count);
|
||||
#endif
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
schedule();
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&info->open_wait, &wait);
|
||||
|
|
@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
|
|||
*/
|
||||
if (tty_hung_up_p(filp) ||
|
||||
(info->flags & ASYNC_CLOSING)) {
|
||||
wait_event_interruptible_tty(tty, info->close_wait,
|
||||
wait_event_interruptible_tty(info->close_wait,
|
||||
!(info->flags & ASYNC_CLOSING));
|
||||
#ifdef SERIAL_DO_RESTART
|
||||
return ((info->flags & ASYNC_HUP_NOTIFY) ?
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ struct imx_port {
|
|||
unsigned int irda_inv_rx:1;
|
||||
unsigned int irda_inv_tx:1;
|
||||
unsigned short trcv_delay; /* transceiver delay */
|
||||
struct clk *clk;
|
||||
struct clk *clk_ipg;
|
||||
struct clk *clk_per;
|
||||
struct imx_uart_data *devdata;
|
||||
};
|
||||
|
||||
|
|
@ -673,7 +674,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
|
|||
* RFDIV is set such way to satisfy requested uartclk value
|
||||
*/
|
||||
val = TXTL << 10 | RXTL;
|
||||
ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2)
|
||||
ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2)
|
||||
/ sport->port.uartclk;
|
||||
|
||||
if(!ufcr_rfdiv)
|
||||
|
|
@ -1286,7 +1287,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
|
|||
else
|
||||
ucfr_rfdiv = 6 - ucfr_rfdiv;
|
||||
|
||||
uartclk = clk_get_rate(sport->clk);
|
||||
uartclk = clk_get_rate(sport->clk_per);
|
||||
uartclk /= ucfr_rfdiv;
|
||||
|
||||
{ /*
|
||||
|
|
@ -1511,14 +1512,22 @@ static int serial_imx_probe(struct platform_device *pdev)
|
|||
goto unmap;
|
||||
}
|
||||
|
||||
sport->clk = clk_get(&pdev->dev, "uart");
|
||||
if (IS_ERR(sport->clk)) {
|
||||
ret = PTR_ERR(sport->clk);
|
||||
sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
|
||||
if (IS_ERR(sport->clk_ipg)) {
|
||||
ret = PTR_ERR(sport->clk_ipg);
|
||||
goto unmap;
|
||||
}
|
||||
clk_prepare_enable(sport->clk);
|
||||
|
||||
sport->port.uartclk = clk_get_rate(sport->clk);
|
||||
sport->clk_per = devm_clk_get(&pdev->dev, "per");
|
||||
if (IS_ERR(sport->clk_per)) {
|
||||
ret = PTR_ERR(sport->clk_per);
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
clk_prepare_enable(sport->clk_per);
|
||||
clk_prepare_enable(sport->clk_ipg);
|
||||
|
||||
sport->port.uartclk = clk_get_rate(sport->clk_per);
|
||||
|
||||
imx_ports[sport->port.line] = sport;
|
||||
|
||||
|
|
@ -1539,8 +1548,8 @@ deinit:
|
|||
if (pdata && pdata->exit)
|
||||
pdata->exit(pdev);
|
||||
clkput:
|
||||
clk_disable_unprepare(sport->clk);
|
||||
clk_put(sport->clk);
|
||||
clk_disable_unprepare(sport->clk_per);
|
||||
clk_disable_unprepare(sport->clk_ipg);
|
||||
unmap:
|
||||
iounmap(sport->port.membase);
|
||||
free:
|
||||
|
|
@ -1558,11 +1567,10 @@ static int serial_imx_remove(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
if (sport) {
|
||||
uart_remove_one_port(&imx_reg, &sport->port);
|
||||
clk_disable_unprepare(sport->clk);
|
||||
clk_put(sport->clk);
|
||||
}
|
||||
uart_remove_one_port(&imx_reg, &sport->port);
|
||||
|
||||
clk_disable_unprepare(sport->clk_per);
|
||||
clk_disable_unprepare(sport->clk_ipg);
|
||||
|
||||
if (pdata && pdata->exit)
|
||||
pdata->exit(pdev);
|
||||
|
|
|
|||
|
|
@ -31,16 +31,19 @@
|
|||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
#define PORT_LTQ_ASC 111
|
||||
#define MAXPORTS 2
|
||||
#define UART_DUMMY_UER_RX 1
|
||||
#define DRVNAME "ltq_asc"
|
||||
#define DRVNAME "lantiq,asc"
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define LTQ_ASC_TBUF (0x0020 + 3)
|
||||
#define LTQ_ASC_RBUF (0x0024 + 3)
|
||||
|
|
@ -114,6 +117,9 @@ static DEFINE_SPINLOCK(ltq_asc_lock);
|
|||
|
||||
struct ltq_uart_port {
|
||||
struct uart_port port;
|
||||
/* clock used to derive divider */
|
||||
struct clk *fpiclk;
|
||||
/* clock gating of the ASC core */
|
||||
struct clk *clk;
|
||||
unsigned int tx_irq;
|
||||
unsigned int rx_irq;
|
||||
|
|
@ -316,7 +322,9 @@ lqasc_startup(struct uart_port *port)
|
|||
struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
|
||||
int retval;
|
||||
|
||||
port->uartclk = clk_get_rate(ltq_port->clk);
|
||||
if (ltq_port->clk)
|
||||
clk_enable(ltq_port->clk);
|
||||
port->uartclk = clk_get_rate(ltq_port->fpiclk);
|
||||
|
||||
ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
|
||||
port->membase + LTQ_ASC_CLC);
|
||||
|
|
@ -382,6 +390,8 @@ lqasc_shutdown(struct uart_port *port)
|
|||
port->membase + LTQ_ASC_RXFCON);
|
||||
ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
|
||||
port->membase + LTQ_ASC_TXFCON);
|
||||
if (ltq_port->clk)
|
||||
clk_disable(ltq_port->clk);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -630,7 +640,7 @@ lqasc_console_setup(struct console *co, char *options)
|
|||
|
||||
port = <q_port->port;
|
||||
|
||||
port->uartclk = clk_get_rate(ltq_port->clk);
|
||||
port->uartclk = clk_get_rate(ltq_port->fpiclk);
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
|
|
@ -668,37 +678,32 @@ static struct uart_driver lqasc_reg = {
|
|||
static int __init
|
||||
lqasc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct ltq_uart_port *ltq_port;
|
||||
struct uart_port *port;
|
||||
struct resource *mmres, *irqres;
|
||||
int tx_irq, rx_irq, err_irq;
|
||||
struct clk *clk;
|
||||
struct resource *mmres, irqres[3];
|
||||
int line = 0;
|
||||
int ret;
|
||||
|
||||
mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!mmres || !irqres)
|
||||
ret = of_irq_to_resource_table(node, irqres, 3);
|
||||
if (!mmres || (ret != 3)) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get memory/irq for serial port\n");
|
||||
return -ENODEV;
|
||||
|
||||
if (pdev->id >= MAXPORTS)
|
||||
return -EBUSY;
|
||||
|
||||
if (lqasc_port[pdev->id] != NULL)
|
||||
return -EBUSY;
|
||||
|
||||
clk = clk_get(&pdev->dev, "fpi");
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("failed to get fpi clk\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
tx_irq = platform_get_irq_byname(pdev, "tx");
|
||||
rx_irq = platform_get_irq_byname(pdev, "rx");
|
||||
err_irq = platform_get_irq_byname(pdev, "err");
|
||||
if ((tx_irq < 0) | (rx_irq < 0) | (err_irq < 0))
|
||||
return -ENODEV;
|
||||
/* check if this is the console port */
|
||||
if (mmres->start != CPHYSADDR(LTQ_EARLY_ASC))
|
||||
line = 1;
|
||||
|
||||
ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL);
|
||||
if (lqasc_port[line]) {
|
||||
dev_err(&pdev->dev, "port %d already allocated\n", line);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ltq_port = devm_kzalloc(&pdev->dev, sizeof(struct ltq_uart_port),
|
||||
GFP_KERNEL);
|
||||
if (!ltq_port)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -709,19 +714,26 @@ lqasc_probe(struct platform_device *pdev)
|
|||
port->ops = &lqasc_pops;
|
||||
port->fifosize = 16;
|
||||
port->type = PORT_LTQ_ASC,
|
||||
port->line = pdev->id;
|
||||
port->line = line;
|
||||
port->dev = &pdev->dev;
|
||||
|
||||
port->irq = tx_irq; /* unused, just to be backward-compatibe */
|
||||
/* unused, just to be backward-compatible */
|
||||
port->irq = irqres[0].start;
|
||||
port->mapbase = mmres->start;
|
||||
|
||||
ltq_port->clk = clk;
|
||||
ltq_port->fpiclk = clk_get_fpi();
|
||||
if (IS_ERR(ltq_port->fpiclk)) {
|
||||
pr_err("failed to get fpi clk\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ltq_port->tx_irq = tx_irq;
|
||||
ltq_port->rx_irq = rx_irq;
|
||||
ltq_port->err_irq = err_irq;
|
||||
/* not all asc ports have clock gates, lets ignore the return code */
|
||||
ltq_port->clk = clk_get(&pdev->dev, NULL);
|
||||
|
||||
lqasc_port[pdev->id] = ltq_port;
|
||||
ltq_port->tx_irq = irqres[0].start;
|
||||
ltq_port->rx_irq = irqres[1].start;
|
||||
ltq_port->err_irq = irqres[2].start;
|
||||
|
||||
lqasc_port[line] = ltq_port;
|
||||
platform_set_drvdata(pdev, ltq_port);
|
||||
|
||||
ret = uart_add_one_port(&lqasc_reg, port);
|
||||
|
|
@ -729,10 +741,17 @@ lqasc_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ltq_asc_match[] = {
|
||||
{ .compatible = DRVNAME },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ltq_asc_match);
|
||||
|
||||
static struct platform_driver lqasc_driver = {
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ltq_asc_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/irqflags.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
|
|
|||
|
|
@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
|
|||
printk("%s(%d):block_til_ready blocking on %s count=%d\n",
|
||||
__FILE__,__LINE__, tty->driver->name, port->count );
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
schedule();
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
}
|
||||
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
|
|
|||
|
|
@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|||
}
|
||||
|
||||
DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
schedule();
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
}
|
||||
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
|
|
|||
|
|
@ -3357,9 +3357,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|||
printk("%s(%d):%s block_til_ready() count=%d\n",
|
||||
__FILE__,__LINE__, tty->driver->name, port->count );
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
schedule();
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
}
|
||||
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,6 @@ void free_tty_struct(struct tty_struct *tty)
|
|||
put_device(tty->dev);
|
||||
kfree(tty->write_buf);
|
||||
tty_buffer_free_all(tty);
|
||||
tty->magic = 0xDEADDEAD;
|
||||
kfree(tty);
|
||||
}
|
||||
|
||||
|
|
@ -574,7 +573,7 @@ void __tty_hangup(struct tty_struct *tty)
|
|||
}
|
||||
spin_unlock(&redirect_lock);
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
|
||||
/* some functions below drop BTM, so we need this bit */
|
||||
set_bit(TTY_HUPPING, &tty->flags);
|
||||
|
|
@ -667,7 +666,7 @@ void __tty_hangup(struct tty_struct *tty)
|
|||
clear_bit(TTY_HUPPING, &tty->flags);
|
||||
tty_ldisc_enable(tty);
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
|
||||
if (f)
|
||||
fput(f);
|
||||
|
|
@ -1104,12 +1103,12 @@ void tty_write_message(struct tty_struct *tty, char *msg)
|
|||
{
|
||||
if (tty) {
|
||||
mutex_lock(&tty->atomic_write_lock);
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
tty->ops->write(tty, msg, strlen(msg));
|
||||
} else
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
tty_write_unlock(tty);
|
||||
}
|
||||
return;
|
||||
|
|
@ -1404,7 +1403,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
|
|||
}
|
||||
initialize_tty_struct(tty, driver, idx);
|
||||
|
||||
tty_lock(tty);
|
||||
retval = tty_driver_install_tty(driver, tty);
|
||||
if (retval < 0)
|
||||
goto err_deinit_tty;
|
||||
|
|
@ -1417,11 +1415,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
|
|||
retval = tty_ldisc_setup(tty, tty->link);
|
||||
if (retval)
|
||||
goto err_release_tty;
|
||||
/* Return the tty locked so that it cannot vanish under the caller */
|
||||
return tty;
|
||||
|
||||
err_deinit_tty:
|
||||
tty_unlock(tty);
|
||||
deinitialize_tty_struct(tty);
|
||||
free_tty_struct(tty);
|
||||
err_module_put:
|
||||
|
|
@ -1430,7 +1426,6 @@ err_module_put:
|
|||
|
||||
/* call the tty release_tty routine to clean out this slot */
|
||||
err_release_tty:
|
||||
tty_unlock(tty);
|
||||
printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, "
|
||||
"clearing slot %d\n", idx);
|
||||
release_tty(tty, idx);
|
||||
|
|
@ -1633,7 +1628,7 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
if (tty_paranoia_check(tty, inode, __func__))
|
||||
return 0;
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
check_tty_count(tty, __func__);
|
||||
|
||||
__tty_fasync(-1, filp, 0);
|
||||
|
|
@ -1642,11 +1637,10 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|
||||
tty->driver->subtype == PTY_TYPE_MASTER);
|
||||
devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
|
||||
/* Review: parallel close */
|
||||
o_tty = tty->link;
|
||||
|
||||
if (tty_release_checks(tty, o_tty, idx)) {
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1658,7 +1652,7 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
if (tty->ops->close)
|
||||
tty->ops->close(tty, filp);
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
/*
|
||||
* Sanity check: if tty->count is going to zero, there shouldn't be
|
||||
* any waiters on tty->read_wait or tty->write_wait. We test the
|
||||
|
|
@ -1681,7 +1675,7 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
opens on /dev/tty */
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
tty_lock_pair(tty, o_tty);
|
||||
tty_lock();
|
||||
tty_closing = tty->count <= 1;
|
||||
o_tty_closing = o_tty &&
|
||||
(o_tty->count <= (pty_master ? 1 : 0));
|
||||
|
|
@ -1712,7 +1706,7 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
|
||||
printk(KERN_WARNING "%s: %s: read/write wait queue active!\n",
|
||||
__func__, tty_name(tty, buf));
|
||||
tty_unlock_pair(tty, o_tty);
|
||||
tty_unlock();
|
||||
mutex_unlock(&tty_mutex);
|
||||
schedule();
|
||||
}
|
||||
|
|
@ -1775,7 +1769,7 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
|
||||
/* check whether both sides are closing ... */
|
||||
if (!tty_closing || (o_tty && !o_tty_closing)) {
|
||||
tty_unlock_pair(tty, o_tty);
|
||||
tty_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1788,16 +1782,14 @@ int tty_release(struct inode *inode, struct file *filp)
|
|||
tty_ldisc_release(tty, o_tty);
|
||||
/*
|
||||
* The release_tty function takes care of the details of clearing
|
||||
* the slots and preserving the termios structure. The tty_unlock_pair
|
||||
* should be safe as we keep a kref while the tty is locked (so the
|
||||
* unlock never unlocks a freed tty).
|
||||
* the slots and preserving the termios structure.
|
||||
*/
|
||||
release_tty(tty, idx);
|
||||
tty_unlock_pair(tty, o_tty);
|
||||
|
||||
/* Make this pty number available for reallocation */
|
||||
if (devpts)
|
||||
devpts_kill_index(inode, idx);
|
||||
tty_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1901,9 +1893,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
|
|||
* Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev.
|
||||
* tty->count should protect the rest.
|
||||
* ->siglock protects ->signal/->sighand
|
||||
*
|
||||
* Note: the tty_unlock/lock cases without a ref are only safe due to
|
||||
* tty_mutex
|
||||
*/
|
||||
|
||||
static int tty_open(struct inode *inode, struct file *filp)
|
||||
|
|
@ -1927,7 +1916,8 @@ retry_open:
|
|||
retval = 0;
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
/* This is protected by the tty_mutex */
|
||||
tty_lock();
|
||||
|
||||
tty = tty_open_current_tty(device, filp);
|
||||
if (IS_ERR(tty)) {
|
||||
retval = PTR_ERR(tty);
|
||||
|
|
@ -1948,19 +1938,17 @@ retry_open:
|
|||
}
|
||||
|
||||
if (tty) {
|
||||
tty_lock(tty);
|
||||
retval = tty_reopen(tty);
|
||||
if (retval < 0) {
|
||||
tty_unlock(tty);
|
||||
if (retval)
|
||||
tty = ERR_PTR(retval);
|
||||
}
|
||||
} else /* Returns with the tty_lock held for now */
|
||||
} else
|
||||
tty = tty_init_dev(driver, index);
|
||||
|
||||
mutex_unlock(&tty_mutex);
|
||||
if (driver)
|
||||
tty_driver_kref_put(driver);
|
||||
if (IS_ERR(tty)) {
|
||||
tty_unlock();
|
||||
retval = PTR_ERR(tty);
|
||||
goto err_file;
|
||||
}
|
||||
|
|
@ -1989,7 +1977,7 @@ retry_open:
|
|||
printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__,
|
||||
retval, tty->name);
|
||||
#endif
|
||||
tty_unlock(tty); /* need to call tty_release without BTM */
|
||||
tty_unlock(); /* need to call tty_release without BTM */
|
||||
tty_release(inode, filp);
|
||||
if (retval != -ERESTARTSYS)
|
||||
return retval;
|
||||
|
|
@ -2001,15 +1989,17 @@ retry_open:
|
|||
/*
|
||||
* Need to reset f_op in case a hangup happened.
|
||||
*/
|
||||
tty_lock();
|
||||
if (filp->f_op == &hung_up_tty_fops)
|
||||
filp->f_op = &tty_fops;
|
||||
tty_unlock();
|
||||
goto retry_open;
|
||||
}
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
if (!noctty &&
|
||||
current->signal->leader &&
|
||||
|
|
@ -2017,10 +2007,11 @@ retry_open:
|
|||
tty->session == NULL)
|
||||
__proc_set_tty(current, tty);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
mutex_unlock(&tty_mutex);
|
||||
return 0;
|
||||
err_unlock:
|
||||
tty_unlock();
|
||||
mutex_unlock(&tty_mutex);
|
||||
/* after locks to avoid deadlock */
|
||||
if (!IS_ERR_OR_NULL(driver))
|
||||
|
|
@ -2103,13 +2094,10 @@ out:
|
|||
|
||||
static int tty_fasync(int fd, struct file *filp, int on)
|
||||
{
|
||||
struct tty_struct *tty = file_tty(filp);
|
||||
int retval;
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
retval = __tty_fasync(fd, filp, on);
|
||||
tty_unlock(tty);
|
||||
|
||||
tty_unlock();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -2946,7 +2934,6 @@ void initialize_tty_struct(struct tty_struct *tty,
|
|||
tty->pgrp = NULL;
|
||||
tty->overrun_time = jiffies;
|
||||
tty_buffer_init(tty);
|
||||
mutex_init(&tty->legacy_mutex);
|
||||
mutex_init(&tty->termios_mutex);
|
||||
mutex_init(&tty->ldisc_mutex);
|
||||
init_waitqueue_head(&tty->write_wait);
|
||||
|
|
|
|||
|
|
@ -568,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
if (IS_ERR(new_ldisc))
|
||||
return PTR_ERR(new_ldisc);
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
/*
|
||||
* We need to look at the tty locking here for pty/tty pairs
|
||||
* when both sides try to change in parallel.
|
||||
|
|
@ -582,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
*/
|
||||
|
||||
if (tty->ldisc->ops->num == ldisc) {
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
tty_ldisc_put(new_ldisc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
/*
|
||||
* Problem: What do we do if this blocks ?
|
||||
* We could deadlock here
|
||||
|
|
@ -595,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
|
||||
tty_wait_until_sent(tty, 0);
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
|
||||
/*
|
||||
|
|
@ -605,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
|
||||
while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
|
||||
mutex_unlock(&tty->ldisc_mutex);
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
wait_event(tty_ldisc_wait,
|
||||
test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
|
||||
o_ldisc = tty->ldisc;
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
/*
|
||||
* Make sure we don't change while someone holds a
|
||||
* reference to the line discipline. The TTY_LDISC bit
|
||||
|
|
@ -650,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
|
||||
retval = tty_ldisc_wait_idle(tty, 5 * HZ);
|
||||
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
|
||||
/* handle wait idle failure locked */
|
||||
|
|
@ -665,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
clear_bit(TTY_LDISC_CHANGING, &tty->flags);
|
||||
mutex_unlock(&tty->ldisc_mutex);
|
||||
tty_ldisc_put(new_ldisc);
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -708,7 +708,7 @@ enable:
|
|||
if (o_work)
|
||||
schedule_work(&o_tty->buf.work);
|
||||
mutex_unlock(&tty->ldisc_mutex);
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -816,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty)
|
|||
* need to wait for another function taking the BTM
|
||||
*/
|
||||
clear_bit(TTY_LDISC, &tty->flags);
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
cancel_work_sync(&tty->buf.work);
|
||||
mutex_unlock(&tty->ldisc_mutex);
|
||||
retry:
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
|
||||
/* At this point we have a closed ldisc and we want to
|
||||
|
|
@ -831,7 +831,7 @@ retry:
|
|||
if (atomic_read(&tty->ldisc->users) != 1) {
|
||||
char cur_n[TASK_COMM_LEN], tty_n[64];
|
||||
long timeout = 3 * HZ;
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
|
||||
while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
|
||||
timeout = MAX_SCHEDULE_TIMEOUT;
|
||||
|
|
@ -912,10 +912,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
|
|||
* race with the set_ldisc code path.
|
||||
*/
|
||||
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
tty_ldisc_halt(tty);
|
||||
tty_ldisc_flush_works(tty);
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -4,59 +4,29 @@
|
|||
#include <linux/semaphore.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
/* Legacy tty mutex glue */
|
||||
/*
|
||||
* The 'big tty mutex'
|
||||
*
|
||||
* This mutex is taken and released by tty_lock() and tty_unlock(),
|
||||
* replacing the older big kernel lock.
|
||||
* It can no longer be taken recursively, and does not get
|
||||
* released implicitly while sleeping.
|
||||
*
|
||||
* Don't use in new code.
|
||||
*/
|
||||
static DEFINE_MUTEX(big_tty_mutex);
|
||||
|
||||
/*
|
||||
* Getting the big tty mutex.
|
||||
*/
|
||||
|
||||
void __lockfunc tty_lock(struct tty_struct *tty)
|
||||
void __lockfunc tty_lock(void)
|
||||
{
|
||||
if (tty->magic != TTY_MAGIC) {
|
||||
printk(KERN_ERR "L Bad %p\n", tty);
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
tty_kref_get(tty);
|
||||
mutex_lock(&tty->legacy_mutex);
|
||||
mutex_lock(&big_tty_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(tty_lock);
|
||||
|
||||
void __lockfunc tty_unlock(struct tty_struct *tty)
|
||||
void __lockfunc tty_unlock(void)
|
||||
{
|
||||
if (tty->magic != TTY_MAGIC) {
|
||||
printk(KERN_ERR "U Bad %p\n", tty);
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
mutex_unlock(&tty->legacy_mutex);
|
||||
tty_kref_put(tty);
|
||||
mutex_unlock(&big_tty_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(tty_unlock);
|
||||
|
||||
/*
|
||||
* Getting the big tty mutex for a pair of ttys with lock ordering
|
||||
* On a non pty/tty pair tty2 can be NULL which is just fine.
|
||||
*/
|
||||
void __lockfunc tty_lock_pair(struct tty_struct *tty,
|
||||
struct tty_struct *tty2)
|
||||
{
|
||||
if (tty < tty2) {
|
||||
tty_lock(tty);
|
||||
tty_lock(tty2);
|
||||
} else {
|
||||
if (tty2 && tty2 != tty)
|
||||
tty_lock(tty2);
|
||||
tty_lock(tty);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(tty_lock_pair);
|
||||
|
||||
void __lockfunc tty_unlock_pair(struct tty_struct *tty,
|
||||
struct tty_struct *tty2)
|
||||
{
|
||||
tty_unlock(tty);
|
||||
if (tty2 && tty2 != tty)
|
||||
tty_unlock(tty2);
|
||||
}
|
||||
EXPORT_SYMBOL(tty_unlock_pair);
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ int tty_port_block_til_ready(struct tty_port *port,
|
|||
|
||||
/* block if port is in the process of being closed */
|
||||
if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
|
||||
wait_event_interruptible_tty(tty, port->close_wait,
|
||||
wait_event_interruptible_tty(port->close_wait,
|
||||
!(port->flags & ASYNC_CLOSING));
|
||||
if (port->flags & ASYNC_HUP_NOTIFY)
|
||||
return -EAGAIN;
|
||||
|
|
@ -296,9 +296,9 @@ int tty_port_block_til_ready(struct tty_port *port,
|
|||
retval = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
tty_unlock(tty);
|
||||
tty_unlock();
|
||||
schedule();
|
||||
tty_lock(tty);
|
||||
tty_lock();
|
||||
}
|
||||
finish_wait(&port->open_wait, &wait);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue