Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 175335
b: refs/heads/master
c: 530646f
h: refs/heads/master
i:
  175333: de2c069
  175331: ad6d883
  175327: bbb2016
v: v3
  • Loading branch information
Alan Cox authored and Greg Kroah-Hartman committed Dec 11, 2009
1 parent f852c10 commit 4f2ce1b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0395b48c78ed822f251ab15d0fbc3ce06f41ffb1
refs/heads/master: 530646f4695b396aeeec2ca912dcc3a9c95e0f52
59 changes: 42 additions & 17 deletions trunk/drivers/mmc/card/sdio_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,13 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
sdio_claim_host(func);
port->func = NULL;
mutex_unlock(&port->func_lock);
if (port->opened)
tty_hangup(port->port.tty);
if (port->opened) {
struct tty_struct *tty = tty_port_tty_get(&port->port);
/* tty_hangup is async so is this safe as is ?? */
if (tty)
tty_hangup(tty);
tty_kref_put(tty);
}
mutex_unlock(&port->open_lock);
sdio_release_irq(func);
sdio_disable_func(func);
Expand Down Expand Up @@ -392,7 +397,7 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port)
static void sdio_uart_receive_chars(struct sdio_uart_port *port,
unsigned int *status)
{
struct tty_struct *tty = port->port.tty;
struct tty_struct *tty = tty_port_tty_get(&port->port);
unsigned int ch, flag;
int max_count = 256;

Expand Down Expand Up @@ -429,34 +434,43 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port,
}

if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
tty_insert_flip_char(tty, ch, flag);
if (tty)
tty_insert_flip_char(tty, ch, flag);

/*
* Overrun is special. Since it's reported immediately,
* it doesn't affect the current character.
*/
if (*status & ~port->ignore_status_mask & UART_LSR_OE)
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
if (tty)
tty_insert_flip_char(tty, 0, TTY_OVERRUN);

*status = sdio_in(port, UART_LSR);
} while ((*status & UART_LSR_DR) && (max_count-- > 0));
tty_flip_buffer_push(tty);
if (tty) {
tty_flip_buffer_push(tty);
tty_kref_put(tty);
}
}

static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
{
struct circ_buf *xmit = &port->xmit;
int count;
struct tty_struct *tty = port->port.tty;
struct tty_struct *tty;

if (port->x_char) {
sdio_out(port, UART_TX, port->x_char);
port->icount.tx++;
port->x_char = 0;
return;
}
if (circ_empty(xmit) || tty->stopped || tty->hw_stopped) {

tty = tty_port_tty_get(&port->port);

if (tty == NULL || circ_empty(xmit) || tty->stopped || tty->hw_stopped) {
sdio_uart_stop_tx(port);
tty_kref_put(tty);
return;
}

Expand All @@ -474,12 +488,13 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)

if (circ_empty(xmit))
sdio_uart_stop_tx(port);
tty_kref_put(tty);
}

static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
{
int status;
struct tty_struct *tty = port->port.tty;
struct tty_struct *tty;

status = sdio_in(port, UART_MSR);

Expand All @@ -494,7 +509,8 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
port->icount.dcd++;
if (status & UART_MSR_DCTS) {
port->icount.cts++;
if (tty->termios->c_cflag & CRTSCTS) {
tty = tty_port_tty_get(&port->port);
if (tty && (tty->termios->c_cflag & CRTSCTS)) {
int cts = (status & UART_MSR_CTS);
if (tty->hw_stopped) {
if (cts) {
Expand All @@ -509,6 +525,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
}
}
}
tty_kref_put(tty);
}
}

Expand Down Expand Up @@ -548,8 +565,10 @@ static void sdio_uart_irq(struct sdio_func *func)
static int sdio_uart_startup(struct sdio_uart_port *port)
{
unsigned long page;
int ret;
struct tty_struct *tty = port->port.tty;
int ret = -ENOMEM;
struct tty_struct *tty = tty_port_tty_get(&port->port);

/* FIXME: What if it is NULL ?? */

/*
* Set the TTY IO error marker - we will only clear this
Expand All @@ -560,7 +579,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
/* Initialise and allocate the transmit buffer. */
page = __get_free_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
goto err0;
port->xmit.buf = (unsigned char *)page;
circ_clear(&port->xmit);

Expand Down Expand Up @@ -614,6 +633,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
sdio_uart_irq(port->func);

sdio_uart_release_func(port);
tty_kref_put(tty);
return 0;

err3:
Expand All @@ -622,12 +642,15 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
sdio_uart_release_func(port);
err1:
free_page((unsigned long)port->xmit.buf);
err0:
tty_kref_put(tty);
return ret;
}

static void sdio_uart_shutdown(struct sdio_uart_port *port)
{
int ret;
struct tty_struct *tty;

ret = sdio_uart_claim_func(port);
if (ret)
Expand All @@ -637,9 +660,11 @@ static void sdio_uart_shutdown(struct sdio_uart_port *port)

/* TODO: wait here for TX FIFO to drain */

tty = tty_port_tty_get(&port->port);
/* Turn off DTR and RTS early. */
if (port->port.tty->termios->c_cflag & HUPCL)
if (tty && (tty->termios->c_cflag & HUPCL))
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
tty_kref_put(tty);

/* Disable interrupts from this port */
sdio_release_irq(port->func);
Expand Down Expand Up @@ -688,11 +713,11 @@ static int sdio_uart_open(struct tty_struct *tty, struct file *filp)

if (!port->opened) {
tty->driver_data = port;
port->port.tty = tty;
tty_port_tty_set(&port->port, tty);
ret = sdio_uart_startup(port);
if (ret) {
tty->driver_data = NULL;
port->port.tty = NULL;
tty_port_tty_set(&port->port, NULL);
mutex_unlock(&port->open_lock);
sdio_uart_port_put(port);
return ret;
Expand Down Expand Up @@ -727,7 +752,7 @@ static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
tty->closing = 1;
sdio_uart_shutdown(port);
tty_ldisc_flush(tty);
port->port.tty = NULL;
tty_port_tty_set(&port->port, NULL);
tty->driver_data = NULL;
tty->closing = 0;
}
Expand Down

0 comments on commit 4f2ce1b

Please sign in to comment.