You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty and serial driver updates from Greg KH: "Here's the large TTY and Serial driver update for 4.7-rc1. A few new serial drivers are added here, and Peter has fixed a bunch of long-standing bugs in the tty layer and serial drivers as normal. Full details in the shortlog. All of these have been in linux-next for a while with no reported issues" * tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (88 commits) MAINTAINERS: 8250: remove website reference serial: core: Fix port mutex assert if lockdep disabled serial: 8250_dw: fix wrong logic in dw8250_check_lcr() tty: vt, finish looping on duplicate tty: vt, return error when con_startup fails QE-UART: add "fsl,t1040-ucc-uart" to of_device_id serial: mctrl_gpio: Drop support for out1-gpios and out2-gpios serial: 8250dw: Add device HID for future AMD UART controller Fix OpenSSH pty regression on close serial: mctrl_gpio: add IRQ locking serial: 8250: Integrate Fintek into 8250_base serial: mps2-uart: add support for early console serial: mps2-uart: add MPS2 UART driver dt-bindings: document the MPS2 UART bindings serial: sirf: Use generic uart-has-rtscts DT property serial: sirf: Introduce helper variable struct device_node *np serial: mxs-auart: Use generic uart-has-rtscts DT property serial: imx: Use generic uart-has-rtscts DT property doc: DT: Add Generic Serial Device Tree Bindings serial: 8250: of: Make tegra_serial_handle_break() static ...
This commit is contained in:
+17
-22
@@ -398,7 +398,7 @@ static void check_modem_status(struct serial_state *info)
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
}
|
||||
|
||||
if ((port->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) {
|
||||
if (tty_port_check_carrier(port) && (dstatus & SER_DCD)) {
|
||||
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
|
||||
printk("ttyS%d CD now %s...", info->line,
|
||||
(!(status & SER_DCD)) ? "on" : "off");
|
||||
@@ -525,7 +525,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if (port->flags & ASYNC_INITIALIZED) {
|
||||
if (tty_port_initialized(port)) {
|
||||
free_page(page);
|
||||
goto errout;
|
||||
}
|
||||
@@ -586,7 +586,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)
|
||||
*/
|
||||
change_speed(tty, info, NULL);
|
||||
|
||||
port->flags |= ASYNC_INITIALIZED;
|
||||
tty_port_set_initialized(port, 1);
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
|
||||
@@ -604,7 +604,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)
|
||||
unsigned long flags;
|
||||
struct serial_state *state;
|
||||
|
||||
if (!(info->tport.flags & ASYNC_INITIALIZED))
|
||||
if (!tty_port_initialized(&info->tport))
|
||||
return;
|
||||
|
||||
state = info;
|
||||
@@ -645,7 +645,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)
|
||||
|
||||
set_bit(TTY_IO_ERROR, &tty->flags);
|
||||
|
||||
info->tport.flags &= ~ASYNC_INITIALIZED;
|
||||
tty_port_set_initialized(&info->tport, 0);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
@@ -727,17 +727,12 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info,
|
||||
info->IER &= ~UART_IER_MSI;
|
||||
if (port->flags & ASYNC_HARDPPS_CD)
|
||||
info->IER |= UART_IER_MSI;
|
||||
if (cflag & CRTSCTS) {
|
||||
port->flags |= ASYNC_CTS_FLOW;
|
||||
tty_port_set_cts_flow(port, cflag & CRTSCTS);
|
||||
if (cflag & CRTSCTS)
|
||||
info->IER |= UART_IER_MSI;
|
||||
} else
|
||||
port->flags &= ~ASYNC_CTS_FLOW;
|
||||
if (cflag & CLOCAL)
|
||||
port->flags &= ~ASYNC_CHECK_CD;
|
||||
else {
|
||||
port->flags |= ASYNC_CHECK_CD;
|
||||
tty_port_set_check_carrier(port, ~cflag & CLOCAL);
|
||||
if (~cflag & CLOCAL)
|
||||
info->IER |= UART_IER_MSI;
|
||||
}
|
||||
/* TBD:
|
||||
* Does clearing IER_MSI imply that we should disable the VBL interrupt ?
|
||||
*/
|
||||
@@ -1089,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
|
||||
port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
||||
|
||||
check_and_exit:
|
||||
if (port->flags & ASYNC_INITIALIZED) {
|
||||
if (tty_port_initialized(port)) {
|
||||
if (change_spd) {
|
||||
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
|
||||
tty->alt_speed = 57600;
|
||||
@@ -1143,7 +1138,7 @@ static int rs_tiocmget(struct tty_struct *tty)
|
||||
|
||||
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
|
||||
return -ENODEV;
|
||||
if (tty->flags & (1 << TTY_IO_ERROR))
|
||||
if (tty_io_error(tty))
|
||||
return -EIO;
|
||||
|
||||
control = info->MCR;
|
||||
@@ -1165,7 +1160,7 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
|
||||
|
||||
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
|
||||
return -ENODEV;
|
||||
if (tty->flags & (1 << TTY_IO_ERROR))
|
||||
if (tty_io_error(tty))
|
||||
return -EIO;
|
||||
|
||||
local_irq_save(flags);
|
||||
@@ -1250,7 +1245,7 @@ static int rs_ioctl(struct tty_struct *tty,
|
||||
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
|
||||
(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
|
||||
(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
|
||||
if (tty->flags & (1 << TTY_IO_ERROR))
|
||||
if (tty_io_error(tty))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -1342,7 +1337,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||
/* Handle transition away from B0 status */
|
||||
if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
|
||||
info->MCR |= SER_DTR;
|
||||
if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
|
||||
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
|
||||
info->MCR |= SER_RTS;
|
||||
local_irq_save(flags);
|
||||
rtsdtr_ctrl(info->MCR);
|
||||
@@ -1395,7 +1390,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
||||
* line status register.
|
||||
*/
|
||||
state->read_status_mask &= ~UART_LSR_DR;
|
||||
if (port->flags & ASYNC_INITIALIZED) {
|
||||
if (tty_port_initialized(port)) {
|
||||
/* disable receive interrupts */
|
||||
custom.intena = IF_RBF;
|
||||
mb();
|
||||
@@ -1495,7 +1490,7 @@ static void rs_hangup(struct tty_struct *tty)
|
||||
rs_flush_buffer(tty);
|
||||
shutdown(tty, info);
|
||||
info->tport.count = 0;
|
||||
info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
|
||||
tty_port_set_active(&info->tport, 0);
|
||||
info->tport.tty = NULL;
|
||||
wake_up_interruptible(&info->tport.open_wait);
|
||||
}
|
||||
@@ -1543,7 +1538,7 @@ static inline void line_info(struct seq_file *m, int line,
|
||||
|
||||
local_irq_save(flags);
|
||||
status = ciab.pra;
|
||||
control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status;
|
||||
control = tty_port_initialized(&state->tport) ? state->MCR : status;
|
||||
local_irq_restore(flags);
|
||||
|
||||
stat_buf[0] = 0;
|
||||
|
||||
+15
-23
@@ -714,7 +714,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
|
||||
wake_up_interruptible(&info->port.delta_msr_wait);
|
||||
}
|
||||
|
||||
if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
|
||||
if ((mdm_change & CyDCD) && tty_port_check_carrier(&info->port)) {
|
||||
if (mdm_status & CyDCD)
|
||||
wake_up_interruptible(&info->port.open_wait);
|
||||
else
|
||||
@@ -1119,7 +1119,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
|
||||
case C_CM_MDCD:
|
||||
info->icount.dcd++;
|
||||
delta_count++;
|
||||
if (info->port.flags & ASYNC_CHECK_CD) {
|
||||
if (tty_port_check_carrier(&info->port)) {
|
||||
u32 dcd = fw_ver > 241 ? param :
|
||||
readl(&info->u.cyz.ch_ctrl->rs_status);
|
||||
if (dcd & C_RS_DCD)
|
||||
@@ -1279,7 +1279,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
|
||||
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
|
||||
if (info->port.flags & ASYNC_INITIALIZED)
|
||||
if (tty_port_initialized(&info->port))
|
||||
goto errout;
|
||||
|
||||
if (!info->type) {
|
||||
@@ -1364,7 +1364,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
|
||||
/* enable send, recv, modem !!! */
|
||||
}
|
||||
|
||||
info->port.flags |= ASYNC_INITIALIZED;
|
||||
tty_port_set_initialized(&info->port, 1);
|
||||
|
||||
clear_bit(TTY_IO_ERROR, &tty->flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
@@ -1424,7 +1424,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
|
||||
struct cyclades_card *card;
|
||||
unsigned long flags;
|
||||
|
||||
if (!(info->port.flags & ASYNC_INITIALIZED))
|
||||
if (!tty_port_initialized(&info->port))
|
||||
return;
|
||||
|
||||
card = info->card;
|
||||
@@ -1448,7 +1448,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
|
||||
some later date (after testing)!!! */
|
||||
|
||||
set_bit(TTY_IO_ERROR, &tty->flags);
|
||||
info->port.flags &= ~ASYNC_INITIALIZED;
|
||||
tty_port_set_initialized(&info->port, 0);
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
} else {
|
||||
#ifdef CY_DEBUG_OPEN
|
||||
@@ -1473,7 +1473,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
|
||||
tty_port_lower_dtr_rts(&info->port);
|
||||
|
||||
set_bit(TTY_IO_ERROR, &tty->flags);
|
||||
info->port.flags &= ~ASYNC_INITIALIZED;
|
||||
tty_port_set_initialized(&info->port, 0);
|
||||
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
}
|
||||
@@ -1711,7 +1711,7 @@ static void cy_do_close(struct tty_port *port)
|
||||
/* Stop accepting input */
|
||||
cyy_writeb(info, CyCAR, channel & 0x03);
|
||||
cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData);
|
||||
if (info->port.flags & ASYNC_INITIALIZED) {
|
||||
if (tty_port_initialized(&info->port)) {
|
||||
/* Waiting for on-board buffers to be empty before
|
||||
closing the port */
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
@@ -2083,17 +2083,12 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
|
||||
info->cor1 |= CyPARITY_NONE;
|
||||
|
||||
/* CTS flow control flag */
|
||||
if (cflag & CRTSCTS) {
|
||||
info->port.flags |= ASYNC_CTS_FLOW;
|
||||
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
|
||||
if (cflag & CRTSCTS)
|
||||
info->cor2 |= CyCtsAE;
|
||||
} else {
|
||||
info->port.flags &= ~ASYNC_CTS_FLOW;
|
||||
info->cor2 &= ~CyCtsAE;
|
||||
}
|
||||
if (cflag & CLOCAL)
|
||||
info->port.flags &= ~ASYNC_CHECK_CD;
|
||||
else
|
||||
info->port.flags |= ASYNC_CHECK_CD;
|
||||
info->cor2 &= ~CyCtsAE;
|
||||
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
|
||||
|
||||
/***********************************************
|
||||
The hardware option, CyRtsAO, presents RTS when
|
||||
@@ -2234,7 +2229,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
|
||||
}
|
||||
/* As the HW flow control is done in firmware, the driver
|
||||
doesn't need to care about it */
|
||||
info->port.flags &= ~ASYNC_CTS_FLOW;
|
||||
tty_port_set_cts_flow(&info->port, 0);
|
||||
|
||||
/* XON/XOFF/XANY flow control flags */
|
||||
sw_flow = 0;
|
||||
@@ -2252,10 +2247,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
|
||||
}
|
||||
|
||||
/* CD sensitivity */
|
||||
if (cflag & CLOCAL)
|
||||
info->port.flags &= ~ASYNC_CHECK_CD;
|
||||
else
|
||||
info->port.flags |= ASYNC_CHECK_CD;
|
||||
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
|
||||
|
||||
if (baud == 0) { /* baud rate is zero, turn off line */
|
||||
cy_writel(&ch_ctrl->rs_control,
|
||||
@@ -2342,7 +2334,7 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
|
||||
info->port.closing_wait = new_serial.closing_wait * HZ / 100;
|
||||
|
||||
check_and_exit:
|
||||
if (info->port.flags & ASYNC_INITIALIZED) {
|
||||
if (tty_port_initialized(&info->port)) {
|
||||
cy_set_line_char(info, tty);
|
||||
ret = 0;
|
||||
} else {
|
||||
|
||||
@@ -632,7 +632,7 @@ int hvc_poll(struct hvc_struct *hp)
|
||||
goto bail;
|
||||
|
||||
/* Now check if we can get data (are we throttled ?) */
|
||||
if (test_bit(TTY_THROTTLED, &tty->flags))
|
||||
if (tty_throttled(tty))
|
||||
goto throttled;
|
||||
|
||||
/* If we aren't notifier driven and aren't throttled, we always
|
||||
@@ -814,7 +814,7 @@ static int hvc_poll_get_char(struct tty_driver *driver, int line)
|
||||
|
||||
n = hp->ops->get_chars(hp->vtermno, &ch, 1);
|
||||
|
||||
if (n == 0)
|
||||
if (n <= 0)
|
||||
return NO_POLL_CHAR;
|
||||
|
||||
return ch;
|
||||
|
||||
@@ -600,7 +600,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
|
||||
|
||||
hvcs_try_write(hvcsd);
|
||||
|
||||
if (!tty || test_bit(TTY_THROTTLED, &tty->flags)) {
|
||||
if (!tty || tty_throttled(tty)) {
|
||||
hvcsd->todo_mask &= ~(HVCS_READ_MASK);
|
||||
goto bail;
|
||||
} else if (!(hvcsd->todo_mask & (HVCS_READ_MASK)))
|
||||
|
||||
@@ -509,7 +509,7 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&hp->lock, flags);
|
||||
if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) {
|
||||
if (tty && hp->n_throttle && !tty_throttled(tty)) {
|
||||
/* we weren't hung up and we weren't throttled, so we can
|
||||
* deliver the rest now */
|
||||
hvsi_send_overflow(hp);
|
||||
|
||||
@@ -1572,6 +1572,11 @@ static void handle_received_SETUP_packet(struct ipw_hardware *hw,
|
||||
sizeof(struct ipw_setup_reboot_msg_ack),
|
||||
ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP,
|
||||
TL_SETUP_SIGNO_REBOOT_MSG_ACK);
|
||||
if (!packet) {
|
||||
pr_err(IPWIRELESS_PCCARD_NAME
|
||||
": Not enough memory to send reboot packet");
|
||||
break;
|
||||
}
|
||||
packet->header.length =
|
||||
sizeof(struct TlSetupRebootMsgAck);
|
||||
send_packet(hw, PRIO_SETUP, &packet->header);
|
||||
|
||||
+7
-12
@@ -438,8 +438,8 @@ static void isicom_tx(unsigned long _data)
|
||||
|
||||
for (; count > 0; count--, port++) {
|
||||
/* port not active or tx disabled to force flow control */
|
||||
if (!(port->port.flags & ASYNC_INITIALIZED) ||
|
||||
!(port->status & ISI_TXOK))
|
||||
if (!tty_port_initialized(&port->port) ||
|
||||
!(port->status & ISI_TXOK))
|
||||
continue;
|
||||
|
||||
txcount = min_t(short, TX_SIZE, port->xmit_cnt);
|
||||
@@ -553,7 +553,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
port = card->ports + channel;
|
||||
if (!(port->port.flags & ASYNC_INITIALIZED)) {
|
||||
if (!tty_port_initialized(&port->port)) {
|
||||
outw(0x0000, base+0x04); /* enable interrupts */
|
||||
spin_unlock(&card->card_lock);
|
||||
return IRQ_HANDLED;
|
||||
@@ -577,7 +577,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
|
||||
header = inw(base);
|
||||
switch (header & 0xff) {
|
||||
case 0: /* Change in EIA signals */
|
||||
if (port->port.flags & ASYNC_CHECK_CD) {
|
||||
if (tty_port_check_carrier(&port->port)) {
|
||||
if (port->status & ISI_DCD) {
|
||||
if (!(header & ISI_DCD)) {
|
||||
/* Carrier has been lost */
|
||||
@@ -758,18 +758,13 @@ static void isicom_config_port(struct tty_struct *tty)
|
||||
outw(channel_setup, base);
|
||||
InterruptTheCard(base);
|
||||
}
|
||||
if (C_CLOCAL(tty))
|
||||
port->port.flags &= ~ASYNC_CHECK_CD;
|
||||
else
|
||||
port->port.flags |= ASYNC_CHECK_CD;
|
||||
tty_port_set_check_carrier(&port->port, !C_CLOCAL(tty));
|
||||
|
||||
/* flow control settings ...*/
|
||||
flow_ctrl = 0;
|
||||
port->port.flags &= ~ASYNC_CTS_FLOW;
|
||||
if (C_CRTSCTS(tty)) {
|
||||
port->port.flags |= ASYNC_CTS_FLOW;
|
||||
tty_port_set_cts_flow(&port->port, C_CRTSCTS(tty));
|
||||
if (C_CRTSCTS(tty))
|
||||
flow_ctrl |= ISICOM_CTSRTS;
|
||||
}
|
||||
if (I_IXON(tty))
|
||||
flow_ctrl |= ISICOM_RESPOND_XONXOFF;
|
||||
if (I_IXOFF(tty))
|
||||
|
||||
+6
-6
@@ -912,7 +912,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
|
||||
|
||||
/* pci hot-un-plug support */
|
||||
for (a = 0; a < brd->numPorts; a++)
|
||||
if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
|
||||
if (tty_port_initialized(&brd->ports[a].port))
|
||||
tty_port_tty_hangup(&brd->ports[a].port, false);
|
||||
|
||||
for (a = 0; a < MAX_PORTS_PER_BOARD; a++)
|
||||
@@ -921,7 +921,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
|
||||
while (1) {
|
||||
opened = 0;
|
||||
for (a = 0; a < brd->numPorts; a++)
|
||||
if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
|
||||
if (tty_port_initialized(&brd->ports[a].port))
|
||||
opened++;
|
||||
mutex_unlock(&moxa_openlock);
|
||||
if (!opened)
|
||||
@@ -1192,13 +1192,13 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
|
||||
tty->driver_data = ch;
|
||||
tty_port_tty_set(&ch->port, tty);
|
||||
mutex_lock(&ch->port.mutex);
|
||||
if (!(ch->port.flags & ASYNC_INITIALIZED)) {
|
||||
if (!tty_port_initialized(&ch->port)) {
|
||||
ch->statusflags = 0;
|
||||
moxa_set_tty_param(tty, &tty->termios);
|
||||
MoxaPortLineCtrl(ch, 1, 1);
|
||||
MoxaPortEnable(ch);
|
||||
MoxaSetFifo(ch, ch->type == PORT_16550A);
|
||||
ch->port.flags |= ASYNC_INITIALIZED;
|
||||
tty_port_set_initialized(&ch->port, 1);
|
||||
}
|
||||
mutex_unlock(&ch->port.mutex);
|
||||
mutex_unlock(&moxa_openlock);
|
||||
@@ -1379,7 +1379,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
|
||||
{
|
||||
struct tty_struct *tty = tty_port_tty_get(&p->port);
|
||||
void __iomem *ofsAddr;
|
||||
unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
|
||||
unsigned int inited = tty_port_initialized(&p->port);
|
||||
u16 intr;
|
||||
|
||||
if (tty) {
|
||||
@@ -1394,7 +1394,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
|
||||
if (inited && !tty_throttled(tty) &&
|
||||
MoxaPortRxQueue(p) > 0) { /* RX */
|
||||
MoxaPortReadData(p);
|
||||
tty_schedule_flip(&p->port);
|
||||
|
||||
+13
-22
@@ -711,8 +711,8 @@ static int mxser_change_speed(struct tty_struct *tty,
|
||||
/* CTS flow control flag and modem status interrupts */
|
||||
info->IER &= ~UART_IER_MSI;
|
||||
info->MCR &= ~UART_MCR_AFE;
|
||||
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
|
||||
if (cflag & CRTSCTS) {
|
||||
info->port.flags |= ASYNC_CTS_FLOW;
|
||||
info->IER |= UART_IER_MSI;
|
||||
if ((info->type == PORT_16550A) || (info->board->chip_flag)) {
|
||||
info->MCR |= UART_MCR_AFE;
|
||||
@@ -744,16 +744,11 @@ static int mxser_change_speed(struct tty_struct *tty,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info->port.flags &= ~ASYNC_CTS_FLOW;
|
||||
}
|
||||
outb(info->MCR, info->ioaddr + UART_MCR);
|
||||
if (cflag & CLOCAL) {
|
||||
info->port.flags &= ~ASYNC_CHECK_CD;
|
||||
} else {
|
||||
info->port.flags |= ASYNC_CHECK_CD;
|
||||
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
|
||||
if (~cflag & CLOCAL)
|
||||
info->IER |= UART_IER_MSI;
|
||||
}
|
||||
outb(info->IER, info->ioaddr + UART_IER);
|
||||
|
||||
/*
|
||||
@@ -826,7 +821,7 @@ static void mxser_check_modem_status(struct tty_struct *tty,
|
||||
port->mon_data.modem_status = status;
|
||||
wake_up_interruptible(&port->port.delta_msr_wait);
|
||||
|
||||
if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
|
||||
if (tty_port_check_carrier(&port->port) && (status & UART_MSR_DDCD)) {
|
||||
if (status & UART_MSR_DCD)
|
||||
wake_up_interruptible(&port->port.open_wait);
|
||||
}
|
||||
@@ -1086,12 +1081,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
|
||||
mutex_lock(&port->mutex);
|
||||
mxser_close_port(port);
|
||||
mxser_flush_buffer(tty);
|
||||
if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
|
||||
if (C_HUPCL(tty))
|
||||
tty_port_lower_dtr_rts(port);
|
||||
}
|
||||
if (tty_port_initialized(port) && C_HUPCL(tty))
|
||||
tty_port_lower_dtr_rts(port);
|
||||
mxser_shutdown_port(port);
|
||||
clear_bit(ASYNCB_INITIALIZED, &port->flags);
|
||||
tty_port_set_initialized(port, 0);
|
||||
mutex_unlock(&port->mutex);
|
||||
info->closing = 0;
|
||||
/* Right now the tty_port set is done outside of the close_end helper
|
||||
@@ -1287,7 +1280,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
|
||||
|
||||
process_txrx_fifo(info);
|
||||
|
||||
if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
|
||||
if (tty_port_initialized(port)) {
|
||||
if (flags != (port->flags & ASYNC_SPD_MASK)) {
|
||||
spin_lock_irqsave(&info->slock, sl_flags);
|
||||
mxser_change_speed(tty, NULL);
|
||||
@@ -1296,7 +1289,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
|
||||
} else {
|
||||
retval = mxser_activate(port, tty);
|
||||
if (retval == 0)
|
||||
set_bit(ASYNCB_INITIALIZED, &port->flags);
|
||||
tty_port_set_initialized(port, 1);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -1334,7 +1327,7 @@ static int mxser_tiocmget(struct tty_struct *tty)
|
||||
|
||||
if (tty->index == MXSER_PORTS)
|
||||
return -ENOIOCTLCMD;
|
||||
if (test_bit(TTY_IO_ERROR, &tty->flags))
|
||||
if (tty_io_error(tty))
|
||||
return -EIO;
|
||||
|
||||
control = info->MCR;
|
||||
@@ -1361,7 +1354,7 @@ static int mxser_tiocmset(struct tty_struct *tty,
|
||||
|
||||
if (tty->index == MXSER_PORTS)
|
||||
return -ENOIOCTLCMD;
|
||||
if (test_bit(TTY_IO_ERROR, &tty->flags))
|
||||
if (tty_io_error(tty))
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&info->slock, flags);
|
||||
@@ -1715,8 +1708,7 @@ static int mxser_ioctl(struct tty_struct *tty,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT &&
|
||||
test_bit(TTY_IO_ERROR, &tty->flags))
|
||||
if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && tty_io_error(tty))
|
||||
return -EIO;
|
||||
|
||||
switch (cmd) {
|
||||
@@ -2257,7 +2249,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
|
||||
iir &= MOXA_MUST_IIR_MASK;
|
||||
tty = tty_port_tty_get(&port->port);
|
||||
if (!tty || port->closing ||
|
||||
!(port->port.flags & ASYNC_INITIALIZED)) {
|
||||
!tty_port_initialized(&port->port)) {
|
||||
status = inb(port->ioaddr + UART_LSR);
|
||||
outb(0x27, port->ioaddr + UART_FCR);
|
||||
inb(port->ioaddr + UART_MSR);
|
||||
@@ -2400,7 +2392,6 @@ static int mxser_initbrd(struct mxser_board *brd,
|
||||
if (brd->chip_flag != MOXA_OTHER_UART)
|
||||
mxser_enable_must_enchance_mode(info->ioaddr);
|
||||
|
||||
info->port.flags = ASYNC_SHARE_IRQ;
|
||||
info->type = brd->uart_type;
|
||||
|
||||
process_txrx_fifo(info);
|
||||
|
||||
+6
-6
@@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm)
|
||||
}
|
||||
}
|
||||
spin_unlock(&gsm_mux_lock);
|
||||
WARN_ON(i == MAX_MUX);
|
||||
/* open failed before registering => nothing to do */
|
||||
if (i == MAX_MUX)
|
||||
return;
|
||||
|
||||
/* In theory disconnecting DLCI 0 is sufficient but for some
|
||||
modems this is apparently not the case. */
|
||||
@@ -2947,7 +2949,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
|
||||
dlci->modem_rx = 0;
|
||||
/* We could in theory open and close before we wait - eg if we get
|
||||
a DM straight back. This is ok as that will have caused a hangup */
|
||||
set_bit(ASYNCB_INITIALIZED, &port->flags);
|
||||
tty_port_set_initialized(port, 1);
|
||||
/* Start sending off SABM messages */
|
||||
gsm_dlci_begin_open(dlci);
|
||||
/* And wait for virtual carrier */
|
||||
@@ -2970,10 +2972,8 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
|
||||
if (tty_port_close_start(&dlci->port, tty, filp) == 0)
|
||||
return;
|
||||
gsm_dlci_begin_close(dlci);
|
||||
if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) {
|
||||
if (C_HUPCL(tty))
|
||||
tty_port_lower_dtr_rts(&dlci->port);
|
||||
}
|
||||
if (tty_port_initialized(&dlci->port) && C_HUPCL(tty))
|
||||
tty_port_lower_dtr_rts(&dlci->port);
|
||||
tty_port_close_end(&dlci->port, tty);
|
||||
tty_port_tty_set(&dlci->port, NULL);
|
||||
return;
|
||||
|
||||
@@ -599,7 +599,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
|
||||
add_wait_queue(&tty->read_wait, &wait);
|
||||
|
||||
for (;;) {
|
||||
if (test_bit(TTY_OTHER_DONE, &tty->flags)) {
|
||||
if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
@@ -827,7 +827,7 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
|
||||
/* set bits for operations that won't block */
|
||||
if (n_hdlc->rx_buf_list.head)
|
||||
mask |= POLLIN | POLLRDNORM; /* readable */
|
||||
if (test_bit(TTY_OTHER_DONE, &tty->flags))
|
||||
if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
|
||||
mask |= POLLHUP;
|
||||
if (tty_hung_up_p(filp))
|
||||
mask |= POLLHUP;
|
||||
|
||||
+34
-38
@@ -1917,18 +1917,6 @@ static inline int input_available_p(struct tty_struct *tty, int poll)
|
||||
return ldata->commit_head - ldata->read_tail >= amt;
|
||||
}
|
||||
|
||||
static inline int check_other_done(struct tty_struct *tty)
|
||||
{
|
||||
int done = test_bit(TTY_OTHER_DONE, &tty->flags);
|
||||
if (done) {
|
||||
/* paired with cmpxchg() in check_other_closed(); ensures
|
||||
* read buffer head index is not stale
|
||||
*/
|
||||
smp_mb__after_atomic();
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* copy_from_read_buf - copy read data directly
|
||||
* @tty: terminal device
|
||||
@@ -2124,7 +2112,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||
struct n_tty_data *ldata = tty->disc_data;
|
||||
unsigned char __user *b = buf;
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
int c, done;
|
||||
int c;
|
||||
int minimum, time;
|
||||
ssize_t retval = 0;
|
||||
long timeout;
|
||||
@@ -2183,32 +2171,35 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||
break;
|
||||
}
|
||||
|
||||
done = check_other_done(tty);
|
||||
|
||||
if (!input_available_p(tty, 0)) {
|
||||
if (done) {
|
||||
retval = -EIO;
|
||||
break;
|
||||
}
|
||||
if (tty_hung_up_p(file))
|
||||
break;
|
||||
if (!timeout)
|
||||
break;
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
if (signal_pending(current)) {
|
||||
retval = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
up_read(&tty->termios_rwsem);
|
||||
|
||||
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
|
||||
timeout);
|
||||
|
||||
tty_buffer_flush_work(tty->port);
|
||||
down_read(&tty->termios_rwsem);
|
||||
continue;
|
||||
if (!input_available_p(tty, 0)) {
|
||||
if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
|
||||
retval = -EIO;
|
||||
break;
|
||||
}
|
||||
if (tty_hung_up_p(file))
|
||||
break;
|
||||
if (!timeout)
|
||||
break;
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
if (signal_pending(current)) {
|
||||
retval = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
up_read(&tty->termios_rwsem);
|
||||
|
||||
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
|
||||
timeout);
|
||||
|
||||
down_read(&tty->termios_rwsem);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ldata->icanon && !L_EXTPROC(tty)) {
|
||||
@@ -2386,12 +2377,17 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
|
||||
|
||||
poll_wait(file, &tty->read_wait, wait);
|
||||
poll_wait(file, &tty->write_wait, wait);
|
||||
if (check_other_done(tty))
|
||||
mask |= POLLHUP;
|
||||
if (input_available_p(tty, 1))
|
||||
mask |= POLLIN | POLLRDNORM;
|
||||
else {
|
||||
tty_buffer_flush_work(tty->port);
|
||||
if (input_available_p(tty, 1))
|
||||
mask |= POLLIN | POLLRDNORM;
|
||||
}
|
||||
if (tty->packet && tty->link->ctrl_status)
|
||||
mask |= POLLPRI | POLLIN | POLLRDNORM;
|
||||
if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
|
||||
mask |= POLLHUP;
|
||||
if (tty_hung_up_p(file))
|
||||
mask |= POLLHUP;
|
||||
if (tty->ops->write && !tty_is_writelocked(tty) &&
|
||||
|
||||
@@ -826,7 +826,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
|
||||
size = __le32_to_cpu(readl(addr));
|
||||
/* DBG1( "%d bytes port: %d", size, index); */
|
||||
|
||||
if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
|
||||
if (tty && tty_throttled(tty)) {
|
||||
DBG1("No room in tty, don't read data, don't ack interrupt, "
|
||||
"disable interrupt");
|
||||
|
||||
|
||||
+2
-4
@@ -44,7 +44,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
|
||||
if (tty->driver->subtype == PTY_TYPE_MASTER)
|
||||
WARN_ON(tty->count > 1);
|
||||
else {
|
||||
if (test_bit(TTY_IO_ERROR, &tty->flags))
|
||||
if (tty_io_error(tty))
|
||||
return;
|
||||
if (tty->count > 2)
|
||||
return;
|
||||
@@ -59,7 +59,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
|
||||
if (!tty->link)
|
||||
return;
|
||||
set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
|
||||
tty_flip_buffer_push(tty->link->port);
|
||||
wake_up_interruptible(&tty->link->read_wait);
|
||||
wake_up_interruptible(&tty->link->write_wait);
|
||||
if (tty->driver->subtype == PTY_TYPE_MASTER) {
|
||||
set_bit(TTY_OTHER_CLOSED, &tty->flags);
|
||||
@@ -247,9 +247,7 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
|
||||
goto out;
|
||||
|
||||
clear_bit(TTY_IO_ERROR, &tty->flags);
|
||||
/* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */
|
||||
clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
|
||||
clear_bit(TTY_OTHER_DONE, &tty->link->flags);
|
||||
set_bit(TTY_THROTTLED, &tty->flags);
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -495,7 +495,7 @@ static void rp_handle_port(struct r_port *info)
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if ((info->port.flags & ASYNC_INITIALIZED) == 0) {
|
||||
if (!tty_port_initialized(&info->port)) {
|
||||
printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
|
||||
"info->flags & NOT_INIT\n");
|
||||
return;
|
||||
@@ -615,7 +615,8 @@ static void rp_do_poll(unsigned long dummy)
|
||||
* the board.
|
||||
* Inputs: board, aiop, chan numbers
|
||||
*/
|
||||
static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
|
||||
static void __init
|
||||
init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
|
||||
{
|
||||
unsigned rocketMode;
|
||||
struct r_port *info;
|
||||
@@ -920,7 +921,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
|
||||
/*
|
||||
* Info->count is now 1; so it's safe to sleep now.
|
||||
*/
|
||||
if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
|
||||
if (!tty_port_initialized(port)) {
|
||||
cp = &info->channel;
|
||||
sSetRxTrigger(cp, TRIG_1);
|
||||
if (sGetChanStatus(cp) & CD_ACT)
|
||||
@@ -944,7 +945,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
|
||||
sEnRxFIFO(cp);
|
||||
sEnTransmit(cp);
|
||||
|
||||
set_bit(ASYNCB_INITIALIZED, &info->port.flags);
|
||||
tty_port_set_initialized(&info->port, 1);
|
||||
|
||||
/*
|
||||
* Set up the tty->alt_speed kludge
|
||||
@@ -1042,9 +1043,10 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
|
||||
}
|
||||
}
|
||||
spin_lock_irq(&port->lock);
|
||||
info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_NORMAL_ACTIVE);
|
||||
tty->closing = 0;
|
||||
spin_unlock_irq(&port->lock);
|
||||
tty_port_set_initialized(port, 0);
|
||||
tty_port_set_active(port, 0);
|
||||
mutex_unlock(&port->mutex);
|
||||
tty_port_tty_set(port, NULL);
|
||||
|
||||
@@ -1512,7 +1514,7 @@ static void rp_hangup(struct tty_struct *tty)
|
||||
sDisCTSFlowCtl(cp);
|
||||
sDisTxSoftFlowCtl(cp);
|
||||
sClrTxXOFF(cp);
|
||||
clear_bit(ASYNCB_INITIALIZED, &info->port.flags);
|
||||
tty_port_set_initialized(&info->port, 0);
|
||||
|
||||
wake_up_interruptible(&info->port.open_wait);
|
||||
}
|
||||
@@ -1624,7 +1626,7 @@ static int rp_write(struct tty_struct *tty,
|
||||
/* Write remaining data into the port's xmit_buf */
|
||||
while (1) {
|
||||
/* Hung up ? */
|
||||
if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
|
||||
if (!tty_port_active(&info->port))
|
||||
goto end;
|
||||
c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
|
||||
c = min(c, XMIT_BUF_SIZE - info->xmit_head);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
struct uart_8250_dma {
|
||||
int (*tx_dma)(struct uart_8250_port *p);
|
||||
int (*rx_dma)(struct uart_8250_port *p, unsigned int iir);
|
||||
int (*rx_dma)(struct uart_8250_port *p);
|
||||
|
||||
/* Filter function */
|
||||
dma_filter_fn fn;
|
||||
@@ -84,7 +84,6 @@ struct serial8250_config {
|
||||
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
|
||||
#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
|
||||
|
||||
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
|
||||
#define SERIAL8250_SHARE_IRQS 1
|
||||
@@ -151,6 +150,12 @@ static inline int serial8250_pnp_init(void) { return 0; }
|
||||
static inline void serial8250_pnp_exit(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_FINTEK
|
||||
int fintek_8250_probe(struct uart_8250_port *uart);
|
||||
#else
|
||||
static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
static inline int is_omap1_8250(struct uart_8250_port *pt)
|
||||
{
|
||||
@@ -190,7 +195,8 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt)
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_DMA
|
||||
extern int serial8250_tx_dma(struct uart_8250_port *);
|
||||
extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir);
|
||||
extern int serial8250_rx_dma(struct uart_8250_port *);
|
||||
extern void serial8250_rx_dma_flush(struct uart_8250_port *);
|
||||
extern int serial8250_request_dma(struct uart_8250_port *);
|
||||
extern void serial8250_release_dma(struct uart_8250_port *);
|
||||
#else
|
||||
@@ -198,10 +204,11 @@ static inline int serial8250_tx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
|
||||
static inline int serial8250_rx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { }
|
||||
static inline int serial8250_request_dma(struct uart_8250_port *p)
|
||||
{
|
||||
return -1;
|
||||
|
||||
@@ -830,6 +830,7 @@ static int serial8250_probe(struct platform_device *dev)
|
||||
uart.port.handle_irq = p->handle_irq;
|
||||
uart.port.handle_break = p->handle_break;
|
||||
uart.port.set_termios = p->set_termios;
|
||||
uart.port.get_mctrl = p->get_mctrl;
|
||||
uart.port.pm = p->pm;
|
||||
uart.port.dev = &dev->dev;
|
||||
uart.port.irqflags |= irqflag;
|
||||
@@ -1022,6 +1023,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
|
||||
/* Possibly override set_termios call */
|
||||
if (up->port.set_termios)
|
||||
uart->port.set_termios = up->port.set_termios;
|
||||
if (up->port.get_mctrl)
|
||||
uart->port.get_mctrl = up->port.get_mctrl;
|
||||
if (up->port.set_mctrl)
|
||||
uart->port.set_mctrl = up->port.set_mctrl;
|
||||
if (up->port.startup)
|
||||
|
||||
@@ -110,30 +110,11 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
|
||||
int serial8250_rx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
|
||||
switch (iir & 0x3f) {
|
||||
case UART_IIR_RLSI:
|
||||
/* 8250_core handles errors and break interrupts */
|
||||
return -EIO;
|
||||
case UART_IIR_RX_TIMEOUT:
|
||||
/*
|
||||
* If RCVR FIFO trigger level was not reached, complete the
|
||||
* transfer and let 8250_core copy the remaining data.
|
||||
*/
|
||||
if (dma->rx_running) {
|
||||
dmaengine_pause(dma->rxchan);
|
||||
__dma_rx_complete(p);
|
||||
dmaengine_terminate_all(dma->rxchan);
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dma->rx_running)
|
||||
return 0;
|
||||
|
||||
@@ -154,10 +135,23 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void serial8250_rx_dma_flush(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
|
||||
if (dma->rx_running) {
|
||||
dmaengine_pause(dma->rxchan);
|
||||
__dma_rx_complete(p);
|
||||
dmaengine_terminate_all(dma->rxchan);
|
||||
}
|
||||
}
|
||||
|
||||
int serial8250_request_dma(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
dma_cap_mask_t mask;
|
||||
struct dma_slave_caps caps;
|
||||
int ret;
|
||||
|
||||
/* Default slave configuration parameters */
|
||||
dma->rxconf.direction = DMA_DEV_TO_MEM;
|
||||
@@ -178,6 +172,16 @@ int serial8250_request_dma(struct uart_8250_port *p)
|
||||
if (!dma->rxchan)
|
||||
return -ENODEV;
|
||||
|
||||
/* 8250 rx dma requires dmaengine driver to support pause/terminate */
|
||||
ret = dma_get_slave_caps(dma->rxchan, &caps);
|
||||
if (ret)
|
||||
goto release_rx;
|
||||
if (!caps.cmd_pause || !caps.cmd_terminate ||
|
||||
caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) {
|
||||
ret = -EINVAL;
|
||||
goto release_rx;
|
||||
}
|
||||
|
||||
dmaengine_slave_config(dma->rxchan, &dma->rxconf);
|
||||
|
||||
/* Get a channel for TX */
|
||||
@@ -185,8 +189,17 @@ int serial8250_request_dma(struct uart_8250_port *p)
|
||||
dma->fn, dma->tx_param,
|
||||
p->port.dev, "tx");
|
||||
if (!dma->txchan) {
|
||||
dma_release_channel(dma->rxchan);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto release_rx;
|
||||
}
|
||||
|
||||
/* 8250 tx dma requires dmaengine driver to support terminate */
|
||||
ret = dma_get_slave_caps(dma->txchan, &caps);
|
||||
if (ret)
|
||||
goto err;
|
||||
if (!caps.cmd_terminate) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dmaengine_slave_config(dma->txchan, &dma->txconf);
|
||||
@@ -197,8 +210,10 @@ int serial8250_request_dma(struct uart_8250_port *p)
|
||||
|
||||
dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
|
||||
&dma->rx_addr, GFP_KERNEL);
|
||||
if (!dma->rx_buf)
|
||||
if (!dma->rx_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* TX buffer */
|
||||
dma->tx_addr = dma_map_single(dma->txchan->device->dev,
|
||||
@@ -208,6 +223,7 @@ int serial8250_request_dma(struct uart_8250_port *p)
|
||||
if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
|
||||
dma_free_coherent(dma->rxchan->device->dev, dma->rx_size,
|
||||
dma->rx_buf, dma->rx_addr);
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -215,10 +231,10 @@ int serial8250_request_dma(struct uart_8250_port *p)
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dma_release_channel(dma->rxchan);
|
||||
dma_release_channel(dma->txchan);
|
||||
|
||||
return -ENOMEM;
|
||||
release_rx:
|
||||
dma_release_channel(dma->rxchan);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_request_dma);
|
||||
|
||||
|
||||
@@ -104,15 +104,16 @@ static void dw8250_check_lcr(struct uart_port *p, int value)
|
||||
dw8250_force_idle(p);
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
__raw_writeq(value & 0xff, offset);
|
||||
#else
|
||||
if (p->type == PORT_OCTEON)
|
||||
__raw_writeq(value & 0xff, offset);
|
||||
else
|
||||
#endif
|
||||
if (p->iotype == UPIO_MEM32)
|
||||
writel(value, offset);
|
||||
else if (p->iotype == UPIO_MEM32BE)
|
||||
iowrite32be(value, offset);
|
||||
else
|
||||
writeb(value, offset);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* FIXME: this deadlocks if port->lock is already held
|
||||
@@ -617,6 +618,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
|
||||
{ "8086228A", 0 },
|
||||
{ "APMC0D08", 0},
|
||||
{ "AMD0020", 0 },
|
||||
{ "AMDI0020", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/*
|
||||
* Probe for F81216A LPC to 4 UART
|
||||
*
|
||||
* Based on drivers/tty/serial/8250_pnp.c, by Russell King, et al
|
||||
*
|
||||
* Copyright (C) 2014 Ricardo Ribalda, Qtechnology A/S
|
||||
* Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -38,19 +36,15 @@
|
||||
#define RXW4C_IRA BIT(3)
|
||||
#define TXW4C_IRA BIT(2)
|
||||
|
||||
#define DRIVER_NAME "8250_fintek"
|
||||
|
||||
struct fintek_8250 {
|
||||
u16 base_port;
|
||||
u8 index;
|
||||
u8 key;
|
||||
long line;
|
||||
};
|
||||
|
||||
static int fintek_8250_enter_key(u16 base_port, u8 key)
|
||||
{
|
||||
|
||||
if (!request_muxed_region(base_port, 2, DRIVER_NAME))
|
||||
if (!request_muxed_region(base_port, 2, "8250_fintek"))
|
||||
return -EBUSY;
|
||||
|
||||
outb(key, base_port + ADDR_PORT);
|
||||
@@ -138,7 +132,7 @@ static int fintek_8250_rs485_config(struct uart_port *port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index)
|
||||
static int find_base_port(struct fintek_8250 *pdata, u16 io_address)
|
||||
{
|
||||
static const u16 addr[] = {0x4e, 0x2e};
|
||||
static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67};
|
||||
@@ -168,10 +162,13 @@ static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index)
|
||||
continue;
|
||||
|
||||
fintek_8250_exit_key(addr[i]);
|
||||
*key = keys[j];
|
||||
*index = k;
|
||||
return addr[i];
|
||||
pdata->key = keys[j];
|
||||
pdata->base_port = addr[i];
|
||||
pdata->index = k;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fintek_8250_exit_key(addr[i]);
|
||||
}
|
||||
}
|
||||
@@ -179,104 +176,21 @@ static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int
|
||||
fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
|
||||
int fintek_8250_probe(struct uart_8250_port *uart)
|
||||
{
|
||||
struct uart_8250_port uart;
|
||||
struct fintek_8250 *pdata;
|
||||
int base_port;
|
||||
u8 key;
|
||||
u8 index;
|
||||
struct fintek_8250 probe_data;
|
||||
|
||||
if (!pnp_port_valid(dev, 0))
|
||||
if (find_base_port(&probe_data, uart->port.iobase))
|
||||
return -ENODEV;
|
||||
|
||||
base_port = fintek_8250_base_port(pnp_port_start(dev, 0), &key, &index);
|
||||
if (base_port < 0)
|
||||
return -ENODEV;
|
||||
|
||||
memset(&uart, 0, sizeof(uart));
|
||||
|
||||
pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
uart.port.private_data = pdata;
|
||||
|
||||
if (!pnp_irq_valid(dev, 0))
|
||||
return -ENODEV;
|
||||
uart.port.irq = pnp_irq(dev, 0);
|
||||
uart.port.iobase = pnp_port_start(dev, 0);
|
||||
uart.port.iotype = UPIO_PORT;
|
||||
uart.port.rs485_config = fintek_8250_rs485_config;
|
||||
memcpy(pdata, &probe_data, sizeof(probe_data));
|
||||
uart->port.rs485_config = fintek_8250_rs485_config;
|
||||
uart->port.private_data = pdata;
|
||||
|
||||
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
|
||||
if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
|
||||
uart.port.flags |= UPF_SHARE_IRQ;
|
||||
uart.port.uartclk = 1843200;
|
||||
uart.port.dev = &dev->dev;
|
||||
|
||||
pdata->key = key;
|
||||
pdata->base_port = base_port;
|
||||
pdata->index = index;
|
||||
pdata->line = serial8250_register_8250_port(&uart);
|
||||
if (pdata->line < 0)
|
||||
return -ENODEV;
|
||||
|
||||
pnp_set_drvdata(dev, pdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fintek_8250_remove(struct pnp_dev *dev)
|
||||
{
|
||||
struct fintek_8250 *pdata = pnp_get_drvdata(dev);
|
||||
|
||||
if (pdata)
|
||||
serial8250_unregister_port(pdata->line);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int fintek_8250_suspend(struct pnp_dev *dev, pm_message_t state)
|
||||
{
|
||||
struct fintek_8250 *pdata = pnp_get_drvdata(dev);
|
||||
|
||||
if (!pdata)
|
||||
return -ENODEV;
|
||||
serial8250_suspend_port(pdata->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fintek_8250_resume(struct pnp_dev *dev)
|
||||
{
|
||||
struct fintek_8250 *pdata = pnp_get_drvdata(dev);
|
||||
|
||||
if (!pdata)
|
||||
return -ENODEV;
|
||||
serial8250_resume_port(pdata->line);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define fintek_8250_suspend NULL
|
||||
#define fintek_8250_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct pnp_device_id fintek_dev_table[] = {
|
||||
/* Qtechnology Panel PC / IO1000 */
|
||||
{ "PNP0501"},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pnp, fintek_dev_table);
|
||||
|
||||
static struct pnp_driver fintek_8250_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.probe = fintek_8250_probe,
|
||||
.remove = fintek_8250_remove,
|
||||
.suspend = fintek_8250_suspend,
|
||||
.resume = fintek_8250_resume,
|
||||
.id_table = fintek_dev_table,
|
||||
};
|
||||
|
||||
module_pnp_driver(fintek_8250_driver);
|
||||
MODULE_DESCRIPTION("Fintek F812164 module");
|
||||
MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user