Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 58487
b: refs/heads/master
c: 9657d75
h: refs/heads/master
i:
  58485: d427cc2
  58483: 0e34e4b
  58479: b87e9ff
v: v3
  • Loading branch information
Dmitry Torokhov committed Jul 10, 2007
1 parent 02fee66 commit 1bc0511
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 310 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: d63219a10126b878abbbffdf4c5bcf29ef756b7f
refs/heads/master: 9657d75c5f0f7d0a9cb507521d3ad1436aea28c9
84 changes: 42 additions & 42 deletions trunk/drivers/input/evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct evdev {
wait_queue_head_t wait;
struct evdev_client *grab;
struct list_head client_list;
struct device dev;
};

struct evdev_client {
Expand Down Expand Up @@ -94,8 +95,10 @@ static int evdev_flush(struct file *file, fl_owner_t id)
return input_flush_device(&evdev->handle, file);
}

static void evdev_free(struct evdev *evdev)
static void evdev_free(struct device *dev)
{
struct evdev *evdev = container_of(dev, struct evdev, dev);

evdev_table[evdev->minor] = NULL;
kfree(evdev);
}
Expand All @@ -114,12 +117,10 @@ static int evdev_release(struct inode *inode, struct file *file)
list_del(&client->node);
kfree(client);

if (!--evdev->open) {
if (evdev->exist)
input_close_device(&evdev->handle);
else
evdev_free(evdev);
}
if (!--evdev->open && evdev->exist)
input_close_device(&evdev->handle);

put_device(&evdev->dev);

return 0;
}
Expand All @@ -139,24 +140,32 @@ static int evdev_open(struct inode *inode, struct file *file)
if (!evdev || !evdev->exist)
return -ENODEV;

get_device(&evdev->dev);

client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
if (!client)
return -ENOMEM;
if (!client) {
error = -ENOMEM;
goto err_put_evdev;
}

client->evdev = evdev;
list_add_tail(&client->node, &evdev->client_list);

if (!evdev->open++ && evdev->exist) {
error = input_open_device(&evdev->handle);
if (error) {
list_del(&client->node);
kfree(client);
return error;
}
if (error)
goto err_free_client;
}

file->private_data = client;
return 0;

err_free_client:
list_del(&client->node);
kfree(client);
err_put_evdev:
put_device(&evdev->dev);
return error;
}

#ifdef CONFIG_COMPAT
Expand Down Expand Up @@ -625,8 +634,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct evdev *evdev;
struct class_device *cdev;
dev_t devt;
int minor;
int error;

Expand All @@ -649,38 +656,32 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
evdev->handle.name = evdev->name;
evdev->handle.handler = handler;
evdev->handle.private = evdev;
sprintf(evdev->name, "event%d", minor);

evdev_table[minor] = evdev;
snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);

devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
"event%d", minor);
evdev->dev.class = &input_class;
evdev->dev.parent = &dev->dev;
evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
evdev->dev.release = evdev_free;
device_initialize(&evdev->dev);

cdev = class_device_create(&input_class, &dev->cdev, devt,
dev->cdev.dev, evdev->name);
if (IS_ERR(cdev)) {
error = PTR_ERR(cdev);
goto err_free_evdev;
}
evdev_table[minor] = evdev;

/* temporary symlink to keep userspace happy */
error = sysfs_create_link(&input_class.subsys.kobj,
&cdev->kobj, evdev->name);
error = device_add(&evdev->dev);
if (error)
goto err_cdev_destroy;
goto err_free_evdev;

error = input_register_handle(&evdev->handle);
if (error)
goto err_remove_link;
goto err_delete_evdev;

return 0;

err_remove_link:
sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
err_cdev_destroy:
class_device_destroy(&input_class, devt);
err_delete_evdev:
device_del(&evdev->dev);
err_free_evdev:
kfree(evdev);
evdev_table[minor] = NULL;
put_device(&evdev->dev);
return error;
}

Expand All @@ -690,10 +691,8 @@ static void evdev_disconnect(struct input_handle *handle)
struct evdev_client *client;

input_unregister_handle(handle);
device_del(&evdev->dev);

sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
class_device_destroy(&input_class,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
evdev->exist = 0;

if (evdev->open) {
Expand All @@ -702,8 +701,9 @@ static void evdev_disconnect(struct input_handle *handle)
list_for_each_entry(client, &evdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&evdev->wait);
} else
evdev_free(evdev);
}

put_device(&evdev->dev);
}

static const struct input_device_id evdev_ids[] = {
Expand Down
Loading

0 comments on commit 1bc0511

Please sign in to comment.