diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2016-09-13 13:15:31 +0100 |
---|---|---|
committer | Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 2024-01-08 10:30:01 +0000 |
commit | 463201c1ca00b11bfc197c2a7d2b076f3b3a7c3a (patch) | |
tree | ff6a29502ac5c3d026b1dffe394b49a543b1744b | |
parent | 16ec22a9d15deab72200f8c76dd5612d1327117b (diff) |
serial: sa1100: add support for transceiver enable GPIO
Add support for a transceiver enable GPIO signal, which allows the
external RS232 transceiver on several platforms to be force-enabled
or force-disabled according to the system state and the hardware
capabilities.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r-- | drivers/tty/serial/sa1100.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 19f332b44e7d..0710fa027244 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -8,6 +8,7 @@ */ #include <linux/module.h> +#include <linux/gpio/consumer.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/console.h> @@ -76,6 +77,7 @@ struct sa1100_port { struct timer_list timer; unsigned int old_status; struct mctrl_gpios *gpios; + struct gpio_desc *xcvr_enable; unsigned wake; }; @@ -562,6 +564,16 @@ sa1100_verify_port(struct uart_port *port, struct serial_struct *ser) return ret; } +static void sa1100_pm(struct uart_port *port, unsigned int state, + unsigned int old) +{ + struct sa1100_port *sport = + container_of(port, struct sa1100_port, port); + + if (sport->xcvr_enable) + gpiod_direction_output(sport->xcvr_enable, !state); +} + static struct uart_ops sa1100_pops = { .tx_empty = sa1100_tx_empty, .set_mctrl = sa1100_set_mctrl, @@ -579,6 +591,7 @@ static struct uart_ops sa1100_pops = { .request_port = sa1100_request_port, .config_port = sa1100_config_port, .verify_port = sa1100_verify_port, + .pm = sa1100_pm, }; static struct sa1100_port sa1100_ports[NR_PORTS]; @@ -911,6 +924,20 @@ static int sa1100_serial_add_one_port(struct sa1100_port *sport, struct platform sport->gpios = NULL; } + sport->xcvr_enable = devm_gpiod_get_optional(sport->port.dev, + "xcvr-enable", GPIOD_ASIS); + if (IS_ERR(sport->xcvr_enable)) { + int err = PTR_ERR(sport->xcvr_enable); + + dev_err(sport->port.dev, "failed to get xcvr gpio: %d\n", + err); + + if (err == -EPROBE_DEFER) + return err; + + sport->xcvr_enable = NULL; + } + device_init_wakeup(sport->port.dev, !!sport->wake); platform_set_drvdata(dev, sport); |