diff mbox series

[4/6] USB: serial: add sysfs attribute to suppress raising DTR & RTS on open

Message ID 20220527222723.676313740227@freecalypso.org
State Superseded
Headers show
Series [1/6] tty: add port flag to suppress raising DTR & RTS on open | expand

Commit Message

Mychaela N. Falconia May 27, 2022, 10:27 p.m. UTC
Add a manual_rtsdtr sysfs attribute to suppress automatic raising of
DTR and RTS modem control signals on serial port open.

This special mode can be used to prevent undesirable side effects on
open for applications where these lines are used for non-standard
purposes such as generating power-on and reset pulses.

Co-developed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
---
 drivers/usb/serial/bus.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 9e38142acd38..f1559d082fad 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -29,6 +29,38 @@  static int usb_serial_device_match(struct device *dev,
 	return 0;
 }
 
+static ssize_t manual_rtsdtr_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct usb_serial_port *port = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", tty_port_manual_rtsdtr(&port->port));
+}
+
+static ssize_t manual_rtsdtr_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct usb_serial_port *port = dev_get_drvdata(dev);
+	bool val;
+	int ret;
+
+	ret = kstrtobool(buf, &val);
+	if (ret)
+		return ret;
+
+	tty_port_set_manual_rtsdtr(&port->port, val);
+
+	return count;
+}
+static DEVICE_ATTR_RW(manual_rtsdtr);
+
+static struct attribute *tty_attrs[] = {
+	&dev_attr_manual_rtsdtr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(tty);
+
 static int usb_serial_device_probe(struct device *dev)
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
@@ -50,8 +82,8 @@  static int usb_serial_device_probe(struct device *dev)
 	}
 
 	minor = port->minor;
-	tty_dev = tty_port_register_device(&port->port, usb_serial_tty_driver,
-					   minor, dev);
+	tty_dev = tty_port_register_device_attr(&port->port,
+			usb_serial_tty_driver, minor, dev, port, tty_groups);
 	if (IS_ERR(tty_dev)) {
 		retval = PTR_ERR(tty_dev);
 		goto err_port_remove;