#define MPC52xx_PSC_IMR_ORERR 0x1000
#define MPC52xx_PSC_IMR_IPC 0x8000
-/* PSC input port change bit */
+/* PSC input port change bits */
#define MPC52xx_PSC_CTS 0x01
#define MPC52xx_PSC_DCD 0x02
#define MPC52xx_PSC_D_CTS 0x10
#define MPC52xx_PSC_D_DCD 0x20
+/* PSC acr bits */
+#define MPC52xx_PSC_IEC_CTS 0x01
+#define MPC52xx_PSC_IEC_DCD 0x02
+
+/* PSC output port bits */
+#define MPC52xx_PSC_OP_RTS 0x01
+#define MPC52xx_PSC_OP_RES 0x02
+
/* PSC mode fields */
#define MPC52xx_PSC_MODE_5_BITS 0x00
#define MPC52xx_PSC_MODE_6_BITS 0x01
#define MPC52xx_PSC_MODE_ONE_STOP_5_BITS 0x00
#define MPC52xx_PSC_MODE_ONE_STOP 0x07
#define MPC52xx_PSC_MODE_TWO_STOP 0x0f
+#define MPC52xx_PSC_MODE_TXCTS 0x10
#define MPC52xx_PSC_RFNUM_MASK 0x01ff
static void
mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- /* Not implemented */
+ if (mctrl & TIOCM_RTS)
+ out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
+ else
+ out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
}
static unsigned int
mpc52xx_uart_get_mctrl(struct uart_port *port)
{
- /* Not implemented */
- return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+ unsigned int ret = TIOCM_DSR;
+ u8 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
+
+ if (!(status & MPC52xx_PSC_CTS))
+ ret |= TIOCM_CTS;
+ if (!(status & MPC52xx_PSC_DCD))
+ ret |= TIOCM_CAR;
+
+ return ret;
}
static void
static void
mpc52xx_uart_enable_ms(struct uart_port *port)
{
- /* Not implemented */
+ struct mpc52xx_psc __iomem *psc = PSC(port);
+
+ /* clear D_*-bits by reading them */
+ in_8(&psc->mpc52xx_psc_ipcr);
+ /* enable CTS and DCD as IPC interrupts */
+ out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
+
+ port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
}
static void
MPC52xx_PSC_MODE_ONE_STOP_5_BITS :
MPC52xx_PSC_MODE_ONE_STOP;
+ if (new->c_cflag & CRTSCTS) {
+ mr1 |= MPC52xx_PSC_MODE_RXRTS;
+ mr2 |= MPC52xx_PSC_MODE_TXCTS;
+ }
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
out_8(&psc->ctur, ctr >> 8);
out_8(&psc->ctlr, ctr & 0xff);
+ if (UART_ENABLE_MS(port, new->c_cflag))
+ mpc52xx_uart_enable_ms(port);
+
/* Reenable TX & RX */
out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
struct uart_port *port = dev_id;
unsigned long pass = ISR_PASS_LIMIT;
unsigned int keepgoing;
+ u8 status;
spin_lock(&port->lock);
if (psc_ops->tx_rdy(port))
keepgoing |= mpc52xx_uart_int_tx_chars(port);
+ status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
+ if (status & MPC52xx_PSC_D_DCD)
+ uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD));
+
+ if (status & MPC52xx_PSC_D_CTS)
+ uart_handle_cts_change(port, !(status & MPC52xx_PSC_CTS));
+
/* Limit number of iteration */
if (!(--pass))
keepgoing = 0;