summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2016-08-04 11:16:23 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-09-21 07:57:11 -0700
commit51db013767c46dc0243a8945085b5a229d9bd281 (patch)
treecd9fa85b271618ce6835e400bf7d7f19bf8c9d51
parent722dc54628ca5cffd3b4581b523775aa422b55df (diff)
Input: serio - add hangup support
The Pulse-Eight USB CEC adapter is a usb device that shows up as a ttyACM0 device. It requires that you run inputattach in order to communicate with it via serio. This all works well, but it would be nice to have a udev rule to automatically start inputattach. That too works OK, but the problem comes when the USB device is unplugged: the tty hangup is never handled by the serio framework so the inputattach utility never exits and you have to kill it manually. By adding this hangup callback the inputattach utility now properly exits as soon as the USB device is unplugged. The udev rule I used on my Debian sid system is: SUBSYSTEM=="tty", KERNEL=="ttyACM[0-9]*", ATTRS{idVendor}=="2548", ATTRS{idProduct}=="1002", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="pulse8-cec-inputattach@%k.service" And /etc/systemd/system/pulse8-cec-inputattach@.service is as follows: =============================================================== [Unit] Description=inputattach for pulse8-cec device on %I [Service] Type=simple ExecStart=/usr/local/bin/inputattach --pulse8-cec /dev/%I KillMode=process =============================================================== Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Tested-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/serio/serport.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 9c927d35c1f5..d189843f3727 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -71,10 +71,7 @@ static void serport_serio_close(struct serio *serio)
spin_lock_irqsave(&serport->lock, flags);
clear_bit(SERPORT_ACTIVE, &serport->flags);
- set_bit(SERPORT_DEAD, &serport->flags);
spin_unlock_irqrestore(&serport->lock, flags);
-
- wake_up_interruptible(&serport->wait);
}
/*
@@ -248,6 +245,19 @@ static long serport_ldisc_compat_ioctl(struct tty_struct *tty,
}
#endif
+static int serport_ldisc_hangup(struct tty_struct *tty)
+{
+ struct serport *serport = (struct serport *) tty->disc_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&serport->lock, flags);
+ set_bit(SERPORT_DEAD, &serport->flags);
+ spin_unlock_irqrestore(&serport->lock, flags);
+
+ wake_up_interruptible(&serport->wait);
+ return 0;
+}
+
static void serport_ldisc_write_wakeup(struct tty_struct * tty)
{
struct serport *serport = (struct serport *) tty->disc_data;
@@ -274,6 +284,7 @@ static struct tty_ldisc_ops serport_ldisc = {
.compat_ioctl = serport_ldisc_compat_ioctl,
#endif
.receive_buf = serport_ldisc_receive,
+ .hangup = serport_ldisc_hangup,
.write_wakeup = serport_ldisc_write_wakeup
};