Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 14554
b: refs/heads/master
c: 252ec9e
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Nov 20, 2005
1 parent 9eca134 commit 8e5ca20
Show file tree
Hide file tree
Showing 13 changed files with 882 additions and 228 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1e6b39fbb61800e3ecee58dc8c4bca57c89365cd
refs/heads/master: 252ec9e28f0cf350e246c065ffe70a2e32b84ad4
5 changes: 5 additions & 0 deletions trunk/MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2907,6 +2907,11 @@ M: zaga@fly.cc.fer.hr
L: linux-scsi@vger.kernel.org
S: Maintained

WISTRON LAPTOP BUTTON DRIVER
P: Miloslav Trmac
M: mitr@volny.cz
S: Maintained

WL3501 WIRELESS PCMCIA CARD DRIVER
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
Expand Down
12 changes: 9 additions & 3 deletions trunk/drivers/input/gameport/gameport.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,20 @@ static struct gameport_event *gameport_get_event(void)
return event;
}

static void gameport_handle_events(void)
static void gameport_handle_event(void)
{
struct gameport_event *event;
struct gameport_driver *gameport_drv;

down(&gameport_sem);

while ((event = gameport_get_event())) {
/*
* Note that we handle only one event here to give swsusp
* a chance to freeze kgameportd thread. Gameport events
* should be pretty rare so we are not concerned about
* taking performance hit.
*/
if ((event = gameport_get_event())) {

switch (event->type) {
case GAMEPORT_REGISTER_PORT:
Expand Down Expand Up @@ -433,7 +439,7 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
static int gameport_thread(void *nothing)
{
do {
gameport_handle_events();
gameport_handle_event();
wait_event_interruptible(gameport_wait,
kthread_should_stop() || !list_empty(&gameport_event_list));
try_to_freeze();
Expand Down
63 changes: 36 additions & 27 deletions trunk/drivers/input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ static struct attribute *input_dev_attrs[] = {
NULL
};

static struct attribute_group input_dev_group = {
static struct attribute_group input_dev_attr_group = {
.attrs = input_dev_attrs,
};

Expand Down Expand Up @@ -717,35 +717,14 @@ struct input_dev *input_allocate_device(void)
return dev;
}

static void input_register_classdevice(struct input_dev *dev)
{
static atomic_t input_no = ATOMIC_INIT(0);
const char *path;

__module_get(THIS_MODULE);

dev->dev = dev->cdev.dev;

snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);

path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s as %s/%s\n",
dev->name ? dev->name : "Unspecified device",
path ? path : "", dev->cdev.class_id);
kfree(path);

class_device_add(&dev->cdev);
sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
}

int input_register_device(struct input_dev *dev)
{
static atomic_t input_no = ATOMIC_INIT(0);
struct input_handle *handle;
struct input_handler *handler;
struct input_device_id *id;
const char *path;
int error;

if (!dev->dynalloc) {
printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
Expand Down Expand Up @@ -773,7 +752,32 @@ int input_register_device(struct input_dev *dev)
INIT_LIST_HEAD(&dev->h_list);
list_add_tail(&dev->node, &input_dev_list);

input_register_classdevice(dev);
dev->cdev.class = &input_class;
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);

error = class_device_add(&dev->cdev);
if (error)
return error;

error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group);
if (error)
goto fail1;

error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
if (error)
goto fail2;

error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
if (error)
goto fail3;

__module_get(THIS_MODULE);

path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s as %s\n",
dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
kfree(path);

list_for_each_entry(handler, &input_handler_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
Expand All @@ -784,6 +788,11 @@ int input_register_device(struct input_dev *dev)
input_wakeup_procfs_readers();

return 0;

fail3: sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
fail2: sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
fail1: class_device_del(&dev->cdev);
return error;
}

void input_unregister_device(struct input_dev *dev)
Expand All @@ -805,7 +814,7 @@ void input_unregister_device(struct input_dev *dev)

sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
class_device_unregister(&dev->cdev);

input_wakeup_procfs_readers();
Expand Down
99 changes: 68 additions & 31 deletions trunk/drivers/input/keyboard/atkbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ static unsigned char atkbd_unxlate_table[128] = {

#define ATKBD_SPECIAL 248

#define ATKBD_LED_EVENT_BIT 0
#define ATKBD_REP_EVENT_BIT 1

static struct {
unsigned char keycode;
unsigned char set2;
Expand Down Expand Up @@ -211,6 +214,10 @@ struct atkbd {
unsigned char err_xl;
unsigned int last;
unsigned long time;

struct work_struct event_work;
struct semaphore event_sem;
unsigned long event_mask;
};

static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
Expand Down Expand Up @@ -424,58 +431,86 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
}

/*
* Event callback from the input module. Events that change the state of
* the hardware are processed here.
* atkbd_event_work() is used to complete processing of events that
* can not be processed by input_event() which is often called from
* interrupt context.
*/

static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
static void atkbd_event_work(void *data)
{
struct atkbd *atkbd = dev->private;
const short period[32] =
{ 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125,
133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
const short delay[4] =
{ 250, 500, 750, 1000 };

struct atkbd *atkbd = data;
struct input_dev *dev = atkbd->dev;
unsigned char param[2];
int i, j;

down(&atkbd->event_sem);

if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) {
param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
| (test_bit(LED_NUML, dev->led) ? 2 : 0)
| (test_bit(LED_CAPSL, dev->led) ? 4 : 0);
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);

if (atkbd->extra) {
param[0] = 0;
param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
| (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0)
| (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
| (test_bit(LED_MISC, dev->led) ? 0x10 : 0)
| (test_bit(LED_MUTE, dev->led) ? 0x20 : 0);
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
}
}

if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) {
i = j = 0;
while (i < 31 && period[i] < dev->rep[REP_PERIOD])
i++;
while (j < 3 && delay[j] < dev->rep[REP_DELAY])
j++;
dev->rep[REP_PERIOD] = period[i];
dev->rep[REP_DELAY] = delay[j];
param[0] = i | (j << 5);
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
}

up(&atkbd->event_sem);
}

/*
* Event callback from the input module. Events that change the state of
* the hardware are processed here. If action can not be performed in
* interrupt context it is offloaded to atkbd_event_work.
*/

static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct atkbd *atkbd = dev->private;

if (!atkbd->write)
return -1;

switch (type) {

case EV_LED:

param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
| (test_bit(LED_NUML, dev->led) ? 2 : 0)
| (test_bit(LED_CAPSL, dev->led) ? 4 : 0);
ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);

if (atkbd->extra) {
param[0] = 0;
param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
| (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0)
| (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
| (test_bit(LED_MISC, dev->led) ? 0x10 : 0)
| (test_bit(LED_MUTE, dev->led) ? 0x20 : 0);
ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
}

set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask);
wmb();
schedule_work(&atkbd->event_work);
return 0;

case EV_REP:

if (atkbd->softrepeat) return 0;

i = j = 0;
while (i < 31 && period[i] < dev->rep[REP_PERIOD])
i++;
while (j < 3 && delay[j] < dev->rep[REP_DELAY])
j++;
dev->rep[REP_PERIOD] = period[i];
dev->rep[REP_DELAY] = delay[j];
param[0] = i | (j << 5);
ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
if (!atkbd->softrepeat) {
set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask);
wmb();
schedule_work(&atkbd->event_work);
}

return 0;
}
Expand Down Expand Up @@ -810,6 +845,8 @@ 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);

switch (serio->id.type) {

Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/input/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ config INPUT_M68K_BEEP
tristate "M68k Beeper support"
depends on M68K

config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface"
depends on X86 && !X86_64
help
Say Y here for support of Winstron laptop button interface, used on
laptops of various brands, including Acer and Fujitsu-Siemens.

To compile this driver as a module, choose M here: the module will
be called wistron_btns.

config INPUT_UINPUT
tristate "User level driver support"
help
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/input/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
Loading

0 comments on commit 8e5ca20

Please sign in to comment.