summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2016-09-13 13:15:31 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-01-08 10:30:01 +0000
commit463201c1ca00b11bfc197c2a7d2b076f3b3a7c3a (patch)
treeff6a29502ac5c3d026b1dffe394b49a543b1744b
parent16ec22a9d15deab72200f8c76dd5612d1327117b (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.c27
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);