mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 11:00:56 +07:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
* master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: (26 commits) Input: add support for Braille devices Input: synaptics - limit rate to 40pps on Toshiba Protege M300 Input: gamecon - add SNES mouse support Input: make modalias code respect allowed buffer size Input: convert /proc handling to seq_file Input: limit attributes' output to PAGE_SIZE Input: gameport - fix memory leak Input: serio - fix memory leak Input: zaurus keyboard driver updates Input: i8042 - fix logic around pnp_register_driver() Input: ns558 - fix logic around pnp_register_driver() Input: pcspkr - separate device and driver registration Input: atkbd - allow disabling on X86_PC (if EMBEDDED) Input: atkbd - disable softrepeat for dumb keyboards Input: atkbd - fix complaints about 'releasing unknown key 0x7f' Input: HID - fix duplicate key mapping for Logitech UltraX remote Input: use kzalloc() throughout the code Input: fix input_free_device() implementation Input: initialize serio and gameport at subsystem level Input: uinput - semaphore to mutex conversion ...
This commit is contained in:
commit
9c8680e2cf
@ -36,12 +36,12 @@ with them.
|
||||
|
||||
All NES and SNES use the same synchronous serial protocol, clocked from
|
||||
the computer's side (and thus timing insensitive). To allow up to 5 NES
|
||||
and/or SNES gamepads connected to the parallel port at once, the output
|
||||
lines of the parallel port are shared, while one of 5 available input lines
|
||||
is assigned to each gamepad.
|
||||
and/or SNES gamepads and/or SNES mice connected to the parallel port at once,
|
||||
the output lines of the parallel port are shared, while one of 5 available
|
||||
input lines is assigned to each gamepad.
|
||||
|
||||
This protocol is handled by the gamecon.c driver, so that's the one
|
||||
you'll use for NES and SNES gamepads.
|
||||
you'll use for NES, SNES gamepads and SNES mice.
|
||||
|
||||
The main problem with PC parallel ports is that they don't have +5V power
|
||||
source on any of their pins. So, if you want a reliable source of power
|
||||
@ -106,7 +106,7 @@ A, Turbo B, Select and Start, and is connected through 5 wires, then it is
|
||||
either a NES or NES clone and will work with this connection. SNES gamepads
|
||||
also use 5 wires, but have more buttons. They will work as well, of course.
|
||||
|
||||
Pinout for NES gamepads Pinout for SNES gamepads
|
||||
Pinout for NES gamepads Pinout for SNES gamepads and mice
|
||||
|
||||
+----> Power +-----------------------\
|
||||
| 7 | o o o o | x x o | 1
|
||||
@ -454,6 +454,7 @@ uses the following kernel/module command line:
|
||||
6 | N64 pad
|
||||
7 | Sony PSX controller
|
||||
8 | Sony PSX DDR controller
|
||||
9 | SNES mouse
|
||||
|
||||
The exact type of the PSX controller type is autoprobed when used so
|
||||
hot swapping should work (but is not recomended).
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/seq_file.h>
|
||||
@ -1478,3 +1479,20 @@ alpha_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
|
||||
#endif
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static __init int add_pcspkr(void)
|
||||
{
|
||||
struct platform_device *pd;
|
||||
int ret;
|
||||
|
||||
pd = platform_device_alloc("pcspkr", -1);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add(pd);
|
||||
if (ret)
|
||||
platform_device_put(pd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall(add_pcspkr);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/mca.h>
|
||||
#include <linux/root_dev.h>
|
||||
@ -1547,6 +1548,23 @@ void __init setup_arch(char **cmdline_p)
|
||||
#endif
|
||||
}
|
||||
|
||||
static __init int add_pcspkr(void)
|
||||
{
|
||||
struct platform_device *pd;
|
||||
int ret;
|
||||
|
||||
pd = platform_device_alloc("pcspkr", -1);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add(pd);
|
||||
if (ret)
|
||||
platform_device_put(pd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall(add_pcspkr);
|
||||
|
||||
#include "setup_arch_post.h"
|
||||
/*
|
||||
* Local Variables:
|
||||
|
@ -233,6 +233,7 @@ config MACH_JAZZ
|
||||
select ARC32
|
||||
select ARCH_MAY_HAVE_PC_FDC
|
||||
select GENERIC_ISA_DMA
|
||||
select I8253
|
||||
select I8259
|
||||
select ISA
|
||||
select SYS_HAS_CPU_R4X00
|
||||
@ -530,6 +531,7 @@ config QEMU
|
||||
select DMA_COHERENT
|
||||
select GENERIC_ISA_DMA
|
||||
select HAVE_STD_PC_SERIAL_PORT
|
||||
select I8253
|
||||
select I8259
|
||||
select ISA
|
||||
select SWAP_IO_SPACE
|
||||
@ -714,6 +716,7 @@ config SNI_RM200_PCI
|
||||
select HAVE_STD_PC_SERIAL_PORT
|
||||
select HW_HAS_EISA
|
||||
select HW_HAS_PCI
|
||||
select I8253
|
||||
select I8259
|
||||
select ISA
|
||||
select SYS_HAS_CPU_R4X00
|
||||
@ -1721,6 +1724,9 @@ config MMU
|
||||
bool
|
||||
default y
|
||||
|
||||
config I8253
|
||||
bool
|
||||
|
||||
source "drivers/pcmcia/Kconfig"
|
||||
|
||||
source "drivers/pci/hotplug/Kconfig"
|
||||
|
@ -59,6 +59,8 @@ obj-$(CONFIG_PROC_FS) += proc.o
|
||||
|
||||
obj-$(CONFIG_64BIT) += cpu-bugs64.o
|
||||
|
||||
obj-$(CONFIG_I8253) += i8253.o
|
||||
|
||||
CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
|
||||
|
||||
EXTRA_AFLAGS := $(CFLAGS)
|
||||
|
28
arch/mips/kernel/i8253.c
Normal file
28
arch/mips/kernel/i8253.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2006 IBM Corporation
|
||||
*
|
||||
* Implements device information for i8253 timer chip
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 as published by the Free Software Foundation
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
static __init int add_pcspkr(void)
|
||||
{
|
||||
struct platform_device *pd;
|
||||
int ret;
|
||||
|
||||
pd = platform_device_alloc("pcspkr", -1);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add(pd);
|
||||
if (ret)
|
||||
platform_device_put(pd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall(add_pcspkr);
|
@ -21,6 +21,7 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ide.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/ioport.h>
|
||||
@ -462,6 +463,29 @@ static int __init early_xmon(char *p)
|
||||
early_param("xmon", early_xmon);
|
||||
#endif
|
||||
|
||||
static __init int add_pcspkr(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct platform_device *pd;
|
||||
int ret;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "pnpPNP,100");
|
||||
of_node_put(np);
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
pd = platform_device_alloc("pcspkr", -1);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add(pd);
|
||||
if (ret)
|
||||
platform_device_put(pd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall(add_pcspkr);
|
||||
|
||||
void probe_machine(void)
|
||||
{
|
||||
extern struct machdep_calls __machine_desc_start;
|
||||
|
@ -25,9 +25,6 @@ obj-$(CONFIG_CONNECTOR) += connector/
|
||||
obj-$(CONFIG_FB_I810) += video/i810/
|
||||
obj-$(CONFIG_FB_INTEL) += video/intelfb/
|
||||
|
||||
# we also need input/serio early so serio bus is initialized by the time
|
||||
# serial drivers start registering their serio ports
|
||||
obj-$(CONFIG_SERIO) += input/serio/
|
||||
obj-y += serial/
|
||||
obj-$(CONFIG_PARPORT) += parport/
|
||||
obj-y += base/ block/ misc/ mfd/ net/ media/
|
||||
@ -53,6 +50,7 @@ obj-$(CONFIG_TC) += tc/
|
||||
obj-$(CONFIG_USB) += usb/
|
||||
obj-$(CONFIG_PCI) += usb/
|
||||
obj-$(CONFIG_USB_GADGET) += usb/gadget/
|
||||
obj-$(CONFIG_SERIO) += input/serio/
|
||||
obj-$(CONFIG_GAMEPORT) += input/gameport/
|
||||
obj-$(CONFIG_INPUT) += input/
|
||||
obj-$(CONFIG_I2O) += message/
|
||||
|
@ -74,7 +74,7 @@ void compute_shiftstate(void);
|
||||
k_self, k_fn, k_spec, k_pad,\
|
||||
k_dead, k_cons, k_cur, k_shift,\
|
||||
k_meta, k_ascii, k_lock, k_lowercase,\
|
||||
k_slock, k_dead2, k_ignore, k_ignore
|
||||
k_slock, k_dead2, k_brl, k_ignore
|
||||
|
||||
typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
|
||||
char up_flag, struct pt_regs *regs);
|
||||
@ -100,7 +100,7 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
|
||||
const int max_vals[] = {
|
||||
255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
|
||||
NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
|
||||
255, NR_LOCK - 1, 255
|
||||
255, NR_LOCK - 1, 255, NR_BRL - 1
|
||||
};
|
||||
|
||||
const int NR_TYPES = ARRAY_SIZE(max_vals);
|
||||
@ -126,7 +126,7 @@ static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */
|
||||
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
|
||||
static int dead_key_next;
|
||||
static int npadch = -1; /* -1 or number assembled on pad */
|
||||
static unsigned char diacr;
|
||||
static unsigned int diacr;
|
||||
static char rep; /* flag telling character repeat */
|
||||
|
||||
static unsigned char ledstate = 0xff; /* undefined */
|
||||
@ -394,22 +394,30 @@ void compute_shiftstate(void)
|
||||
* Otherwise, conclude that DIACR was not combining after all,
|
||||
* queue it and return CH.
|
||||
*/
|
||||
static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
|
||||
static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
|
||||
{
|
||||
int d = diacr;
|
||||
unsigned int d = diacr;
|
||||
unsigned int i;
|
||||
|
||||
diacr = 0;
|
||||
|
||||
for (i = 0; i < accent_table_size; i++) {
|
||||
if ((d & ~0xff) == BRL_UC_ROW) {
|
||||
if ((ch & ~0xff) == BRL_UC_ROW)
|
||||
return d | ch;
|
||||
} else {
|
||||
for (i = 0; i < accent_table_size; i++)
|
||||
if (accent_table[i].diacr == d && accent_table[i].base == ch)
|
||||
return accent_table[i].result;
|
||||
}
|
||||
|
||||
if (ch == ' ' || ch == d)
|
||||
if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
|
||||
return d;
|
||||
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, d);
|
||||
else if (d < 0x100)
|
||||
put_queue(vc, d);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
@ -419,6 +427,9 @@ static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
|
||||
static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
|
||||
{
|
||||
if (diacr) {
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, diacr);
|
||||
else if (diacr < 0x100)
|
||||
put_queue(vc, diacr);
|
||||
diacr = 0;
|
||||
}
|
||||
@ -615,7 +626,7 @@ static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, s
|
||||
printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n");
|
||||
}
|
||||
|
||||
static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
|
||||
static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs)
|
||||
{
|
||||
if (up_flag)
|
||||
return; /* no action, if this is a key release */
|
||||
@ -628,6 +639,9 @@ static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct
|
||||
diacr = value;
|
||||
return;
|
||||
}
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, value);
|
||||
else if (value < 0x100)
|
||||
put_queue(vc, value);
|
||||
}
|
||||
|
||||
@ -636,13 +650,23 @@ static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct
|
||||
* dead keys modifying the same character. Very useful
|
||||
* for Vietnamese.
|
||||
*/
|
||||
static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
|
||||
static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs)
|
||||
{
|
||||
if (up_flag)
|
||||
return;
|
||||
diacr = (diacr ? handle_diacr(vc, value) : value);
|
||||
}
|
||||
|
||||
static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
|
||||
{
|
||||
k_unicode(vc, value, up_flag, regs);
|
||||
}
|
||||
|
||||
static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
|
||||
{
|
||||
k_deadunicode(vc, value, up_flag, regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Obsolete - for backwards compatibility only
|
||||
*/
|
||||
@ -650,7 +674,7 @@ static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct
|
||||
{
|
||||
static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
|
||||
value = ret_diacr[value];
|
||||
k_dead2(vc, value, up_flag, regs);
|
||||
k_deadunicode(vc, value, up_flag, regs);
|
||||
}
|
||||
|
||||
static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
|
||||
@ -835,6 +859,62 @@ static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struc
|
||||
}
|
||||
}
|
||||
|
||||
/* by default, 300ms interval for combination release */
|
||||
static long brl_timeout = 300;
|
||||
MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for combination on first release, < 0 for dead characters)");
|
||||
module_param(brl_timeout, long, 0644);
|
||||
static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
|
||||
{
|
||||
static unsigned pressed,committing;
|
||||
static unsigned long releasestart;
|
||||
|
||||
if (kbd->kbdmode != VC_UNICODE) {
|
||||
if (!up_flag)
|
||||
printk("keyboard mode must be unicode for braille patterns\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
k_unicode(vc, BRL_UC_ROW, up_flag, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > 8)
|
||||
return;
|
||||
|
||||
if (brl_timeout < 0) {
|
||||
k_deadunicode(vc, BRL_UC_ROW | (1 << (value - 1)), up_flag, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (up_flag) {
|
||||
if (brl_timeout) {
|
||||
if (!committing ||
|
||||
jiffies - releasestart > (brl_timeout * HZ) / 1000) {
|
||||
committing = pressed;
|
||||
releasestart = jiffies;
|
||||
}
|
||||
pressed &= ~(1 << (value - 1));
|
||||
if (!pressed) {
|
||||
if (committing) {
|
||||
k_unicode(vc, BRL_UC_ROW | committing, 0, regs);
|
||||
committing = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (committing) {
|
||||
k_unicode(vc, BRL_UC_ROW | committing, 0, regs);
|
||||
committing = 0;
|
||||
}
|
||||
pressed &= ~(1 << (value - 1));
|
||||
}
|
||||
} else {
|
||||
pressed |= 1 << (value - 1);
|
||||
if (!brl_timeout)
|
||||
committing = pressed;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
|
||||
* or (ii) whatever pattern of lights people want to show using KDSETLED,
|
||||
@ -1125,9 +1205,13 @@ static void kbd_keycode(unsigned int keycode, int down,
|
||||
}
|
||||
|
||||
if (keycode > NR_KEYS)
|
||||
if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
|
||||
keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
|
||||
else
|
||||
return;
|
||||
|
||||
else
|
||||
keysym = key_map[keycode];
|
||||
|
||||
type = KTYP(keysym);
|
||||
|
||||
if (type < 0xf0) {
|
||||
|
@ -49,9 +49,8 @@ static struct input_handle *evbug_connect(struct input_handler *handler, struct
|
||||
{
|
||||
struct input_handle *handle;
|
||||
|
||||
if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
|
||||
if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL)))
|
||||
return NULL;
|
||||
memset(handle, 0, sizeof(struct input_handle));
|
||||
|
||||
handle->dev = dev;
|
||||
handle->handler = handler;
|
||||
|
@ -130,9 +130,8 @@ static int evdev_open(struct inode * inode, struct file * file)
|
||||
if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
|
||||
return accept_err;
|
||||
|
||||
if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
|
||||
if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
memset(list, 0, sizeof(struct evdev_list));
|
||||
|
||||
list->evdev = evdev_table[i];
|
||||
list_add_tail(&list->node, &evdev_table[i]->list);
|
||||
@ -609,9 +608,8 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(evdev = kmalloc(sizeof(struct evdev), GFP_KERNEL)))
|
||||
if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL)))
|
||||
return NULL;
|
||||
memset(evdev, 0, sizeof(struct evdev));
|
||||
|
||||
INIT_LIST_HEAD(&evdev->list);
|
||||
init_waitqueue_head(&evdev->wait);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched.h> /* HZ */
|
||||
#include <linux/mutex.h>
|
||||
|
||||
/*#include <asm/io.h>*/
|
||||
|
||||
@ -43,10 +44,10 @@ EXPORT_SYMBOL(gameport_start_polling);
|
||||
EXPORT_SYMBOL(gameport_stop_polling);
|
||||
|
||||
/*
|
||||
* gameport_sem protects entire gameport subsystem and is taken
|
||||
* gameport_mutex protects entire gameport subsystem and is taken
|
||||
* every time gameport port or driver registrered or unregistered.
|
||||
*/
|
||||
static DECLARE_MUTEX(gameport_sem);
|
||||
static DEFINE_MUTEX(gameport_mutex);
|
||||
|
||||
static LIST_HEAD(gameport_list);
|
||||
|
||||
@ -265,6 +266,7 @@ static void gameport_queue_event(void *object, struct module *owner,
|
||||
if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) {
|
||||
if (!try_module_get(owner)) {
|
||||
printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type);
|
||||
kfree(event);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -342,7 +344,7 @@ static void gameport_handle_event(void)
|
||||
struct gameport_event *event;
|
||||
struct gameport_driver *gameport_drv;
|
||||
|
||||
down(&gameport_sem);
|
||||
mutex_lock(&gameport_mutex);
|
||||
|
||||
/*
|
||||
* Note that we handle only one event here to give swsusp
|
||||
@ -379,7 +381,7 @@ static void gameport_handle_event(void)
|
||||
gameport_free_event(event);
|
||||
}
|
||||
|
||||
up(&gameport_sem);
|
||||
mutex_unlock(&gameport_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -464,7 +466,7 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut
|
||||
struct device_driver *drv;
|
||||
int retval;
|
||||
|
||||
retval = down_interruptible(&gameport_sem);
|
||||
retval = mutex_lock_interruptible(&gameport_mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -484,7 +486,7 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut
|
||||
retval = -EINVAL;
|
||||
}
|
||||
|
||||
up(&gameport_sem);
|
||||
mutex_unlock(&gameport_mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -521,7 +523,7 @@ static void gameport_init_port(struct gameport *gameport)
|
||||
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
init_MUTEX(&gameport->drv_sem);
|
||||
mutex_init(&gameport->drv_mutex);
|
||||
device_initialize(&gameport->dev);
|
||||
snprintf(gameport->dev.bus_id, sizeof(gameport->dev.bus_id),
|
||||
"gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1);
|
||||
@ -661,10 +663,10 @@ void __gameport_register_port(struct gameport *gameport, struct module *owner)
|
||||
*/
|
||||
void gameport_unregister_port(struct gameport *gameport)
|
||||
{
|
||||
down(&gameport_sem);
|
||||
mutex_lock(&gameport_mutex);
|
||||
gameport_disconnect_port(gameport);
|
||||
gameport_destroy_port(gameport);
|
||||
up(&gameport_sem);
|
||||
mutex_unlock(&gameport_mutex);
|
||||
}
|
||||
|
||||
|
||||
@ -717,7 +719,7 @@ void gameport_unregister_driver(struct gameport_driver *drv)
|
||||
{
|
||||
struct gameport *gameport;
|
||||
|
||||
down(&gameport_sem);
|
||||
mutex_lock(&gameport_mutex);
|
||||
drv->ignore = 1; /* so gameport_find_driver ignores it */
|
||||
|
||||
start_over:
|
||||
@ -731,7 +733,7 @@ void gameport_unregister_driver(struct gameport_driver *drv)
|
||||
}
|
||||
|
||||
driver_unregister(&drv->driver);
|
||||
up(&gameport_sem);
|
||||
mutex_unlock(&gameport_mutex);
|
||||
}
|
||||
|
||||
static int gameport_bus_match(struct device *dev, struct device_driver *drv)
|
||||
@ -743,9 +745,9 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv)
|
||||
|
||||
static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv)
|
||||
{
|
||||
down(&gameport->drv_sem);
|
||||
mutex_lock(&gameport->drv_mutex);
|
||||
gameport->drv = drv;
|
||||
up(&gameport->drv_sem);
|
||||
mutex_unlock(&gameport->drv_mutex);
|
||||
}
|
||||
|
||||
int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode)
|
||||
@ -796,5 +798,5 @@ static void __exit gameport_exit(void)
|
||||
kthread_stop(gameport_task);
|
||||
}
|
||||
|
||||
module_init(gameport_init);
|
||||
subsys_initcall(gameport_init);
|
||||
module_exit(gameport_exit);
|
||||
|
@ -252,14 +252,14 @@ static struct pnp_driver ns558_pnp_driver;
|
||||
|
||||
#endif
|
||||
|
||||
static int pnp_registered = 0;
|
||||
|
||||
static int __init ns558_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
int error;
|
||||
|
||||
if (pnp_register_driver(&ns558_pnp_driver) >= 0)
|
||||
pnp_registered = 1;
|
||||
error = pnp_register_driver(&ns558_pnp_driver);
|
||||
if (error && error != -ENODEV) /* should be ENOSYS really */
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Probe ISA ports after PnP, so that PnP ports that are already
|
||||
@ -270,7 +270,7 @@ static int __init ns558_init(void)
|
||||
while (ns558_isa_portlist[i])
|
||||
ns558_isa_probe(ns558_isa_portlist[i++]);
|
||||
|
||||
return (list_empty(&ns558_list) && !pnp_registered) ? -ENODEV : 0;
|
||||
return list_empty(&ns558_list) && error ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
static void __exit ns558_exit(void)
|
||||
@ -283,7 +283,6 @@ static void __exit ns558_exit(void)
|
||||
kfree(ns558);
|
||||
}
|
||||
|
||||
if (pnp_registered)
|
||||
pnp_unregister_driver(&ns558_pnp_driver);
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,11 @@
|
||||
#include <linux/random.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
|
||||
MODULE_DESCRIPTION("Input core");
|
||||
@ -224,7 +226,7 @@ int input_open_device(struct input_handle *handle)
|
||||
struct input_dev *dev = handle->dev;
|
||||
int err;
|
||||
|
||||
err = down_interruptible(&dev->sem);
|
||||
err = mutex_lock_interruptible(&dev->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -236,7 +238,7 @@ int input_open_device(struct input_handle *handle)
|
||||
if (err)
|
||||
handle->open--;
|
||||
|
||||
up(&dev->sem);
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -255,13 +257,13 @@ void input_close_device(struct input_handle *handle)
|
||||
|
||||
input_release_device(handle);
|
||||
|
||||
down(&dev->sem);
|
||||
mutex_lock(&dev->mutex);
|
||||
|
||||
if (!--dev->users && dev->close)
|
||||
dev->close(dev);
|
||||
handle->open--;
|
||||
|
||||
up(&dev->sem);
|
||||
mutex_unlock(&dev->mutex);
|
||||
}
|
||||
|
||||
static void input_link_handle(struct input_handle *handle)
|
||||
@ -315,21 +317,6 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max)
|
||||
{
|
||||
int i;
|
||||
int len = 0;
|
||||
|
||||
for (i = NBITS(max) - 1; i > 0; i--)
|
||||
if (bitmap[i])
|
||||
break;
|
||||
|
||||
for (; i >= 0; i--)
|
||||
len += snprintf(buf + len, max(buf_size - len, 0),
|
||||
"%lx%s", bitmap[i], i > 0 ? " " : "");
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
static struct proc_dir_entry *proc_bus_input_dir;
|
||||
@ -342,7 +329,7 @@ static inline void input_wakeup_procfs_readers(void)
|
||||
wake_up(&input_devices_poll_wait);
|
||||
}
|
||||
|
||||
static unsigned int input_devices_poll(struct file *file, poll_table *wait)
|
||||
static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
int state = input_devices_state;
|
||||
poll_wait(file, &input_devices_poll_wait, wait);
|
||||
@ -351,115 +338,171 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SPRINTF_BIT(ev, bm) \
|
||||
do { \
|
||||
len += sprintf(buf + len, "B: %s=", #ev); \
|
||||
len += input_print_bitmap(buf + len, INT_MAX, \
|
||||
dev->bm##bit, ev##_MAX); \
|
||||
len += sprintf(buf + len, "\n"); \
|
||||
} while (0)
|
||||
|
||||
#define TEST_AND_SPRINTF_BIT(ev, bm) \
|
||||
do { \
|
||||
if (test_bit(EV_##ev, dev->evbit)) \
|
||||
SPRINTF_BIT(ev, bm); \
|
||||
} while (0)
|
||||
|
||||
static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
|
||||
static struct list_head *list_get_nth_element(struct list_head *list, loff_t *pos)
|
||||
{
|
||||
struct input_dev *dev;
|
||||
struct list_head *node;
|
||||
loff_t i = 0;
|
||||
|
||||
list_for_each(node, list)
|
||||
if (i++ == *pos)
|
||||
return node;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct list_head *list_get_next_element(struct list_head *list, struct list_head *element, loff_t *pos)
|
||||
{
|
||||
if (element->next == list)
|
||||
return NULL;
|
||||
|
||||
++(*pos);
|
||||
return element->next;
|
||||
}
|
||||
|
||||
static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
/* acquire lock here ... Yes, we do need locking, I knowi, I know... */
|
||||
|
||||
return list_get_nth_element(&input_dev_list, pos);
|
||||
}
|
||||
|
||||
static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
return list_get_next_element(&input_dev_list, v, pos);
|
||||
}
|
||||
|
||||
static void input_devices_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
/* release lock here */
|
||||
}
|
||||
|
||||
static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
|
||||
unsigned long *bitmap, int max)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = NBITS(max) - 1; i > 0; i--)
|
||||
if (bitmap[i])
|
||||
break;
|
||||
|
||||
seq_printf(seq, "B: %s=", name);
|
||||
for (; i >= 0; i--)
|
||||
seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : "");
|
||||
seq_putc(seq, '\n');
|
||||
}
|
||||
|
||||
static int input_devices_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct input_dev *dev = container_of(v, struct input_dev, node);
|
||||
const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
|
||||
struct input_handle *handle;
|
||||
const char *path;
|
||||
|
||||
off_t at = 0;
|
||||
int len, cnt = 0;
|
||||
|
||||
list_for_each_entry(dev, &input_dev_list, node) {
|
||||
|
||||
path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
|
||||
|
||||
len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
|
||||
seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
|
||||
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
|
||||
|
||||
len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
|
||||
len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
|
||||
len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : "");
|
||||
len += sprintf(buf + len, "H: Handlers=");
|
||||
seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
|
||||
seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : "");
|
||||
seq_printf(seq, "S: Sysfs=%s\n", path ? path : "");
|
||||
seq_printf(seq, "H: Handlers=");
|
||||
|
||||
list_for_each_entry(handle, &dev->h_list, d_node)
|
||||
len += sprintf(buf + len, "%s ", handle->name);
|
||||
seq_printf(seq, "%s ", handle->name);
|
||||
seq_putc(seq, '\n');
|
||||
|
||||
len += sprintf(buf + len, "\n");
|
||||
input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX);
|
||||
if (test_bit(EV_KEY, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX);
|
||||
if (test_bit(EV_REL, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "REL", dev->relbit, REL_MAX);
|
||||
if (test_bit(EV_ABS, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "ABS", dev->absbit, ABS_MAX);
|
||||
if (test_bit(EV_MSC, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "MSC", dev->mscbit, MSC_MAX);
|
||||
if (test_bit(EV_LED, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "LED", dev->ledbit, LED_MAX);
|
||||
if (test_bit(EV_SND, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "SND", dev->sndbit, SND_MAX);
|
||||
if (test_bit(EV_FF, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "FF", dev->ffbit, FF_MAX);
|
||||
if (test_bit(EV_SW, dev->evbit))
|
||||
input_seq_print_bitmap(seq, "SW", dev->swbit, SW_MAX);
|
||||
|
||||
SPRINTF_BIT(EV, ev);
|
||||
TEST_AND_SPRINTF_BIT(KEY, key);
|
||||
TEST_AND_SPRINTF_BIT(REL, rel);
|
||||
TEST_AND_SPRINTF_BIT(ABS, abs);
|
||||
TEST_AND_SPRINTF_BIT(MSC, msc);
|
||||
TEST_AND_SPRINTF_BIT(LED, led);
|
||||
TEST_AND_SPRINTF_BIT(SND, snd);
|
||||
TEST_AND_SPRINTF_BIT(FF, ff);
|
||||
TEST_AND_SPRINTF_BIT(SW, sw);
|
||||
|
||||
len += sprintf(buf + len, "\n");
|
||||
|
||||
at += len;
|
||||
|
||||
if (at >= pos) {
|
||||
if (!*start) {
|
||||
*start = buf + (pos - (at - len));
|
||||
cnt = at - pos;
|
||||
} else cnt += len;
|
||||
buf += len;
|
||||
if (cnt >= count)
|
||||
break;
|
||||
}
|
||||
seq_putc(seq, '\n');
|
||||
|
||||
kfree(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (&dev->node == &input_dev_list)
|
||||
*eof = 1;
|
||||
static struct seq_operations input_devices_seq_ops = {
|
||||
.start = input_devices_seq_start,
|
||||
.next = input_devices_seq_next,
|
||||
.stop = input_devices_seq_stop,
|
||||
.show = input_devices_seq_show,
|
||||
};
|
||||
|
||||
return (count > cnt) ? cnt : count;
|
||||
}
|
||||
|
||||
static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
|
||||
static int input_proc_devices_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct input_handler *handler;
|
||||
return seq_open(file, &input_devices_seq_ops);
|
||||
}
|
||||
|
||||
off_t at = 0;
|
||||
int len = 0, cnt = 0;
|
||||
int i = 0;
|
||||
static struct file_operations input_devices_fileops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = input_proc_devices_open,
|
||||
.poll = input_proc_devices_poll,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
list_for_each_entry(handler, &input_handler_list, node) {
|
||||
static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
/* acquire lock here ... Yes, we do need locking, I knowi, I know... */
|
||||
seq->private = (void *)(unsigned long)*pos;
|
||||
return list_get_nth_element(&input_handler_list, pos);
|
||||
}
|
||||
|
||||
static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
seq->private = (void *)(unsigned long)(*pos + 1);
|
||||
return list_get_next_element(&input_handler_list, v, pos);
|
||||
}
|
||||
|
||||
static void input_handlers_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
/* release lock here */
|
||||
}
|
||||
|
||||
static int input_handlers_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct input_handler *handler = container_of(v, struct input_handler, node);
|
||||
|
||||
seq_printf(seq, "N: Number=%ld Name=%s",
|
||||
(unsigned long)seq->private, handler->name);
|
||||
if (handler->fops)
|
||||
len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n",
|
||||
i++, handler->name, handler->minor);
|
||||
else
|
||||
len = sprintf(buf, "N: Number=%d Name=%s\n",
|
||||
i++, handler->name);
|
||||
seq_printf(seq, " Minor=%d", handler->minor);
|
||||
seq_putc(seq, '\n');
|
||||
|
||||
at += len;
|
||||
|
||||
if (at >= pos) {
|
||||
if (!*start) {
|
||||
*start = buf + (pos - (at - len));
|
||||
cnt = at - pos;
|
||||
} else cnt += len;
|
||||
buf += len;
|
||||
if (cnt >= count)
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (&handler->node == &input_handler_list)
|
||||
*eof = 1;
|
||||
static struct seq_operations input_handlers_seq_ops = {
|
||||
.start = input_handlers_seq_start,
|
||||
.next = input_handlers_seq_next,
|
||||
.stop = input_handlers_seq_stop,
|
||||
.show = input_handlers_seq_show,
|
||||
};
|
||||
|
||||
return (count > cnt) ? cnt : count;
|
||||
static int input_proc_handlers_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &input_handlers_seq_ops);
|
||||
}
|
||||
|
||||
static struct file_operations input_fileops;
|
||||
static struct file_operations input_handlers_fileops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = input_proc_handlers_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init input_proc_init(void)
|
||||
{
|
||||
@ -471,20 +514,19 @@ static int __init input_proc_init(void)
|
||||
|
||||
proc_bus_input_dir->owner = THIS_MODULE;
|
||||
|
||||
entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL);
|
||||
entry = create_proc_entry("devices", 0, proc_bus_input_dir);
|
||||
if (!entry)
|
||||
goto fail1;
|
||||
|
||||
entry->owner = THIS_MODULE;
|
||||
input_fileops = *entry->proc_fops;
|
||||
input_fileops.poll = input_devices_poll;
|
||||
entry->proc_fops = &input_fileops;
|
||||
entry->proc_fops = &input_devices_fileops;
|
||||
|
||||
entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL);
|
||||
entry = create_proc_entry("handlers", 0, proc_bus_input_dir);
|
||||
if (!entry)
|
||||
goto fail2;
|
||||
|
||||
entry->owner = THIS_MODULE;
|
||||
entry->proc_fops = &input_handlers_fileops;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -512,13 +554,14 @@ static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \
|
||||
struct input_dev *input_dev = to_input_dev(dev); \
|
||||
int retval; \
|
||||
\
|
||||
retval = down_interruptible(&input_dev->sem); \
|
||||
retval = mutex_lock_interruptible(&input_dev->mutex); \
|
||||
if (retval) \
|
||||
return retval; \
|
||||
\
|
||||
retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \
|
||||
retval = scnprintf(buf, PAGE_SIZE, \
|
||||
"%s\n", input_dev->name ? input_dev->name : ""); \
|
||||
\
|
||||
up(&input_dev->sem); \
|
||||
mutex_unlock(&input_dev->mutex); \
|
||||
\
|
||||
return retval; \
|
||||
} \
|
||||
@ -528,46 +571,51 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
|
||||
INPUT_DEV_STRING_ATTR_SHOW(phys);
|
||||
INPUT_DEV_STRING_ATTR_SHOW(uniq);
|
||||
|
||||
static int print_modalias_bits(char *buf, int size, char prefix, unsigned long *arr,
|
||||
unsigned int min, unsigned int max)
|
||||
static int input_print_modalias_bits(char *buf, int size,
|
||||
char name, unsigned long *bm,
|
||||
unsigned int min_bit, unsigned int max_bit)
|
||||
{
|
||||
int len, i;
|
||||
int len = 0, i;
|
||||
|
||||
len = snprintf(buf, size, "%c", prefix);
|
||||
for (i = min; i < max; i++)
|
||||
if (arr[LONG(i)] & BIT(i))
|
||||
len += snprintf(buf + len, size - len, "%X,", i);
|
||||
len += snprintf(buf, max(size, 0), "%c", name);
|
||||
for (i = min_bit; i < max_bit; i++)
|
||||
if (bm[LONG(i)] & BIT(i))
|
||||
len += snprintf(buf + len, max(size - len, 0), "%X,", i);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int print_modalias(char *buf, int size, struct input_dev *id)
|
||||
static int input_print_modalias(char *buf, int size, struct input_dev *id,
|
||||
int add_cr)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, size, "input:b%04Xv%04Xp%04Xe%04X-",
|
||||
id->id.bustype,
|
||||
id->id.vendor,
|
||||
id->id.product,
|
||||
id->id.version);
|
||||
len = snprintf(buf, max(size, 0),
|
||||
"input:b%04Xv%04Xp%04Xe%04X-",
|
||||
id->id.bustype, id->id.vendor,
|
||||
id->id.product, id->id.version);
|
||||
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'e', id->evbit, 0, EV_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'r', id->relbit, 0, REL_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'a', id->absbit, 0, ABS_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'm', id->mscbit, 0, MSC_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'l', id->ledbit, 0, LED_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
's', id->sndbit, 0, SND_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'f', id->ffbit, 0, FF_MAX);
|
||||
len += input_print_modalias_bits(buf + len, size - len,
|
||||
'w', id->swbit, 0, SW_MAX);
|
||||
|
||||
if (add_cr)
|
||||
len += snprintf(buf + len, max(size - len, 0), "\n");
|
||||
|
||||
len += print_modalias_bits(buf + len, size - len, 'e', id->evbit,
|
||||
0, EV_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'k', id->keybit,
|
||||
KEY_MIN_INTERESTING, KEY_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'r', id->relbit,
|
||||
0, REL_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'a', id->absbit,
|
||||
0, ABS_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'm', id->mscbit,
|
||||
0, MSC_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'l', id->ledbit,
|
||||
0, LED_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 's', id->sndbit,
|
||||
0, SND_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'f', id->ffbit,
|
||||
0, FF_MAX);
|
||||
len += print_modalias_bits(buf + len, size - len, 'w', id->swbit,
|
||||
0, SW_MAX);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -576,9 +624,9 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
|
||||
struct input_dev *id = to_input_dev(dev);
|
||||
ssize_t len;
|
||||
|
||||
len = print_modalias(buf, PAGE_SIZE, id);
|
||||
len += snprintf(buf + len, PAGE_SIZE-len, "\n");
|
||||
return len;
|
||||
len = input_print_modalias(buf, PAGE_SIZE, id, 1);
|
||||
|
||||
return max_t(int, len, PAGE_SIZE);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
|
||||
|
||||
@ -598,7 +646,7 @@ static struct attribute_group input_dev_attr_group = {
|
||||
static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \
|
||||
{ \
|
||||
struct input_dev *input_dev = to_input_dev(dev); \
|
||||
return sprintf(buf, "%04x\n", input_dev->id.name); \
|
||||
return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
|
||||
} \
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
|
||||
|
||||
@ -620,11 +668,33 @@ static struct attribute_group input_dev_id_attr_group = {
|
||||
.attrs = input_dev_id_attrs,
|
||||
};
|
||||
|
||||
static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
|
||||
int max, int add_cr)
|
||||
{
|
||||
int i;
|
||||
int len = 0;
|
||||
|
||||
for (i = NBITS(max) - 1; i > 0; i--)
|
||||
if (bitmap[i])
|
||||
break;
|
||||
|
||||
for (; i >= 0; i--)
|
||||
len += snprintf(buf + len, max(buf_size - len, 0),
|
||||
"%lx%s", bitmap[i], i > 0 ? " " : "");
|
||||
|
||||
if (add_cr)
|
||||
len += snprintf(buf + len, max(buf_size - len, 0), "\n");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#define INPUT_DEV_CAP_ATTR(ev, bm) \
|
||||
static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \
|
||||
{ \
|
||||
struct input_dev *input_dev = to_input_dev(dev); \
|
||||
return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\
|
||||
int len = input_print_bitmap(buf, PAGE_SIZE, \
|
||||
input_dev->bm##bit, ev##_MAX, 1); \
|
||||
return min_t(int, len, PAGE_SIZE); \
|
||||
} \
|
||||
static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
|
||||
|
||||
@ -678,12 +748,36 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
|
||||
envp[*cur_index] = buffer + *cur_len;
|
||||
|
||||
*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
|
||||
if (*cur_len > buffer_size)
|
||||
if (*cur_len >= buffer_size)
|
||||
return -ENOMEM;
|
||||
|
||||
*cur_len += input_print_bitmap(buffer + *cur_len,
|
||||
max(buffer_size - *cur_len, 0),
|
||||
bitmap, max) + 1;
|
||||
bitmap, max, 0) + 1;
|
||||
if (*cur_len > buffer_size)
|
||||
return -ENOMEM;
|
||||
|
||||
(*cur_index)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
struct input_dev *dev)
|
||||
{
|
||||
if (*cur_index >= num_envp - 1)
|
||||
return -ENOMEM;
|
||||
|
||||
envp[*cur_index] = buffer + *cur_len;
|
||||
|
||||
*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0),
|
||||
"MODALIAS=");
|
||||
if (*cur_len >= buffer_size)
|
||||
return -ENOMEM;
|
||||
|
||||
*cur_len += input_print_modalias(buffer + *cur_len,
|
||||
max(buffer_size - *cur_len, 0),
|
||||
dev, 0) + 1;
|
||||
if (*cur_len > buffer_size)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -709,6 +803,16 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \
|
||||
do { \
|
||||
int err = input_add_uevent_modalias_var(envp, \
|
||||
num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
dev); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
static int input_dev_uevent(struct class_device *cdev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
{
|
||||
@ -744,9 +848,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
|
||||
if (test_bit(EV_SW, dev->evbit))
|
||||
INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
|
||||
|
||||
envp[i++] = buffer + len;
|
||||
len += snprintf(buffer + len, buffer_size - len, "MODALIAS=");
|
||||
len += print_modalias(buffer + len, buffer_size - len, dev) + 1;
|
||||
INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
@ -790,7 +892,7 @@ int input_register_device(struct input_dev *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
init_MUTEX(&dev->sem);
|
||||
mutex_init(&dev->mutex);
|
||||
set_bit(EV_SYN, dev->evbit);
|
||||
|
||||
/*
|
||||
|
@ -171,9 +171,8 @@ static int joydev_open(struct inode *inode, struct file *file)
|
||||
if (i >= JOYDEV_MINORS || !joydev_table[i])
|
||||
return -ENODEV;
|
||||
|
||||
if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL)))
|
||||
if (!(list = kzalloc(sizeof(struct joydev_list), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
memset(list, 0, sizeof(struct joydev_list));
|
||||
|
||||
list->joydev = joydev_table[i];
|
||||
list_add_tail(&list->node, &joydev_table[i]->list);
|
||||
@ -457,9 +456,8 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(joydev = kmalloc(sizeof(struct joydev), GFP_KERNEL)))
|
||||
if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL)))
|
||||
return NULL;
|
||||
memset(joydev, 0, sizeof(struct joydev));
|
||||
|
||||
INIT_LIST_HEAD(&joydev->list);
|
||||
init_waitqueue_head(&joydev->wait);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/amigahw.h>
|
||||
@ -52,7 +53,7 @@ MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is
|
||||
__obsolete_setup("amijoy=");
|
||||
|
||||
static int amijoy_used;
|
||||
static DECLARE_MUTEX(amijoy_sem);
|
||||
static DEFINE_MUTEX(amijoy_mutex);
|
||||
static struct input_dev *amijoy_dev[2];
|
||||
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
|
||||
|
||||
@ -85,7 +86,7 @@ static int amijoy_open(struct input_dev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = down_interruptible(&amijoy_sem);
|
||||
err = mutex_lock_interruptible(&amijoy_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -97,16 +98,16 @@ static int amijoy_open(struct input_dev *dev)
|
||||
|
||||
amijoy_used++;
|
||||
out:
|
||||
up(&amijoy_sem);
|
||||
mutex_unlock(&amijoy_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void amijoy_close(struct input_dev *dev)
|
||||
{
|
||||
down(&amijoy_sem);
|
||||
mutex_lock(&amijoy_mutex);
|
||||
if (!--amijoy_used)
|
||||
free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
|
||||
up(&amijoy_sem);
|
||||
mutex_unlock(&amijoy_mutex);
|
||||
}
|
||||
|
||||
static int __init amijoy_init(void)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/parport.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
||||
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
|
||||
@ -111,7 +112,7 @@ struct db9 {
|
||||
struct pardevice *pd;
|
||||
int mode;
|
||||
int used;
|
||||
struct semaphore sem;
|
||||
struct mutex mutex;
|
||||
char phys[DB9_MAX_DEVICES][32];
|
||||
};
|
||||
|
||||
@ -525,7 +526,7 @@ static int db9_open(struct input_dev *dev)
|
||||
struct parport *port = db9->pd->port;
|
||||
int err;
|
||||
|
||||
err = down_interruptible(&db9->sem);
|
||||
err = mutex_lock_interruptible(&db9->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -539,7 +540,7 @@ static int db9_open(struct input_dev *dev)
|
||||
mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
|
||||
}
|
||||
|
||||
up(&db9->sem);
|
||||
mutex_unlock(&db9->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -548,14 +549,14 @@ static void db9_close(struct input_dev *dev)
|
||||
struct db9 *db9 = dev->private;
|
||||
struct parport *port = db9->pd->port;
|
||||
|
||||
down(&db9->sem);
|
||||
mutex_lock(&db9->mutex);
|
||||
if (!--db9->used) {
|
||||
del_timer_sync(&db9->timer);
|
||||
parport_write_control(port, 0x00);
|
||||
parport_data_forward(port);
|
||||
parport_release(db9->pd);
|
||||
}
|
||||
up(&db9->sem);
|
||||
mutex_unlock(&db9->mutex);
|
||||
}
|
||||
|
||||
static struct db9 __init *db9_probe(int parport, int mode)
|
||||
@ -603,7 +604,7 @@ static struct db9 __init *db9_probe(int parport, int mode)
|
||||
goto err_unreg_pardev;
|
||||
}
|
||||
|
||||
init_MUTEX(&db9->sem);
|
||||
mutex_init(&db9->mutex);
|
||||
db9->pd = pd;
|
||||
db9->mode = mode;
|
||||
init_timer(&db9->timer);
|
||||
|
@ -7,6 +7,7 @@
|
||||
* Based on the work of:
|
||||
* Andree Borrmann John Dahlstrom
|
||||
* David Kuder Nathan Hand
|
||||
* Raphael Assenat
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -36,6 +37,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/parport.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
||||
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
|
||||
@ -72,8 +74,9 @@ __obsolete_setup("gc_3=");
|
||||
#define GC_N64 6
|
||||
#define GC_PSX 7
|
||||
#define GC_DDR 8
|
||||
#define GC_SNESMOUSE 9
|
||||
|
||||
#define GC_MAX 8
|
||||
#define GC_MAX 9
|
||||
|
||||
#define GC_REFRESH_TIME HZ/100
|
||||
|
||||
@ -83,7 +86,7 @@ struct gc {
|
||||
struct timer_list timer;
|
||||
unsigned char pads[GC_MAX + 1];
|
||||
int used;
|
||||
struct semaphore sem;
|
||||
struct mutex mutex;
|
||||
char phys[GC_MAX_DEVICES][32];
|
||||
};
|
||||
|
||||
@ -93,7 +96,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
|
||||
|
||||
static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
|
||||
"Multisystem 2-button joystick", "N64 controller", "PSX controller",
|
||||
"PSX DDR controller" };
|
||||
"PSX DDR controller", "SNES mouse" };
|
||||
/*
|
||||
* N64 support.
|
||||
*/
|
||||
@ -207,7 +210,10 @@ static void gc_n64_process_packet(struct gc *gc)
|
||||
|
||||
#define GC_NES_DELAY 6 /* Delay between bits - 6us */
|
||||
#define GC_NES_LENGTH 8 /* The NES pads use 8 bits of data */
|
||||
#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the last 4 bits are unused */
|
||||
#define GC_SNES_LENGTH 12 /* The SNES true length is 16, but the
|
||||
last 4 bits are unused */
|
||||
#define GC_SNESMOUSE_LENGTH 32 /* The SNES mouse uses 32 bits, the first
|
||||
16 bits are equivalent to a gamepad */
|
||||
|
||||
#define GC_NES_POWER 0xfc
|
||||
#define GC_NES_CLOCK 0x01
|
||||
@ -242,11 +248,15 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
|
||||
|
||||
static void gc_nes_process_packet(struct gc *gc)
|
||||
{
|
||||
unsigned char data[GC_SNES_LENGTH];
|
||||
unsigned char data[GC_SNESMOUSE_LENGTH];
|
||||
struct input_dev *dev;
|
||||
int i, j, s;
|
||||
int i, j, s, len;
|
||||
char x_rel, y_rel;
|
||||
|
||||
gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data);
|
||||
len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH :
|
||||
(gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH);
|
||||
|
||||
gc_nes_read_packet(gc, len, data);
|
||||
|
||||
for (i = 0; i < GC_MAX_DEVICES; i++) {
|
||||
|
||||
@ -269,6 +279,44 @@ static void gc_nes_process_packet(struct gc *gc)
|
||||
for (j = 0; j < 8; j++)
|
||||
input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
|
||||
|
||||
if (s & gc->pads[GC_SNESMOUSE]) {
|
||||
/*
|
||||
* The 4 unused bits from SNES controllers appear to be ID bits
|
||||
* so use them to make sure iwe are dealing with a mouse.
|
||||
* gamepad is connected. This is important since
|
||||
* my SNES gamepad sends 1's for bits 16-31, which
|
||||
* cause the mouse pointer to quickly move to the
|
||||
* upper left corner of the screen.
|
||||
*/
|
||||
if (!(s & data[12]) && !(s & data[13]) &&
|
||||
!(s & data[14]) && (s & data[15])) {
|
||||
input_report_key(dev, BTN_LEFT, s & data[9]);
|
||||
input_report_key(dev, BTN_RIGHT, s & data[8]);
|
||||
|
||||
x_rel = y_rel = 0;
|
||||
for (j = 0; j < 7; j++) {
|
||||
x_rel <<= 1;
|
||||
if (data[25 + j] & s)
|
||||
x_rel |= 1;
|
||||
|
||||
y_rel <<= 1;
|
||||
if (data[17 + j] & s)
|
||||
y_rel |= 1;
|
||||
}
|
||||
|
||||
if (x_rel) {
|
||||
if (data[24] & s)
|
||||
x_rel = -x_rel;
|
||||
input_report_rel(dev, REL_X, x_rel);
|
||||
}
|
||||
|
||||
if (y_rel) {
|
||||
if (data[16] & s)
|
||||
y_rel = -y_rel;
|
||||
input_report_rel(dev, REL_Y, y_rel);
|
||||
}
|
||||
}
|
||||
}
|
||||
input_sync(dev);
|
||||
}
|
||||
}
|
||||
@ -524,10 +572,10 @@ static void gc_timer(unsigned long private)
|
||||
gc_n64_process_packet(gc);
|
||||
|
||||
/*
|
||||
* NES and SNES pads
|
||||
* NES and SNES pads or mouse
|
||||
*/
|
||||
|
||||
if (gc->pads[GC_NES] || gc->pads[GC_SNES])
|
||||
if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE])
|
||||
gc_nes_process_packet(gc);
|
||||
|
||||
/*
|
||||
@ -552,7 +600,7 @@ static int gc_open(struct input_dev *dev)
|
||||
struct gc *gc = dev->private;
|
||||
int err;
|
||||
|
||||
err = down_interruptible(&gc->sem);
|
||||
err = mutex_lock_interruptible(&gc->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -562,7 +610,7 @@ static int gc_open(struct input_dev *dev)
|
||||
mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
|
||||
}
|
||||
|
||||
up(&gc->sem);
|
||||
mutex_unlock(&gc->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -570,13 +618,13 @@ static void gc_close(struct input_dev *dev)
|
||||
{
|
||||
struct gc *gc = dev->private;
|
||||
|
||||
down(&gc->sem);
|
||||
mutex_lock(&gc->mutex);
|
||||
if (!--gc->used) {
|
||||
del_timer_sync(&gc->timer);
|
||||
parport_write_control(gc->pd->port, 0x00);
|
||||
parport_release(gc->pd);
|
||||
}
|
||||
up(&gc->sem);
|
||||
mutex_unlock(&gc->mutex);
|
||||
}
|
||||
|
||||
static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
|
||||
@ -609,10 +657,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
|
||||
input_dev->open = gc_open;
|
||||
input_dev->close = gc_close;
|
||||
|
||||
if (pad_type != GC_SNESMOUSE) {
|
||||
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
|
||||
} else
|
||||
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
|
||||
|
||||
gc->pads[0] |= gc_status_bit[idx];
|
||||
gc->pads[pad_type] |= gc_status_bit[idx];
|
||||
@ -630,6 +681,13 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
|
||||
|
||||
break;
|
||||
|
||||
case GC_SNESMOUSE:
|
||||
set_bit(BTN_LEFT, input_dev->keybit);
|
||||
set_bit(BTN_RIGHT, input_dev->keybit);
|
||||
set_bit(REL_X, input_dev->relbit);
|
||||
set_bit(REL_Y, input_dev->relbit);
|
||||
break;
|
||||
|
||||
case GC_SNES:
|
||||
for (i = 4; i < 8; i++)
|
||||
set_bit(gc_snes_btn[i], input_dev->keybit);
|
||||
@ -693,7 +751,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
|
||||
goto err_unreg_pardev;
|
||||
}
|
||||
|
||||
init_MUTEX(&gc->sem);
|
||||
mutex_init(&gc->mutex);
|
||||
gc->pd = pd;
|
||||
init_timer(&gc->timer);
|
||||
gc->timer.data = (long) gc;
|
||||
|
@ -42,14 +42,14 @@ static int make_magnitude_modifier(struct iforce* iforce,
|
||||
unsigned char data[3];
|
||||
|
||||
if (!no_alloc) {
|
||||
down(&iforce->mem_mutex);
|
||||
mutex_lock(&iforce->mem_mutex);
|
||||
if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
|
||||
iforce->device_memory.start, iforce->device_memory.end, 2L,
|
||||
NULL, NULL)) {
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
}
|
||||
|
||||
data[0] = LO(mod_chunk->start);
|
||||
@ -75,14 +75,14 @@ static int make_period_modifier(struct iforce* iforce,
|
||||
period = TIME_SCALE(period);
|
||||
|
||||
if (!no_alloc) {
|
||||
down(&iforce->mem_mutex);
|
||||
mutex_lock(&iforce->mem_mutex);
|
||||
if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
|
||||
iforce->device_memory.start, iforce->device_memory.end, 2L,
|
||||
NULL, NULL)) {
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
}
|
||||
|
||||
data[0] = LO(mod_chunk->start);
|
||||
@ -115,14 +115,14 @@ static int make_envelope_modifier(struct iforce* iforce,
|
||||
fade_duration = TIME_SCALE(fade_duration);
|
||||
|
||||
if (!no_alloc) {
|
||||
down(&iforce->mem_mutex);
|
||||
mutex_lock(&iforce->mem_mutex);
|
||||
if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
|
||||
iforce->device_memory.start, iforce->device_memory.end, 2L,
|
||||
NULL, NULL)) {
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
}
|
||||
|
||||
data[0] = LO(mod_chunk->start);
|
||||
@ -152,14 +152,14 @@ static int make_condition_modifier(struct iforce* iforce,
|
||||
unsigned char data[10];
|
||||
|
||||
if (!no_alloc) {
|
||||
down(&iforce->mem_mutex);
|
||||
mutex_lock(&iforce->mem_mutex);
|
||||
if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
|
||||
iforce->device_memory.start, iforce->device_memory.end, 2L,
|
||||
NULL, NULL)) {
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
up(&iforce->mem_mutex);
|
||||
mutex_unlock(&iforce->mem_mutex);
|
||||
}
|
||||
|
||||
data[0] = LO(mod_chunk->start);
|
||||
|
@ -350,7 +350,7 @@ int iforce_init_device(struct iforce *iforce)
|
||||
|
||||
init_waitqueue_head(&iforce->wait);
|
||||
spin_lock_init(&iforce->xmit_lock);
|
||||
init_MUTEX(&iforce->mem_mutex);
|
||||
mutex_init(&iforce->mem_mutex);
|
||||
iforce->xmit.buf = iforce->xmit_data;
|
||||
iforce->dev = input_dev;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <linux/serio.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
/* This module provides arbitrary resource management routines.
|
||||
* I use it to manage the device's memory.
|
||||
@ -45,6 +45,7 @@
|
||||
*/
|
||||
#include <linux/ioport.h>
|
||||
|
||||
|
||||
#define IFORCE_MAX_LENGTH 16
|
||||
|
||||
/* iforce::bus */
|
||||
@ -146,7 +147,7 @@ struct iforce {
|
||||
wait_queue_head_t wait;
|
||||
struct resource device_memory;
|
||||
struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
|
||||
struct semaphore mem_mutex;
|
||||
struct mutex mem_mutex;
|
||||
};
|
||||
|
||||
/* Get hi and low bytes of a 16-bits int */
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
||||
MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
|
||||
@ -86,7 +87,7 @@ static struct tgfx {
|
||||
char phys[TGFX_MAX_DEVICES][32];
|
||||
int sticks;
|
||||
int used;
|
||||
struct semaphore sem;
|
||||
struct mutex sem;
|
||||
} *tgfx_base[TGFX_MAX_PORTS];
|
||||
|
||||
/*
|
||||
@ -128,7 +129,7 @@ static int tgfx_open(struct input_dev *dev)
|
||||
struct tgfx *tgfx = dev->private;
|
||||
int err;
|
||||
|
||||
err = down_interruptible(&tgfx->sem);
|
||||
err = mutex_lock_interruptible(&tgfx->sem);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -138,7 +139,7 @@ static int tgfx_open(struct input_dev *dev)
|
||||
mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
|
||||
}
|
||||
|
||||
up(&tgfx->sem);
|
||||
mutex_unlock(&tgfx->sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -146,13 +147,13 @@ static void tgfx_close(struct input_dev *dev)
|
||||
{
|
||||
struct tgfx *tgfx = dev->private;
|
||||
|
||||
down(&tgfx->sem);
|
||||
mutex_lock(&tgfx->sem);
|
||||
if (!--tgfx->used) {
|
||||
del_timer_sync(&tgfx->timer);
|
||||
parport_write_control(tgfx->pd->port, 0x00);
|
||||
parport_release(tgfx->pd);
|
||||
}
|
||||
up(&tgfx->sem);
|
||||
mutex_unlock(&tgfx->sem);
|
||||
}
|
||||
|
||||
|
||||
@ -191,7 +192,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
|
||||
goto err_unreg_pardev;
|
||||
}
|
||||
|
||||
init_MUTEX(&tgfx->sem);
|
||||
mutex_init(&tgfx->sem);
|
||||
tgfx->pd = pd;
|
||||
init_timer(&tgfx->timer);
|
||||
tgfx->timer.data = (long) tgfx;
|
||||
|
@ -13,7 +13,7 @@ menuconfig INPUT_KEYBOARD
|
||||
if INPUT_KEYBOARD
|
||||
|
||||
config KEYBOARD_ATKBD
|
||||
tristate "AT keyboard" if !X86_PC
|
||||
tristate "AT keyboard" if EMBEDDED || !X86_PC
|
||||
default y
|
||||
select SERIO
|
||||
select SERIO_LIBPS2
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/serio.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/libps2.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define DRIVER_DESC "AT and PS/2 keyboard driver"
|
||||
|
||||
@ -216,7 +217,7 @@ struct atkbd {
|
||||
unsigned long time;
|
||||
|
||||
struct work_struct event_work;
|
||||
struct semaphore event_sem;
|
||||
struct mutex event_mutex;
|
||||
unsigned long event_mask;
|
||||
};
|
||||
|
||||
@ -302,19 +303,19 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
|
||||
if (atkbd->translated) {
|
||||
|
||||
if (atkbd->emul ||
|
||||
!(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
|
||||
code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA ||
|
||||
(code == ATKBD_RET_ERR && !atkbd->err_xl) ||
|
||||
(code == ATKBD_RET_BAT && !atkbd->bat_xl))) {
|
||||
(code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 &&
|
||||
code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA &&
|
||||
(code != ATKBD_RET_ERR || atkbd->err_xl) &&
|
||||
(code != ATKBD_RET_BAT || atkbd->bat_xl))) {
|
||||
atkbd->release = code >> 7;
|
||||
code &= 0x7f;
|
||||
}
|
||||
|
||||
if (!atkbd->emul) {
|
||||
if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
|
||||
atkbd->bat_xl = !atkbd->release;
|
||||
atkbd->bat_xl = !(data >> 7);
|
||||
if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f))
|
||||
atkbd->err_xl = !atkbd->release;
|
||||
atkbd->err_xl = !(data >> 7);
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,7 +450,7 @@ static void atkbd_event_work(void *data)
|
||||
unsigned char param[2];
|
||||
int i, j;
|
||||
|
||||
down(&atkbd->event_sem);
|
||||
mutex_lock(&atkbd->event_mutex);
|
||||
|
||||
if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) {
|
||||
param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
|
||||
@ -480,7 +481,7 @@ static void atkbd_event_work(void *data)
|
||||
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
|
||||
}
|
||||
|
||||
up(&atkbd->event_sem);
|
||||
mutex_unlock(&atkbd->event_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -846,7 +847,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
|
||||
atkbd->dev = dev;
|
||||
ps2_init(&atkbd->ps2dev, serio);
|
||||
INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
|
||||
init_MUTEX(&atkbd->event_sem);
|
||||
mutex_init(&atkbd->event_mutex);
|
||||
|
||||
switch (serio->id.type) {
|
||||
|
||||
@ -862,9 +863,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
|
||||
atkbd->softrepeat = atkbd_softrepeat;
|
||||
atkbd->scroll = atkbd_scroll;
|
||||
|
||||
if (!atkbd->write)
|
||||
atkbd->softrepeat = 1;
|
||||
|
||||
if (atkbd->softrepeat)
|
||||
atkbd->softraw = 1;
|
||||
|
||||
|
@ -29,11 +29,11 @@
|
||||
#define KB_COLS 12
|
||||
#define KB_ROWMASK(r) (1 << (r))
|
||||
#define SCANCODE(r,c) ( ((r)<<4) + (c) + 1 )
|
||||
/* zero code, 124 scancodes + 3 hinge combinations */
|
||||
#define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 +3 )
|
||||
#define SCAN_INTERVAL (HZ/10)
|
||||
/* zero code, 124 scancodes */
|
||||
#define NR_SCANCODES ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 )
|
||||
|
||||
#define HINGE_SCAN_INTERVAL (HZ/4)
|
||||
#define SCAN_INTERVAL (50) /* ms */
|
||||
#define HINGE_SCAN_INTERVAL (250) /* ms */
|
||||
|
||||
#define CORGI_KEY_CALENDER KEY_F1
|
||||
#define CORGI_KEY_ADDRESS KEY_F2
|
||||
@ -49,9 +49,6 @@
|
||||
#define CORGI_KEY_MAIL KEY_F10
|
||||
#define CORGI_KEY_OK KEY_F11
|
||||
#define CORGI_KEY_MENU KEY_F12
|
||||
#define CORGI_HINGE_0 KEY_KP0
|
||||
#define CORGI_HINGE_1 KEY_KP1
|
||||
#define CORGI_HINGE_2 KEY_KP2
|
||||
|
||||
static unsigned char corgikbd_keycode[NR_SCANCODES] = {
|
||||
0, /* 0 */
|
||||
@ -63,7 +60,6 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = {
|
||||
CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0, /* 81-96 */
|
||||
KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0, /* 97-112 */
|
||||
CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0, /* 113-124 */
|
||||
CORGI_HINGE_0, CORGI_HINGE_1, CORGI_HINGE_2 /* 125-127 */
|
||||
};
|
||||
|
||||
|
||||
@ -187,7 +183,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
|
||||
|
||||
/* if any keys are pressed, enable the timer */
|
||||
if (num_pressed)
|
||||
mod_timer(&corgikbd_data->timer, jiffies + SCAN_INTERVAL);
|
||||
mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));
|
||||
|
||||
spin_unlock_irqrestore(&corgikbd_data->lock, flags);
|
||||
}
|
||||
@ -228,6 +224,7 @@ static void corgikbd_timer_callback(unsigned long data)
|
||||
* 0x0c - Keyboard and Screen Closed
|
||||
*/
|
||||
|
||||
#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
|
||||
#define HINGE_STABLE_COUNT 2
|
||||
static int sharpsl_hinge_state;
|
||||
static int hinge_count;
|
||||
@ -239,6 +236,7 @@ static void corgikbd_hinge_timer(unsigned long data)
|
||||
unsigned long flags;
|
||||
|
||||
gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB);
|
||||
gprr |= (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0);
|
||||
if (gprr != sharpsl_hinge_state) {
|
||||
hinge_count = 0;
|
||||
sharpsl_hinge_state = gprr;
|
||||
@ -249,27 +247,38 @@ static void corgikbd_hinge_timer(unsigned long data)
|
||||
|
||||
input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
|
||||
input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
|
||||
input_report_switch(corgikbd_data->input, SW_2, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0));
|
||||
input_sync(corgikbd_data->input);
|
||||
|
||||
spin_unlock_irqrestore(&corgikbd_data->lock, flags);
|
||||
}
|
||||
}
|
||||
mod_timer(&corgikbd_data->htimer, jiffies + HINGE_SCAN_INTERVAL);
|
||||
mod_timer(&corgikbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int corgikbd_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
int i;
|
||||
struct corgikbd *corgikbd = platform_get_drvdata(dev);
|
||||
|
||||
corgikbd->suspended = 1;
|
||||
/* strobe 0 is the power key so this can't be made an input for
|
||||
powersaving therefore i = 1 */
|
||||
for (i = 1; i < CORGI_KEY_STROBE_NUM; i++)
|
||||
pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_IN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgikbd_resume(struct platform_device *dev)
|
||||
{
|
||||
int i;
|
||||
struct corgikbd *corgikbd = platform_get_drvdata(dev);
|
||||
|
||||
for (i = 1; i < CORGI_KEY_STROBE_NUM; i++)
|
||||
pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
|
||||
|
||||
/* Upon resume, ignore the suspend key for a short while */
|
||||
corgikbd->suspend_jiffies=jiffies;
|
||||
corgikbd->suspended = 0;
|
||||
@ -333,10 +342,11 @@ static int __init corgikbd_probe(struct platform_device *pdev)
|
||||
clear_bit(0, input_dev->keybit);
|
||||
set_bit(SW_0, input_dev->swbit);
|
||||
set_bit(SW_1, input_dev->swbit);
|
||||
set_bit(SW_2, input_dev->swbit);
|
||||
|
||||
input_register_device(corgikbd->input);
|
||||
|
||||
mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
|
||||
mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
|
||||
|
||||
/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
|
||||
for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) {
|
||||
@ -351,6 +361,9 @@ static int __init corgikbd_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
|
||||
pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
|
||||
|
||||
/* Setup the headphone jack as an input */
|
||||
pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -256,10 +256,13 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
|
||||
return -ENOMEM;
|
||||
|
||||
kbd->dev = input_allocate_device();
|
||||
if (!kbd->dev) goto bail1;
|
||||
if (!kbd->dev)
|
||||
goto bail0;
|
||||
|
||||
kbd->dev->private = kbd;
|
||||
|
||||
if (serio_open(serio, drv)) goto bail0;
|
||||
if (serio_open(serio, drv))
|
||||
goto bail1;
|
||||
|
||||
serio_set_drvdata(serio, kbd);
|
||||
kbd->serio = serio;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define SCANCODE(r,c) (((r)<<4) + (c) + 1)
|
||||
#define NR_SCANCODES ((KB_ROWS<<4) + 1)
|
||||
|
||||
#define SCAN_INTERVAL (50) /* ms */
|
||||
#define HINGE_SCAN_INTERVAL (150) /* ms */
|
||||
|
||||
#define SPITZ_KEY_CALENDER KEY_F1
|
||||
@ -230,7 +231,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
|
||||
|
||||
/* if any keys are pressed, enable the timer */
|
||||
if (num_pressed)
|
||||
mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(100));
|
||||
mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));
|
||||
|
||||
spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
|
||||
}
|
||||
@ -287,6 +288,7 @@ static void spitzkbd_hinge_timer(unsigned long data)
|
||||
unsigned long flags;
|
||||
|
||||
state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB));
|
||||
state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT));
|
||||
if (state != sharpsl_hinge_state) {
|
||||
hinge_count = 0;
|
||||
sharpsl_hinge_state = state;
|
||||
@ -299,6 +301,7 @@ static void spitzkbd_hinge_timer(unsigned long data)
|
||||
|
||||
input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
|
||||
input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
|
||||
input_report_switch(spitzkbd_data->input, SW_2, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0));
|
||||
input_sync(spitzkbd_data->input);
|
||||
|
||||
spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
|
||||
@ -397,6 +400,7 @@ static int __init spitzkbd_probe(struct platform_device *dev)
|
||||
clear_bit(0, input_dev->keybit);
|
||||
set_bit(SW_0, input_dev->swbit);
|
||||
set_bit(SW_1, input_dev->swbit);
|
||||
set_bit(SW_2, input_dev->swbit);
|
||||
|
||||
input_register_device(input_dev);
|
||||
|
||||
@ -432,6 +436,9 @@ static int __init spitzkbd_probe(struct platform_device *dev)
|
||||
request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr,
|
||||
SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
|
||||
"Spitzkbd SWB", spitzkbd);
|
||||
request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr,
|
||||
SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
|
||||
"Spitzkbd HP", spitzkbd);
|
||||
|
||||
printk(KERN_INFO "input: Spitz Keyboard Registered\n");
|
||||
|
||||
@ -450,6 +457,7 @@ static int spitzkbd_remove(struct platform_device *dev)
|
||||
free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd);
|
||||
free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd);
|
||||
free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd);
|
||||
free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd);
|
||||
|
||||
del_timer_sync(&spitzkbd->htimer);
|
||||
del_timer_sync(&spitzkbd->timer);
|
||||
|
@ -24,7 +24,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
||||
MODULE_DESCRIPTION("PC Speaker beeper driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct platform_device *pcspkr_platform_device;
|
||||
static DEFINE_SPINLOCK(i8253_beep_lock);
|
||||
|
||||
static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
|
||||
@ -135,35 +134,11 @@ static struct platform_driver pcspkr_platform_driver = {
|
||||
|
||||
static int __init pcspkr_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = platform_driver_register(&pcspkr_platform_driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pcspkr_platform_device = platform_device_alloc("pcspkr", -1);
|
||||
if (!pcspkr_platform_device) {
|
||||
err = -ENOMEM;
|
||||
goto err_unregister_driver;
|
||||
}
|
||||
|
||||
err = platform_device_add(pcspkr_platform_device);
|
||||
if (err)
|
||||
goto err_free_device;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_device:
|
||||
platform_device_put(pcspkr_platform_device);
|
||||
err_unregister_driver:
|
||||
platform_driver_unregister(&pcspkr_platform_driver);
|
||||
|
||||
return err;
|
||||
return platform_driver_register(&pcspkr_platform_driver);
|
||||
}
|
||||
|
||||
static void __exit pcspkr_exit(void)
|
||||
{
|
||||
platform_device_unregister(pcspkr_platform_device);
|
||||
platform_driver_unregister(&pcspkr_platform_driver);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ static int uinput_open(struct inode *inode, struct file *file)
|
||||
if (!newdev)
|
||||
return -ENOMEM;
|
||||
|
||||
init_MUTEX(&newdev->sem);
|
||||
mutex_init(&newdev->mutex);
|
||||
spin_lock_init(&newdev->requests_lock);
|
||||
init_waitqueue_head(&newdev->requests_waitq);
|
||||
init_waitqueue_head(&newdev->waitq);
|
||||
@ -340,7 +340,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t
|
||||
struct uinput_device *udev = file->private_data;
|
||||
int retval;
|
||||
|
||||
retval = down_interruptible(&udev->sem);
|
||||
retval = mutex_lock_interruptible(&udev->mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -348,7 +348,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t
|
||||
uinput_inject_event(udev, buffer, count) :
|
||||
uinput_setup_device(udev, buffer, count);
|
||||
|
||||
up(&udev->sem);
|
||||
mutex_unlock(&udev->mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -369,7 +369,7 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count,
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = down_interruptible(&udev->sem);
|
||||
retval = mutex_lock_interruptible(&udev->mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -388,7 +388,7 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count,
|
||||
}
|
||||
|
||||
out:
|
||||
up(&udev->sem);
|
||||
mutex_unlock(&udev->mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -439,7 +439,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
|
||||
udev = file->private_data;
|
||||
|
||||
retval = down_interruptible(&udev->sem);
|
||||
retval = mutex_lock_interruptible(&udev->mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -589,7 +589,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
|
||||
out:
|
||||
up(&udev->sem);
|
||||
mutex_unlock(&udev->mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -249,10 +249,13 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
|
||||
return -ENOMEM;
|
||||
|
||||
ptr->dev = input_allocate_device();
|
||||
if (!ptr->dev) goto bail0;
|
||||
if (!ptr->dev)
|
||||
goto bail0;
|
||||
|
||||
ptr->dev->private = ptr;
|
||||
|
||||
if (serio_open(serio, driver)) goto bail1;
|
||||
if (serio_open(serio, driver))
|
||||
goto bail1;
|
||||
|
||||
serio_set_drvdata(serio, ptr);
|
||||
ptr->serio = serio;
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/libps2.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include "psmouse.h"
|
||||
#include "synaptics.h"
|
||||
#include "logips2pp.h"
|
||||
@ -98,13 +100,13 @@ __obsolete_setup("psmouse_resetafter=");
|
||||
__obsolete_setup("psmouse_rate=");
|
||||
|
||||
/*
|
||||
* psmouse_sem protects all operations changing state of mouse
|
||||
* psmouse_mutex protects all operations changing state of mouse
|
||||
* (connecting, disconnecting, changing rate or resolution via
|
||||
* sysfs). We could use a per-device semaphore but since there
|
||||
* rarely more than one PS/2 mouse connected and since semaphore
|
||||
* is taken in "slow" paths it is not worth it.
|
||||
*/
|
||||
static DECLARE_MUTEX(psmouse_sem);
|
||||
static DEFINE_MUTEX(psmouse_mutex);
|
||||
|
||||
static struct workqueue_struct *kpsmoused_wq;
|
||||
|
||||
@ -868,7 +870,7 @@ static void psmouse_resync(void *p)
|
||||
int failed = 0, enabled = 0;
|
||||
int i;
|
||||
|
||||
down(&psmouse_sem);
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
if (psmouse->state != PSMOUSE_RESYNCING)
|
||||
goto out;
|
||||
@ -948,7 +950,7 @@ static void psmouse_resync(void *p)
|
||||
if (parent)
|
||||
psmouse_activate(parent);
|
||||
out:
|
||||
up(&psmouse_sem);
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -974,14 +976,14 @@ static void psmouse_disconnect(struct serio *serio)
|
||||
|
||||
sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group);
|
||||
|
||||
down(&psmouse_sem);
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
|
||||
/* make sure we don't have a resync in progress */
|
||||
up(&psmouse_sem);
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
flush_workqueue(kpsmoused_wq);
|
||||
down(&psmouse_sem);
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
|
||||
parent = serio_get_drvdata(serio->parent);
|
||||
@ -1004,7 +1006,7 @@ static void psmouse_disconnect(struct serio *serio)
|
||||
if (parent)
|
||||
psmouse_activate(parent);
|
||||
|
||||
up(&psmouse_sem);
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
}
|
||||
|
||||
static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
|
||||
@ -1076,7 +1078,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
|
||||
struct input_dev *input_dev;
|
||||
int retval = -ENOMEM;
|
||||
|
||||
down(&psmouse_sem);
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
/*
|
||||
* If this is a pass-through port deactivate parent so the device
|
||||
@ -1144,7 +1146,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
|
||||
if (parent)
|
||||
psmouse_activate(parent);
|
||||
|
||||
up(&psmouse_sem);
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -1161,7 +1163,7 @@ static int psmouse_reconnect(struct serio *serio)
|
||||
return -1;
|
||||
}
|
||||
|
||||
down(&psmouse_sem);
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
|
||||
parent = serio_get_drvdata(serio->parent);
|
||||
@ -1195,7 +1197,7 @@ static int psmouse_reconnect(struct serio *serio)
|
||||
if (parent)
|
||||
psmouse_activate(parent);
|
||||
|
||||
up(&psmouse_sem);
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1273,7 +1275,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
retval = down_interruptible(&psmouse_sem);
|
||||
retval = mutex_lock_interruptible(&psmouse_mutex);
|
||||
if (retval)
|
||||
goto out_unpin;
|
||||
|
||||
@ -1281,7 +1283,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
|
||||
|
||||
if (psmouse->state == PSMOUSE_IGNORE) {
|
||||
retval = -ENODEV;
|
||||
goto out_up;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
|
||||
@ -1299,8 +1301,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
|
||||
if (parent)
|
||||
psmouse_activate(parent);
|
||||
|
||||
out_up:
|
||||
up(&psmouse_sem);
|
||||
out_unlock:
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
out_unpin:
|
||||
serio_unpin_driver(serio);
|
||||
return retval;
|
||||
@ -1357,11 +1359,11 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
up(&psmouse_sem);
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
serio_unpin_driver(serio);
|
||||
serio_unregister_child_port(serio);
|
||||
serio_pin_driver_uninterruptible(serio);
|
||||
down(&psmouse_sem);
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
if (serio->drv != &psmouse_drv) {
|
||||
input_free_device(new_dev);
|
||||
|
@ -247,14 +247,12 @@ static void synaptics_pt_create(struct psmouse *psmouse)
|
||||
{
|
||||
struct serio *serio;
|
||||
|
||||
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
if (!serio) {
|
||||
printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(serio, 0, sizeof(struct serio));
|
||||
|
||||
serio->id.type = SERIO_PS_PSTHRU;
|
||||
strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
|
||||
strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
|
||||
@ -615,6 +613,13 @@ static struct dmi_system_id toshiba_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Toshiba Portege M300",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
@ -623,10 +628,9 @@ int synaptics_init(struct psmouse *psmouse)
|
||||
{
|
||||
struct synaptics_data *priv;
|
||||
|
||||
psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
|
||||
psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -1;
|
||||
memset(priv, 0, sizeof(struct synaptics_data));
|
||||
|
||||
if (synaptics_query_hardware(psmouse)) {
|
||||
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
|
||||
|
@ -412,9 +412,8 @@ static int mousedev_open(struct inode * inode, struct file * file)
|
||||
if (i >= MOUSEDEV_MINORS || !mousedev_table[i])
|
||||
return -ENODEV;
|
||||
|
||||
if (!(list = kmalloc(sizeof(struct mousedev_list), GFP_KERNEL)))
|
||||
if (!(list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
memset(list, 0, sizeof(struct mousedev_list));
|
||||
|
||||
spin_lock_init(&list->packet_lock);
|
||||
list->pos_x = xres / 2;
|
||||
@ -626,9 +625,8 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mousedev = kmalloc(sizeof(struct mousedev), GFP_KERNEL)))
|
||||
if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL)))
|
||||
return NULL;
|
||||
memset(mousedev, 0, sizeof(struct mousedev));
|
||||
|
||||
INIT_LIST_HEAD(&mousedev->list);
|
||||
init_waitqueue_head(&mousedev->wait);
|
||||
|
@ -103,9 +103,8 @@ static struct input_handle *power_connect(struct input_handler *handler,
|
||||
{
|
||||
struct input_handle *handle;
|
||||
|
||||
if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
|
||||
if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL)))
|
||||
return NULL;
|
||||
memset(handle, 0, sizeof(struct input_handle));
|
||||
|
||||
handle->dev = dev;
|
||||
handle->handler = handler;
|
||||
|
@ -872,9 +872,8 @@ int hil_mlc_register(hil_mlc *mlc) {
|
||||
for (i = 0; i < HIL_MLC_DEVMEM; i++) {
|
||||
struct serio *mlc_serio;
|
||||
hil_mlc_copy_di_scratch(mlc, i);
|
||||
mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL);
|
||||
mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL);
|
||||
mlc->serio[i] = mlc_serio;
|
||||
memset(mlc_serio, 0, sizeof(*mlc_serio));
|
||||
mlc_serio->id = hil_mlc_serio_id;
|
||||
mlc_serio->write = hil_mlc_serio_write;
|
||||
mlc_serio->open = hil_mlc_serio_open;
|
||||
|
@ -192,7 +192,9 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
|
||||
#include <linux/pnp.h>
|
||||
|
||||
static int i8042_pnp_kbd_registered;
|
||||
static unsigned int i8042_pnp_kbd_devices;
|
||||
static int i8042_pnp_aux_registered;
|
||||
static unsigned int i8042_pnp_aux_devices;
|
||||
|
||||
static int i8042_pnp_command_reg;
|
||||
static int i8042_pnp_data_reg;
|
||||
@ -219,6 +221,7 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
|
||||
strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
|
||||
}
|
||||
|
||||
i8042_pnp_kbd_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -239,6 +242,7 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *
|
||||
strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
|
||||
}
|
||||
|
||||
i8042_pnp_aux_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -287,21 +291,23 @@ static void i8042_pnp_exit(void)
|
||||
|
||||
static int __init i8042_pnp_init(void)
|
||||
{
|
||||
int result_kbd = 0, result_aux = 0;
|
||||
char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
|
||||
int err;
|
||||
|
||||
if (i8042_nopnp) {
|
||||
printk(KERN_INFO "i8042: PNP detection disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((result_kbd = pnp_register_driver(&i8042_pnp_kbd_driver)) >= 0)
|
||||
err = pnp_register_driver(&i8042_pnp_kbd_driver);
|
||||
if (!err)
|
||||
i8042_pnp_kbd_registered = 1;
|
||||
|
||||
if ((result_aux = pnp_register_driver(&i8042_pnp_aux_driver)) >= 0)
|
||||
err = pnp_register_driver(&i8042_pnp_aux_driver);
|
||||
if (!err)
|
||||
i8042_pnp_aux_registered = 1;
|
||||
|
||||
if (result_kbd <= 0 && result_aux <= 0) {
|
||||
if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
|
||||
i8042_pnp_exit();
|
||||
#if defined(__ia64__)
|
||||
return -ENODEV;
|
||||
@ -311,24 +317,24 @@ static int __init i8042_pnp_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (result_kbd > 0)
|
||||
if (i8042_pnp_kbd_devices)
|
||||
snprintf(kbd_irq_str, sizeof(kbd_irq_str),
|
||||
"%d", i8042_pnp_kbd_irq);
|
||||
if (result_aux > 0)
|
||||
if (i8042_pnp_aux_devices)
|
||||
snprintf(aux_irq_str, sizeof(aux_irq_str),
|
||||
"%d", i8042_pnp_aux_irq);
|
||||
|
||||
printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
|
||||
i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "",
|
||||
i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
|
||||
i8042_pnp_aux_name,
|
||||
i8042_pnp_data_reg, i8042_pnp_command_reg,
|
||||
kbd_irq_str, (result_kbd > 0 && result_aux > 0) ? "," : "",
|
||||
kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
|
||||
aux_irq_str);
|
||||
|
||||
#if defined(__ia64__)
|
||||
if (result_kbd <= 0)
|
||||
if (!i8042_pnp_kbd_devices)
|
||||
i8042_nokbd = 1;
|
||||
if (result_aux <= 0)
|
||||
if (!i8042_pnp_aux_devices)
|
||||
i8042_noaux = 1;
|
||||
#endif
|
||||
|
||||
|
@ -84,7 +84,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
|
||||
maxbytes = sizeof(ps2dev->cmdbuf);
|
||||
}
|
||||
|
||||
down(&ps2dev->cmd_sem);
|
||||
mutex_lock(&ps2dev->cmd_mutex);
|
||||
|
||||
serio_pause_rx(ps2dev->serio);
|
||||
ps2dev->flags = PS2_FLAG_CMD;
|
||||
@ -94,7 +94,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
|
||||
wait_event_timeout(ps2dev->wait,
|
||||
!(ps2dev->flags & PS2_FLAG_CMD),
|
||||
msecs_to_jiffies(timeout));
|
||||
up(&ps2dev->cmd_sem);
|
||||
mutex_unlock(&ps2dev->cmd_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -177,7 +177,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
|
||||
return -1;
|
||||
}
|
||||
|
||||
down(&ps2dev->cmd_sem);
|
||||
mutex_lock(&ps2dev->cmd_mutex);
|
||||
|
||||
serio_pause_rx(ps2dev->serio);
|
||||
ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
|
||||
@ -229,7 +229,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
|
||||
ps2dev->flags = 0;
|
||||
serio_continue_rx(ps2dev->serio);
|
||||
|
||||
up(&ps2dev->cmd_sem);
|
||||
mutex_unlock(&ps2dev->cmd_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman
|
||||
|
||||
void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
|
||||
{
|
||||
init_MUTEX(&ps2dev->cmd_sem);
|
||||
mutex_init(&ps2dev->cmd_mutex);
|
||||
init_waitqueue_head(&ps2dev->wait);
|
||||
ps2dev->serio = serio;
|
||||
}
|
||||
|
@ -171,9 +171,8 @@ static struct serio * __init parkbd_allocate_serio(void)
|
||||
{
|
||||
struct serio *serio;
|
||||
|
||||
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
if (serio) {
|
||||
memset(serio, 0, sizeof(struct serio));
|
||||
serio->id.type = parkbd_mode;
|
||||
serio->write = parkbd_write,
|
||||
strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
|
||||
|
@ -111,11 +111,10 @@ static int __devinit rpckbd_probe(struct platform_device *dev)
|
||||
{
|
||||
struct serio *serio;
|
||||
|
||||
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
if (!serio)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(serio, 0, sizeof(struct serio));
|
||||
serio->id.type = SERIO_8042;
|
||||
serio->write = rpckbd_write;
|
||||
serio->open = rpckbd_open;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
||||
MODULE_DESCRIPTION("Serio abstraction core");
|
||||
@ -52,10 +53,10 @@ EXPORT_SYMBOL(serio_rescan);
|
||||
EXPORT_SYMBOL(serio_reconnect);
|
||||
|
||||
/*
|
||||
* serio_sem protects entire serio subsystem and is taken every time
|
||||
* serio_mutex protects entire serio subsystem and is taken every time
|
||||
* serio port or driver registrered or unregistered.
|
||||
*/
|
||||
static DECLARE_MUTEX(serio_sem);
|
||||
static DEFINE_MUTEX(serio_mutex);
|
||||
|
||||
static LIST_HEAD(serio_list);
|
||||
|
||||
@ -70,9 +71,9 @@ static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
|
||||
{
|
||||
int retval;
|
||||
|
||||
down(&serio->drv_sem);
|
||||
mutex_lock(&serio->drv_mutex);
|
||||
retval = drv->connect(serio, drv);
|
||||
up(&serio->drv_sem);
|
||||
mutex_unlock(&serio->drv_mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -81,20 +82,20 @@ static int serio_reconnect_driver(struct serio *serio)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
down(&serio->drv_sem);
|
||||
mutex_lock(&serio->drv_mutex);
|
||||
if (serio->drv && serio->drv->reconnect)
|
||||
retval = serio->drv->reconnect(serio);
|
||||
up(&serio->drv_sem);
|
||||
mutex_unlock(&serio->drv_mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void serio_disconnect_driver(struct serio *serio)
|
||||
{
|
||||
down(&serio->drv_sem);
|
||||
mutex_lock(&serio->drv_mutex);
|
||||
if (serio->drv)
|
||||
serio->drv->disconnect(serio);
|
||||
up(&serio->drv_sem);
|
||||
mutex_unlock(&serio->drv_mutex);
|
||||
}
|
||||
|
||||
static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
|
||||
@ -195,6 +196,7 @@ static void serio_queue_event(void *object, struct module *owner,
|
||||
if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
|
||||
if (!try_module_get(owner)) {
|
||||
printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);
|
||||
kfree(event);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -272,7 +274,7 @@ static void serio_handle_event(void)
|
||||
struct serio_event *event;
|
||||
struct serio_driver *serio_drv;
|
||||
|
||||
down(&serio_sem);
|
||||
mutex_lock(&serio_mutex);
|
||||
|
||||
/*
|
||||
* Note that we handle only one event here to give swsusp
|
||||
@ -314,7 +316,7 @@ static void serio_handle_event(void)
|
||||
serio_free_event(event);
|
||||
}
|
||||
|
||||
up(&serio_sem);
|
||||
mutex_unlock(&serio_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -449,7 +451,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
|
||||
struct device_driver *drv;
|
||||
int retval;
|
||||
|
||||
retval = down_interruptible(&serio_sem);
|
||||
retval = mutex_lock_interruptible(&serio_mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -469,7 +471,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
|
||||
retval = -EINVAL;
|
||||
}
|
||||
|
||||
up(&serio_sem);
|
||||
mutex_unlock(&serio_mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -524,7 +526,7 @@ static void serio_init_port(struct serio *serio)
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
spin_lock_init(&serio->lock);
|
||||
init_MUTEX(&serio->drv_sem);
|
||||
mutex_init(&serio->drv_mutex);
|
||||
device_initialize(&serio->dev);
|
||||
snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id),
|
||||
"serio%ld", (long)atomic_inc_return(&serio_no) - 1);
|
||||
@ -661,10 +663,10 @@ void __serio_register_port(struct serio *serio, struct module *owner)
|
||||
*/
|
||||
void serio_unregister_port(struct serio *serio)
|
||||
{
|
||||
down(&serio_sem);
|
||||
mutex_lock(&serio_mutex);
|
||||
serio_disconnect_port(serio);
|
||||
serio_destroy_port(serio);
|
||||
up(&serio_sem);
|
||||
mutex_unlock(&serio_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -672,17 +674,17 @@ void serio_unregister_port(struct serio *serio)
|
||||
*/
|
||||
void serio_unregister_child_port(struct serio *serio)
|
||||
{
|
||||
down(&serio_sem);
|
||||
mutex_lock(&serio_mutex);
|
||||
if (serio->child) {
|
||||
serio_disconnect_port(serio->child);
|
||||
serio_destroy_port(serio->child);
|
||||
}
|
||||
up(&serio_sem);
|
||||
mutex_unlock(&serio_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Submits register request to kseriod for subsequent execution.
|
||||
* Can be used when it is not obvious whether the serio_sem is
|
||||
* Can be used when it is not obvious whether the serio_mutex is
|
||||
* taken or not and when delayed execution is feasible.
|
||||
*/
|
||||
void __serio_unregister_port_delayed(struct serio *serio, struct module *owner)
|
||||
@ -765,7 +767,7 @@ void serio_unregister_driver(struct serio_driver *drv)
|
||||
{
|
||||
struct serio *serio;
|
||||
|
||||
down(&serio_sem);
|
||||
mutex_lock(&serio_mutex);
|
||||
drv->manual_bind = 1; /* so serio_find_driver ignores it */
|
||||
|
||||
start_over:
|
||||
@ -779,7 +781,7 @@ void serio_unregister_driver(struct serio_driver *drv)
|
||||
}
|
||||
|
||||
driver_unregister(&drv->driver);
|
||||
up(&serio_sem);
|
||||
mutex_unlock(&serio_mutex);
|
||||
}
|
||||
|
||||
static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
|
||||
@ -858,7 +860,7 @@ static int serio_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* called from serio_driver->connect/disconnect methods under serio_sem */
|
||||
/* called from serio_driver->connect/disconnect methods under serio_mutex */
|
||||
int serio_open(struct serio *serio, struct serio_driver *drv)
|
||||
{
|
||||
serio_set_drv(serio, drv);
|
||||
@ -870,7 +872,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* called from serio_driver->connect/disconnect methods under serio_sem */
|
||||
/* called from serio_driver->connect/disconnect methods under serio_mutex */
|
||||
void serio_close(struct serio *serio)
|
||||
{
|
||||
if (serio->close)
|
||||
@ -923,5 +925,5 @@ static void __exit serio_exit(void)
|
||||
kthread_stop(serio_task);
|
||||
}
|
||||
|
||||
module_init(serio_init);
|
||||
subsys_initcall(serio_init);
|
||||
module_exit(serio_exit);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define DRIVER_DESC "Raw serio driver"
|
||||
|
||||
@ -46,7 +47,7 @@ struct serio_raw_list {
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
static DECLARE_MUTEX(serio_raw_sem);
|
||||
static DEFINE_MUTEX(serio_raw_mutex);
|
||||
static LIST_HEAD(serio_raw_list);
|
||||
static unsigned int serio_raw_no;
|
||||
|
||||
@ -81,7 +82,7 @@ static int serio_raw_open(struct inode *inode, struct file *file)
|
||||
struct serio_raw_list *list;
|
||||
int retval = 0;
|
||||
|
||||
retval = down_interruptible(&serio_raw_sem);
|
||||
retval = mutex_lock_interruptible(&serio_raw_mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -95,12 +96,11 @@ static int serio_raw_open(struct inode *inode, struct file *file)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(list = kmalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
|
||||
if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
|
||||
retval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(list, 0, sizeof(struct serio_raw_list));
|
||||
list->serio_raw = serio_raw;
|
||||
file->private_data = list;
|
||||
|
||||
@ -108,7 +108,7 @@ static int serio_raw_open(struct inode *inode, struct file *file)
|
||||
list_add_tail(&list->node, &serio_raw->list);
|
||||
|
||||
out:
|
||||
up(&serio_raw_sem);
|
||||
mutex_unlock(&serio_raw_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -130,12 +130,12 @@ static int serio_raw_release(struct inode *inode, struct file *file)
|
||||
struct serio_raw_list *list = file->private_data;
|
||||
struct serio_raw *serio_raw = list->serio_raw;
|
||||
|
||||
down(&serio_raw_sem);
|
||||
mutex_lock(&serio_raw_mutex);
|
||||
|
||||
serio_raw_fasync(-1, file, 0);
|
||||
serio_raw_cleanup(serio_raw);
|
||||
|
||||
up(&serio_raw_sem);
|
||||
mutex_unlock(&serio_raw_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, siz
|
||||
int retval;
|
||||
unsigned char c;
|
||||
|
||||
retval = down_interruptible(&serio_raw_sem);
|
||||
retval = mutex_lock_interruptible(&serio_raw_mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@ -219,7 +219,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, siz
|
||||
};
|
||||
|
||||
out:
|
||||
up(&serio_raw_sem);
|
||||
mutex_unlock(&serio_raw_mutex);
|
||||
return written;
|
||||
}
|
||||
|
||||
@ -275,14 +275,13 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
|
||||
struct serio_raw *serio_raw;
|
||||
int err;
|
||||
|
||||
if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) {
|
||||
if (!(serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL))) {
|
||||
printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
down(&serio_raw_sem);
|
||||
mutex_lock(&serio_raw_mutex);
|
||||
|
||||
memset(serio_raw, 0, sizeof(struct serio_raw));
|
||||
snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++);
|
||||
serio_raw->refcnt = 1;
|
||||
serio_raw->serio = serio;
|
||||
@ -325,7 +324,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
|
||||
serio_set_drvdata(serio, NULL);
|
||||
kfree(serio_raw);
|
||||
out:
|
||||
up(&serio_raw_sem);
|
||||
mutex_unlock(&serio_raw_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -350,7 +349,7 @@ static void serio_raw_disconnect(struct serio *serio)
|
||||
{
|
||||
struct serio_raw *serio_raw;
|
||||
|
||||
down(&serio_raw_sem);
|
||||
mutex_lock(&serio_raw_mutex);
|
||||
|
||||
serio_raw = serio_get_drvdata(serio);
|
||||
|
||||
@ -361,7 +360,7 @@ static void serio_raw_disconnect(struct serio *serio)
|
||||
if (!serio_raw_cleanup(serio_raw))
|
||||
wake_up_interruptible(&serio_raw->wait);
|
||||
|
||||
up(&serio_raw_sem);
|
||||
mutex_unlock(&serio_raw_mutex);
|
||||
}
|
||||
|
||||
static struct serio_device_id serio_raw_serio_ids[] = {
|
||||
|
@ -157,9 +157,8 @@ static int tsdev_open(struct inode *inode, struct file *file)
|
||||
if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
|
||||
return -ENODEV;
|
||||
|
||||
if (!(list = kmalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
|
||||
if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
memset(list, 0, sizeof(struct tsdev_list));
|
||||
|
||||
list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0;
|
||||
|
||||
@ -379,9 +378,8 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(tsdev = kmalloc(sizeof(struct tsdev), GFP_KERNEL)))
|
||||
if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL)))
|
||||
return NULL;
|
||||
memset(tsdev, 0, sizeof(struct tsdev));
|
||||
|
||||
INIT_LIST_HEAD(&tsdev->list);
|
||||
init_waitqueue_head(&tsdev->wait);
|
||||
|
@ -510,7 +510,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||
case 0x025: map_key_clear(KEY_TV); break;
|
||||
case 0x026: map_key_clear(KEY_MENU); break;
|
||||
case 0x031: map_key_clear(KEY_AUDIO); break;
|
||||
case 0x032: map_key_clear(KEY_SUBTITLE); break;
|
||||
case 0x032: map_key_clear(KEY_TEXT); break;
|
||||
case 0x033: map_key_clear(KEY_LAST); break;
|
||||
case 0x047: map_key_clear(KEY_MP3); break;
|
||||
case 0x048: map_key_clear(KEY_DVD); break;
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
@ -40,7 +41,7 @@ struct gameport {
|
||||
struct gameport *parent, *child;
|
||||
|
||||
struct gameport_driver *drv;
|
||||
struct semaphore drv_sem; /* protects serio->drv so attributes can pin driver */
|
||||
struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
|
||||
|
||||
struct device dev;
|
||||
unsigned int registered; /* port has been fully registered with driver core */
|
||||
@ -137,12 +138,12 @@ static inline void gameport_set_drvdata(struct gameport *gameport, void *data)
|
||||
*/
|
||||
static inline int gameport_pin_driver(struct gameport *gameport)
|
||||
{
|
||||
return down_interruptible(&gameport->drv_sem);
|
||||
return mutex_lock_interruptible(&gameport->drv_mutex);
|
||||
}
|
||||
|
||||
static inline void gameport_unpin_driver(struct gameport *gameport)
|
||||
{
|
||||
up(&gameport->drv_sem);
|
||||
mutex_unlock(&gameport->drv_mutex);
|
||||
}
|
||||
|
||||
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner);
|
||||
|
@ -512,6 +512,15 @@ struct input_absinfo {
|
||||
#define KEY_FN_S 0x1e3
|
||||
#define KEY_FN_B 0x1e4
|
||||
|
||||
#define KEY_BRL_DOT1 0x1f1
|
||||
#define KEY_BRL_DOT2 0x1f2
|
||||
#define KEY_BRL_DOT3 0x1f3
|
||||
#define KEY_BRL_DOT4 0x1f4
|
||||
#define KEY_BRL_DOT5 0x1f5
|
||||
#define KEY_BRL_DOT6 0x1f6
|
||||
#define KEY_BRL_DOT7 0x1f7
|
||||
#define KEY_BRL_DOT8 0x1f8
|
||||
|
||||
/* We avoid low common keys in module aliases so they don't get huge. */
|
||||
#define KEY_MIN_INTERESTING KEY_MUTE
|
||||
#define KEY_MAX 0x1ff
|
||||
@ -929,7 +938,7 @@ struct input_dev {
|
||||
|
||||
struct input_handle *grab;
|
||||
|
||||
struct semaphore sem; /* serializes open and close operations */
|
||||
struct mutex mutex; /* serializes open and close operations */
|
||||
unsigned int users;
|
||||
|
||||
struct class_device cdev;
|
||||
@ -995,11 +1004,6 @@ static inline void init_input_dev(struct input_dev *dev)
|
||||
|
||||
struct input_dev *input_allocate_device(void);
|
||||
|
||||
static inline void input_free_device(struct input_dev *dev)
|
||||
{
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
static inline struct input_dev *input_get_device(struct input_dev *dev)
|
||||
{
|
||||
return to_input_dev(class_device_get(&dev->cdev));
|
||||
@ -1010,6 +1014,11 @@ static inline void input_put_device(struct input_dev *dev)
|
||||
class_device_put(&dev->cdev);
|
||||
}
|
||||
|
||||
static inline void input_free_device(struct input_dev *dev)
|
||||
{
|
||||
input_put_device(dev);
|
||||
}
|
||||
|
||||
int input_register_device(struct input_dev *);
|
||||
void input_unregister_device(struct input_dev *);
|
||||
|
||||
|
@ -135,6 +135,8 @@ static inline void chg_vc_kbd_led(struct kbd_struct * kbd, int flag)
|
||||
|
||||
#define U(x) ((x) ^ 0xf000)
|
||||
|
||||
#define BRL_UC_ROW 0x2800
|
||||
|
||||
/* keyboard.c */
|
||||
|
||||
struct console;
|
||||
|
@ -44,6 +44,7 @@ extern unsigned short plain_map[NR_KEYS];
|
||||
#define KT_ASCII 9
|
||||
#define KT_LOCK 10
|
||||
#define KT_SLOCK 12
|
||||
#define KT_BRL 14
|
||||
|
||||
#define K(t,v) (((t)<<8)|(v))
|
||||
#define KTYP(x) ((x) >> 8)
|
||||
@ -427,5 +428,17 @@ extern unsigned short plain_map[NR_KEYS];
|
||||
|
||||
#define NR_LOCK 8
|
||||
|
||||
#define K_BRL_BLANK K(KT_BRL, 0)
|
||||
#define K_BRL_DOT1 K(KT_BRL, 1)
|
||||
#define K_BRL_DOT2 K(KT_BRL, 2)
|
||||
#define K_BRL_DOT3 K(KT_BRL, 3)
|
||||
#define K_BRL_DOT4 K(KT_BRL, 4)
|
||||
#define K_BRL_DOT5 K(KT_BRL, 5)
|
||||
#define K_BRL_DOT6 K(KT_BRL, 6)
|
||||
#define K_BRL_DOT7 K(KT_BRL, 7)
|
||||
#define K_BRL_DOT8 K(KT_BRL, 8)
|
||||
|
||||
#define NR_BRL 9
|
||||
|
||||
#define MAX_DIACR 256
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@ struct ps2dev {
|
||||
struct serio *serio;
|
||||
|
||||
/* Ensures that only one command is executing at a time */
|
||||
struct semaphore cmd_sem;
|
||||
struct mutex cmd_mutex;
|
||||
|
||||
/* Used to signal completion from interrupt handler */
|
||||
wait_queue_head_t wait;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
||||
@ -42,7 +43,7 @@ struct serio {
|
||||
struct serio *parent, *child;
|
||||
|
||||
struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */
|
||||
struct semaphore drv_sem; /* protects serio->drv so attributes can pin driver */
|
||||
struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
|
||||
|
||||
struct device dev;
|
||||
unsigned int registered; /* port has been fully registered with driver core */
|
||||
@ -151,17 +152,17 @@ static inline void serio_continue_rx(struct serio *serio)
|
||||
*/
|
||||
static inline int serio_pin_driver(struct serio *serio)
|
||||
{
|
||||
return down_interruptible(&serio->drv_sem);
|
||||
return mutex_lock_interruptible(&serio->drv_mutex);
|
||||
}
|
||||
|
||||
static inline void serio_pin_driver_uninterruptible(struct serio *serio)
|
||||
{
|
||||
down(&serio->drv_sem);
|
||||
mutex_lock(&serio->drv_mutex);
|
||||
}
|
||||
|
||||
static inline void serio_unpin_driver(struct serio *serio)
|
||||
{
|
||||
up(&serio->drv_sem);
|
||||
mutex_unlock(&serio->drv_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ struct uinput_request {
|
||||
|
||||
struct uinput_device {
|
||||
struct input_dev *dev;
|
||||
struct semaphore sem;
|
||||
struct mutex mutex;
|
||||
enum uinput_state state;
|
||||
wait_queue_head_t waitq;
|
||||
unsigned char ready;
|
||||
|
Loading…
Reference in New Issue
Block a user