4 * by Artur Lipowski <alipowski@interia.pl>
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.
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.
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
29 #include "rc-core-priv.h"
30 #include <media/lirc.h>
31 #include <media/lirc_dev.h>
33 #define LOGHEAD "lirc_dev (%s[%d]): "
35 static dev_t lirc_base_dev;
37 /* Used to keep track of allocated lirc devices */
38 #define LIRC_MAX_DEVICES 256
39 static DEFINE_IDA(lirc_ida);
41 /* Only used for sysfs but defined to void otherwise */
42 static struct class *lirc_class;
44 static void lirc_release_device(struct device *ld)
46 struct lirc_dev *d = container_of(ld, struct lirc_dev, dev);
47 struct rc_dev *rcdev = d->rdev;
49 if (rcdev->driver_type == RC_DRIVER_IR_RAW)
50 kfifo_free(&rcdev->rawir);
53 module_put(THIS_MODULE);
54 put_device(d->dev.parent);
58 lirc_allocate_device(void)
62 d = kzalloc(sizeof(*d), GFP_KERNEL);
64 device_initialize(&d->dev);
65 d->dev.class = lirc_class;
66 d->dev.release = lirc_release_device;
67 __module_get(THIS_MODULE);
72 EXPORT_SYMBOL(lirc_allocate_device);
74 void lirc_free_device(struct lirc_dev *d)
81 EXPORT_SYMBOL(lirc_free_device);
83 int lirc_register_device(struct lirc_dev *d)
85 struct rc_dev *rcdev = d->rdev;
90 pr_err("driver pointer must be not NULL!\n");
95 pr_err("dev parent pointer not filled in!\n");
100 pr_err("fops pointer not filled in!\n");
104 /* some safety check 8-) */
105 d->name[sizeof(d->name) - 1] = '\0';
107 if (rcdev->driver_type == RC_DRIVER_IR_RAW) {
108 if (kfifo_alloc(&rcdev->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL))
112 init_waitqueue_head(&rcdev->wait_poll);
114 minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
119 d->dev.devt = MKDEV(MAJOR(lirc_base_dev), d->minor);
120 dev_set_name(&d->dev, "lirc%d", d->minor);
122 cdev_init(&d->cdev, d->fops);
123 d->cdev.owner = d->owner;
125 err = cdev_device_add(&d->cdev, &d->dev);
127 ida_simple_remove(&lirc_ida, minor);
131 get_device(d->dev.parent);
133 dev_info(&d->dev, "lirc_dev: driver %s registered at minor = %d\n",
138 EXPORT_SYMBOL(lirc_register_device);
140 void lirc_unregister_device(struct lirc_dev *d)
142 struct rc_dev *rcdev;
149 dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
152 mutex_lock(&rcdev->lock);
154 if (rcdev->lirc_open) {
155 dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
157 wake_up_poll(&rcdev->wait_poll, POLLHUP);
160 mutex_unlock(&rcdev->lock);
162 cdev_device_del(&d->cdev, &d->dev);
163 ida_simple_remove(&lirc_ida, d->minor);
166 EXPORT_SYMBOL(lirc_unregister_device);
168 int __init lirc_dev_init(void)
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);
178 retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
181 class_destroy(lirc_class);
182 pr_err("alloc_chrdev_region failed\n");
186 pr_info("IR Remote Control driver registered, major %d\n",
187 MAJOR(lirc_base_dev));
192 void __exit lirc_dev_exit(void)
194 class_destroy(lirc_class);
195 unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);