32124fb5c88e722c4f0fb011d9864888a4d26cac
[linux-2.6-block.git] / drivers / media / rc / lirc_dev.c
1 /*
2  * LIRC base driver
3  *
4  * by Artur Lipowski <alipowski@interia.pl>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  */
17
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
20 #include <linux/module.h>
21 #include <linux/sched/signal.h>
22 #include <linux/ioctl.h>
23 #include <linux/poll.h>
24 #include <linux/mutex.h>
25 #include <linux/device.h>
26 #include <linux/cdev.h>
27 #include <linux/idr.h>
28
29 #include "rc-core-priv.h"
30 #include <media/lirc.h>
31 #include <media/lirc_dev.h>
32
33 #define LOGHEAD         "lirc_dev (%s[%d]): "
34
35 static dev_t lirc_base_dev;
36
37 /* Used to keep track of allocated lirc devices */
38 #define LIRC_MAX_DEVICES 256
39 static DEFINE_IDA(lirc_ida);
40
41 /* Only used for sysfs but defined to void otherwise */
42 static struct class *lirc_class;
43
44 static void lirc_release_device(struct device *ld)
45 {
46         struct lirc_dev *d = container_of(ld, struct lirc_dev, dev);
47         struct rc_dev *rcdev = d->rdev;
48
49         if (rcdev->driver_type == RC_DRIVER_IR_RAW)
50                 kfifo_free(&rcdev->rawir);
51
52         kfree(d);
53         module_put(THIS_MODULE);
54         put_device(d->dev.parent);
55 }
56
57 struct lirc_dev *
58 lirc_allocate_device(void)
59 {
60         struct lirc_dev *d;
61
62         d = kzalloc(sizeof(*d), GFP_KERNEL);
63         if (d) {
64                 device_initialize(&d->dev);
65                 d->dev.class = lirc_class;
66                 d->dev.release = lirc_release_device;
67                 __module_get(THIS_MODULE);
68         }
69
70         return d;
71 }
72 EXPORT_SYMBOL(lirc_allocate_device);
73
74 void lirc_free_device(struct lirc_dev *d)
75 {
76         if (!d)
77                 return;
78
79         put_device(&d->dev);
80 }
81 EXPORT_SYMBOL(lirc_free_device);
82
83 int lirc_register_device(struct lirc_dev *d)
84 {
85         struct rc_dev *rcdev = d->rdev;
86         int minor;
87         int err;
88
89         if (!d) {
90                 pr_err("driver pointer must be not NULL!\n");
91                 return -EBADRQC;
92         }
93
94         if (!d->dev.parent) {
95                 pr_err("dev parent pointer not filled in!\n");
96                 return -EINVAL;
97         }
98
99         if (!d->fops) {
100                 pr_err("fops pointer not filled in!\n");
101                 return -EINVAL;
102         }
103
104         /* some safety check 8-) */
105         d->name[sizeof(d->name) - 1] = '\0';
106
107         if (rcdev->driver_type == RC_DRIVER_IR_RAW) {
108                 if (kfifo_alloc(&rcdev->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL))
109                         return -ENOMEM;
110         }
111
112         init_waitqueue_head(&rcdev->wait_poll);
113
114         minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
115         if (minor < 0)
116                 return minor;
117
118         d->minor = minor;
119         d->dev.devt = MKDEV(MAJOR(lirc_base_dev), d->minor);
120         dev_set_name(&d->dev, "lirc%d", d->minor);
121
122         cdev_init(&d->cdev, d->fops);
123         d->cdev.owner = d->owner;
124
125         err = cdev_device_add(&d->cdev, &d->dev);
126         if (err) {
127                 ida_simple_remove(&lirc_ida, minor);
128                 return err;
129         }
130
131         get_device(d->dev.parent);
132
133         dev_info(&d->dev, "lirc_dev: driver %s registered at minor = %d\n",
134                  d->name, d->minor);
135
136         return 0;
137 }
138 EXPORT_SYMBOL(lirc_register_device);
139
140 void lirc_unregister_device(struct lirc_dev *d)
141 {
142         struct rc_dev *rcdev;
143
144         if (!d)
145                 return;
146
147         rcdev = d->rdev;
148
149         dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
150                 d->name, d->minor);
151
152         mutex_lock(&rcdev->lock);
153
154         if (rcdev->lirc_open) {
155                 dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
156                         d->name, d->minor);
157                 wake_up_poll(&rcdev->wait_poll, POLLHUP);
158         }
159
160         mutex_unlock(&rcdev->lock);
161
162         cdev_device_del(&d->cdev, &d->dev);
163         ida_simple_remove(&lirc_ida, d->minor);
164         put_device(&d->dev);
165 }
166 EXPORT_SYMBOL(lirc_unregister_device);
167
168 int __init lirc_dev_init(void)
169 {
170         int retval;
171
172         lirc_class = class_create(THIS_MODULE, "lirc");
173         if (IS_ERR(lirc_class)) {
174                 pr_err("class_create failed\n");
175                 return PTR_ERR(lirc_class);
176         }
177
178         retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
179                                      "BaseRemoteCtl");
180         if (retval) {
181                 class_destroy(lirc_class);
182                 pr_err("alloc_chrdev_region failed\n");
183                 return retval;
184         }
185
186         pr_info("IR Remote Control driver registered, major %d\n",
187                                                 MAJOR(lirc_base_dev));
188
189         return 0;
190 }
191
192 void __exit lirc_dev_exit(void)
193 {
194         class_destroy(lirc_class);
195         unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);
196 }