Patch "Input: i8042 - break load dependency between atkbd/psmouse and i8042" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
Input: i8042 - break load dependency between atkbd/psmouse and i8042
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
input-i8042-break-load-dependency-between-atkbd-psmouse-and-i8042.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
4097461897df91041382ff6fcd2bfa7ee6b2448cMon Sep 17 00:00:00 2001
From: Dmitry Torokhov <[email protected]>
Date: Mon, 25 Jul 2016 11:36:54 -0700
Subject: Input: i8042 - break load dependency between atkbd/psmouse and i8042
From: Dmitry Torokhov <[email protected]>
commit 4097461897df91041382ff6fcd2bfa7ee6b2448c upstream.
As explained in [email protected] we have a hard load dependency between i8042 and atkbd which prevents keyboard from working on Gen2 Hyper-V VMs.
Quoted 6 lines
hyperv_keyboardinvokesserio_interrupt(), which needs a valid serio driver likeatkbd.c.atkbd.cdepends onlibps2.cbecause it invokesps2_command().libps2.cdepends oni8042.cbecause it invokesi8042_check_port_owner(). As a result,hyperv_keyboardactually depends oni8042.c.
Quoted 6 lines
For a Generation 2 Hyper-V VM (meaning no i8042 device emulated), if a Linux VM (like Arch Linux) happens to configure
CONFIG_SERIO_I8042=mrather than =y, atkbd.ko can't load because i8042.ko can't load(due to no i8042 device emulated) and finallyhyperv_keyboardcan't work and the user can't input: https://bugs.archlinux.org/task/39820
(Ubuntu/RHEL/SUSE aren't affected since they useCONFIG_SERIO_I8042=y)
To break the dependency we move away from using i8042_check_port_owner() and instead allow serio port owner specify a mutex that clients should use to serialize PS/2 command stream.
--- drivers/input/serio/i8042.c | 16 +--------------- drivers/input/serio/libps2.c | 10 ++++------ include/linux/i8042.h | 6 ------ include/linux/serio.h | 24 +++++++++++++++++++----- 4 files changed, 24 insertions(+), 32 deletions(-)
drivers/input/serio/i8042.c +1 -15
@@ -1277,6 +1277,7 @@ static int __init i8042_create_kbd_port( serio->start = i8042_start; serio->stop = i8042_stop; serio->close = i8042_port_close; + serio->ps2_cmd_mutex = &i8042_mutex; serio->port_data = port; serio->dev.parent = &i8042_platform_device->dev;strlcpy (serio->name,"i8042 KBD port" ,sizeof (serio->name));
@@ -1373,21 +1374,6 @@ static void i8042_unregister_ports(void) } } -/* -* Checks whether port belongs to i8042 controller. -*/ -bool i8042_check_port_owner (const struct serio *port) -{ -int i; - -for (i =0 ; i <I8042_NUM_PORTS ; i++) -if (i8042_ports[i].serio == port) -return true; - -return false; -} -EXPORT_SYMBOL (i8042_check_port_owner); -static void i8042_free_irqs (void ) {if (i8042_aux_irq_registered)
drivers/input/serio/libps2.c +4 -6
@@ -56,19 +56,17 @@ EXPORT_SYMBOL(ps2_sendbyte);void ps2_begin_command (struct ps2dev *ps2dev) { -mutex_lock (&ps2dev->cmd_mutex); +struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; -if (i8042_check_port_owner (ps2dev->serio)) -i8042_lock_chip (); +mutex_lock (m); }EXPORT_SYMBOL (ps2_begin_command);void ps2_end_command (struct ps2dev *ps2dev) { -if (i8042_check_port_owner (ps2dev->serio)) -i8042_unlock_chip (); +struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; -mutex_unlock (&ps2dev->cmd_mutex); +mutex_unlock (m); }EXPORT_SYMBOL (ps2_end_command);
include/linux/i8042.h +0 -6
@@ -62,7 +62,6 @@ struct serio;void i8042_lock_chip (void );void i8042_unlock_chip (void );int i8042_command (unsigned char *param,int command); -bool i8042_check_port_owner (const struct serio *);int i8042_install_filter (bool (*filter)(unsigned char data,unsigned char str,struct serio *serio)); int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
@@ -83,11 +82,6 @@ static inline int i8042_command(unsignedreturn -ENODEV ; } -static inline bool i8042_check_port_owner (const struct serio *serio) -{ -return false; -} -static inline int i8042_install_filter (bool (*filter)(unsigned char data,unsigned char str,struct serio *serio)) {
include/linux/serio.h +19 -5
@@ -31,7 +31,8 @@ struct serio {struct serio_device_id id; -spinlock_t lock;/* protects critical sections from port's interrupt handler */ +/* Protects critical sections from port's interrupt handler */ +spinlock_t lock;int (*write)(struct serio *,unsigned char );int (*open)(struct serio *);
@@ -40,16 +41,29 @@ struct serio {void (*stop)(struct serio *);struct serio *parent; -struct list_head child_node;/* Entry in parent->children list */ +/* Entry in parent->children list */ +struct list_head child_node;struct list_head children; -unsigned int depth;/* level of nesting in serio hierarchy */ +/* Level of nesting in serio hierarchy */ +unsigned int depth; -struct serio_driver *drv;/* accessed from interrupt, must be protected by serio->lock and serio->sem */ -struct mutex drv_mutex;/* protects serio->drv so attributes can pin driver */ +/* +* serio->drv is accessed from interrupt handlers; when modifying +* caller should acquire serio->drv_mutex and serio->lock. +*/ +struct serio_driver *drv; +/* Protects serio->drv so attributes can pin current driver */ +struct mutex drv_mutex;struct device dev;struct list_head node; + +/* +* For use by PS/2 layer when several ports share hardware and +* may get indigestion when exposed to concurrent access (i8042). +*/ +struct mutex *ps2_cmd_mutex; };#define to_serio_port (d) container_of(d, struct serio, dev)
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/input-elan_i2c-properly-wake-up-touchpad-on-asus-laptops.patch queue-4.7/input-i8042-break-load-dependency-between-atkbd-psmouse-and-i8042.patch