mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Input: i8042 - break load dependency between atkbd/psmouse and i8042
As explained in 1407814240-4275-1-git-send-email-decui@microsoft.com we have a hard load dependency between i8042 and atkbd which prevents keyboard from working on Gen2 Hyper-V VMs. > hyperv_keyboard invokes serio_interrupt(), which needs a valid serio > driver like atkbd.c. atkbd.c depends on libps2.c because it invokes > ps2_command(). libps2.c depends on i8042.c because it invokes > i8042_check_port_owner(). As a result, hyperv_keyboard actually > depends on i8042.c. > > 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=m > rather than =y, atkbd.ko can't load because i8042.ko can't load(due to > no i8042 device emulated) and finally hyperv_keyboard can't work and > the user can't input: https://bugs.archlinux.org/task/39820 > (Ubuntu/RHEL/SUSE aren't affected since they use CONFIG_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. Reported-by: Mark Laws <mdl@60hz.org> Tested-by: Mark Laws <mdl@60hz.org> Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
887ec0bfbd
commit
4097461897
4 changed files with 24 additions and 32 deletions
|
@ -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)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue