aboutsummaryrefslogtreecommitdiff
path: root/drivers/tty/serial/sc16is7xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/sc16is7xx.c')
-rw-r--r--drivers/tty/serial/sc16is7xx.c83
1 files changed, 48 insertions, 35 deletions
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index f61d98e09dc3..db2bb1c0d36c 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -223,7 +223,7 @@
* trigger levels. Trigger levels from 4 characters to 60 characters are
* available with a granularity of four.
*
- * When the trigger level setting in TLR is zero, the SC16IS740/750/760 uses the
+ * When the trigger level setting in TLR is zero, the SC16IS74x/75x/76x uses the
* trigger level setting defined in FCR. If TLR has non-zero trigger level value
* the trigger level defined in FCR is discarded. This applies to both transmit
* FIFO and receive FIFO trigger level setting.
@@ -234,7 +234,7 @@
#define SC16IS7XX_TLR_TX_TRIGGER(words) ((((words) / 4) & 0x0f) << 0)
#define SC16IS7XX_TLR_RX_TRIGGER(words) ((((words) / 4) & 0x0f) << 4)
-/* IOControl register bits (Only 750/760) */
+/* IOControl register bits (Only 75x/76x) */
#define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */
#define SC16IS7XX_IOCONTROL_MODEM_A_BIT (1 << 1) /* Enable GPIO[7:4] as modem A pins */
#define SC16IS7XX_IOCONTROL_MODEM_B_BIT (1 << 2) /* Enable GPIO[3:0] as modem B pins */
@@ -249,9 +249,9 @@
#define SC16IS7XX_EFCR_RTS_INVERT_BIT (1 << 5) /* RTS output inversion */
#define SC16IS7XX_EFCR_IRDA_MODE_BIT (1 << 7) /* IrDA mode
* 0 = rate upto 115.2 kbit/s
- * - Only 750/760
+ * - Only 75x/76x
* 1 = rate upto 1.152 Mbit/s
- * - Only 760
+ * - Only 76x
*/
/* EFR register bits */
@@ -358,7 +358,6 @@ static struct uart_driver sc16is7xx_uart = {
static void sc16is7xx_ier_set(struct uart_port *port, u8 bit);
static void sc16is7xx_stop_tx(struct uart_port *port);
-#define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e)))
#define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e)))
static int sc16is7xx_line(struct uart_port *port)
@@ -667,9 +666,9 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
}
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
sc16is7xx_stop_tx(port);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
return;
}
@@ -695,13 +694,13 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
sc16is7xx_fifo_write(port, to_send);
}
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
if (uart_circ_empty(xmit))
sc16is7xx_stop_tx(port);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static unsigned int sc16is7xx_get_hwmctrl(struct uart_port *port)
@@ -733,7 +732,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one)
one->old_mctrl = status;
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
if ((changed & TIOCM_RNG) && (status & TIOCM_RNG))
port->icount.rng++;
if (changed & TIOCM_DSR)
@@ -744,7 +743,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one)
uart_handle_cts_change(port, status & TIOCM_CTS);
wake_up_interruptible(&port->state->port.delta_msr_wait);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
@@ -823,9 +822,9 @@ static void sc16is7xx_tx_proc(struct kthread_work *ws)
sc16is7xx_handle_tx(port);
mutex_unlock(&s->efr_lock);
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static void sc16is7xx_reconf_rs485(struct uart_port *port)
@@ -836,14 +835,14 @@ static void sc16is7xx_reconf_rs485(struct uart_port *port)
struct serial_rs485 *rs485 = &port->rs485;
unsigned long irqflags;
- spin_lock_irqsave(&port->lock, irqflags);
+ uart_port_lock_irqsave(port, &irqflags);
if (rs485->flags & SER_RS485_ENABLED) {
efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT;
if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT;
}
- spin_unlock_irqrestore(&port->lock, irqflags);
+ uart_port_unlock_irqrestore(port, irqflags);
sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr);
}
@@ -854,10 +853,10 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws)
struct sc16is7xx_one_config config;
unsigned long irqflags;
- spin_lock_irqsave(&one->port.lock, irqflags);
+ uart_port_lock_irqsave(&one->port, &irqflags);
config = one->config;
memset(&one->config, 0, sizeof(one->config));
- spin_unlock_irqrestore(&one->port.lock, irqflags);
+ uart_port_unlock_irqrestore(&one->port, irqflags);
if (config.flags & SC16IS7XX_RECONF_MD) {
u8 mcr = 0;
@@ -963,18 +962,18 @@ static void sc16is7xx_throttle(struct uart_port *port)
* value set in MCR register. Stop reading data from RX FIFO so the
* AutoRTS feature will de-activate RTS output.
*/
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static void sc16is7xx_unthrottle(struct uart_port *port)
{
unsigned long flags;
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
sc16is7xx_ier_set(port, SC16IS7XX_IER_RDI_BIT);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static unsigned int sc16is7xx_tx_empty(struct uart_port *port)
@@ -1113,7 +1112,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
/* Setup baudrate generator */
baud = sc16is7xx_set_baud(port, baud);
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
/* Update timeout according to new baud rate */
uart_update_timeout(port, termios->c_cflag, baud);
@@ -1121,7 +1120,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
if (UART_ENABLE_MS(port, termios->c_cflag))
sc16is7xx_enable_ms(port);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static int sc16is7xx_config_rs485(struct uart_port *port, struct ktermios *termios,
@@ -1208,9 +1207,9 @@ static int sc16is7xx_startup(struct uart_port *port)
sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val);
/* Enable modem status polling */
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
sc16is7xx_enable_ms(port);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
return 0;
}
@@ -1409,6 +1408,29 @@ static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s)
}
#endif
+static void sc16is7xx_setup_irda_ports(struct sc16is7xx_port *s)
+{
+ int i;
+ int ret;
+ int count;
+ u32 irda_port[2];
+ struct device *dev = s->p[0].port.dev;
+
+ count = device_property_count_u32(dev, "irda-mode-ports");
+ if (count < 0 || count > ARRAY_SIZE(irda_port))
+ return;
+
+ ret = device_property_read_u32_array(dev, "irda-mode-ports",
+ irda_port, count);
+ if (ret)
+ return;
+
+ for (i = 0; i < count; i++) {
+ if (irda_port[i] < s->devtype->nr_uart)
+ s->p[irda_port[i]].irda_mode = true;
+ }
+}
+
/*
* Configure ports designated to operate as modem control lines.
*/
@@ -1591,16 +1613,7 @@ static int sc16is7xx_probe(struct device *dev,
sc16is7xx_power(&s->p[i].port, 0);
}
- if (dev->of_node) {
- struct property *prop;
- const __be32 *p;
- u32 u;
-
- of_property_for_each_u32(dev->of_node, "irda-mode-ports",
- prop, p, u)
- if (u < devtype->nr_uart)
- s->p[u].irda_mode = true;
- }
+ sc16is7xx_setup_irda_ports(s);
ret = sc16is7xx_setup_mctrl_ports(s);
if (ret)